
この戦略は,動的移動指標 ((DMI)) をベースに,多頭のみの長線戦略を設計し,平均実波幅 ((ATR) と組み合わせて尾行ストップを行うことで,損失のリスクを制御する.さらに最適化するために,この戦略は,取引時間とスタンプラー500指数の季節的なフィルタリング条件を組み込むこともある.
この戦略は,指定された取引日 (月曜日から金曜日) と取引時間 (デフォルトの現地時間9:30-20:30) にのみポジションを開きます.
ADXが27より大きいとき,現在の価格トレンド状態であることを示す。このとき,もし+DI線がDI線を貫くならば,多行信号を生成する。
取引開始後,ATRの5.5倍でストップを設定し,ストップラインは価格の上昇に伴い上昇し,利益を確保します.
S&P500の季節ルールが選択的に適用され,歴史上最も良い時期でのみポジションを開きます.
トレンド指数とストップ・ローズメカニズムを組み合わせて,効率的にトレンドを追跡し,個々のポジションの損失を制御します.
取引時間と季節的なフィルタリング条件を利用することで,市場の異常な波動期を回避し,誤報率を下げることができる.
DMIとATRは成熟した技術指標であり,パラメータの調整が柔軟で,量化最適化に適しています.
DMIとATRのパラメータを正しく設定しない場合,信号が多すぎたり少すぎたりすることがあります.テストのためにパラメータを調整する必要があります.
止損幅は,不必要な止損を引き起こす可能性があることを大きく設定する. 止損幅は,損失を効果的に制御できない可能性があることを小さく設定する.
取引時間や季節のルールにより,利益の機会の一部を排除する可能性があります. 波効果を評価する必要があります.
MACD,ブリン帯などの他の指標と組み合わせて,入場・出場ルールを設計することも考えられます.
異なるATR倍数ストップをテストし,ストップ幅を動的に調整することも考えられます.
取引の時間帯を調整したり,季節的な取引の開始終了時間を最適化したりできます.
自動最適化パラメータは,機械学習の方法を適用して試すことができます.
この戦略は,トレンド分析とリスク管理技術を統合し,トレンド追跡戦略の激しい変動の問題をある程度克服しています.同時に,取引時間と季節的なフィルターを追加することで,誤信号を減らすことができます.パラメータの調整と機能拡張により,この戦略は,より良い安定した収益を得ることができます.
/*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)