Strategie zur Umkehrung des doppelten gleitenden Durchschnitts

Schriftsteller:ChaoZhang, Datum: 2023-11-17 16:56:24
Tags:

img

Übersicht

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.

Strategie Logik

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.

Analyse der Vorteile

Die wichtigsten Vorteile der Strategie zur Umkehrung der doppelten MA sind:

  1. Die schnellen gleitenden Durchschnitte können kurzfristige Umkehrungen mit kleineren Drawdowns schnell erfassen.

  2. Einfach umzusetzen und leicht zu verstehen.

  3. Hoch konfigurierbar mit mehreren einstellbaren Parametern.

  4. Die einfache Logik und der hohe Frequenzhandel machen es sehr geeignet für automatisierten Handel.

  5. Das Risiko kann mit einem Stop-Loss-Mechanismus kontrolliert werden.

Risikoanalyse

Die Strategie birgt auch einige Risiken:

  1. 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.

  2. Das Risiko von Whipsaw-Trades: Der umgekehrte Trend kann sich schnell wieder umkehren und Folgeverluste verursachen.

  3. Obwohl Stop Loss den einzelnen Verlust begrenzt, kann ein aufeinanderfolgender Stop Loss immer noch zu großen Drawdowns führen.

  4. Übermäßige Optimierung der Parameter kann zu Überanpassung und schlechter Performance beim Live-Handel führen.

Zu den Lösungen gehören:

  1. Optimieren Sie die Parameter, um schnellere MAs zu finden.

  2. Fügen Sie Filter wie Volumen- und Volatilitätsindikatoren hinzu, um Whipsaw-Trades zu vermeiden.

  3. Anpassung der Stop-Loss-Position, um die Wahrscheinlichkeit eines aufeinander folgenden Stop-Loss zu senken.

  4. Robustheitstest von Parametermengen zur Bewertung von Überanpassungrisiken.

Verbesserungsrichtlinien

Die Strategie kann in folgenden Bereichen weiter optimiert werden:

  1. Verschiedene Arten von MAs testen, um empfindlichere zu finden, wie KAMA, ZLEMA usw.

  2. Optimieren Sie die MA-Länge, um die optimale Kombination zu finden.

  3. Verschiedene Datenquellen testen, z. B. Schließpreis, Medianpreis, typischer Preis usw.

  4. Hinzufügen eines Trendfilters, um ungeeignete Umkehrsignale wie den Donchian Channel zu vermeiden.

  5. Hinzufügen anderer Indikatoren zur Bestätigung, wie MACD, OBV usw.

  6. Verbesserung der Risikomanagementmechanismen, wie zum Beispiel die Verlagerung von Stop Loss, Maximalverlust usw.

  7. Optimierung des Portfolios, um die optimale Vermögensallokation zu finden.

  8. Robustheitstest von Parametern zur Bewertung der Risiken einer Überanpassung.

Schlussfolgerung

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

Mehr