均线斜率交叉趋势跟踪策略

Author: ChaoZhang, Date: 2023-10-17 17:02:30
Tags:

均线斜率交叉趋势跟踪策略

概述

该策略利用两条不同长度的指数移动平均线(EMA)的斜率交叉来生成趋势跟踪信号。默认使用长度为130和400的EMA,这两个参数的组合效果很好。

当快线EMA斜率上穿慢线EMA斜率且价格高于200周期的EMA时做多;当快线EMA斜率下穿慢线EMA斜率且价格低于200周期的EMA时做空。

斜率方向相反交叉时平仓。

该策略在比特币和流动性强、市值大的Altcoin上表现最佳,但在波动性较大的资产上也运作良好,尤其是这些资产经常出现趋势行情时。

最适合4小时时间框架。

还配套了一个可选的波动率过滤器,仅当两条斜率之间的差值大于特定阈值时才开仓,目的是避免价格横盘震荡时噪音远大于信号时打开仓位。

效果惊人,请享用!

策略原理

该策略的核心是比较两条不同长度EMA指数移动平均线的斜率。

首先计算长度为130和400的EMA,然后计算各自的斜率,再对各自的斜率计算长度为3的EMA得到平滑后的斜率曲线。

当快线EMA斜率上穿慢线EMA斜率时产生买入信号;当快线EMA斜率下穿慢线EMA斜率时产生卖出信号。

为过滤震荡,可以选配200周期的EMA作为趋势过滤器,仅在价格高于该EMA时考虑做多信号,低于时考虑做空信号。

此外,还可以选配一个波动率过滤器,仅当两条斜率之间的差值大于预设阈值时才产生信号,从而过滤掉斜率交叉但波动率不足的情况。

当快慢斜率反向交叉时,平掉仓位停止盈亏。

优势分析

  1. 使用斜率交叉产生信号,可以有效跟踪趋势

  2. 调整EMA周期参数组合,可以适应不同的市场环境

  3. 趋势过滤器能避免被震荡行情误导

  4. 波动率过滤器可过滤假信号

  5. 规则简单清晰,容易理解实现

  6. 可在多个时间框架上使用

风险分析

  1. 大幅震荡行情中可能出现频繁 Open 和 Close

  2. EMA周期参数不当可能错过趋势转折点

  3. 须适当调整参数组合以适应市场环境变化

  4. 与 MA 系统类似,大趋势末尾可能反转损失

优化方向

  1. 尝试不同的 EMA 周期组合参数,寻找最佳参数

  2. 根据不同币种特性和市场环境选择参数

  3. 可以考虑加入止损策略控制风险

  4. 可以考虑动态调整 EMA 周期参数

  5. 尝试不同的波动率阈值参数

  6. 测试在不同时间框架上的效果

总结

该策略整体思路清晰易懂,利用 EMA 斜率交叉产生信号,可有效跟踪趋势;配套趋势过滤器和波动率过滤器可减少噪音交易。通过调整 EMA 周期参数组合可适应不同市场环境。总体来说是一种简单实用的趋势跟踪策略,值得在实盘中测试优化。


/*backtest
start: 2023-10-09 00:00:00
end: 2023-10-16 00:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// strategy(title="Slopes",initial_capital=1000, default_qty_type=strategy.percent_of_equity, commission_type=strategy.commission.percent, commission_value=0.06, slippage = 2, default_qty_value=30, overlay=false)

//definizione input

start = timestamp(input(2018, "start year"), input(1, "start month"), input(1, "start day"), 00, 00)
end = timestamp(input(2020, "end year"), input(1, "end month"), input(1, "end day"), 00, 00)

average = input (title="Source MA Type", type=input.string, defval="EMA",options=["EMA","SMA"])

len1=input(130,title="Fast MA Length")
len2=input(400,title="Slow MA Length")

smoothingavg = input (title="Smoothing MAs Type", type=input.string, defval="EMA",options=["EMA","SMA"])
smoothingavglen = input (3,title="Smoothing MAs Length")

trendfilter=input(true,title="Trend Filter")
trendfilterperiod=input(200,title="Trend Filter MA Period")
trendfiltertype=input (title="Trend Filter MA Type", type=input.string, defval="EMA",options=["EMA","SMA"])

volatilityfilter=input(false,title="Volatility Filter")
volatilitydelta=input(0.0003,step=0.0001,title="Delta Slopes EMA")

//variabili

m1 = if average == "EMA" 
    ema(close,len1)
else
    sma(close,len1)

m2=if average == "EMA" 
    ema(close,len2)
else
    sma(close,len2)

slp1=(m1-m1[1])/m1
slp2=(m2-m2[1])/m2

e1=if smoothingavg == "EMA" 
    ema(slp1,smoothingavglen)
else
    sma(slp1,smoothingavglen)

e2=if smoothingavg == "EMA" 
    ema(slp2,smoothingavglen)
else
    sma(slp2,smoothingavglen)

plot(e1,color=color.yellow)
plot(e2,color=color.red)
//plot (abs(e1-e2),color=color.white)
//plot (ema(e1-e2,9),color=color.yellow)

//variabili accessorie e condizioni

TrendConditionL=if trendfiltertype =="EMA"
    close>ema(close,trendfilterperiod)
else
    close>sma(close,trendfilterperiod)
    
TrendConditionS=if trendfiltertype =="EMA"
    close<ema(close,trendfilterperiod)
else
    close<sma(close,trendfilterperiod)
    
VolatilityCondition = abs(e1-e2) > volatilitydelta

ConditionEntryL= if trendfilter == true
    if volatilityfilter == true
        e1>e2 and TrendConditionL and VolatilityCondition
    else
        e1>e2 and TrendConditionL
else
    if volatilityfilter == true
        e1>e2 and VolatilityCondition
    else 
        e1>e2

ConditionEntryS= if trendfilter == true
    if volatilityfilter == true
        e1<e2 and TrendConditionS and VolatilityCondition
    else 
        e1<e2 and TrendConditionS
else
    if volatilityfilter == true
        e1<e2 and VolatilityCondition
    else
        e1<e2

ConditionExitL=crossunder(e1,e2)
ConditionExitS=crossover(e1,e2)

if true
    if ConditionExitS
        if strategy.position_size < 0
            strategy.close("SLPShort")

if true
    if ConditionExitL
        if strategy.position_size > 0
            strategy.close("SLPLong")

if true
    if ConditionEntryL
        strategy.entry ("SLPLong",long=true)
        
if true
    if ConditionEntryS 
        strategy.entry("SLPShort",long=false)

更多内容