该策略利用双移动平均线的交叉作为交易信号,结合ATR止损来进行趋势跟踪交易。其核心思想是当短期移动平均线上穿长期移动平均线时做多,下穿时做空,同时利用ATR来设置止损位, dynamically trailing stops.
该策略主要通过两组移动平均线来判断趋势方向。快速移动平均线长度为25天,慢速移动平均线长度为100天。当快速移动平均线上穿慢速移动平均线时产生买入信号;当快速移动平均线下穿慢速移动平均线时产生卖出信号。
为了过滤掉部分假信号,策略增加了一个交叉次数计数器crossCount。只有当快速移动平均线在lookback期间(默认25天)内交叉次数少于maxNoCross时(默认为10次),才会触发信号。
此外,策略还增加了一个确认机制,即在初始信号发出后,如果价格重新进入两条移动平均线之间,也会确认该信号。
在入场后,策略利用ATR指标来设定止损距离。ATR测量过去一定周期内的价格波动范围,这里用ATR的14倍来设置止损距离。止损线会随着价格走势进行浮动追踪。
该策略具有以下几点优势:
使用双移动平均线结合交叉滤波机制,可以有效过滤假信号,抓住较强势力的趋势。
增加确认机制,避免被假突破凋空。
利用ATR浮动追踪止损,可以最大限度锁住盈利,防止承担过大回撤。
方便优化的参数较少,容易实施。
可在多种市场中应用,包括数字货币和传统基础市场。
综合利用多种指标进行策略构建,使得策略较为稳健。
该策略主要存在以下风险:
在震荡盘整阶段,移动平均线交叉频繁,容易造成多次亏损。
ATR参数设置不当可能造成止损过于宽松或过于紧致。
大幅度跳空或Gap可能直接触发止损。
突发重大事件导致价格剧烈波动也可能直接止损。
移动平均线参数不合理可能导致错过趋势或产生太多假信号。
近期价格波动范围变化可能导致ATR止损距离不适应。
该策略可以从以下几个方面进行进一步优化:
对移动平均线参数进行优化,找到更合适的组合。可以测试不同周期参数及权重移动平均。
测试不同的ATR周期参数,找到更好的止损距离。
增加附加过滤条件,如交易量放大,震荡指标等,提高信号质量。
结合趋势判断指标,避免在震荡行情中被套。
增加机器学习算法,通过历史数据训练,自动优化参数组合。
在大级别图表中寻找更多确认,避免被短线噪音误导。
设定盈利头寸减仓规则,逐步锁定利润。
本策略整合运用双移动平均线交叉、趋势过滤、确认机制和ATR动态止损等多种技术指标。在参数优化和风险控制方面还有提升空间,但其交易思路简单清晰,容易实施复制,是一种较为稳健的趋势跟踪策略。
/*backtest start: 2023-10-02 00:00:00 end: 2023-11-01 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=3 strategy("QuantCat Intraday Strategy (15M)", overlay=true) //MA's for basic signals, can experiment with these values fastEMA = sma(close, 25) slowEMA = sma(close, 100) //Parameters for validation of position lookback_value = 25 maxNoCross=10 //value used for maximum number of crosses on a certain MA to mitigate noise and maximise value from trending markets //Amount of crosses on MA to filter out noise ema25_crossover = (cross(close, fastEMA)) == true ? 1 : 0 ema25_crossover_sum = sum(ema25_crossover, lookback_value) ///potentially change lookback value to alter results crossCount = (ema25_crossover_sum <= maxNoCross) //Entries long agrLong = ((crossover(fastEMA, slowEMA)) and (crossCount == true)) ? true : false consLong = ((close < fastEMA) and (close > slowEMA) and (fastEMA > slowEMA) and (crossCount == true)) ? true : false //Entries short agrShort = ((crossunder(fastEMA, slowEMA)) and (crossCount == true)) ? true : false consShort = ((close > fastEMA) and (close < slowEMA) and (fastEMA < slowEMA) and (crossCount == true)) ? true : false //ATR atrLkb = input(14, minval=1, title='ATR Stop Period') atrRes = input("15", title='ATR Resolution') atr = request.security(syminfo.tickerid, atrRes, atr(atrLkb)) //Strategy longCondition = ((agrLong or consLong) == true) if (longCondition) strategy.entry("Long", strategy.long) shortCondition = ((agrShort or consShort) == true) if (shortCondition) strategy.entry("Short", strategy.short) //Stop multiplier stopMult = 4 //horizontal stoplosses longStop = na longStop := shortCondition ? na : longCondition and strategy.position_size <=0 ? close - (atr * stopMult) : longStop[1] shortStop = na shortStop := longCondition ? na : shortCondition and strategy.position_size >=0 ? close + (atr * stopMult) : shortStop[1] //Strategy exit functions strategy.exit("Long ATR Stop", "Long", stop=longStop) strategy.exit("Short ATR Stop", "Short", stop=shortStop) //Plots redgreen = (fastEMA > slowEMA) ? green : red p1 = plot(fastEMA, title="Fast EMA", color=redgreen, linewidth=2) p2 = plot(slowEMA, title="Slow EMA", color=redgreen, linewidth=2) fill(p1, p2, color=redgreen) s1 = plot(longStop, style=linebr, color=red, linewidth=2, title='Long ATR Stop') s2 = plot(shortStop, style=linebr, color=red, linewidth=2, title='Short ATR Stop') fill(p2, s1, color=red, transp=95) fill(p2, s2, color=red, transp=95)