Die Hauptidee dieser Strategie besteht darin, das Breakout-Band zu verwenden, um die Trendrichtung zu identifizieren und den festen Stop-Loss für das Risikomanagement zu kombinieren. Die Strategie berechnet zunächst die höchsten und niedrigsten Preise über einen bestimmten Zeitraum, um ein Breakout-Band zu bilden. Wenn der Preis durch das Breakout-Band bricht, wird ein Handelssignal generiert. Darüber hinaus ermöglicht die Strategie den Händlern, einen festen Stop-Loss-Betrag festzulegen. Jedes Mal, wenn ein Trade platziert wird, berechnet das System die Positionsgröße auf der Grundlage des festen Stop-Loss-Betrags, so dass jeder Verlust festgelegt wird.
Die Strategie besteht aus vier Hauptteilen: Positionsmanagement, Breakout-Band-Identifizierung, Stop-Loss-Einstellung und Positionsdimensionierung.
Erstens wird mit der Strategie überprüft, ob eine offene Position vorhanden ist, und wenn ja, werden keine neuen Signale generiert.
Zweitens berechnet die Strategie die höchsten und niedrigsten Preise über einen Zeitraum, um ein Breakout-Band zu bilden. Wenn der Preis aus dem Band bricht, wird ein Handelssignal generiert. Insbesondere, wenn der Preis über das obere Band bricht, wird ein langes Signal generiert. Wenn der Preis unter das untere Band bricht, wird ein kurzes Signal generiert.
Darüber hinaus setzt die Strategie, wenn ein langes Signal erzeugt wird, den Mittelpunkt des Breakout-Bands als Stop-Loss. Das gleiche gilt für kurze Signale. Um den Stop-Loss zu verfolgen, passt die Strategie den Stop-Loss auch in Echtzeit an, wenn sie in Position ist.
Schließlich erlaubt die Strategie die Festlegung eines festen Stop-Loss-Betrags. Wenn ein Signal generiert wird, berechnet die Strategie die Anzahl der Pips vom Stop-Loss zum aktuellen Preis und kombiniert Faktoren wie Tickgröße und Wechselkurs, um die Preisänderung zwischen Stop-Loss und aktuellem Preis in monetären Begriffen zu bestimmen. Die Positionsgröße wird dann auf der Grundlage des festen Stop-Loss-Betrags berechnet.
Die wichtigsten Konzepte sind die Identifizierung der Trendrichtung mit Breakout-Bändern und die Steuerung des Risikos mit einem festen Stop-Loss.
Diese feste Stop-Loss-Strategie mit Breakout-Band hat folgende Vorteile:
Die Strategie verwendet einen festen Stop-Loss-Betrag anstelle einer festen Stop-Loss-Distanz. Dies vermeidet das Problem, dass das Risiko bei Produkten mit unterschiedlichen Tickwerten nicht festgelegt werden kann. Aus der Sicht des Risikomanagements ist der feste monetäre Stop-Loss fortschrittlicher.
Die Strategie kann die Positionsgröße auf der Grundlage des festen Stop-Loss-Betrags intelligent berechnen, so dass der Verlust pro Handel kontrolliert wird und somit das Risikopositionsrisiko angemessen verwaltet wird.
Einfache und effektive Breakout-Identifizierung. Die Identifizierung von Breakouts mit Bands ist einfach und direkt und kann die Trendrichtung effektiv identifizieren. Im Vergleich zu einem Breakout eines einzelnen Preisniveaus kann diese Breakout-Band-Identifizierung mehr falsche Signale weg vom Trend vermeiden.
Die Fähigkeit der Strategie, den Stop-Loss in Echtzeit für den Trailing-Stop-Loss anzupassen, trägt dazu bei, mehr Gewinne zu erzielen.
Die Strategie ist für alle Produkte anwendbar. Solange die Parameter richtig eingestellt sind, kann die Festbetrag-Stop-Loss-Risikokontrolle erreicht werden, was die Strategie sehr vielseitig macht.
Die Codestruktur ist klar und modular, sodass sie leicht zu verstehen und zu optimieren ist.
Trotz der Vorteile sind einige Risiken für die Strategie zu beachten:
Breakout-Musterqualität nicht getestet. Die Strategie beurteilt nicht die Breakout-Musterqualität und kann einige Signalen niedriger Qualität erzeugen. Andere Indikatoren sind erforderlich, um Signale zu filtern.
Der festgelegte Stop-Loss kann zu mechanisch sein. Die Marktpreise liegen oft im Unterschied. Der festgelegte Stop-Loss kann sich zu sehr auf Regeln stützen und an Anpassungsflexibilität mangelt.
Die Strategie beschränkt nicht die Handelsfrequenz und kann zu oft gehandelt werden.
Die Festsetzung des Feststandsverlusts ist für die Gesamtrisikokontrolle von entscheidender Bedeutung und muss die Kapitalgröße, den Risikobereitschaft usw. berücksichtigen.
Die Ausbruchrichtung kann falsche Signale geben. Falsche Ausbruchsignale können bei Kursschwankungen oder Pullbacks auftreten. Mehr Bedingungen sind erforderlich, um die Strategie zu optimieren.
Keine Gewinnnahme. Die Strategie hat derzeit keine Gewinnnahme-Fähigkeit, um aktiv Gewinne zu erzielen. Dies kann zu unbefriedigenden Gewinnen führen.
Um diesen Risiken entgegenzuwirken, sind einige Möglichkeiten zur Optimierung der Strategie:
Hinzufügen von Indikatoren zur Filterqualität von Signalen, z. B. MACD, KD usw.
Einbeziehung von Indikatoren für die Durchbruchfestigkeit zur Bewertung der Qualität, z. B. Beurteilung der Festigkeit durch Volumenänderungen.
Hinzufügen von Frequenzlimits für offene Geschäfte, z. B. ein Geschäft pro Tag.
Optimierung der festen Stop-Loss-Logik, z. B. prozentual basierender Stop-Loss über einem Schwellenwert.
Zusätzliche Filter, z. B. Volatilität, Erhöhung des Stop-Loss usw.
Einbeziehung von Profit-taking-Strategien, z. B. Profit-taking in der Nähe von Widerstand.
Auf der Grundlage der Analyse kann die Strategie in folgenden Aspekten optimiert werden:
Zusätzliche Filter zur Verbesserung der Signalqualität unter Verwendung mehrerer technischer Indikatoren und Bewertung der Trendqualität.
Optimierung des Stop-Loss für mehr Flexibilität. Kann nach einem bestimmten Retracement auf einen prozentualen Trailing-Stop wechseln. Kann auch dynamisch basierend auf der Volatilität optimieren.
Kontrolle der Handelsfrequenz, um Überhandelungen durch Hinzufügen von Filtern für Zeiträume oder Häufigkeit zu vermeiden.
Einbeziehung von Trendindikatoren zur Verbesserung des Zeitplans, z. B. Warten auf eine Trendbestätigung.
Optimierung der Gewinnentnahme-Strategien zur Verbesserung der Rentabilität durch Gewinnziel, Profitstop, Volatilitätsstop usw.
Optimierung von Risikoparametern auf der Grundlage von Backtests, wie fester Stoppmenge, Ausfallzeit usw.
Refactoring-Code für eine bessere Erweiterbarkeit durch weitere Trennung von Signal-, Filter-, Risiko- und Gewinnmodulen.
Test mehr Produkte auf Arbitrage-Möglichkeiten.
Durch diese Optimierungsdimensionen kann die Breakout-Stop-Loss-Strategie robuster und profitabler werden.
Insgesamt ist die Strategie vernünftig, wenn man Breakout-Bänder verwendet, um Trends und Festbetrags-Stopps für die Risikokontrolle zu identifizieren. Die Konzepte sind progressiv für das Risikomanagement. Die Positionsgrößenlogik ist auch für die Kontrolle von Verlusten pro Handel geeignet. Die Strategie kann jedoch durch verschiedene Optimierungen verbessert werden, um die Signalqualität, die Flexibilität beim Stop-Loss, die Rentabilität usw. zu verbessern. Durch die Einbeziehung von Trendfiltern, die Verbesserung der Gewinnentnahme und die strenge Kontrolle der Handelsfrequenz können erhebliche Verbesserungen erzielt werden. Abschließend bietet die Strategie einen Rahmen für das Lernen von Risikomanagement- und Positionsgrößentechniken und schafft den Grundstein für weitere Forschung zu komplexeren Arbitrage- und Multi-Strategie-Systemen.
/*backtest start: 2023-10-26 00:00:00 end: 2023-10-28 03:00:00 period: 10m 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/ //@version=4 //@author=Takazudo strategy("Fixed price SL", overlay=true, default_qty_type=strategy.fixed, initial_capital=0, currency=currency.USD) var COLOR_TRANSPARENT = color.new(#000000, 100) var COLOR_ENTRY_BAND = color.new(#43A6F5, 30) //============================================================================ // config //============================================================================ // Money management _g1 = 'Money management' var config_riskPrice = input(100, minval=1, title="Risk price for each entry", group=_g1) var config_depositCurrency = input(title="Deposit currency", type=input.string, defval="USD", options=["USD"], group=_g1) // Entry strategy _g2 = 'Entry strategy' var config_entryBandBars = input(defval = 100, title = "Entry band bar count", minval=1, group=_g2) // Backtesting range _g3 = 'Backtesting range' fromYear = input(defval = 2018, title = "From Year", minval = 1970, group=_g3) fromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12, group=_g3) fromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31, group=_g3) toYear = input(defval = 2020, title = "To Year", minval = 1970, group=_g3) toMonth = input(defval = 12, title = "To Month", minval = 1, maxval = 12, group=_g3) toDay = input(defval = 31, title = "To Day", minval = 1, maxval = 31, group=_g3) //============================================================================ // exchange caliculations //============================================================================ // mico pip size caliculation // ex1: AUDCAD -> 0.0001 // ex2: USDJPY -> 0.01 f_calcMicroPipSize() => _base = syminfo.basecurrency _quote = syminfo.currency _result = 0.0001 if _quote == 'JPY' _result := _result * 100 if _base == 'BTC' _result := _result * 100 _result // convert price to pips f_convertPriceToPips(_price) => _microPipSize = f_calcMicroPipSize() _price / _microPipSize // caliculate exchange rate between deposit and quote currency f_calcDepositExchangeSymbolId() => _result = '' _deposit = config_depositCurrency _quote = syminfo.currency if (_deposit == 'USD') and (_quote == 'USD') _result := na if (_deposit == 'USD') and (_quote == 'AUD') _result := 'OANDA:AUDUSD' if (_deposit == 'EUR') and (_quote == 'USD') _result := 'OANDA:EURUSD' if (_deposit == 'USD') and (_quote == 'GBP') _result := 'OANDA:GBPUSD' if (_deposit == 'USD') and (_quote == 'NZD') _result := 'OANDA:NZDUSD' if (_deposit == 'USD') and (_quote == 'CAD') _result := 'OANDA:USDCAD' if (_deposit == 'USD') and (_quote == 'CHF') _result := 'OANDA:USDCHF' if (_deposit == 'USD') and (_quote == 'JPY') _result := 'OANDA:USDJPY' _result // Let's say we need CAD to USD exchange // However there's only "OANDA:USDCAD" symbol. // Then we need to invert the exhchange rate. // this function tells us whether we should invert the rate or not f_calcShouldInvert() => _result = false _deposit = config_depositCurrency _quote = syminfo.currency if (_deposit == 'USD') and (_quote == 'CAD') _result := true if (_deposit == 'USD') and (_quote == 'CHF') _result := true if (_deposit == 'USD') and (_quote == 'JPY') _result := true _result // caliculate how much quantity should I buy or sell f_calcQuantitiesForEntry(_depositExchangeRate, _slPips) => _microPipSize = f_calcMicroPipSize() _priceForEachPipAsDeposit = _microPipSize * _depositExchangeRate _losePriceOnSl = _priceForEachPipAsDeposit * _slPips floor(config_riskPrice / _losePriceOnSl) //============================================================================ // Quantity caliculation //============================================================================ depositExchangeSymbolId = f_calcDepositExchangeSymbolId() // caliculate deposit exchange rate rate = security(depositExchangeSymbolId, timeframe.period, hl2) shouldInvert = f_calcShouldInvert() depositExchangeRate = if config_depositCurrency == syminfo.currency // if USDUSD, no exchange of course 1 else // else, USDCAD to CADUSD invert if we need shouldInvert ? (1 / rate) : rate //============================================================================ // Range Edge caliculation //============================================================================ f_calcEntryBand_high() => _highest = max(open[3], close[3]) for i = 4 to (config_entryBandBars - 1) _highest := max(_highest, open[i], close[i]) _highest f_calcEntryBand_low() => _lowest = min(open[3], close[3]) for i = 4 to (config_entryBandBars - 1) _lowest := min(_lowest, open[i], close[i]) _lowest entryBand_high = f_calcEntryBand_high() entryBand_low = f_calcEntryBand_low() entryBand_height = entryBand_high - entryBand_low plot(entryBand_high, color=COLOR_ENTRY_BAND, linewidth=1) plot(entryBand_low, color=COLOR_ENTRY_BAND, linewidth=1) rangeBreakDetected_long = entryBand_high < close rangeBreakDetected_short = entryBand_low > close shouldMakeEntryLong = (strategy.position_size == 0) and rangeBreakDetected_long shouldMakeEntryShort = (strategy.position_size == 0) and rangeBreakDetected_short //============================================================================ // SL & Quantity //============================================================================ var sl_long = hl2 var sl_short = hl2 entryQty = 0 slPips = 0.0 // just show info bubble f_showEntryInfo(_isLong) => _str = 'SL pips: ' + tostring(slPips) + '\n' + 'Qty: ' + tostring(entryQty) _bandHeight = entryBand_high - entryBand_low _y = _isLong ? (entryBand_low + _bandHeight * 1/4) : (entryBand_high - _bandHeight * 1/4) _style = _isLong ? label.style_label_up : label.style_label_down label.new(bar_index, _y, _str, size=size.large, style=_style) if shouldMakeEntryLong sl_long := (entryBand_high + entryBand_low) / 2 slPips := f_convertPriceToPips(close - sl_long) entryQty := f_calcQuantitiesForEntry(depositExchangeRate, slPips) if shouldMakeEntryShort sl_short := (entryBand_high + entryBand_low) / 2 slPips := f_convertPriceToPips(sl_short - close) entryQty := f_calcQuantitiesForEntry(depositExchangeRate, slPips) // trailing SL if strategy.position_size > 0 sl_long := max(sl_long, entryBand_low) if strategy.position_size < 0 sl_short := min(sl_short, entryBand_high) //============================================================================ // backtest duration //============================================================================ // Calculate start/end date and time condition startDate = timestamp(fromYear, fromMonth, fromDay, 00, 00) finishDate = timestamp(toYear, toMonth, toDay, 00, 00) //============================================================================ // make entries //============================================================================ if (true) if shouldMakeEntryLong strategy.entry(id="Long", long=true, stop=close, qty=entryQty) f_showEntryInfo(true) if shouldMakeEntryShort strategy.entry(id="Short", long=false, stop=close, qty=entryQty) f_showEntryInfo(false) strategy.exit('Long-SL/TP', 'Long', stop=sl_long) strategy.exit('Short-SL/TP', 'Short', stop=sl_short) //============================================================================ // plot misc //============================================================================ sl = strategy.position_size > 0 ? sl_long : strategy.position_size < 0 ? sl_short : na plot(sl, color=color.red, style=plot.style_cross, linewidth=2, title="SL") value_bgcolor = rangeBreakDetected_long ? color.green : rangeBreakDetected_short ? color.red : COLOR_TRANSPARENT bgcolor(value_bgcolor, transp=95)