螺旋上升突破均线策略


创建日期: 2024-01-15 11:45:23 最后修改: 2024-01-15 11:45:23
复制: 0 点击次数: 353
avatar of ChaoZhang ChaoZhang
1
关注
1243
关注者

螺旋上升突破均线策略

概述

该策略综合应用了螺旋通道指标和差速率指标,当价格突破上轨线和均线时产生买入信号。同理,当价格突破下轨线和均线时,产生卖出信号。该策略通过螺旋通道来判断价格的趋势方向,并利用差速率指标来检测价格动能,在两个指标同时确认的基础上产生交易信号,从而取得较好的胜率。

策略原理

该策略主要基于两个指标:

  1. 螺旋通道(Spiral Channels):计算上下轨线,用来判断价格的趋势方向。当价格突破上轨时看涨,突破下轨时看跌。

  2. 差速率指标(ROC):检测价格是否在加速,用来判断价格动能。 ROC大于某个正值时表示价格在上涨加速,小于某个负值时表示价格在下跌加速。

在螺旋通道和差速率指标同时发出多头信号时产生买入信号。也就是价格要同时突破上轨和显示出上涨加速的迹象。产生卖出信号的逻辑也是类似的。

这样的组合可以提高信号的可靠性,避免在没有明确趋势的情况下盲目交易。

策略优势

  1. 综合判断价格趋势和动能,信号较为可靠,胜率较高。

  2. 通过参数优化,可以调整策略的交易频率。如调整差速率指标的参数,从而控制开仓的敏感度。

  3. 采用停损来控制单笔亏损。参数可自定义设置。

  4. 重新入场机制可以追踪趋势,进一步提升盈利能力。

策略风险

  1. 会漏掉部分交易机会,盈利能力受到一定限制。

  2. 突破型策略容易被套牢。当价格反转时,可能带来较大的亏损。

  3. 参数设置不当可能导致交易信号过于频繁或稀疏。

  4. 固定百分比的止损无法完全避免较大的单笔亏损的发生。

策略优化方向

  1. 对差速率指标的参数进行测试,找到最佳参数组合。

  2. 测试不同的止损水平,平衡盈亏比和胜率。

  3. 添加其他指标过滤,如量能指标、震荡指标等,提高信号质量。

  4. 测试不同的市场,寻找最匹配该策略的品种。

  5. 优化策略的仓位管理,不同市况下采用不同的仓位。

总结

该策略综合运用螺旋通道和差速率指标判断价格的趋势和动能,在确保交易信号质量的同时,通过重新入场以及参数优化来维持盈利的能力。风险控制以固定百分比的止损为主,可以做进一步优化。总的来说,该策略较完整,适合作为量化交易的基础框架。

策略源码
/*backtest
start: 2024-01-07 00:00:00
end: 2024-01-14 00:00:00
period: 45m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("SSL Chaikin BF 🚀", overlay=true, precision=2, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.075)

/////////////// Time Frame ///////////////
_0 = input(false,  "════════ Test Period ═══════")
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

testPeriod() => true

/////////////// Chaikin MF /////////////// 
_1 = input(false,  "═══════ Chaikin MF ═══════")
length = input(20, minval=1, title = "Chaikin SMA Length")
upperThreshold = input(0.04, step=0.01, title="Upper Threshold")
lowerThreshold = input(0.02, step=0.01, title="Lower Threshold")
ad = close==high and close==low or high==low ? 0 : ((2*close-low-high)/(high-low))*volume
mf = sum(ad, length) / sum(volume, length)

/////////////// SSL Channels /////////////// 
_2 = input(false,  "═════════ SSL ══════════")
len1=input(title="SMA Length 1", defval=12)
len2=input(title="SMA Length 2", defval=13)

smaHigh = sma(high, len1)
smaLow = sma(low, len2)

Hlv = 0
Hlv := close > smaHigh ? 1 : close < smaLow ? -1 : Hlv[1]
sslDown = Hlv < 0 ? smaHigh : smaLow
sslUp = Hlv < 0 ? smaLow : smaHigh

///////////// Rate Of Change ///////////// 
_3 = input(false,  "══════ Rate of Change ══════")
source = close
roclength = input(13, "ROC Length",  minval=1)
pcntChange = input(4, "ROC % Change", minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

///////////////  Strategy  /////////////// 
long = sslUp > sslDown and isMoving() or crossover(mf, upperThreshold)
short = sslUp < sslDown and isMoving() or crossunder(mf, lowerThreshold)

last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) 

//////////////// Stop loss /////////////// 
_4 = input(false,  "════════ Stop Loss ═══════")
sl_inp = input(2.0, title='Stop Loss %') / 100

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

/////////////// Execution /////////////// 
if testPeriod()
    strategy.entry("L", strategy.long, when=long)
    strategy.entry("S", strategy.short, when=short)
    strategy.exit("L SL", "L", stop=long_sl, when=since_longEntry > 0)
    strategy.exit("S SL", "S", stop=short_sl, when=since_shortEntry > 0)

/////////////// Plotting /////////////// 
p1 = plot(sslDown, linewidth = 1, color=color.red)
p2 = plot(sslUp, linewidth = 1, color=color.lime)
fill(p1, p2,  color = sslDown < sslUp ? color.lime : color.red, transp=80)
bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)
bgcolor(crossover(mf, upperThreshold) ? color.blue : crossunder(mf, lowerThreshold) ? color.orange : na, transp=30)