Strategie zur Umkehrung des doppelten gleitenden Durchschnitts

Schriftsteller:ChaoZhang, Datum: 2023-12-25 13:24:14
Tags:

img

Übersicht

Die Dual Moving Average Reversal Strategy ist eine quantitative Handelsstrategie, die doppelte gleitende Durchschnitte verwendet, um kurzfristige und langfristige Trends zu identifizieren.

Strategie Logik

Die Strategie zur Umkehrung des doppelten gleitenden Durchschnitts beruht auf folgenden Annahmen:

  1. Der 200-Tage-SMA zeigt den vorherrschenden langfristigen Trend des Marktes an. Wenn der Preis über der 200-Tage-Linie liegt, signalisiert er, dass sich der Markt in einem langfristigen Aufwärtstrend befindet.

  2. Der 10-Tage-SMA zeigt kurzfristige Kursrückgänge an. Wenn der Preis unter die 10-Tage-Linie fällt, zeigt er an, dass ein vorübergehender Rückgang eingetreten ist.

  3. Bei einem anhaltenden Aufwärtstrend kann jeder kurzfristige Rückgang als Kaufmöglichkeit angesehen werden, um den Aufwärtstrend effizient zu überwinden.

Auf der Grundlage der vorstehenden Annahmen werden die Handelssignale wie folgt erzeugt:

  1. Wenn der Schlusskurs über den 200-Tage-SMA und gleichzeitig unter den 10-Tage-SMA geht, löst er ein Kaufsignal aus, da er zeigt, dass der langfristige Trend positiv bleibt, aber ein kurzfristiger Rückgang eingetreten ist.

  2. Wenn der Kurs bei einer Long-Position über den 10-Tage-SMA zurückgeht, ist der kurzfristige Trend umgekehrt, so dass die Position sofort geschlossen wird.

  3. Wenn ein starker Abschwung eintritt (über einen vorgegebenen Schwellenwert hinaus), bietet er als Gegensatzsignal die Möglichkeit, den Rückgang zu kaufen.

Mit diesem Design zielt die Strategie darauf ab, während dauerhafter Aufwärtstrends effizient auf Aufwärtstrends zu profitieren und gleichzeitig das Risiko mit Stop-Losses zu kontrollieren.

Vorteile

Die Strategie zur Umkehrung des doppelten gleitenden Durchschnitts weist folgende Hauptvorteile auf:

  1. Die Strategie ist einfach und leicht verständlich.
  2. Die doppelten gleitenden Durchschnittsfilter lassen kurz- und langfristige Trends effektiv erkennen.
  3. Es bietet eine gute Zeiteffizienz, indem es kurzfristige Umkehrungen nutzt.
  4. Der eingebaute Stop-Loss-Mechanismus kontrolliert das Risiko einzelner Positionen streng.
  5. Durch die flexible Parametrierung ist diese Strategie für Indizes und Aktien weit verbreitet.

Risiken

Obwohl die Strategie generell wirksam ist, hat sie folgende Einschränkungen:

  1. Die Strategie sollte bei ausgedehnten Konsolidierungen deaktiviert werden.
  2. Eine ausschließliche Abhängigkeit von gleitenden Durchschnitten hat Einschränkungen bei der Signalgenauigkeit.
  3. Die festgelegte Stop-Loss-Methode ist unflexibel, andere Stop-Loss-Techniken könnten getestet werden.
  4. Optimale Parameter müssen für verschiedene Märkte kalibriert werden. Unteroptimale Einstellungen verringern die Zuverlässigkeit.

Möglichkeiten zur Verbesserung

Zu den weiteren Verbesserungen dieser Strategie gehören:

  1. Test anderer gleitender Durchschnittslängen, um die optimale Kombination zu finden.
  2. Hinzufügen unterstützender Indikatoren, um zuverlässigere Signale zu erzeugen, z. B. Volumen- und Volatilitätsmetriken.
  3. Erforschen Sie andere Stop-Loss-Techniken wie Trailing-Stop-Loss, zeitbasierte Stop-Loss.
  4. Aufbau von Anpassungsfähigkeiten in die Einstiegsregeln und Stop-Loss-Parameter, die eine Anpassung an sich ändernde Marktdynamiken ermöglichen.
  5. Einbeziehung von Algorithmen des maschinellen Lernens zur weiteren Optimierung von Parametern unter Verwendung historischer Daten.

Schlussfolgerung

Zusammenfassend ist die Dual Moving Average Reversal Strategy ein äußerst praktischer Ansatz. Sie ermöglicht eine profitable Pullback-Fading während anhaltender Aufwärtstrends mithilfe einer gleitenden Durchschnittsanalyse in Verbindung mit Stop-Losses. Sie bietet auch Marktregime-Erkennung und Risikokontrolle. Mit kontinuierlicher Verbesserung bietet die Strategie ein starkes Potenzial, differenzierte Performance zu liefern.


/*backtest
start: 2023-11-24 00:00:00
end: 2023-12-24 00:00:00
period: 1h
basePeriod: 15m
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/
// © Gold_D_Roger
//note: spreading 1 statement over multiple lines needs 1 apce + 1 tab | multi line function is 1 tab
//Recommended tickers: SPY (D), QQQ (D) and big indexes, AAPL (4H)

//@version=5
strategy("Davin's 10/200MA Pullback on SPY Strategy v2.0",
     overlay=true,
     initial_capital=10000,
     default_qty_type=strategy.percent_of_equity,
     default_qty_value=10, // 10% of equity on each trade
     commission_type=strategy.commission.cash_per_contract, 
     commission_value=0.1) //Insert your broker's rate, IB is 0.005USD or tiered

//Best parameters
// SPY D
// Stop loss 0.15
// commission of 0.005 USD using Interactive brokers
// Exit on lower close 
// Buy more when x% down --> 14%
// DO NOT include stop condition using MA crossover

// Get User Input
i_ma1           = input.int(title="MA Length 1", defval=200, step=10, group="Strategy Parameters", tooltip="Long-term MA 200")
i_ma2           = input.int(title="MA Length 2", defval=10, step=10, group="Strategy Parameters", tooltip="Short-term MA 10")
i_ma3           = input.int(title="MA Length 3", defval=50, step=1, group="Strategy Parameters", tooltip="MA for crossover signals`")
i_stopPercent   = input.float(title="Stop Loss Percent", defval=0.15, step=0.01, group="Strategy Parameters", tooltip="Hard stop loss of 10%")
i_startTime     = input(title="Start filter", defval=timestamp("01 Jan 2013 13:30 +0000"), group="Time filter", tooltip="Start date and time to begin")
i_endTime       = input(title="End filter", defval=timestamp("01 Jan 2099 19:30 +0000"), group="Time filter", tooltip="End date and time to stop")
i_lowerClose    = input.bool(title="Exit on lower close", defval=true, group="Strategy Parameters", tooltip="Wait for lower close after above 10SMA before exiting") // optimise exit strat, boolean type creates tickbox type inputs
i_contrarianBuyTheDip = input.bool(title="Buy whenever more than x% drawdown", defval=true, group="Strategy Parameters", tooltip="Buy the dip! Whenever x% or more drawdown on SPY")
i_contrarianTrigger = input.int(title="Trigger % drop to buy the dip", defval=14, step=1, group="Strategy Parameters", tooltip="% drop to trigger contrarian Buy the Dip!") 
//14% to be best for SPY 1D
//20% best for AMZN 1D
i_stopByCrossover_MA2_3 = input.bool(title="Include stop condition using MA crossover", defval=false, group="Strategy Parameters", tooltip="Sell when crossover of MA2/1 happens")

// Get indicator values
ma1 = ta.sma(close,i_ma1) //param 1
ma2 = ta.sma(close,i_ma2) //param 2
ma3 = ta.sma(close,i_ma3) //param 3
ma_9 = ta.ema(close,9) //param 2
ma_20 = ta.ema(close,20) //param 3

// Check filter(s)
f_dateFilter = true //make sure date entries are within acceptable range

// Highest price of the prev 52 days: https://www.tradingcode.net/tradingview/largest-maximum-value/#:~:text=()%20versus%20ta.-,highest(),max()%20and%20ta.
highest52 = ta.highest(high,52)
overall_change = ((highest52 - close[0]) / highest52) * 100

// Check buy/sell conditions
var float buyPrice = 0 //intialise buyPrice, this will change when we enter a trade ; float = decimal number data type 0.0
buyCondition  = (close > ma1 and close < ma2 and strategy.position_size == 0 and f_dateFilter) or (strategy.position_size == 0 and i_contrarianBuyTheDip==true and overall_change > i_contrarianTrigger and f_dateFilter) // higher than 200sma, lower than short term ma (pullback) + avoid pyramiding positions
sellCondition = close > ma2 and strategy.position_size > 0 and (not i_lowerClose or close < low[1])  //check if we already in trade + close above 10MA; 
// third condition: EITHER i_lowerClose not turned on OR closing price has to be < previous candle's LOW [1]

stopDistance  = strategy.position_size > 0 ? ((buyPrice - close)/close) : na // check if in trade > calc % drop dist from entry, if not na
stopPrice     = strategy.position_size > 0 ? (buyPrice - (buyPrice * i_stopPercent)) : na // calc SL price if in trade, if not, na
stopCondition = (strategy.position_size > 0 and stopDistance > i_stopPercent) or (strategy.position_size > 0 and (i_stopByCrossover_MA2_3==true and ma3 < ma1))


// Enter positions
if buyCondition 
    strategy.entry(id="Long", direction=strategy.long) //long only

    
if buyCondition[1] // if buyCondition is true prev candle
    buyPrice := open // entry price = current bar opening price

// Exit position
if sellCondition or stopCondition 
    strategy.close(id="Long", comment = "Exit" + (stopCondition ? "Stop loss=true" : "")) // if condition? "Value for true" : "value for false"
    buyPrice := na //reset buyPrice

// Plot
plot(buyPrice, color=color.lime, style=plot.style_linebr)
plot(stopPrice, color=color.red, style=plot.style_linebr, offset = -1)
plot(ma1, color=color.blue) //defval=200
plot(ma2, color=color.white) //defval=10
plot(ma3, color=color.yellow) // defval=50






Mehr