동적 추적 정지 길게만 트렌드를 따라 시즌 필터와 전략

저자:차오장, 날짜: 2024-02-27 14:01:56
태그:

img

전반적인 설명

이 전략은 동적 움직임 지수 (DMI) 를 기반으로 한 장기 트렌드 다음 전략을 설계하며, 하향 위험을 제어하기 위해 평균 진정한 범위 (ATR) 를 추적합니다. 또한 추가 최적화 및 가장자리를 위해 거래 시간 및 S&P500 계절성 필터를 통합합니다.

전략 논리

  1. 이 전략은 특정 거래일 (월~금) 및 거래 시간 (현지 시간 기준 오전 9시 30분~오후 8시 30분) 에만 거래를 합니다.

  2. ADX가 27보다 높을 때 시장이 트렌드에 있음을 신호합니다. +DI가 -DI보다 높으면 긴 신호가 생성됩니다.

  3. 포지션을 열고 나면, 스톱 로스는 입상 가격의 5.5x ATR로 설정되며, 가격 상승에 따라 수익을 확보하기 위해 상승합니다.

  4. 선택적으로, S&P500 계절 패턴이 활성화되어 있어 거래는 역사적으로 상승기간에만 발생합니다.

이점 분석

  1. 트렌드 메트릭과 스톱 로스를 결합하면 트렌드를 효과적으로 타고 거래당 손실을 제어할 수 있습니다.

  2. 거래 시간 및 계절성 필터는 비정상적인 변동성을 피하고 잘못된 신호를 줄이는 데 도움이됩니다.

  3. DMI와 ATR는 양자 최적화에 적합한 매개 변수 조정의 유연성을 가진 성숙한 기술 지표입니다.

위험 분석

  1. 잘못된 DMI 및 ATR 매개 변수는 너무 많은 신호 또는 너무 적은 신호로 이어질 수 있습니다. 매개 변수 조정이 필요합니다.

  2. 너무 넓게 설정된 스톱 손실은 불필요한 스톱을 유발할 수 있습니다. 너무 단단하게 설정하면 손실을 제어할 수 없습니다.

  3. 거래 시간 및 계절성 규칙은 수익성있는 기회를 필터링 할 수 있습니다. 필터 효과는 평가되어야합니다.

최적화 방향

  1. MACD, 볼링거 밴드 같은 다른 지표를 결합하여 입출구 규칙을 고려하십시오.

  2. 스톱 손실 또는 스톱 손실 스케일의 동적 조정을 위해 다른 ATR 배수를 테스트합니다.

  3. 거래시간을 조정하거나 계절별 입출출 날짜를 최적화하는 테스트

  4. 자동 조정 매개 변수에 기계 학습 방법을 적용해보세요.

결론

이 전략은 트렌드 시스템에서 높은 변동성을 극복하기 위해 트렌드 추적 및 리스크 제어 기술을 통합합니다. 거래 시간 및 계절 필터를 추가하면 잘못된 신호가 더욱 감소합니다. 매개 변수 조정 및 기능 확장으로이 전략은 더 안정적인 이익을 얻을 수 있습니다.


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


더 많은