Dynamischer Nachfolgestart Lang nur Trend nach Strategie mit Saisonalitätsfilter

Schriftsteller:ChaoZhang, Datum: 2024-02-27 14:01:56
Tags:

img

Übersicht

Diese Strategie entwirft eine auf dem Dynamic Movement Index (DMI) basierende Strategie, bei der ein Durchschnittlicher Wahrer Bereich (ATR) nach dem Stop-Loss folgt, um Abwärtsrisiken zu kontrollieren.

Strategie Logik

  1. Die Strategie tritt nur an bestimmten Handelstagen (Mon-Freitag) und Handelszeiten (Standard 9: 30 Uhr - 20: 30 Uhr Ortszeit) ein.

  2. Wenn der ADX über 27 liegt, signalisiert dies, dass der Markt in einem Trend ist.

  3. Nach Eröffnung einer Position wird der Stop-Loss auf 5,5 x ATR vom Einstiegspreis festgelegt und steigt mit steigendem Preis nach oben, um Gewinne zu erzielen.

  4. Optional sind saisonale Muster des S&P500 aktiviert, so dass nur in historisch bullischen Perioden gehandelt wird.

Analyse der Vorteile

  1. Die Kombination von Trendmetriken und Stop Loss hilft, Trends effektiv zu steuern und Verluste pro Handel zu kontrollieren.

  2. Handelszeiten und Saisonalitätsfilter helfen, abnormale Volatilität zu vermeiden und falsche Signale zu reduzieren.

  3. DMI und ATR sind ausgereifte technische Indikatoren mit Flexibilität bei der Parameter-Ausrichtung, die für die Quant-Optimierung geeignet sind.

Risikoanalyse

  1. Bei falschen DMI- und ATR-Parametern kann es zu zu vielen oder zu wenigen Signalen kommen.

  2. Ein zu breites Stop Loss kann zu unnötigen Stops führen, ein zu enges Set kann Verluste nicht kontrollieren.

  3. Die Handelszeiten und die Regeln der Saisonalität können einige profitable Möglichkeiten filtern.

Optimierungsrichtlinien

  1. Sie sollten andere Indikatoren wie MACD, Bollinger Bands für Ein- und Ausstiegsregeln kombinieren.

  2. Versuche verschiedene ATR-Multiplikatoren für den Stoppverlust oder die dynamische Anpassung der Stoppverlustskala.

  3. Testen Sie die Anpassung der Handelszeiten oder die Optimierung der saisonalen Ein- und Ausstiegsdaten.

  4. Versuchen Sie, maschinelle Lernmethoden für die automatische Abstimmung von Parametern anzuwenden.

Schlussfolgerung

Diese Strategie integriert Trend-Following- und Risikokontrolltechniken, um hohe Volatilitätsprobleme mit Trendsystemen zu überwinden.


/*backtest
start: 2024-01-27 00:00:00
end: 2024-02-26 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy(title="DMI Strategy with ADX and ATR-based Trailing SL (Long Only) and Seasonality", shorttitle="MBV-SP500-CLIMBER", overlay=true)

// Eingabeparameter für Long-Positionen
len = input.int(14, minval=1, title="DI Length")
lensig = input.int(14, title="ADX Smoothing", minval=1, maxval=50)
adxLongThreshold = input.float(27.0, title="ADX Threshold for Long", minval=0)
atrLength = input.int(14, title="ATR Length")
atrLongMultiplier = input.float(5.5, title="ATR Multiplier for Trailing SL (Long)")

startTimeHH = input.int(09, title="startTime hh")
startTimeMM = input.int(30, title="startTime mm")

endTimeHH = input.int(20, title="endTime hh")
endTimeMM = input.int(30, title="endTime mm")

// Zeitzone des Nutzers als Eingabeparameter
timezoneOffset = input.int(1, title="Timezone Offset (Hours from UTC)", minval=-12, maxval=14)


// Zusätzliche Einstellung für SP500-Saisonalität
enableSeasonality = input.bool(false, title="Enable SP500 Seasonality")
seasonColor = color.new(color.blue, 90)
activeTimeColor = color.new(color.yellow, 90) // Farbe für aktive Handelszeiten

// Handelstage und -zeiten
tradeMonday = input.bool(true, title="Trade on Monday")
tradeTuesday = input.bool(true, title="Trade on Tuesday")
tradeWednesday = input.bool(true, title="Trade on Wednesday")
tradeThursday = input.bool(true, title="Trade on Thursday")
tradeFriday = input.bool(true, title="Trade on Friday")

// Konvertierung der Uhrzeit in Unix-Zeitstempel
getUnixTime(hour, minute) =>
    adjustedHour = hour - timezoneOffset
    sessionDate = timestamp(year, month, dayofmonth, 0, 0)
    sessionDate + adjustedHour * 60 * 60000 + minute * 60000

// Start- und Endzeit als Unix-Zeitstempel
// + 1 Stunde wegen UTC
startTime = getUnixTime(startTimeHH, startTimeMM)
endTime = getUnixTime(endTimeHH, endTimeMM)


// Überprüfen, ob der aktuelle Zeitpunkt innerhalb der Handelszeit liegt
isTradingTime() => true

// Saisonale Zeiträume definieren
isSeason(time) =>
    m = month(time)
    d = dayofmonth(time)
    (m == 1 and d >= 1) or (m == 2 and d <= 15) or (m == 3 and d >= 23) or (m == 4 and d <= 17) or (m == 5 and d >= 12) or (m == 6 and d >= 27 and d <= 8) or (m == 7 and d <= 29) or (m == 10 and d >= 15) or (m == 11 and d >= 1) or (m == 12 and d <= 2) or (m == 12 and d >= 20 and d <= 27)

// Hintergrundfarbe für saisonale Bereiche und aktive Handelszeiten
bgcolor(enableSeasonality and isSeason(time) ? seasonColor : na)
bgcolor(isTradingTime() ? color.new(activeTimeColor, 90) : na)

// Berechnung von +DM, -DM, ATR
up = ta.change(high)
down = -ta.change(low)
plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
trur = ta.rma(ta.tr, len)
atr = ta.atr(atrLength)

// Berechnung von +DI, -DI und ADX
plus = fixnan(100 * ta.rma(plusDM, len) / trur)
minus = fixnan(100 * ta.rma(minusDM, len) / trur)
sum = plus + minus
adx = 100 * ta.rma(math.abs(plus - minus) / (sum == 0 ? 1 : sum), lensig)

// Logik für LONG Signale unter Berücksichtigung der Saisonalität und Zeitfilter
longSignal = ta.crossover(adx, adxLongThreshold) and plus > minus and isTradingTime()
longSignal := longSignal and (not enableSeasonality or (enableSeasonality and isSeason(time)))


// Variable für Trailing Stop-Loss
var float longTrailingSL = na

// Variablen für die Eröffnungszeit und den Eröffnungspreis der Position
var int openBarIndex = na
var float openPrice = na

// Handelslogik für Long-Positionen
// ohne strategy.position_size == 0 gilt die Kondition für ALLE Signale und nicht nur für das erste
if (longSignal and strategy.position_size == 0)
    strategy.entry("Long", strategy.long)
    openBarIndex := bar_index
    openPrice := close
    longTrailingSL := close - atr * atrLongMultiplier

//if (longSignal)
   //longTrailingSL := close - atr * atrLongMultiplier

// Aktualisierung des Trailing Stop-Loss
if strategy.position_size > 0
    longTrailingSL := math.max(longTrailingSL, close - atr * atrLongMultiplier)

// Ausstieg aus Long-Positionen
strategy.exit("Close Long", "Long", stop=longTrailingSL)

// Anzeige des ATR-basierten Trailing Stops für Long-Positionen
//plot(strategy.position_size > 0 ? longTrailingSL : na, color=color.red, title="ATR Trailing Stop Long")

// Anzeige des ATR-basierten Trailing Stops für Long-Positionen
plot(strategy.position_size > 0 ? longTrailingSL : na, color=color.new(color.red, 75), style=plot.style_circles, linewidth=1, title="Trailing Stop-Loss")


// Wenn eine Position geschlossen wird, zeichnen Sie die Linie
// if strategy.position_size[1] > 0 and strategy.position_size == 0
//     lineColor = longTrailingSL > openPrice ? color.new(color.green, 50) : color.new(color.red, 50) // Hellgrün für Gewinne, Hellrot für Verluste
//     line.new(openBarIndex, openPrice, bar_index, longTrailingSL, width=3, color=lineColor)


Mehr