Quantitative Handelsstrategie auf Basis von Supertrend-Indikatoren und Aktienkurvenhandel

Schriftsteller:ChaoZhang, Datum: 15.01.2024 Uhr
Tags:

img

Übersicht

Die Kernidee dieser Strategie besteht darin, den Supertrend-Indikator mit dem Aktienkurvenhandel zu kombinieren. Wenn der Supertrend-Indikator ein Kauf- oder Verkaufssignal erzeugt, führen wir den Handel nicht direkt aus. Stattdessen überprüfen wir, ob die aktuelle Aktienkurve unter ihrem gleitenden Durchschnitt liegt. Wir werden nur dann Positionen eröffnen, wenn die Aktienkurve über dem gleitenden Durchschnitt liegt. Wenn die Aktienkurve unter dem gleitenden Durchschnitt liegt, pausieren wir den Handel für die aktuelle Strategie. Dies kann die Ausweitung von Verlusten effektiv verhindern.

Strategie Logik

Diese Strategie besteht hauptsächlich aus zwei Teilen:

  1. Supertrend-Indikator
  2. Aktienkurvenhandel

Die Berechnungsformel für den Supertrend-Indikator lautet:

Obergrenze = Quellpreis - ATR-Multiplikator * ATR Unterer Band = Quellpreis + ATR-Multiplikator * ATR

Der Supertrend-Indikator verwendet den ATR, um die oberen und unteren Bands festzulegen. Ein Ausbruch über dem oberen Band steht für ein Verkaufssignal, während ein Ausbruch unter dem unteren Band für ein Kaufsignal steht.

Die Idee hinter dem Handel mit Aktienkurven ist, dass wir den gleitenden Durchschnitt der Aktienkurve der Strategie nehmen. Wenn die Aktienkurve unter ihren gleitenden Durchschnitt fällt, pausieren wir den Handel für die aktuelle Strategie und warten, bis die Aktienkurve über dem gleitenden Durchschnitt zurückfällt, bevor wir den Handel wieder aktivieren.

Diese Strategie kombiniert die beiden Techniken, so dass wir, nachdem der Supertrend-Indikator ein Handelssignal generiert hat, nicht direkt in Trades treten. Stattdessen überprüfen wir, ob die aktuelle Aktienkurve über ihrem gleitenden Durchschnitt liegt. Nur wenn beide Bedingungen erfüllt sind, werden wir Positionen eröffnen. Dies kann die Risiken des Supertrend-Indikators selbst wirksam mindern und übermäßige Verluste verhindern.

Vorteile

Die wichtigsten Vorteile dieser Strategie sind:

  1. Der Supertrend-Indikator selbst kann Verluste nicht wirksam eindämmen. Der Aktienkurvenhandel macht diesen Mangel aus.

  2. Wenn der Handel ungünstig wird, pausiert er den Handel, um übermäßige Verluste zu vermeiden.

  3. Der Handel wird automatisch unterbrochen, wenn die Aktienkurve unter den gleitenden Durchschnitt fällt, und wieder aufgenommen, wenn die Aktienkurve wieder über sie zurückspringt.

Risiken

Diese Strategie birgt auch einige Risiken:

  1. Bei falschen Parameter-Einstellungen kann der Handel mit Aktienkurven unwirksam werden.

  2. Es kann vorkommen, daß es bei einer Veränderung der Marktentwicklung nicht möglich ist, die Positionen umgehend anzupassen, was zu Verlusten führen kann.

  3. Es kann gute Handelschancen verpassen, während es darauf wartet, dass sich die Aktienkurve erholt.

Gegenmaßnahmen:

  1. Optimieren Sie die Parameter und wählen Sie den besten gleitenden Durchschnitt aus.

  2. Einbeziehung anderer Indikatoren zur Beurteilung des Trends und entsprechende Anpassung der Positionen.

  3. Verkürzung der Laufzeit des ausgesetzten Handels, um die Wahrscheinlichkeit fehlender Chancen zu verringern.

Optimierungsrichtlinien

Wir können die Strategie aus folgenden Gesichtspunkten optimieren:

  1. Versuche verschiedene Parameterkombinationen, um die optimale ATR-Periode und den Multiplikator zu finden.

  2. Versuchen Sie andere Arten von gleitenden Durchschnitten, wie exponentielle gleitende Durchschnitt, Hull gleitende Durchschnitt usw.

  3. Hinzufügen anderer Indikatoren zur Bestimmung der Marktentwicklung und Anpassung der Positionen bei Trendänderungen.

  4. Eine zu lange Periode kann Gelegenheiten verpassen, während eine zu kurze Periode zu häufig Pausen einlegen kann.

  5. Optimieren Sie die Bedingungen, um den Handel zu pausieren, z. B. setzen Sie eine Stop-Loss-Schwelle vor der Aussetzung.

Schlussfolgerung

Diese Strategie kombiniert den Supertrend-Indikator geschickt mit dem Aktienkurvenhandel und nutzt die Stärken beider Techniken. Die Testergebnisse zeigen, dass die Anwendung des Aktienkurvenhandels in den meisten Fällen tatsächlich die Rentabilität verringert. Als solche ist diese Strategie für defensive Trader besser geeignet. Mit Parameter- und Logikoptimierung kann sie zu einer sehr praktischen quantitativen Handelsstrategie werden.


/*backtest
start: 2023-01-14 00:00:00
end: 2024-01-14 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy('Supertrend & Equity curve with EMA', overlay=false, format=format.price, precision=2, initial_capital=100000)

eqlen = input.int(25, "EQ EMA len", group = "New Equity Curve Settings")
shEQandMA = input.bool(true, "Show Original Equity Curve and MA")
shEQfilt = input.bool(true, "Show Filtered Equity Curve by MA")

Periods = input(title='ATR Period', defval=10, group = "SuperTrend Settings")
src = input(hl2, title='Source', group = "SuperTrend Settings")
Multiplier = input.float(title='ATR Multiplier', step=0.1, defval=3.0, group = "SuperTrend Settings")
changeATR = input(title='Change ATR Calculation Method ?', defval=true, group = "SuperTrend Settings")

//SuperTrend Code
atr2 = ta.sma(ta.tr, Periods)
atr = changeATR ? ta.atr(Periods) : atr2
up = src - Multiplier * atr
up1 = nz(up[1], up)
up := close[1] > up1 ? math.max(up, up1) : up
dn = src + Multiplier * atr
dn1 = nz(dn[1], dn)
dn := close[1] < dn1 ? math.min(dn, dn1) : dn
trend = 1
trend := nz(trend[1], trend)
trend := trend == -1 and close > dn1 ? 1 : trend == 1 and close < up1 ? -1 : trend

// Strategy main code
buySignal = trend == 1 and trend[1] == -1
sellSignal = trend == -1 and trend[1] == 1
if buySignal
    strategy.entry('Long', strategy.long)
if sellSignal
    strategy.entry('Short', strategy.short)



//Equity Curve calcs
eq = strategy.netprofit
ch = ta.change(eq)
neq = ch != 0 ? eq : na
mova = ta.ema(neq,eqlen)

// New Equity Curve
var float neweq = 0
var int ttrades = 0
var int wintrades = 0
var int losetrades = 0

switch
    strategy.netprofit == strategy.netprofit[1]  => na
    strategy.netprofit < mova and strategy.netprofit[1] > mova  => neweq := neweq + ch
    strategy.netprofit < mova and strategy.netprofit[1] < mova => na
    strategy.netprofit > mova and strategy.netprofit[1] > mova => neweq := neweq + ch

newch = ta.change(neweq)
switch
    newch == 0 => na
    newch > 0 => 
        wintrades := wintrades +1
        ttrades := ttrades +1
    newch < 0 =>
        losetrades := losetrades +1
        ttrades := ttrades +1

//plot(eq, linewidth = 2)
//plot(mova, color=color.red)
//plot(neweq, color= color.green, linewidth = 3)


//Table 
var testTable = table.new(position = position.top_right, columns = 5, rows = 10, bgcolor = color.green, border_width = 1)
table.cell(table_id = testTable, column = 0, row = 0, text = "Strategy: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 1, row = 0, text = "Original: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 2, row = 0, text = "Equity Curve EMA: ", bgcolor=color.white)     

table.cell(table_id = testTable, column = 0, row = 1, text = "Total Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 2, text = "Win Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 3, text = "Lose Trades: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 4, text = "Win Rate: ", bgcolor=color.white)     
table.cell(table_id = testTable, column = 0, row = 5, text = "Net Profit: ", bgcolor=color.white)     

//Equity Curve EMA stat
table.cell(table_id = testTable, column = 2, row = 1, text = str.tostring(ttrades), bgcolor=color.white)     
table.cell(table_id = testTable, column = 2, row = 2, text = str.tostring(wintrades), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 3, text = str.tostring(losetrades), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 4, text = str.tostring(math.round(100*wintrades/ttrades,2)), bgcolor=color.white)
table.cell(table_id = testTable, column = 2, row = 5, text = str.tostring(math.round(neweq)), bgcolor=color.white)

//Original Strategy stat
// table.cell(table_id = testTable, column = 1, row = 1, text = str.tostring(strategy.closedtrades), bgcolor=color.white)     
// table.cell(table_id = testTable, column = 1, row = 2, text = str.tostring(strategy.wintrades), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 3, text = str.tostring(strategy.losstrades), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 4, text = str.tostring(math.round(100*strategy.wintrades/strategy.closedtrades,2)), bgcolor=color.white)
// table.cell(table_id = testTable, column = 1, row = 5, text = str.tostring(math.round(strategy.netprofit)), bgcolor=color.white)




//New Equity curve
var newcurve = array.new_float(0)
var int ida = 0
var bool printEQ = false
if newch !=0 
    array.push(newcurve, neweq)
if bar_index > last_bar_index - array.size(newcurve) - 1 - 20  and array.size(newcurve) > 20 
    printEQ := true
else
    printEQ := false

plot(printEQ and ida < strategy.closedtrades and shEQfilt ? array.get(newcurve, ida) : na, color=color.green, linewidth = 2)

if printEQ
    ida := ida + 1
if ida >= array.size(newcurve) and printEQ
    ida := array.size(newcurve) -1



//Original Equity curve
var newcurve2 = array.new_float(0)
var int ida2 = 0
var bool printEQ2 = false
if ch !=0 
    array.push(newcurve2, eq)
if bar_index > last_bar_index - array.size(newcurve2) - 1 - 20  and array.size(newcurve2) > 20 
    printEQ2 := true
else
    printEQ2 := false

plot(printEQ2 and ida2 < strategy.closedtrades and shEQandMA  ? array.get(newcurve2, ida2) : na, color=color.blue, linewidth = 2)

if printEQ2
    ida2 := ida2 + 1
if ida2 >= array.size(newcurve2) and printEQ2
    ida2 := array.size(newcurve2) -1



//Moving Average Array
var marray = array.new_float(0)
if ch
    array.push(marray, mova)

plot(printEQ2 and  array.size(marray) > 40 and shEQandMA ? array.get(marray, ida2-1) : na, color=color.red, linewidth = 1)

hline(0,"0 line", color=color.black, linestyle = hline.style_dotted)


if (last_bar_index-1) and array.size(newcurve2) > 20 and array.size(newcurve) > 20
    l = label.new(bar_index+2, array.get(newcurve2, array.size(newcurve2)-1), "Original Equity Curve", color=color.rgb(33, 149, 243, 85), textcolor = color.black, style = label.style_label_left)
    label.delete(l[1])
    f = label.new(bar_index+2, array.get(newcurve, array.size(newcurve)-1), "Filtered Equity Curve", color=color.rgb(69, 238, 97, 85), textcolor = color.black, style = label.style_label_left)
    label.delete(f[1])

Mehr