Preisausbruchsstrategie mit dynamischer Trailing-Stop-Long-Position und saisonalem Filter


Erstellungsdatum: 2024-02-27 14:01:56 zuletzt geändert: 2024-02-27 14:01:56
Kopie: 0 Klicks: 631
1
konzentrieren Sie sich auf
1621
Anhänger

Preisausbruchsstrategie mit dynamischer Trailing-Stop-Long-Position und saisonalem Filter

Überblick

Die Strategie basiert auf dem dynamischen beweglichen Indikator (DMI) und hat eine langfristige Strategie, die nur mehrere Köpfe macht, während die Folgeverluste in Kombination mit der durchschnittlichen tatsächlichen Breite (ATR) durchgeführt werden, um das Verlustrisiko zu kontrollieren. Zur weiteren Optimierung ist die Strategie auch in die Handelszeiten und die saisonalen Filterbedingungen des S&P 500-Index integriert, was einen gewissen Vorteil hat.

Strategieprinzip

  1. Die Strategie besteht darin, nur an bestimmten Handelstagen (Montag bis Freitag) und zu bestimmten Handelszeiten (default 9.30 bis 20.30 Uhr Ortszeit) Positionen zu eröffnen.

  2. Wenn der ADX größer als 27 ist, ist er in einem Preistrend. Wenn der +DI-Line die -DI-Line durchbricht, erzeugt er ein Mehrwertsignal.

  3. Nach dem Börsengang wird ein Stop-Loss-Bereich mit einer Höhe von 5,5 ATR eingestellt, wobei die Stop-Line mit steigenden Preisen nach oben bewegt wird, um einen Gewinn zu sichern.

  4. Die saisonale Regel des S&P 500 Index kann optional angewendet werden und nur in historisch günstigen Zeiten eröffnet werden.

Analyse der Stärken

  1. In Kombination mit Trendindikatoren und Stop-Loss-Mechanismen können Trends effektiv verfolgt und Verluste für einzelne Positionen kontrolliert werden.

  2. Die Verwendung von Handelszeiten und saisonalen Filterbedingungen vermeidet außergewöhnliche Schwankungen des Marktes und reduziert die Falschmeldung.

  3. Die DMI und ATR sind ausgereifte technische Indikatoren, die sich flexibel an die Parameter anpassen lassen und für die quantitative Optimierung geeignet sind.

Risikoanalyse

  1. Die falsche Einstellung der DMI- und ATR-Parameter kann zu viel oder zu wenig Signal erzeugen. Die Parameter müssen für Tests angepasst werden.

  2. Die Stop-Loss-Marge ist so groß, dass unnötige Verluste verursacht werden können. Die Stop-Loss-Marge ist so klein, dass die Verluste nicht effektiv kontrolliert werden können.

  3. Handelszeiten und saisonale Regeln können Gewinne ausfiltern. Der Effekt der Schwankungen muss bewertet werden.

Optimierungsrichtung

  1. Die Ein- und Ausstiegsregeln können in Kombination mit anderen Indikatoren wie MACD, Brinband usw. in Betracht gezogen werden.

  2. Verschiedene ATR-Multiplikator-Stop-Methoden können getestet werden, und es kann auch eine dynamische Anpassung der Stop-Werte in Betracht gezogen werden.

  3. Es kann getestet werden, um die Zeitspanne der Transaktionen anzupassen oder die Anfangs- und Endzeiten der saisonalen Transaktionen zu optimieren.

  4. Es kann versucht werden, die Parameter automatisch zu optimieren, indem man Methoden des maschinellen Lernens anwendet.

Zusammenfassen

Die Strategie integriert Trendanalysen und Risikokontrolltechniken und überwindet zu einem gewissen Grad die starken Schwankungen der Trendverfolgungsstrategie. Die Hinzufügung von Handelszeiten und saisonalen Filterungen reduziert die Fehlsignale. Durch die Optimierung der Parameter und die Erweiterung der Funktionen kann die Strategie bessere stabile Erträge erzielen.

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