三移动平均线量化交易策略

Author: ChaoZhang, Date: 2024-01-23 14:20:50
Tags:

三移动平均线量化交易策略

本策略通过计算三条不同周期的移动平均线,并结合价格突破形成交易信号,属于典型的趋势跟踪策略。该策略旨在跟踪市场中期趋势,通过动态调整参数可以适用于不同品种和交易环境。

原理

该策略包含三条移动平均线:MA1、MA2和MA3。MA1和MA2之间形成交易通道,其交叉给出交易信号;MA3用于过滤信号。

当快速平均线MA1上穿中期平均线MA2时,表明短期趋势变强,这时如果价格高于长期平均线MA3,则产生做多信号;相反,如果MA1下穿MA2,并且价格低于MA3,则产生做空信号。

MA3的作用是过滤掉短期市场噪音,只在确定趋势进入中长期阶段后产生信号。该策略通过动态调整三条移动平均线的参数,可以在不同市场中寻找最佳参数组合。

优势

  • 通过多组移动平均线捕捉不同周期趋势
  • MA3过滤信号,避免被套利
  • 可自定义平均线类型及参数,适应性强
  • 可视化交叉以识别信号点

风险

  • 大周期趋势逆转时,移动平均线交叉滞后
  • 交易频率可能过高,增加交易成本和滑点风险
  • 参数不当可能导致过度交易或信号指示滞后

可通过调整MA周期,优化参数选择不同品种;优化止损策略,控制单笔损失;结合其他技术指标确认信号有效性,降低误信号概率。

优化方向

  • 增加其他指标判断趋势,如MACD、布林带等
  • 增加止损/止盈策略
  • 动态调整参数,寻找最优参数组合
  • 不同品种参数优化
  • 考虑交易成本,优化交易频率

总结

本策略通过计算三条移动平均线并观察交叉产生交易信号,使用快中慢配合的思路判断趋势,是一个典型的趋势跟踪策略。该策略通过参数优化可以适用于不同品种,但存在被套和错过转折点的风险。未来可通过引入其他技术指标判断信号有效性,开发动态参数优化机制等进行优化,使策略更具弹性。


/*backtest
start: 2023-01-16 00:00:00
end: 2024-01-22 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Meesemoo

//@version=4
strategy("Custom MA Strategy Tester", overlay = true)
MA1Period = input(13, title="MA1 Period")
MA1Type = input(title="MA1 Type", defval="SMA", options=["RMA", "SMA", "EMA", "WMA", "HMA", "DEMA", "TEMA"])
MA1Source = input(title="MA1 Source", type=input.source, defval=close)
MA1Visible = input(title="MA1 Visible", type=input.bool, defval=true)
MA2Period = input(50, title="MA2 Period")
MA2Type = input(title="MA2 Type", defval="SMA", options=["RMA", "SMA", "EMA", "WMA", "HMA", "DEMA", "TEMA"])
MA2Source = input(title="MA2 Source", type=input.source, defval=close)
MA2Visible = input(title="MA2 Visible", type=input.bool, defval=true) 
MA3Period = input(200, title="MA3 Period")
MA3Type = input(title="MA3 Type", defval="SMA", options=["RMA", "SMA", "EMA", "WMA", "HMA", "DEMA", "TEMA"])
MA3Source = input(title="MA3 Source", type=input.source, defval=close)
MA3Visible = input(title="MA3 Visible", type=input.bool, defval=true)
ShowCrosses = input(title="Show Crosses", type=input.bool, defval=true)

MA1 = if MA1Type == "SMA"
    sma(MA1Source, MA1Period)
else
    if MA1Type == "EMA"
        ema(MA1Source, MA1Period)
    else
        if MA1Type == "WMA"
            wma(MA1Source, MA1Period)
        else
            if MA1Type == "RMA"
                rma(MA1Source, MA1Period)
            else
                if MA1Type == "HMA"
                    wma(2*wma(MA1Source, MA1Period/2)-wma(MA1Source, MA1Period), round(sqrt(MA1Period)))
                else
                    if MA1Type == "DEMA"
                        e = ema(MA1Source, MA1Period)
                        2 * e - ema(e, MA1Period)
                    else
                        if MA1Type == "TEMA"
                            e = ema(MA1Source, MA1Period)
                            3 * (e - ema(e, MA1Period)) + ema(ema(e, MA1Period), MA1Period)

                    
MA2 = if MA2Type == "SMA"
    sma(MA2Source, MA2Period)
else
    if MA2Type == "EMA"
        ema(MA2Source, MA2Period)
    else
        if MA2Type == "WMA"
            wma(MA2Source, MA2Period)
        else
            if MA2Type == "RMA"
                rma(MA2Source, MA2Period)
            else
                if MA2Type == "HMA"
                    wma(2*wma(MA2Source, MA2Period/2)-wma(MA2Source, MA2Period), round(sqrt(MA2Period)))
                else
                    if MA2Type == "DEMA"
                        e = ema(MA2Source, MA2Period)
                        2 * e - ema(e, MA2Period)
                    else
                        if MA2Type == "TEMA"
                            e = ema(MA2Source, MA2Period)
                            3 * (e - ema(e, MA2Period)) + ema(ema(e, MA2Period), MA2Period)
                    
MA3 = if MA3Type == "SMA"
    sma(MA3Source, MA3Period)
else
    if MA3Type == "EMA"
        ema(MA3Source, MA3Period)
    else
        if MA3Type == "WMA"
            wma(MA3Source, MA3Period)
        else
            if MA3Type == "RMA"
                rma(MA3Source, MA3Period)
            else
                if MA3Type == "HMA"
                    wma(2*wma(MA3Source, MA3Period/2)-wma(MA3Source, MA3Period), round(sqrt(MA3Period)))
                else
                    if MA3Type == "DEMA"
                        e = ema(MA3Source, MA3Period)
                        2 * e - ema(e, MA3Period)
                    else
                        if MA3Type == "TEMA"
                            e = ema(MA3Source, MA3Period)
                            3 * (e - ema(e, MA3Period)) + ema(ema(e, MA3Period), MA3Period)
                    


p1 = plot(MA1Visible ? MA1 : na, color=color.green, linewidth=1)
p2 = plot(MA2Visible ? MA2 : na, color=color.yellow, linewidth=1)
p3 = plot(MA3Visible ? MA3 : na, color=color.red, linewidth=2)

fill(p1, p2, color.silver, transp=80, title="Fill")


start = timestamp(2019, 1, 1, 1, 0)
end = timestamp(2025, 1, 1, 1, 0)

if time >= start and time <= end
    longCondition = crossover(MA1, MA2) and close > MA3
    if (longCondition)
        strategy.entry("Long", strategy.long)
        
    shortCondition = crossunder(MA1, MA2) and close < MA3
    if (shortCondition)
        strategy.entry("Short", strategy.short)

更多内容