Die Dual Moving Average Reversion Strategie ist eine typische kurzfristige Mittelumkehrhandelsstrategie. Die Strategie generiert Handelssignale durch zwei gleitende Durchschnitte mit unterschiedlichen Parameter-Einstellungen. Sie zielt darauf ab, Gewinne zu erzielen, wenn eine Trendumkehr stattfindet.
Die Strategie verwendet zwei gleitende Durchschnitte, um Handelssignale zu generieren.
Wenn die Maopening nach oben geht, zeigt dies an, dass der aktuelle Markt in einem Aufwärtstrend ist. Wenn die Maopening nach unten geht, zeigt dies an, dass der aktuelle Markt in einem Abwärtstrend ist. Maclosing wird mit einem Koeffizienten größer als 1 multipliziert, um es empfindlicher für die Erzeugung früherer Umkehrsignale zu machen.
Wenn die Maopening nach oben geht und das Maclosing unterhalb der Maopening kreuzt, zeigt dies eine Trendumkehr an. Die Strategie wird eine Short-Position eröffnen. Wenn die Maopening nach unten geht und das Maclosing über die Maopening kreuzt, zeigt dies eine Trendumkehr an. Die Strategie wird eine Long-Position eröffnen.
Die Parameter der Strategie umfassen MA-Typ, Länge, Datenquelle usw. Die Handelsleistung kann durch Anpassung dieser Parameter optimiert werden. Es gibt auch einige konfigurierbare Optionen wie Eintrittsregel, Stop Loss usw.
Die wichtigsten Vorteile der Strategie zur Umkehrung der doppelten MA sind:
Die schnellen gleitenden Durchschnitte können kurzfristige Umkehrungen mit kleineren Drawdowns schnell erfassen.
Einfach umzusetzen und leicht zu verstehen.
Hoch konfigurierbar mit mehreren einstellbaren Parametern.
Die einfache Logik und der hohe Frequenzhandel machen es sehr geeignet für automatisierten Handel.
Das Risiko kann mit einem Stop-Loss-Mechanismus kontrolliert werden.
Die Strategie birgt auch einige Risiken:
Die Verzögerung der MA-Crossover-Signale. Die MA selbst liegen hinter dem Preis zurück. Der Crossover kann auftreten, nachdem sich der Trend für einige Zeit umgekehrt hat.
Das Risiko von Whipsaw-Trades: Der umgekehrte Trend kann sich schnell wieder umkehren und Folgeverluste verursachen.
Obwohl Stop Loss den einzelnen Verlust begrenzt, kann ein aufeinanderfolgender Stop Loss immer noch zu großen Drawdowns führen.
Übermäßige Optimierung der Parameter kann zu Überanpassung und schlechter Performance beim Live-Handel führen.
Zu den Lösungen gehören:
Optimieren Sie die Parameter, um schnellere MAs zu finden.
Fügen Sie Filter wie Volumen- und Volatilitätsindikatoren hinzu, um Whipsaw-Trades zu vermeiden.
Anpassung der Stop-Loss-Position, um die Wahrscheinlichkeit eines aufeinander folgenden Stop-Loss zu senken.
Robustheitstest von Parametermengen zur Bewertung von Überanpassungrisiken.
Die Strategie kann in folgenden Bereichen weiter optimiert werden:
Verschiedene Arten von MAs testen, um empfindlichere zu finden, wie KAMA, ZLEMA usw.
Optimieren Sie die MA-Länge, um die optimale Kombination zu finden.
Verschiedene Datenquellen testen, z. B. Schließpreis, Medianpreis, typischer Preis usw.
Hinzufügen eines Trendfilters, um ungeeignete Umkehrsignale wie den Donchian Channel zu vermeiden.
Hinzufügen anderer Indikatoren zur Bestätigung, wie MACD, OBV usw.
Verbesserung der Risikomanagementmechanismen, wie zum Beispiel die Verlagerung von Stop Loss, Maximalverlust usw.
Optimierung des Portfolios, um die optimale Vermögensallokation zu finden.
Robustheitstest von Parametern zur Bewertung der Risiken einer Überanpassung.
Die Dual-MA-Umkehrung ist eine einfache und praktische kurzfristige Handelsstrategie. Sie eignet sich zur Erfassung von kurzfristigen Umkehrungen mit quantitativen Trades. Allerdings bestehen Risiken wie Verzögerungen und Whipsaw-Trades. Die Strategie kann durch Optimierung von Parametern, Hinzufügen von Filtern, Verbesserung der Risikokontrolle usw. verbessert werden, um eine stabile und effiziente Strategie mit einer guten realen Handelsleistung zu entwickeln.
/*backtest start: 2023-10-17 00:00:00 end: 2023-11-16 00:00:00 period: 1h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy(title = "hamster-bot MRS 2", overlay = true, default_qty_type = strategy.percent_of_equity, initial_capital = 100, default_qty_value = 100, pyramiding = 9, commission_value = 0.045, backtest_fill_limits_assumption = 1) info_options = "Options" on_close = input(false, title = "Entry on close", inline=info_options, group=info_options) OFFS = input.int(0, minval = 0, maxval = 1, title = "| Offset View", inline=info_options, group=info_options) trade_offset = input.int(0, minval = 0, maxval = 1, title = "Trade", inline=info_options, group=info_options) use_kalman_filter = input.bool(false, title="Use Kalman filter", group=info_options) //MA Opening info_opening = "MA Opening" maopeningtyp = input.string("SMA", title="Type", options=["SMA", "EMA", "TEMA", "DEMA", "ZLEMA", "WMA", "Hma", "Thma", "Ehma", "H", "L", "DMA"], title = "", inline=info_opening, group=info_opening) maopeningsrc = input.source(ohlc4, title = "", inline=info_opening, group=info_opening) maopeninglen = input.int(3, minval = 1, maxval = 200, title = "", inline=info_opening, group=info_opening) //MA Closing info_closing = "MA Closing" maclosingtyp = input.string("SMA", title="Type", options=["SMA", "EMA", "TEMA", "DEMA", "ZLEMA", "WMA", "Hma", "Thma", "Ehma", "H", "L", "DMA"], title = "", inline=info_closing, group=info_closing) maclosingsrc = input.source(ohlc4, title = "", inline=info_closing, group=info_closing) maclosinglen = input.int(3, minval = 1, maxval = 200, title = "", inline=info_closing, group=info_closing) maclosingmul = input.float(1, step = 0.005, title = "mul", inline=info_closing, group=info_closing) long1on = input(true, title = "", inline = "long1") long1shift = input.float(0.96, step = 0.005, title = "Long", inline = "long1") long1lot = input.int(10, minval = 0, maxval = 10000, step = 10, title = "Lot 1", inline = "long1") short1on = input(true, title = "", inline = "short1") short1shift = input.float(1.04, step = 0.005, title = "short", inline = "short1") short1lot = input.int(10, minval = 0, maxval = 10000, step = 10, title = "Lot 1", inline = "short1") startTime = input(timestamp("01 Jan 2010 00:00 +0000"), "Start date", inline = "period") finalTime = input(timestamp("31 Dec 2030 23:59 +0000"), "Final date", inline = "period") HMA(_src, _length) => ta.wma(2 * ta.wma(_src, _length / 2) - ta.wma(_src, _length), math.round(math.sqrt(_length))) EHMA(_src, _length) => ta.ema(2 * ta.ema(_src, _length / 2) - ta.ema(_src, _length), math.round(math.sqrt(_length))) THMA(_src, _length) => ta.wma(ta.wma(_src,_length / 3) * 3 - ta.wma(_src, _length / 2) - ta.wma(_src, _length), _length) tema(sec, length)=> tema1= ta.ema(sec, length) tema2= ta.ema(tema1, length) tema3= ta.ema(tema2, length) tema_r = 3*tema1-3*tema2+tema3 donchian(len) => math.avg(ta.lowest(len), ta.highest(len)) ATR_func(_src, _len)=> atrLow = low - ta.atr(_len) trailAtrLow = atrLow trailAtrLow := na(trailAtrLow[1]) ? trailAtrLow : atrLow >= trailAtrLow[1] ? atrLow : trailAtrLow[1] supportHit = _src <= trailAtrLow trailAtrLow := supportHit ? atrLow : trailAtrLow trailAtrLow f_dema(src, len)=> EMA1 = ta.ema(src, len) EMA2 = ta.ema(EMA1, len) DEMA = (2*EMA1)-EMA2 f_zlema(src, period) => lag = math.round((period - 1) / 2) ema_data = src + (src - src[lag]) zl= ta.ema(ema_data, period) f_kalman_filter(src) => float value1= na float value2 = na value1 := 0.2 * (src - src[1]) + 0.8 * nz(value1[1]) value2 := 0.1 * (ta.tr) + 0.8 * nz(value2[1]) lambda = math.abs(value1 / value2) alpha = (-math.pow(lambda, 2) + math.sqrt(math.pow(lambda, 4) + 16 * math.pow(lambda, 2)))/8 value3 = float(na) value3 := alpha * src + (1 - alpha) * nz(value3[1]) //SWITCH ma_func(modeSwitch, src, len, use_k_f=true) => modeSwitch == "SMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.sma(src, len)) : ta.sma(src, len) : modeSwitch == "RMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.rma(src, len)) : ta.rma(src, len) : modeSwitch == "EMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.ema(src, len)) : ta.ema(src, len) : modeSwitch == "TEMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(tema(src, len)) : tema(src, len): modeSwitch == "DEMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(f_dema(src, len)) : f_dema(src, len): modeSwitch == "ZLEMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(f_zlema(src, len)) : f_zlema(src, len): modeSwitch == "WMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.wma(src, len)) : ta.wma(src, len): modeSwitch == "VWMA" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.vwma(src, len)) : ta.vwma(src, len): modeSwitch == "Hma" ? use_kalman_filter and use_k_f ? f_kalman_filter(HMA(src, len)) : HMA(src, len): modeSwitch == "Ehma" ? use_kalman_filter and use_k_f ? f_kalman_filter(EHMA(src, len)) : EHMA(src, len): modeSwitch == "Thma" ? use_kalman_filter and use_k_f ? f_kalman_filter(THMA(src, len/2)) : THMA(src, len/2): modeSwitch == "ATR" ? use_kalman_filter and use_k_f ? f_kalman_filter(ATR_func(src, len)): ATR_func(src, len) : modeSwitch == "L" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.lowest(len)): ta.lowest(len) : modeSwitch == "H" ? use_kalman_filter and use_k_f ? f_kalman_filter(ta.highest(len)): ta.highest(len) : modeSwitch == "DMA" ? donchian(len) : na //Var sum = 0.0 maopening = 0.0 maclosing = 0.0 os = maopeningsrc cs = maclosingsrc pos = strategy.position_size p = 0.0 p := pos == 0 ? (strategy.equity / 100) / close : p[1] truetime = true loss = 0.0 maxloss = 0.0 equity = 0.0 //MA Opening maopening := ma_func(maopeningtyp, maopeningsrc, maopeninglen) //MA Closing maclosing := ma_func(maclosingtyp, maclosingsrc, maclosinglen) * maclosingmul long1 = long1on == false ? 0 : long1shift == 0 ? 0 : long1lot == 0 ? 0 : maopening == 0 ? 0 : maopening * long1shift short1 = short1on == false ? 0 : short1shift == 0 ? 0 : short1lot == 0 ? 0 : maopening == 0 ? 0 : maopening * short1shift //Colors maopeningcol = maopening == 0 ? na : color.blue maclosingcol = maclosing == 0 ? na : color.fuchsia long1col = long1 == 0 ? na : color.green short1col = short1 == 0 ? na : color.red //Lines plot(maopening, offset = OFFS, color = maopeningcol) plot(maclosing, offset = OFFS, color = maclosingcol) long1line = long1 == 0 ? close : long1 short1line = short1 == 0 ? close : short1 plot(long1line, offset = OFFS, color = long1col) plot(short1line, offset = OFFS, color = short1col) //Lots lotlong1 = p * long1lot lotshort1 = p * short1lot //Entry if maopening > 0 and maclosing > 0 and truetime //Long sum := 0 strategy.entry("L", strategy.long, lotlong1, limit = on_close ? na : long1, when = long1 > 0 and pos <= sum and (on_close ? close <= long1[trade_offset] : true)) sum := lotlong1 //Short sum := 0 pos := -1 * pos strategy.entry("S", strategy.short, lotshort1, limit = on_close ? na : short1, when = short1 > 0 and pos <= sum and (on_close ? close >= short1[trade_offset] : true)) sum := lotshort1 strategy.exit("Exit", na, limit = maclosing) if time > finalTime strategy.close_all()