Doppel-Gleichgewichts-Umkehr


Erstellungsdatum: 2023-11-17 16:56:24 zuletzt geändert: 2023-11-17 16:56:24
Kopie: 1 Klicks: 627
1
konzentrieren Sie sich auf
1617
Anhänger

Doppel-Gleichgewichts-Umkehr

Überblick

Die Dual Moving Average Reversion Strategy ist eine typische kurzfristige Reversion-Handelsstrategie. Sie verwendet zwei unterschiedliche Parameter-Sätze, um ein Handelssignal auszusenden, das Gewinne erzielt, wenn ein Trend umgekehrt wird.

Strategieprinzip

Die Strategie verwendet zwei Maopening-Linien zur Erzeugung von Handelssignalen. Die erste Maopening-Linien werden verwendet, um die Richtung der Tendenz zu bestimmen, und die zweite Maoplosing-Linien werden verwendet, um Handelssignale zu senden.

Wenn der Maopening steigt, ist er in der Aufwärtsphase des Trends; wenn der Maopening fällt, ist er in der Abwärtsphase des Trends. Maclosing wird mit einem Faktor größer als 1 multipliziert, was es empfindlicher macht, ein Umkehrsignal zu senden.

Konkret, wenn der Maopening steigt und der Maclosing unter dem Maopening fällt, bedeutet dies eine Trendwende, in der die Strategie eine Leerstellung eröffnet. Wenn der Maopening fällt und der Maclosing über dem Maopening fällt, bedeutet dies eine Trendwende, in der die Strategie einen Plus eröffnet.

Die Parameter der Strategie umfassen die Art der Durchschnittslinie, die Länge und die Datenquelle. Sie können diese Parameter anpassen, um bessere Handelsergebnisse zu erzielen. Zusätzlich enthält die Strategie einige Optionen, wie z. B. die Art der Positionseröffnung, die Art der Stop-Loss-Methode usw., die nach Bedarf eingestellt werden können.

Analyse der Stärken

Die Vorteile einer doppelten Gleichgewichtsumkehr sind vor allem:

  1. Kleiner Rückzug, geeignet für den Short-Line-Handel. Mit zwei schnellen Durchschnittslinien kann eine Umkehrung des kurzfristigen Trends schnell erfasst werden, kleiner Rückzug.

  2. Einfache Umsetzung, leicht zu beherrschen. Die Kreuzung von zwei Gleichlinien ist ein Handelssignal, sehr einfach und klar.

  3. Die Parameter sind vielseitig anpassbar und optimierbar. Die Parameter und Faktoren, die zwei Durchschnittslinien enthalten, können durch Optimierung die optimale Parameterkombination gefunden werden.

  4. Programmierbar, geeignet für automatisierte Transaktionen. Die Strategie ist einfach und klar, die Ausführungsfrequenz ist hoch und eignet sich hervorragend für die Programmierung von automatisierten Transaktionen.

  5. Kontrollierbare Risiken mit Stop-Loss-Mechanismen. Sie können mobile Stop-Loss oder numerische Stop-Loss-Mechanismen einrichten und einzelne Verluste steuern.

Risikoanalyse

Die Strategie der doppelten Gleichgewichtsumkehr birgt einige Risiken:

  1. Bei einer doppelten Gleichgewichtskreuzung gibt es eine Verzögerung. Die Gleichgewichtskreuzung selbst liegt hinter dem Preis zurück, und der Trend könnte sich bereits eine Zeitlang umgekehrt haben, wenn die Kreuzung stattfindet.

  2. Die Trendwende kann nicht dauerhaft sein und könnte sich bald wieder umkehren und zu einer Falle führen.

  3. Die Rücknahme bleibt bestehen. Eine rechtzeitige Verringerung der Einzelschäden kann zu einer Verringerung der Einzelschäden führen, aber eine kontinuierliche Verringerung der Einzelschäden kann zu einer größeren Rücknahme führen.

  4. Datenoptimierungsrisiken. Überoptimierungsparameter, die in historischen Daten gut funktionieren, aber nicht in der Realität.

Risiken können mit folgenden Lösungen begegnet werden:

  1. Optimieren Sie die Parameter und finden Sie eine schnell ansprechende Mittellinie.

  2. In Kombination mit anderen Indikatoren, wie z. B. Quantitäts- und Volatilitätsindikatoren, sollte die Gefangenschaft vermieden werden.

  3. Anpassung der Stop-Loss-Position, um die Wahrscheinlichkeit einer fortlaufenden Stop-Loss zu verringern.

  4. Multiparameter-Optimierungstests zur Beurteilung der Parameterstärke.

Optimierungsrichtung

Die Strategie der doppelten Gleichgewichtsumkehr kann in folgenden Bereichen optimiert werden:

  1. Verschiedene Arten von Durchschnittslinien werden getestet, um nach einer höheren Reaktionsempfindlichkeit zu suchen.

  2. Optimierung der Mittellinienparameter, um die optimale Länge-Kombination zu finden. Die mittellinien-Effekte sind in der Regel besser bei kürzeren Perioden.

  3. Verschiedene Datenquellen, wie z.B. Schlusskurs, Mittelkurs, Typischer Kurs, werden getestet.

  4. Trendfilter hinzugefügt, um unangemessene Umkehrsignale zu vermeiden. Donchian-Kanal usw. verfügbar

  5. In Verbindung mit anderen Indikatoren, wie z. B. MACD, OBV usw.

  6. Erhöhung der Risikomanagement-Mechanismen, wie beispielsweise mobile Stop-Losses, Maximalverluste auf Konten usw.;

  7. Portfolio-Optimierung, um die optimale Vermögensverteilung zu finden.

  8. Erhöhung der Parameter-Fitness-Tests zur Beurteilung des Risikos einer Überoptimierung der Parameter.

Zusammenfassen

Die Double Equilibrium Reversal Strategy ist eine einfache und praktische Short-Line-Strategie, die geeignet ist, um kurzfristige Marktreversationen zu erfassen. Die Strategie ist klein, leicht umzusetzen und eignet sich hervorragend für den Umsatz. Es gibt jedoch einige Probleme, wie Rückstandsrisiken, Lockdowns usw.

Strategiequellcode
/*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()