
这个策略是一种基于农历日期的加密货币交易方法,通过利用农历周期的特定日期进行买入和卖出操作。该策略从农历新年开始,一直持续到当年阳历12月底,遵循简单的规则:在每个农历月的第5天买入,在每个农历月的第26天卖出。这种方法尝试捕捉可能与农历周期相关的市场模式,为交易者提供了一种结构化且易于遵循的交易框架。该策略考虑了手续费和滑点因素,并使用100%的可用资金进行投资,适用于2020年至2026年的时间范围。
该策略的核心原理是基于农历周期对加密货币市场可能存在的影响。代码通过以下方式实现这一理念:
策略使用精确的日期计算方法,通过数组存储每个农历月的天数,并累计计算从农历新年开始的总天数,从而准确定位当前的农历日期。这种方法保证了交易信号的准确触发。
分析该策略的代码,可以总结出以下优势:
尽管该策略具有上述优势,但也存在一些潜在风险:
为了降低这些风险,交易者可以考虑结合其他技术指标进行交易确认,或者设置固定止损位来限制单次交易的损失。
通过深入分析代码,可以提出以下几个优化方向:
引入止损机制:添加百分比或绝对金额的止损条件,在亏损达到特定阈值时自动平仓,避免大幅度的损失。优化代码可以增加类似if strategy.position_size > 0 and close < entry_price * (1 - stop_loss_percent)的条件判断。
融入技术指标确认:结合趋势指标(如移动平均线)或动量指标(如相对强弱指数RSI)作为辅助条件,只在技术指标提供有利信号时执行农历日期交易。这样可以提高信号质量。
优化买卖日期:通过历史数据回测,分析哪些农历日期对组合实际上提供了最佳的买入和卖出时机,而不是固定使用第5天和第26天。可能某些特定的日期组合表现更佳。
部分仓位管理:修改策略以使用部分资金而非100%资金进行交易,或根据市场波动性动态调整仓位大小,以分散风险。
添加市场状态过滤器:在极端市场条件下(如高波动性或明显的熊市趋势)暂停策略执行,避免在不利环境中交易。
拓展适用时间范围:增加更多年份的农历数据,或开发一个自动计算农历日期的函数,使策略可以无限期运行。
增加多品种交易:将策略扩展到多个加密货币或其他资产类别,观察农历周期在不同市场中的表现差异。
这些优化方向的实施可以显著提高策略的鲁棒性和适应性,同时保持其简单直观的核心理念。
基于农历周期的加密货币交易策略提供了一种独特的交易视角,利用特定的农历日期进行买入和卖出操作。该策略最大的优势在于其简单明确的规则和易于实施的特点,结合了农历周期这一独特因素,可能捕捉到常规技术分析所忽视的市场模式。
然而,该策略也面临缺乏风险管理和市场适应性的挑战。为了提高策略的有效性,建议引入止损机制、技术指标确认和优化买卖日期等改进措施。这些优化不仅可以减少潜在风险,还能增强策略在不同市场环境下的适应能力。
值得注意的是,任何交易策略都需要经过充分的回测和前向测试,以验证其在实际市场条件下的表现。交易者在采用该策略时,应根据自身风险承受能力和投资目标进行适当调整,并结合其他分析方法做出更全面的交易决策。
/*backtest
start: 2024-08-11 00:00:00
end: 2025-08-09 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
//@version=5
strategy("Lunar ETHUSDT Trading 100% Invest with Fee & Slippage (2020~2026)", overlay=true, commission_type=strategy.commission.percent, commission_value=0.1)
// Fee and slippage settings
feePercent = 0.1 // 0.1%
slippageTicks = 3
tickSize = syminfo.mintick
slippage = slippageTicks * tickSize
// Function for lunar new year start date and monthly lengths by year
f_get_lunar_data() =>
y = year(time)
if y == 2020
[timestamp("Asia/Seoul", 2020, 1, 25, 0, 0), array.from(29,30,29,30,29,30,29,30,29,30,30,29)]
else if y == 2021
[timestamp("Asia/Seoul", 2021, 2, 12, 0, 0), array.from(30,29,30,29,30,29,30,29,30,29,30,30)]
else if y == 2022
[timestamp("Asia/Seoul", 2022, 2, 1, 0, 0), array.from(29,30,29,30,29,30,29,30,30,29,30,29)]
else if y == 2023
[timestamp("Asia/Seoul", 2023, 1, 22, 0, 0), array.from(30,29,30,29,30,29,30,30,29,30,29,30)]
else if y == 2024
[timestamp("Asia/Seoul", 2024, 2, 10, 0, 0), array.from(30,29,30,29,30,29,30,29,30,29,30,30,29)]
else if y == 2025
[timestamp("Asia/Seoul", 2025, 1, 29, 0, 0), array.from(29,30,29,30,29,30,29,30,30,29,30,29)]
else if y == 2026
[timestamp("Asia/Seoul", 2026, 2, 17, 0, 0), array.from(30,29,30,29,30,29,30,30,29,30,29,30)]
else
[na, array.new_int()]
// Function to create cumulative monthly days array
f_get_lunar_md(days_arr) =>
arr = array.new_int()
sum = 0
for i = 0 to array.size(days_arr) - 1
sum += array.get(days_arr, i)
array.push(arr, sum)
arr
// Get lunar start date and monthly lengths
[ts_start, lunar_lengths] = f_get_lunar_data()
valid = not na(ts_start)
days_since = valid ? math.floor((time - ts_start) / 86400000) : na
cumulative = valid ? f_get_lunar_md(lunar_lengths) : na
// Declare lunar month, day, last day variables
var int lunar_month = na
var int lunar_day = na
var int lunar_last_day = na
// Calculate lunar date
if valid and not na(days_since) and days_since >= 0
lunar_month := na
lunar_day := na
lunar_last_day := na
for i = 0 to array.size(cumulative) - 1
cum = array.get(cumulative, i)
prev = i == 0 ? 0 : array.get(cumulative, i - 1)
if days_since < cum
lunar_month := i + 1
lunar_day := days_since - prev + 1
lunar_last_day := array.get(lunar_lengths, i)
break
else
lunar_month := na
lunar_day := na
lunar_last_day := na
// Buy condition: Lunar day 5 and no current position
buy_condition = not na(lunar_day) and lunar_day == 5 and strategy.position_size == 0
// Sell condition: Lunar day 26 and holding position
sell_condition = not na(lunar_day) and lunar_day == 26 and strategy.position_size > 0
// Buy/sell price adjusted for slippage and fee
price_buy = close + slippage
price_buy_with_fee = price_buy * (1 + feePercent * 0.01)
price_sell = close - slippage
price_sell_with_fee = price_sell * (1 - feePercent * 0.01)
// Calculate buy quantity using 100% of equity
qty = math.floor(strategy.equity / price_buy_with_fee)
// Buy order (limit)
if buy_condition and qty > 0
strategy.entry("Lunar Buy", strategy.long, qty, limit=price_buy)
// Sell order (close all)
if sell_condition and strategy.position_size > 0
strategy.close("Lunar Buy")
// True range variable (for label position adjustment)
tr = ta.tr(true)
// Date format creation
yr = year(time)
mo = month(time)
dy = dayofmonth(time)
mo_str = mo < 10 ? "0" + str.tostring(mo) : str.tostring(mo)
dy_str = dy < 10 ? "0" + str.tostring(dy) : str.tostring(dy)
solar_str = str.tostring(yr) + "-" + mo_str + "-" + dy_str
// Display solar and lunar date and position label (on bar close)
if barstate.islastconfirmedhistory and not na(lunar_day)
label.new(bar_index, high - tr * 6, "Solar: " + solar_str + "\nLunar: " + str.tostring(lunar_month) + "-" + str.tostring(lunar_day) ,
style=label.style_label_up, size=size.normal, color=color.new(color.teal, 50), textcolor=color.white)
// Display "15" label at bottom on lunar day 15 (lowest of last 50 bars - 1 true range)
if not na(lunar_day) and lunar_day == 15
low_offset = ta.lowest(low, 50) - tr
label.new(bar_index, low_offset, "15", style=label.style_label_down, color=color.orange, textcolor=color.white, size=size.normal)