Estratégia de rompimento de preço com posição longa de trailing stop dinâmico e filtro sazonal


Data de criação: 2024-02-27 14:01:56 última modificação: 2024-02-27 14:01:56
cópia: 0 Cliques: 628
1
focar em
1617
Seguidores

Estratégia de rompimento de preço com posição longa de trailing stop dinâmico e filtro sazonal

Visão geral

Esta estratégia baseia-se em um indicador móvel dinâmico (DMI) para desenhar uma estratégia de linha longa que só faz vários cabeçalhos, e ao mesmo tempo em combinação com a amplitude média real (ATR) para fazer um stop-loss de seguimento para controlar o risco de perda. Para otimização adicional, a estratégia também incorpora condições de filtragem sazonal do tempo de negociação e do índice S&P 500, com algumas vantagens.

Princípio da estratégia

  1. A estratégia só abriu posições nos dias de negociação designados (de segunda a sexta-feira) e nas horas de negociação (default local 9:30-20:30).

  2. Quando o ADX é maior que 27, ele está em uma tendência de preço.

  3. Depois de abrir a posição, o stop loss é definido em 5,5 vezes o ATR, e a linha de stop loss sobe com o aumento do preço, garantindo o lucro.

  4. Aplicação opcional da regra sazonal do S&P 500, abrindo posições apenas em períodos de melhor desempenho histórico.

Análise de vantagens

  1. A combinação de indicadores de tendência e mecanismos de stop loss permite um acompanhamento eficaz da tendência e o controle da perda de cada posição.

  2. O uso de filtros sazonais e horários de negociação permite evitar períodos de volatilidade anormal do mercado e reduzir a taxa de falsidade.

  3. DMI e ATR são indicadores técnicos maduros, com flexibilidade de ajuste de parâmetros, adequados para otimização quantitativa.

Análise de Riscos

  1. A configuração incorreta dos parâmetros DMI e ATR pode causar sinal excessivo ou insuficiente. Os parâmetros precisam ser ajustados para o teste.

  2. A quantidade de stop loss é maior do que a quantidade de stop loss desnecessária. A quantidade de stop loss menor do que a quantidade de stop loss que não pode ser eficazmente controlada.

  3. Os horários de negociação e as regras sazonais podem filtrar algumas oportunidades de lucro. Os efeitos de filtragem devem ser avaliados.

Direção de otimização

  1. Pode-se considerar a combinação de outros indicadores, como MACD, faixa de Bryn e outros, para projetar regras de entrada e saída.

  2. Pode-se testar diferentes métodos de stop loss do ATR, e também pode-se considerar o ajuste dinâmico da amplitude de stop loss.

  3. Pode-se testar o ajuste do período de negociação, ou otimizar o início e o fim de negociações sazonais.

  4. Pode-se tentar aplicar métodos de aprendizagem de máquina para otimizar automaticamente os parâmetros.

Resumir

Esta estratégia integra a análise de tendências com a tecnologia de controle de risco, superando, em parte, o problema da forte oscilação da estratégia de acompanhamento de tendências. Ao mesmo tempo, adicionar o tempo de negociação e a filtragem sazonal pode reduzir os sinais errados.

Código-fonte da estratégia
/*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)