Die Twin Range Filter Strategie ist eine Handelsstrategie, die auf der Preisvolatilität basiert. Sie verwendet zwei Durchschnittsbereichsindikatoren mit verschiedenen Parameter-Einstellungen, kombiniert mit der Beziehung zwischen Preis und Bereich, um Handelssignale zu generieren.
Diese Strategie verwendet zwei glatte Bereichsindikatoren mit unterschiedlichen Periodenlängen: einen schnellen Bereichsindikator (Standardperiode 27) und einen langsamen Bereichsindikator (Standardperiode 55).
Die Strategie Twin Range Filter vergleicht den Preis mit den beiden Bereichsindikatoren, um festzustellen, ob er sich derzeit innerhalb eines bestimmten Schwingungsbereichs befindet.
Insbesondere verwendet die Strategie eine Medianlinie als Benchmark, die der Durchschnitt der beiden Bereichsindikatoren ist. Ein langes Signal wird erzeugt, wenn der Preis um einen schnellen Bereich über der Medianlinie liegt; ein kurzes Signal wird erzeugt, wenn der Preis um einen schnellen Bereich unter die Medianlinie fällt.
Um falsche Signale zu filtern, fügt es auch eine Bedingung hinzu: Ein Signal wird nur erzeugt, wenn die aktuelle Kursbewegung mit der vorherigen Periode übereinstimmt.
Zusammenfassend lässt sich sagen, dass diese Strategie den Schwingungsbereich mit Zwillings-Range-Indikatoren identifiziert und Aufträge generiert, wenn der Preis den Bereich durchbricht.
Die Vorteile der Strategie des Twin-Range-Filters:
Nutzt Preisvolatilitätsmerkmale, die sich an hochvolatile Vermögenswerte wie Bitcoin anpassen lassen.
Die beiden Indikatoren enthalten unterschiedliche Zeitrahmen, wobei der schnelle kurzfristige Chancen erfasst, während der langsame langfristige Trends berücksichtigt.
Durch das Hinzufügen von Kursrichtungfiltern werden falsche Signale von kurzfristigen Schwankungen reduziert.
Einfache und klare Logik, leicht zu verstehen und umzusetzen, geeignet für den Algo-Handel.
Einige Risiken der Strategie:
Es stützt sich auf Volatilitätsindikatoren und kann in Umgebungen mit geringer Volatilität unterdurchschnittlich abschneiden.
Die Bereichsparameter müssen für verschiedene Produkte optimiert werden, da sonst Handelsmöglichkeiten verpasst oder falsche Signale auftreten können.
Die Divergenz zwischen Preis und Volatilität wird nicht berücksichtigt, wenn die Volatilität ohne entsprechenden Preisanstieg steigt.
In Umgebungen mit hoher Volatilität müssen die Stop-Loss-Level möglicherweise angepasst werden.
Die Strategie kann in mehreren Aspekten verbessert werden:
Test und Optimierung der Bereichsparameter, um optimale Kombinationen für verschiedene Produkte und Zeitrahmen zu finden.
Hinzufügen dynamischer Stop-Loss-Mechanismen basierend auf der jüngsten Volatilität, um die Stop-Loss-Strategie zu optimieren.
Hinzufügen von Filtern, die auf der Differenz von Preis-Volatilität basieren, um falsche Signale zu vermeiden.
Einbeziehung anderer Indikatoren wie Volumenänderungen zur Erhöhung der Eintrittssicherheit.
Testen und ergänzen Sie für die Strategie geeignete Mechanismen zur Gewinnentnahme.
Insgesamt ist der Twin Range Filter eine effektive Handelsstrategie für hochvolatile Vermögenswerte. Er nutzt die Preisvolatilitätsmerkmale gut und erzeugt eine einfache und klare Handelslogik. Mit weiteren Verbesserungen wie Parameteroptimierung und Risikomanagement kann er zu einer wertvollen Komponente in einem Quant-Trading-System werden. Er bietet auch Einblicke in den algorithmischen Handel basierend auf den Merkmalen der Marktvolatilität.
/*backtest start: 2023-11-05 00:00:00 end: 2023-11-12 00:00:00 period: 30m basePeriod: 15m 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/ // © colinmck, greenmask9 //@version=4 strategy(title="Twin Range Filter Algo", overlay=true) source = input(defval=close, title="Source") // Smooth Average Range per1 = input(defval=27, minval=1, title="Fast period") mult1 = input(defval=1.6, minval=0.1, title="Fast range") per2 = input(defval=55, minval=1, title="Slow period") mult2 = input(defval=2, minval=0.1, title="Slow range") smoothrng(x, t, m) => wper = t * 2 - 1 avrng = ema(abs(x - x[1]), t) smoothrng = ema(avrng, wper) * m smoothrng smrng1 = smoothrng(source, per1, mult1) smrng2 = smoothrng(source, per2, mult2) smrng = (smrng1 + smrng2) / 2 // Range Filter rngfilt(x, r) => rngfilt = x rngfilt := x > nz(rngfilt[1]) ? x - r < nz(rngfilt[1]) ? nz(rngfilt[1]) : x - r : x + r > nz(rngfilt[1]) ? nz(rngfilt[1]) : x + r rngfilt filt = rngfilt(source, smrng) upward = 0.0 upward := filt > filt[1] ? nz(upward[1]) + 1 : filt < filt[1] ? 0 : nz(upward[1]) downward = 0.0 downward := filt < filt[1] ? nz(downward[1]) + 1 : filt > filt[1] ? 0 : nz(downward[1]) hband = filt + smrng lband = filt - smrng longCond = bool(na) shortCond = bool(na) longCond := source > filt and source > source[1] and upward > 0 or source > filt and source < source[1] and upward > 0 shortCond := source < filt and source < source[1] and downward > 0 or source < filt and source > source[1] and downward > 0 CondIni = 0 CondIni := longCond ? 1 : shortCond ? -1 : CondIni[1] long = longCond and CondIni[1] == -1 short = shortCond and CondIni[1] == 1 // Plotting // Strategy // From this part on, programmer is greenmaks9 // Separator = input(title="Following conditions and backtest algorithm are added by @greenmask9 🎯, original script is written by @colinmck 👍. Read both of their's release notes for more info on how this script works.", type=input.bool, defval=false) disabler = input(title="Disable greenmask9's ATR conditions", type=input.bool, defval=false) //second l2 = input(title="ATR1", defval=32, minval=1) s2 = input(title="Smoothing", defval="SMA", options=["RMA", "SMA", "EMA", "WMA"]) atr2(source, l2) => if s2 == "SMA" sma(source, l2) else if s2 == "RMA" rma(source, l2) else if s2 == "EMA" ema(source, l2) else wma(source, l2) //third l3 = input(title="ATR2", defval=64, minval=1) s3 = input(title="Smoothing", defval="RMA", options=["RMA", "SMA", "EMA", "WMA"]) atr3(source, l3) => if s3 == "RMA" rma(source, l3) else if s3 == "SMA" sma(source, l3) else if s3 == "EMA" ema(source, l3) else wma(source, l3) atr20=atr2(tr(true), l2) atr30=atr3(tr(true), l3) strategy.initial_capital = 50000 ordersize=floor(strategy.initial_capital/close) profit = input(title="Ticks profit", type=input.integer, defval=900) stop = input(title="Ticks stoploss", type=input.integer, defval=300) maxcandles_till_close = input(title="Time stoploss", type=input.integer, defval=17) bull = long and (atr20<atr30 or disabler) bear = short and (atr20<atr30 or disabler) bullclock = barssince(bull) bearclock = barssince(bear) if (bull) strategy.entry("Twin Long", strategy.long, ordersize) strategy.exit("Exit", from_entry = "Twin Long", profit = profit, loss = stop) if (bear) strategy.entry("Twin Short", strategy.short, ordersize) strategy.exit("Exit", from_entry = "Twin Short", profit = profit, loss = stop) //time stoploss strategy.close("Twin Long", when = bullclock == maxcandles_till_close, comment = "Timed out") strategy.close("Twin Short", when = bearclock == maxcandles_till_close, comment = "Timed out")