基于指数移动平均线和MACD指标的量化交易策略


创建日期: 2023-12-08 16:58:01 最后修改: 2023-12-08 17:04:03
复制: 0 点击次数: 466
avatar of ChaoZhang ChaoZhang
1
关注
1236
关注者

基于指数移动平均线和MACD指标的量化交易策略

概述

该策略结合了指数移动平均线和MACD指标的突破信号,设定长短两种持仓周期,通过趋势跟踪和反转交易实现获利。

策略原理

该策略主要基于以下原理:

  1. 计算200日指数移动平均线,判断大趋势方向。 closes价格高于该平均线为看涨,低于为看跌。

  2. 基于最高价、最低价、收盘价的中值价格绘制指数移动平均线,计算该平均线与最高价和最低价的差值,构建MACD柱状图。

  3. 计算MACD柱状图的9日移动平均线,构建MACD信号线。

  4. 当MACD从下往上突破信号线时产生买入信号;从上往下突破信号线时,产生卖出信号。

  5. 结合大趋势方向,判断行情进入较长的趋势还是短线的反转。

策略优势

该策略结合趋势和反转交易,既可以跟踪较长周期的趋势,也可以捕捉短线上的反转机会,灵活应对不同的行情情况。

具体优势包括:

  1. 使用200日移动平均线判断主要趋势方向,避免逆势操作。

  2. MACD指标对短期价格变化较为敏感,可以捕捉较有效的反转机会。

  3. 不同参数设置下的MACD组合,可以实现多时间框架的交易信号。

  4. 结合止损策略,可以有效控制单笔损失。

策略风险

该策略主要存在以下风险:

  1. 长短周期指标发出交易信号时,可能存在一定时间差,需要综合判断大趋势。

  2. MACD作为反转指标,当出现剧烈行情时,其指标解释力会降低。

  3. 止损点设置不当,可能过早止损或止损幅度过大。

  4. 突破信号判定过于频繁,可能产生更多假信号。

对应解决方法:

  1. 优化MACD参数,调整指标的敏感性。

  2. 结合其他指标判断行情阶段,避免盲目跟踪MACD信号。

  3. 测试并优化止损策略参数。

  4. 增加过滤条件,避免出现过多假信号。

策略优化方向

该策略可从以下几个方向进行优化:

  1. 优化移动平均线和MACD的参数,获得更有效的交易信号。

  2. 增加 autres Some other indicators to enhance the effectiveness of the strategy. Volume, RSI 等其他指标来增强策略的有效性。

  3. Set up a position sizing strategy rather than fixed lots for each trade. 为每个交易设立头寸控制策略,而不是固定数量。

  4. Add more advanced exit rules rather than just stop loss. Such as profit target, trailing stops etc. 增加更高级的退出规则,而不仅仅是止损,例如止盈,移动止损等。

  5. Backtest with more complex fee settings to better simulate real trading environoment. 用更复杂的手续费设置来回测,以便更好地模拟实盘环境。

  6. Walk forward analysis, robustness test among multiple products to enhance reliability. 实现步移分析、不同产品的稳健性测试以提高可靠性。

总结

该策略同时兼顾趋势和反转交易,关键在于指标参数的设定以及对大趋势理解的准确性。通过不断优化参数设定、增加滤波条件等手段,可以使策略对行情信号判断更加准确、获利更加稳定。总体来说,该策略集成度较高,具有很好的应用前景。

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

//@version=4
strategy("Strategia EMA + Impulse MACD", shorttitle="EMA+IMACD", overlay=true)

// Impostazioni
ema_length = input(200, title="Periodo EMA a 200", type=input.integer)
lengthMA = input(34, title="Periodo EMA", type=input.integer)
lengthSignal = input(9, title="Periodo Signal", type=input.integer)
lengthImpulseMACD = input(12, title="Periodo Impulse MACD", type=input.integer)
lengthImpulseMACDSignal = input(9, title="Periodo Impulse MACD Signal", type=input.integer)
stopLossPeriod = input(20, title="Periodo Stop Loss", type=input.integer)

var float ema200 = na
if bar_index >= ema_length
    ema200 := ema(close, ema_length)

// Impulse MACD
var float hi = na
var float lo = na
var float mi = na
var float impulseMACD = na
var float impulseMACDSignal = na

calc_smma(src, len) =>
    var float smma = na
    if na(smma)
        smma := sma(src, len)
    else
        smma := (smma[1] * (len - 1) + src) / len
    smma

calc_zlema(src, length) =>
    ema1 = ema(src, length)
    ema2 = ema(ema1, length)
    d = ema1 - ema2
    ema1 + d

if bar_index >= lengthMA
    src = hlc3
    hi := calc_smma(high, lengthMA)
    lo := calc_smma(low, lengthMA)
    mi := calc_zlema(src, lengthMA)

    impulseMACD := (mi > hi) ? (mi - hi) : (mi < lo) ? (mi - lo) : 0
    impulseMACDSignal := sma(impulseMACD, lengthSignal)

// Calcolo dello stop loss
var float stopLossLong = na
var float stopLossShort = na

stopLossLong := lowest(low, stopLossPeriod)
stopLossShort := highest(high, stopLossPeriod)

// Calcolo del take profit
var float takeProfitLong = na
var float takeProfitShort = na

if not na(stopLossLong)
    takeProfitLong := close + (close - stopLossLong) * 1.5
if not na(stopLossShort)
    takeProfitShort := close - (stopLossShort - close) * 1.5

// Condizioni per aprire una posizione long
longCondition = not na(ema200) and not na(impulseMACD) and not na(impulseMACDSignal) and close > ema200 and impulseMACD < 0 and impulseMACDSignal < 0 and crossover(impulseMACD, impulseMACDSignal)

// Condizioni per aprire una posizione short
shortCondition = not na(ema200) and not na(impulseMACD) and not na(impulseMACDSignal) and close < ema200 and impulseMACD > 0 and impulseMACDSignal > 0 and crossunder(impulseMACD, impulseMACDSignal)

// Disegna l'EMA 200 sul grafico
plot(ema200, color=color.blue, title="EMA 200")

// Imposta lo stop loss e il take profit
strategy.entry("Long", strategy.long, when=longCondition)
strategy.entry("Short", strategy.short, when=shortCondition)
strategy.exit("Take Profit/Stop Loss Long", from_entry="Long", stop=stopLossLong, limit=takeProfitLong)
strategy.exit("Take Profit/Stop Loss Short", from_entry="Short", stop=stopLossShort, limit=takeProfitShort)

// Impulse MACD
plot(0, color=color.gray, linewidth=1, title="MidLine")
plot(impulseMACD, color=color.red, linewidth=2, title="ImpulseMACD", style=plot.style_histogram)
plot(impulseMACDSignal, color=color.blue, linewidth=2, title="ImpulseMACDSignal", style=plot.style_histogram)

// Disegna le operazioni long e short sul grafico
plotshape(series=longCondition, location=location.belowbar, color=color.green, style=shape.triangleup, title="Long Entry")
plotshape(series=shortCondition, location=location.abovebar, color=color.red, style=shape.triangledown, title="Short Entry")