
Cette stratégie est basée sur l’indicateur dynamique de mouvement (DMI) et a été conçue comme une stratégie de longue ligne qui ne fait que plusieurs têtes, tout en effectuant un arrêt de suivi en combinaison avec l’amplitude réelle moyenne (ATR) pour contrôler le risque de perte. Afin d’optimiser davantage, la stratégie intègre également des conditions de filtrage saisonnières pour les heures de négociation et l’indice S&P 500, avec un certain avantage.
La stratégie consiste à ouvrir des positions uniquement les jours de négociation indiqués (du lundi au vendredi) et les heures de négociation (de 9h30 à 20h30 heure locale par défaut).
Lorsque l’ADX est supérieur à 27, il indique qu’il est actuellement dans la tendance des prix.
Une fois la position ouverte, le stop loss est fixé à 5,5 fois l’ATR et la ligne de stop loss augmente avec l’augmentation du prix, assurant un profit.
La règle saisonnière de l’indice S&P 500 peut être appliquée de manière sélective, et les positions ne sont ouvertes que dans les meilleures périodes de l’histoire.
La combinaison d’un indicateur de tendance et d’un mécanisme de stop-loss permet de suivre efficacement la tendance et de contrôler la perte de chaque position.
Les conditions de filtrage saisonnière et les heures de négociation permettent d’éviter les périodes de volatilité exceptionnelle du marché et de réduire le taux de fausses informations.
Le DMI et l’ATR sont des indicateurs techniques matures, dont les paramètres sont adaptés pour une optimisation quantitative.
Une mauvaise configuration des paramètres DMI et ATR peut entraîner un signal trop ou trop faible. Il est nécessaire d’ajuster les paramètres pour les tester.
La marge de stop-loss est plus grande que la marge de stop-loss nécessaire. La marge de stop-loss est plus petite que la marge de stop-loss non contrôlable.
Les horaires de négociation et les règles saisonnières peuvent filtrer certaines opportunités de profit. L’effet de levier doit être évalué.
Les règles d’entrée et de sortie peuvent être envisagées en combinaison avec d’autres indicateurs, tels que le MACD, la ceinture de Brin, etc.
Il est possible de tester différents modes de stop multiples ATR et d’envisager d’ajuster dynamiquement le stop.
Il est possible d’ajuster la période de négociation ou d’optimiser le début et la fin des transactions saisonnières.
On peut essayer d’optimiser automatiquement les paramètres en appliquant des méthodes d’apprentissage automatique.
Cette stratégie intègre l’analyse de tendance et la technologie de contrôle des risques, ce qui surmonte dans une certaine mesure les problèmes d’oscillation des stratégies de suivi des tendances. En ajoutant des heures de négociation et des filtres saisonniers, les signaux erronés peuvent être réduits. Grâce à l’optimisation des paramètres et à l’extension des fonctions, cette stratégie peut obtenir de meilleurs rendements stables.
/*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)