Breakout-Band-Fixed Stop Loss-Strategie

Schriftsteller:ChaoZhang, Datum: 2023-11-03 14:31:21
Tags:

img

Übersicht

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.

Strategieprinzip

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.

Vorteile

Diese feste Stop-Loss-Strategie mit Breakout-Band hat folgende Vorteile:

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. Die Codestruktur ist klar und modular, sodass sie leicht zu verstehen und zu optimieren ist.

Risiken

Trotz der Vorteile sind einige Risiken für die Strategie zu beachten:

  1. 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.

  2. 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.

  3. Die Strategie beschränkt nicht die Handelsfrequenz und kann zu oft gehandelt werden.

  4. Die Festsetzung des Feststandsverlusts ist für die Gesamtrisikokontrolle von entscheidender Bedeutung und muss die Kapitalgröße, den Risikobereitschaft usw. berücksichtigen.

  5. Die Ausbruchrichtung kann falsche Signale geben. Falsche Ausbruchsignale können bei Kursschwankungen oder Pullbacks auftreten. Mehr Bedingungen sind erforderlich, um die Strategie zu optimieren.

  6. 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:

  1. Hinzufügen von Indikatoren zur Filterqualität von Signalen, z. B. MACD, KD usw.

  2. Einbeziehung von Indikatoren für die Durchbruchfestigkeit zur Bewertung der Qualität, z. B. Beurteilung der Festigkeit durch Volumenänderungen.

  3. Hinzufügen von Frequenzlimits für offene Geschäfte, z. B. ein Geschäft pro Tag.

  4. Optimierung der festen Stop-Loss-Logik, z. B. prozentual basierender Stop-Loss über einem Schwellenwert.

  5. Zusätzliche Filter, z. B. Volatilität, Erhöhung des Stop-Loss usw.

  6. Einbeziehung von Profit-taking-Strategien, z. B. Profit-taking in der Nähe von Widerstand.

Optimierungsrichtlinien

Auf der Grundlage der Analyse kann die Strategie in folgenden Aspekten optimiert werden:

  1. Zusätzliche Filter zur Verbesserung der Signalqualität unter Verwendung mehrerer technischer Indikatoren und Bewertung der Trendqualität.

  2. 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.

  3. Kontrolle der Handelsfrequenz, um Überhandelungen durch Hinzufügen von Filtern für Zeiträume oder Häufigkeit zu vermeiden.

  4. Einbeziehung von Trendindikatoren zur Verbesserung des Zeitplans, z. B. Warten auf eine Trendbestätigung.

  5. Optimierung der Gewinnentnahme-Strategien zur Verbesserung der Rentabilität durch Gewinnziel, Profitstop, Volatilitätsstop usw.

  6. Optimierung von Risikoparametern auf der Grundlage von Backtests, wie fester Stoppmenge, Ausfallzeit usw.

  7. Refactoring-Code für eine bessere Erweiterbarkeit durch weitere Trennung von Signal-, Filter-, Risiko- und Gewinnmodulen.

  8. Test mehr Produkte auf Arbitrage-Möglichkeiten.

Durch diese Optimierungsdimensionen kann die Breakout-Stop-Loss-Strategie robuster und profitabler werden.

Schlussfolgerung

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)


Mehr