Eine ATR- und Breakout-basierte ETF-Handelsstrategie

Schriftsteller:ChaoZhang, Datum: 26.12.2023
Tags:

img

Übersicht

Dies ist eine ETF-Algorithmus-Handelsstrategie, die auf der Basis von Average True Range (ATR) und Preis-Breakout basiert.

Strategie Logik

Die Strategie beruht hauptsächlich auf folgenden Grundsätzen:

  1. Verwenden Sie die höchsten und niedrigsten Preise eines bestimmten Zeitraums (z. B. 20 Kerzen), um den Kurstrend und die Kursrichtung zu bestimmen.

  2. Verwenden Sie ATR, um den Stop-Loss-Level dynamisch zu berechnen. Der Stop-Loss wird an einem Abstand des ATR-Wertes eines ATR-Zeitraums multipliziert mit einem Koeffizienten (z. B. 2) vom Einstiegspreis platziert.

  3. Verwenden Sie ATR, um die Gewinnspanne zu bestimmen. Der Gewinnspanne wird an einem Abstand des ATR-Wertes eines ATR-Zeitraums multipliziert mit einem Koeffizienten (z. B. 1) vom Einstiegspreis platziert.

  4. Verwenden Sie den ATR-Trailer-Multiplikator, um Stop-Loss zu verfolgen.

Die Strategie ist einfach und zuverlässig, da sie sowohl die Kursentwicklungsrichtung berücksichtigt, um die Kursbewegungen rechtzeitig zu erfassen, als auch Stop-Loss und Take-Profit für die Gewinnentnahme und Risikokontrolle festlegt.

Analyse der Vorteile

Zu den Vorteilen dieser Strategie gehören:

  1. Die Strategielogik ist einfach und klar, leicht verständlich und umsetzbar.

  2. Die Verwendung von ATR zur Berechnung von adaptiven Stop-Loss- und Take-Profit-Levels hilft bei der flexiblen Positionsgröße und Risikokontrolle.

  3. Breakout-Strategien sind gut darin, Preistrends zu erfassen, was zu guten Renditen führt.

  4. Der Trailer Stop Loss kann Positionen rechtzeitig schließen und übermäßige Verluste vermeiden.

  5. Es eignet sich für Produkte mit offensichtlichen Trends, wie ETFs und Aktien.

Risikoanalyse

Zu den Risiken der Strategie gehören:

  1. Bei der Preiskonsolidierung können mehr falsche Signale und Umkehröffnungen auftreten.

  2. Eine unsachgemäße Einstellung der Parameter kann zu fehlenden Kursentwicklungen oder zu vielen unnötigen Trades führen.

  3. Extreme Parameterwerte können zu einem übermäßig aggressiven oder übermäßig konservativen Stop-Loss und Take-Profit führen und die Rentabilität der Strategie beeinflussen.

  4. Auch die zugrunde liegenden Risiken von ETFs, wie Politik- und Prämienrisiken, können sich auf die Strategieleistung auswirken.

Entsprechende Lösungen

  1. Optimieren Sie die Parameter, um unnötige Transaktionen zu verringern.
  2. Fügen Sie mehr Faktoren und Filter hinzu, um Handelssignale zu bestätigen.
  3. Anpassung der Parameter an unterschiedliche Märkte.
  4. Diversifizierung der Anlage- und Kontrollpositionsgröße eines einzigen ETF.

Optimierungsrichtlinien

Die Strategie kann in folgenden Aspekten weiter optimiert werden:

  1. Fügen Sie Indikatoren wie gleitenden Durchschnitt hinzu, um falsche Signale auszufiltern.

  2. Entwicklung eines modularisierten Parameteroptimierungsmoduls zur automatischen Abstimmung von Parametern für verschiedene Zeiträume und Produkte.

  3. Einführung von Modellen für maschinelles Lernen zur Vorhersage der nächsten Höchst- und Tiefstpreise der Kerze zur Bestimmung von Ausbruchssignalen.

  4. Um einen falschen Ausbruch zu vermeiden, sollten Sie einen Handelsvolumenüberschuss in Betracht ziehen.

  5. Optimierung der ursprünglichen Positionsgröße und der Zuteilungsprozentsätze anpassungsfähig für verschiedene Produkte und Marktsysteme.

Schlussfolgerung

Die Strategie hat eine klare und einfache Logik. Die Kernmechanismen von Breakout und adaptivem ATR Stop-Loss/Take-Profit können Risiken effektiv kontrollieren und Gewinne einfangen.


/*backtest
start: 2023-12-18 00:00:00
end: 2023-12-21 03:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © FX_minds

//@version=4
strategy("ETF tradedr", overlay=true, pyramiding=100, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

//------------------------------ get user input
lookback                   = input(title="HH LL lookback", type=input.integer, defval=20)
ATR_periode                = input(title="ATR period", type=input.integer, defval=14)
ATR_SL_multiplier          = input(title="ATR SL multiplier", type=input.float, defval=2)
ATR_TP_multiplier          = input(title="ATR TP multiplier", type=input.float, defval=1)
trailing_SL_ATR_multiplier = input(title="ATR trailing SL multiplier", type=input.float, defval=3.5)
lookback_trailing_SL       = input(title="trailing SL lookback", type=input.integer, defval=4)
max_sequel_trades          = input(title="max sequel trades", type=input.float, defval=1)
trade_long                 = input(title= "trade long ?", type=input.bool, defval=true)
trade_short                = input(title= "trade short ?", type=input.bool, defval=false)

//------------------------------ determine entry conditions
long_condition   = barstate.isconfirmed and crossover(high, highest(high, lookback)[1])
short_condition  = barstate.isconfirmed and crossunder(low, lowest(low, lookback)[1])


//------------------------------ count open long trades
count_open_longs = 0
count_open_longs := nz(count_open_longs[1])

if (long_condition) 
    count_open_longs := count_open_longs +1
    //label.new(bar_index, low, tostring(count_open_longs, "#"), xloc.bar_index, yloc.belowbar, color.green, label.style_none, color.green, size.large)

if (short_condition)
    count_open_longs := 0


//------------------------------ count open short trades
count_open_shorts = 0
count_open_shorts := nz(count_open_shorts[1])

if (short_condition)
    count_open_shorts := count_open_shorts +1
    //label.new(bar_index, low, tostring(count_open_shorts, "#"), xloc.bar_index, yloc.belowbar, color.red, label.style_none, color.red, size.large)

if (long_condition)
    count_open_shorts := 0


//------------------------------ calculate entryprice
entryprice_long = long_condition ? close : na
entryprice_short = short_condition ? close : na


//------------------------------ calculate SL & TP
SL_distance = atr(ATR_periode) * ATR_SL_multiplier
TP_distance  = atr(ATR_periode) * ATR_TP_multiplier
trailing_SL_distance = atr(ATR_periode) * trailing_SL_ATR_multiplier

SL_long = entryprice_long - SL_distance
SL_short = entryprice_short + SL_distance

trailing_SL_short = lowest(close, lookback_trailing_SL) + trailing_SL_distance
trailing_SL_long  = highest(close, lookback_trailing_SL) - trailing_SL_distance

trailing_SL_short_signal = crossover(high, trailing_SL_short[1])
trailing_SL_long_signal = crossunder(low, trailing_SL_long[1])


//------------------------------ plot entry price & SL  
plot(entryprice_long, style=plot.style_linebr, color=color.white)
plot(SL_long, style=plot.style_linebr, color=color.red)
plot(SL_short, style=plot.style_linebr, color=color.green)
plot(trailing_SL_short, style=plot.style_linebr, color=color.red)
plot(trailing_SL_long, style=plot.style_linebr, color=color.green)


//------------------------------ submit entry orders
if (long_condition) and (count_open_longs <= max_sequel_trades) and (trade_long == true)
    strategy.entry("Long" + tostring(count_open_longs, "#"), strategy.long)
    strategy.exit("SL Long"+ tostring(count_open_longs, "#"), 
     from_entry="Long" + tostring(count_open_longs, "#"), stop=SL_long)

if (short_condition) and (count_open_shorts <= max_sequel_trades) and (trade_short == true)
    strategy.entry("Short" + tostring(count_open_shorts, "#"), strategy.short)
    strategy.exit("SL Short" + tostring(count_open_shorts, "#"), 
     from_entry="Short" + tostring(count_open_shorts, "#"), stop=SL_short)
    

//------------------------------ submit exit conditions
if (trailing_SL_long_signal)
    strategy.close("Long" + tostring(count_open_longs, "#"))
    strategy.close("Long" + tostring(count_open_longs-1, "#"))
    strategy.close("Long" + tostring(count_open_longs-2, "#"))
    strategy.close("Long" + tostring(count_open_longs-4, "#"))
    strategy.close("Long" + tostring(count_open_longs-5, "#"))
    strategy.close("Long" + tostring(count_open_longs-6, "#"))
    strategy.close("Long" + tostring(count_open_longs-7, "#"))
    strategy.close("Long" + tostring(count_open_longs-8, "#"))
    strategy.close("Long" + tostring(count_open_longs-9, "#"))
    
if (trailing_SL_short_signal)
    strategy.close("Short" + tostring(count_open_shorts, "#"))
    strategy.close("Short" + tostring(count_open_shorts-1, "#"))
    strategy.close("Short" + tostring(count_open_shorts-2, "#"))
    strategy.close("Short" + tostring(count_open_shorts-3, "#"))
    strategy.close("Short" + tostring(count_open_shorts-4, "#"))
    strategy.close("Short" + tostring(count_open_shorts-5, "#"))
    strategy.close("Short" + tostring(count_open_shorts-6, "#"))
    strategy.close("Short" + tostring(count_open_shorts-7, "#"))
    strategy.close("Short" + tostring(count_open_shorts-8, "#"))
    strategy.close("Short" + tostring(count_open_shorts-9, "#"))



Mehr