
Eine dynamische Preiskanal-Breakout-Strategie ist eine quantitative Handelsstrategie, die auf dem Donchian-Preiskanal-Indikator basiert. Die Strategie beurteilt die Richtung der Marktentwicklung anhand der oberen und unteren Grenzen der Preiskanal und errichtet eine Über- oder Unterposition, wenn der Preis den Kanal durchbricht.
Die Hauptidee dieser Strategie ist die Verwendung von Breakouts des Donchan-Preiskanals. Wenn der Preis die Obergrenze des Kanals überschreitet, wird ein Mehrkopf-Suchtrend erstellt; wenn der Preis die untere Grenze des Kanals überschreitet, wird ein Kurzkopf-Suchtrend erstellt.
Der Preiskanal wird mit der folgenden Formel berechnet:
Obergrenze = N-Zyklus-Höchstwert des Höchstpreises
Untergrenze = N-Zyklus-Mindestwert des niedrigsten Preises
Die mittlere Linie = (die obere Grenze + die untere Grenze) /2
N ist die Länge des Durchgangszyklus, wobei 50 in dieser Strategie standardmäßig angenommen wird.
Es wird eine Positionsüberschreitung eingerichtet, wenn der Höchstpreis der neuesten K-Linie die Obergrenze des Kanals überschreitet.
Ein Short-Position wird eingerichtet, wenn der Mindestpreis der neuesten K-Linie die untere Grenze des Kanals überschreitet.
Beispiel:
Der höchste Punkt der K-Linie überschreitet nicht die oberen Grenzen des Kanals. Derzeit ist die K-Linie an der oberen Grenze des Kanals. === Errichtung von mehreren Positionen ===
Es gibt zwei Varianten der Ausgangsregeln:
Pinto: Der Stop-Loss-Preis ist die untere Grenze des Kanals.
Der Stop-Loss-Preis ist die Obergrenze für den Kanal.
Alle Positionen, egal ob mehrköpfige oder leere Positionen, werden gelöscht, wenn der Preis wieder unter die Mittellinie fällt.
Die Risikokontrolle nutzt eine proportionale Stop-Loss-Methode, bei der die spezifische Stop-Loss-Distanz anhand der Durchgangsbreite und des prozentualen annehmbaren Risikos berechnet wird.
Mehr Stop-Loss-Distanz = Einstiegspreis * (1 - Prozentsatz der Risikoverfügbarkeit)
Stop-Loss-Distanz = Einstiegspreis * (1 + RP)
Ein Beispiel ist die Einstellung mit einem Plusrisiko von 2%, einem Einstiegspreis von 10.000 USD und einer Plus-Stop-Line von 10.000 * (1 - 2%) = 9.800 USD.
Wenn die Preise die oberen und unteren Grenzen des Kanals überschreiten, wird wahrscheinlich ein neuer Richtungstrend eingeleitet. Der Einstieg kann dann erhebliche Preisänderungen einfangen.
Die Anwendung von Proportionalen Stop-Losses ermöglicht es, einzelne Verluste in den erträglichen Bereich zu halten.
Die Parameter wie die Länge des Kanalzyklus, die Risikoproportion und die Stop-Loss-Methode können optimiert werden, um mehr Marktbedingungen anzupassen.
Wenn der Preis die oberen und unteren Grenzen des Kanals durchbricht, bedeutet dies nicht, dass ein Trend gebildet werden muss. Es besteht die Wahrscheinlichkeit, dass ein Fehlschlag eintritt, der leicht zu einem Verlust führt.
Wenn der Markt in einer breiten Bandbreite schwankt, können die Preise häufig die oberen und unteren Grenzen des Kanals auslösen, was zu erhöhten Transaktionsgebühren und Verlusten von Gleitpunkten führt, wenn zu häufig gehandelt wird.
Die Länge der Preiskanäle kann als Variable betrachtet werden, die automatisch an die Marktfluktuation angepasst wird. Die Länge der Kanäle wird bei Marktschwankungen vergrößert und bei klaren Trends verkleinert.
In Kombination mit anderen Indikatoren, wie z. B. der Quantenenergie-Indikator, der Moving Average, kann der Zeitpunkt des Einstiegs gefiltert werden, um einen Nichtabbruch bei Erschütterungen zu vermeiden.
Test-Optimierung von Parameterkombinationen mit mehr historischen Daten, um optimale Parameter für eine breitere Palette von Marktbedingungen zu ermitteln.
Die Dynamic Price Channel Strategie ist im Allgemeinen eine einfachere und intuitivere Trendverfolgungsstrategie. Ihre Vorteile liegen in der Klarheit der Kennzeichen und der einfachen Erfassung; die Risikokontrolle ist relativ vernünftig. Es gibt jedoch einige Probleme, die weiter optimiert werden müssen, wie die Behandlung von Fehlschlägen und Schockmärkten. Die Strategie eignet sich besser als Hilfsmittel für den Trendhandel und ist besser geeignet für die Verwendung mit anderen technischen Indikatoren oder Modellen.
/*backtest
start: 2022-12-06 00:00:00
end: 2023-12-12 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//Noro
//@version=4
strategy(title = "Noro's RiskChannel Strategy", shorttitle = "RiskChannel str", overlay = true, default_qty_type = strategy.percent_of_equity, initial_capital = 100, default_qty_value = 100, pyramiding = 0, commission_value = 0.1)
//Settings
needlong = input(true, defval = true, title = "Long")
needshort = input(true, defval = true, title = "Short")
risklong = input(2.0, minval = 0.0, maxval = 99.9, title = "Risk size for long, %")
riskshort = input(2.0, minval = 0.0, maxval = 99.9, title = "Risk size for short, %")
stoptype = input(defval = "Center", options = ["Channel", "Center"], title = "Stop-loss type")
lotsize = input(100, defval = 100, minval = 1, maxval = 10000, title = "Lot, %")
pclen = input(50, minval = 1, title = "Price Channel Length")
showll = input(true, defval = true, title = "Show lines")
showof = input(true, defval = true, title = "Show offset")
showdd = input(true, defval = true, title = "Show label (drawdown)")
showbg = input(false, defval = false, title = "Show background")
fromyear = input(1900, defval = 1900, minval = 1900, maxval = 2100, title = "From Year")
toyear = input(2100, defval = 2100, minval = 1900, maxval = 2100, title = "To Year")
frommonth = input(01, defval = 01, minval = 01, maxval = 12, title = "From Month")
tomonth = input(12, defval = 12, minval = 01, maxval = 12, title = "To Month")
fromday = input(01, defval = 01, minval = 01, maxval = 31, title = "From day")
today = input(31, defval = 31, minval = 01, maxval = 31, title = "To day")
//Price Channel
h = highest(high, pclen)
l = lowest(low, pclen)
center = (h + l) / 2
//Stop-loss
needstop = stoptype == "Center" or needlong == false or needshort == false
sl = center
//Lines
pccol = showll ? color.black : na
slcol = showll and stoptype == "Center" ? color.red : na
offset = showof ? 1 : 0
plot(h, offset = offset, color = pccol, title = "Channel High")
plot(center, offset = offset, color = slcol, title = "Cannel Center")
plot(l, offset = offset, color = pccol, title = "Channel Low")
//Background
size = strategy.position_size
bgcol = showbg == false ? na : size > 0 ? color.lime : size < 0 ? color.red : na
bgcolor(bgcol, transp = 70)
//Var
loss = 0.0
maxloss = 0.0
equity = 0.0
truetime = time > timestamp(fromyear, frommonth, fromday, 00, 00) and time < timestamp(toyear, tomonth, today, 23, 59)
//Lot size
risksizelong = -1 * risklong
risklonga = stoptype == "Center" ? ((center / h) - 1) * 100 : ((l / h) - 1) * 100
coeflong = abs(risksizelong / risklonga)
lotlong = (strategy.equity / close) * coeflong
risksizeshort = -1 * riskshort
riskshorta = stoptype == "Center" ? ((center / l) - 1) * 100 : ((h / l) - 1) * 100
coefshort = abs(risksizeshort / riskshorta)
lotshort = (strategy.equity / close) * coefshort
//Trading
if h > 0
strategy.entry("Long", strategy.long, lotlong, stop = h, when = strategy.position_size <= 0 and needlong and truetime)
strategy.entry("Short", strategy.short, lotshort, stop = l, when = strategy.position_size >= 0 and needshort and truetime)
sl := sl != 0 ? sl : size > 0 ? l : size < 0 ? h : na
if size > 0 and needstop
strategy.exit("Stop Long", "Long", stop = sl)
if size < 0 and needstop
strategy.exit("Stop Short", "Short", stop = sl)
if time > timestamp(toyear, tomonth, today, 23, 59)
strategy.close_all()
strategy.cancel("Long")
strategy.cancel("Short")
if showdd
//Drawdown
max = 0.0
max := max(strategy.equity, nz(max[1]))
dd = (strategy.equity / max - 1) * 100
min = 100.0
min := min(dd, nz(min[1]))
//Max loss size
equity := strategy.position_size == 0 ? strategy.equity : equity[1]
loss := equity < equity[1] ? ((equity / equity[1]) - 1) * 100 : 0
maxloss := min(nz(maxloss[1]), loss)
//Label
min := round(min * 100) / 100
maxloss := round(maxloss * 100) / 100
labeltext = "Drawdown: " + tostring(min) + "%" + "\nMax.loss " + tostring(maxloss) + "%"
var label la = na
label.delete(la)
tc = min > -100 ? color.white : color.red
osx = timenow + round(change(time)*10)
osy = highest(100)
// la := label.new(x = osx, y = osy, text = labeltext, xloc = xloc.bar_time, yloc = yloc.price, color = color.black, style = label.style_labelup, textcolor = tc)