双MA顺势突破策略是一个利用两个不同周期的移动平均线进行趋势判断和入场的量化交易策略。策略主要通过慢速MA判断整体趋势方向,并利用快速MA进行入场过滤,在大级别趋势方向一致时,选择反转K线进行入场,以追求更高的胜率和盈利率。
该策略主要由以下几部分构成:
趋势判断: 通过计算21周期的MA,定义为慢速MA,其位置较为平稳,可用于判断整体趋势方向。当价格上涨时接近该MA值即为上升趋势,当价格下跌时接近该MA值即为下降趋势。
入场过滤: 计算5周期的MA,定义为快速MA。只有当价格突破慢速MA时,同时也突破快速MA,才产生交易信号。这个设计主要是进一步过滤假突破的可能性。
K线过滤: 策略只在该周期K线为阴线时做多,或该周期K线为阳线时做空。这是考虑到使用反转K线入场可获得更高的成功率。同时结合快速RSI指标避免在过度超买或超卖区域入场。
加仓过滤: 对于加密货币市场,策略额外增加了三倍波动突破的加仓条件,在大级别下跌过程中筛选出超跌机会。
止损设计: 策略支持移动止损。当开仓后,会根据设置的止损百分比实时更新止损位。
该策略具有以下优势:
该策略也存在一些风险:
针对这些风险,可从以下几个方面进行优化:
该策略主要可从以下几个方面进行优化:
参数优化:通过更系统的回测,优化快慢MA的周期参数组合,提高整体收益风险比。
模式识别:增加像KDJ,MACD等其他指标,识别更可靠的反转信号。
止损优化:开发浮动止损、追踪止损等算法,降低止损被触发概率。
机器学习:收集并标记更多历史数据,使用机器学习方法自动生成交易规则。
量化调仓:根据市场状态,自动调整仓位管理策略。
双MA顺势突破策略总体来说是一个比较简单实用的趋势跟踪策略。相比复杂的机器学习算法,该策略更容易解释和掌握,可靠性也较高。随着参数优化、功能扩展与机器学习引入,该策略具有很大的改进潜力,是量化交易的一个很好的起点。
/*backtest
start: 2023-12-31 00:00:00
end: 2024-01-07 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=2
strategy(title = "Noro's Trend MAs Strategy v2.0 +CB", shorttitle = "Trend MAs str 2.0", overlay=true, default_qty_type = strategy.percent_of_equity, default_qty_value=100.0, pyramiding=0)
//Settings
needlong = input(true, "long")
needshort = input(true, "short")
needstops = input(false, "stops")
stoppercent = input(5, defval = 5, minval = 1, maxval = 50, title = "Stop, %")
useohlc4 = input(false, defval = false, title = "Use OHLC4")
usefastsma = input(true, "Use fast MA Filter")
fastlen = input(5, defval = 5, minval = 1, maxval = 50, title = "fast MA Period")
slowlen = input(21, defval = 20, minval = 2, maxval = 200, title = "slow MA Period")
bars = input(2, defval = 2, minval = 0, maxval = 3, title = "Bars Q")
needbg = input(false, defval = false, title = "Need trend Background?")
needarr = input(false, defval = false, title = "Need entry arrows?")
needex = input(true, defval = true, title = "Need extreme? (crypto/fiat only!!!)")
src = useohlc4 == true ? ohlc4 : close
//PriceChannel 1
lasthigh = highest(src, slowlen)
lastlow = lowest(src, slowlen)
center = (lasthigh + lastlow) / 2
//PriceChannel 2
lasthigh2 = highest(src, fastlen)
lastlow2 = lowest(src, fastlen)
center2 = (lasthigh2 + lastlow2) / 2
//Trend
trend = low > center and low[1] > center[1] ? 1 : high < center and high[1] < center[1] ? -1 : trend[1]
//Bars
bar = close > open ? 1 : close < open ? -1 : 0
redbars = bars == 0 ? 1 : bars == 1 and bar == -1 ? 1 : bars == 2 and bar == -1 and bar[1] == -1 ? 1 : bars == 3 and bar == -1 and bar[1] == -1 and bar[2] == -1 ? 1 : 0
greenbars = bars == 0 ? 1 : bars == 1 and bar == 1 ? 1 : bars == 2 and bar == 1 and bar[1] == 1 ? 1 : bars == 3 and bar == 1 and bar[1] == 1 and bar[2] == 1 ? 1 : 0
//Fast RSI
fastup = rma(max(change(close), 0), 2)
fastdown = rma(-min(change(close), 0), 2)
fastrsi = fastdown == 0 ? 100 : fastup == 0 ? 0 : 100 - (100 / (1 + fastup / fastdown))
//CryptoBottom
mac = sma(close, 10)
len = abs(close - mac)
sma = sma(len, 100)
max = max(open, close)
min = min(open, close)
up3 = close < open and len > sma * 3 and min < min[1] and fastrsi < 10 ? 1 : 0
//Signals
up = trend == 1 and (low < center2 or usefastsma == false) and (redbars == 1) ? 1 : 0
dn = trend == -1 and (high > center2 or usefastsma == false) and (greenbars == 1) ? 1 : 0
up2 = high < center and high < center2 and bar == -1 ? 1 : 0
dn2 = low > center and low > center2 and bar == 1 ? 0 : 0
//Lines
plot(center, color = blue, linewidth = 3, transp = 0, title = "Slow MA")
plot(center2, color = red, linewidth = 3, transp = 0, title = "PriceChannel 2")
//Arrows
plotarrow(up == 1 and needarr == true ? 1 : 0, colorup = black, colordown = black, transp = 0)
plotarrow(dn == 1 and needarr == true ? -1 : 0, colorup = black, colordown = black, transp = 0)
//Background
col = needbg == false ? na : trend == 1 ? lime : red
bgcolor(col, transp = 90)
//Alerts
alertcondition(up == 1, title='buy', message='Uptrend')
alertcondition(dn == 1, title='sell', message='Downtrend')
//Trading
stoplong = up == 1 and needstops == true ? close - (close / 100 * stoppercent) : stoplong[1]
stopshort = dn == 1 and needstops == true ? close + (close / 100 * stoppercent) : stopshort[1]
longCondition = up == 1 or (up2 == 1 and needex == true) or up3 == 1
if (longCondition)
strategy.entry("Long", strategy.long, needlong == false ? 0 : na)
strategy.exit("Stop Long", "Long", stop = stoplong)
shortCondition = dn == 1
if (shortCondition)
strategy.entry("Short", strategy.short, needshort == false ? 0 : na)
strategy.exit("Stop Short", "Short", stop = stopshort)