基于Stochastic指标和CCI指标的趋势跟踪策略


创建日期: 2023-11-22 16:23:31 最后修改: 2023-11-22 16:23:31
复制: 1 点击次数: 844
avatar of ChaoZhang ChaoZhang
1
关注
1617
关注者

基于Stochastic指标和CCI指标的趋势跟踪策略

概述

该策略结合了Stochastic指标和CCI指标,以识别趋势方向,利用Rate of Change指标过滤掉震荡趋势,实现对趋势的跟踪。策略采用突破入场,止损出场的交易方式。

策略原理

  1. Stochastic指标判断多空形态
    当Stochastic指标上穿其最近一个bar时为买入信号,下穿其最近一个bar时为卖出信号
  2. CCI指标判断趋势方向
    CCI大于0为多头市场,小于0为空头市场
  3. Rate of Change指标过滤震荡趋势
    设置Rate of Change的参数,判断价格是否处于活跃的趋势中
  4. 入场和出场规则
    买入信号:Stochastic上穿最近一个bar且CCI大于0且价格趋势活跃
    卖出信号:Stochastic下穿最近一个bar且CCI小于0且价格趋势活跃
    止损 exit: 长线 3% 止损,短线 3% 止损

优势分析

  1. 结合Stochastic指标和CCI指标判断趋势方向,精确率较高
  2. Rate of Change指标可有效滤掉震荡趋势,避免无效交易
  3. 多空双向交易,可捕捉不同类型的趋势
  4. 突破入场追趋势,及时把握趋势机会
  5. 严格止损规避重大损失,有效控制风险

风险分析

  1. 策略参数设置不当可能导致过于保守或激进
  2. 指标作用有限,极端行情下可能失效
  3. 突破入场会略过趋势初期,部分利润被切割
  4. 止损过小容易被突破,过大则风险控制不当

优化方向

  1. 参数优化。改进参数设置,寻找最优参数组合
  2. 多标配合。加入更多判断趋势的指标,提高决策效果
  3. 积极止损。设置追踪止损或时间步移止损,减少止损被突破概率
  4. 风险评估。加入最大回撤等风险指标约束,全面控制风险敞口

总结

该策略整合 Stochastic、CCI 和 Rate of Change 三大指标判断趋势方向,以突破追踪的方式把握趋势机会。策略优势在于指标搭配判断准确,有效过滤震荡行情,通过严格的止损控制风险。下一步可从参数优化、多标配合、止损策略等方面进行改进,使策略更稳健、灵活。

策略源码
/*backtest
start: 2022-11-15 00:00:00
end: 2023-11-21 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("Stochastic CCI BF 🚀", overlay=false, 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 ///////////////
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

///////////// CCI ///////////// 
src = close
ccilength = input(13, minval=1, title="CCI Length")
c=cci(src, ccilength)

///////////// Stochastic ///////////// 
len = input(19, minval=1, title="RSI Length")
lenema = input(12, minval=1, title="RSI-EMA Length")
up = rma(max(change(src), 0), len)
down = rma(-min(change(src), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
out = ema(rsi, lenema)

///////////// Rate Of Change ///////////// 
source = close
roclength = input(30, minval=1)
pcntChange = input(7.0, 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 = out > out[1] and isMoving() and c > 0
short = out < out[1] and isMoving() and c < 0

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])

sl_inp = input(3.0, title='Stop Loss %') / 100 

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

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_signal)
    strategy.entry("S", strategy.short, when=short_signal)
    strategy.exit("L Ex", "L", stop=long_sl, when=since_longEntry > 0)
    strategy.exit("S Ex", "S", stop=short_sl, when=since_shortEntry > 0)

/////////////// Plotting /////////////// 
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)
bgcolor(not isMoving() ? color.white : long ? color.lime : short ? color.red : na, transp=80)
plot(out, color = out > out[1] ? color.lime:color.red, linewidth = 2, title="Stoch")
plot(c, color = c > 0 ? color.lime:color.red, linewidth = 2, title="CCI")