Breakout Trend Follower V2

Schriftsteller:ChaoZhang, Datum: 2023-11-01 17:24:08
Tags:

img

Übersicht

Diese Strategie ist eine Variation meiner anderen Breakout Trend Follower Strategie. In der anderen Strategie können Sie einen gleitenden Durchschnitt verwenden, um als Filter für Ihre Trades zu fungieren (d.h. wenn der Preis unter dem gleitenden Durchschnitt liegt, wird er nicht lange dauern). Nachdem ich das Tool entwickelt habe, das Trends in höheren Zeitrahmen erkennt, wollte ich sehen, ob dies ein besserer Filter als ein gleitender Durchschnitt sein könnte.

Dieses Skript ermöglicht es Ihnen also, sich die Trends in höheren Zeitrahmen anzuschauen (d.h. gibt es höhere Höchststände und höhere Tiefstände? Wenn ja, ist dies ein Aufwärtstrend). Sie können nur Trades tätigen, wenn Sie mit dem Trend verbunden sind. Sie haben die Möglichkeit, bis zu zwei Trends auszuwählen, um als Filter zu fungieren. Jede Trendrichtung wird für einfache Referenz auf einer Tabelle auf dem Diagramm angezeigt. Die aktuellen Pivot-Hoch- und Tiefstände werden auf dem Diagramm dargestellt, so dass Sie sehen können, wann Sie sowohl den Trend des aktuellen Zeitrahmens als auch die Trends auf höherem Niveau durchbrechen.

Was ich fand, war, dass dies im Allgemeinen nicht so gut funktioniert wie die andere Strategie, aber es scheint viel wählerischer mit Trades zu sein.

Strategie Logik

Die Kernlogik dieser Strategie besteht darin, Trends anhand von Ausbrüchen von Unterstützungs- und Widerstandsniveaus in höheren Zeitrahmen zu identifizieren und Trades in Richtung des Trends zu führen.

Insbesondere werden folgende Schritte durchgeführt:

  1. Berechnen Sie Pivot-Unterstützungs- und Widerstandsniveaus für den aktuellen Zeitrahmen (z. B. 1 Stunde).

  2. Berechnen Sie Pivot-Unterstützungs- und Widerstandsniveaus für einen oder mehrere höhere Zeitrahmen (z. B. 4 Stunden und täglich).

  3. Diese Unterstützungs- und Widerstandsniveaus werden als horizontale Linien auf dem Diagramm dargestellt.

  4. Bestimmt die Trendrichtung, basierend darauf, ob der Preis vorherige Höchst- oder Tiefpunkte durchbricht.

  5. Ermöglichen Sie dem Benutzer, einen oder mehrere Trends in höheren Zeitrahmen als Filterbedingung auszuwählen. D. h. Erwägen Sie nur, Trades zu tätigen, wenn sich der aktuelle Trend in höheren Zeitrahmen mit dem Trend in höheren Zeitrahmen übereinstimmt.

  6. Wenn die Trendfilterbedingung erfüllt ist und der aktuelle Preis das Schlüsselniveau durchbricht, wird der Long- oder Short-Eintrag eingegeben.

  7. Wenn sich der Preis bewegt, passen Sie den Stop-Loss auf neue Tiefpunkte an, um Gewinne zu erzielen und dem Trend zu folgen.

  8. Ausgang, wenn der Stop-Loss ausgelöst wird oder das wichtigste Unterstützungs-/Widerstandsniveau gebrochen wird.

Durch die Analyse von Trends über mehrere Zeitrahmen hinweg versucht die Strategie nur in Richtung stärkerer Trends zu handeln, um die Gewinnrate zu verbessern.

Vorteile der Strategie

  • Durch die Verwendung mehrerer Zeitrahmen zur Beurteilung von Trends kann eine stärkere Trendrichtung genauer ermittelt und Lärm vermieden werden.

  • Nur der Handel mit wichtigen Trends verbessert die Gewinnrate erheblich.

  • Unterstützungs- und Widerstandsniveaus liefern klare Einstiegs- und Stop-Loss-Niveaus.

  • Anpassung von Stopps entlang des Trends, um die Gewinnverbindung zu maximieren.

  • Einfache und klare Strategielogik, leicht zu verstehen und zu optimieren.

Risiken der Strategie

  • Verlässt sich auf längerfristige Trends, ist anfällig für Trendumkehrungen.

  • Kann Filter wie Gewinndaten hinzufügen.

  • Keine Positionsgrößenregelung eingestellt. Größe sollte nach Kontogröße, Volatilität usw. optimiert werden.

  • Begrenzte Backtest-Periode, die Tests in verschiedenen Marktumgebungen erweitern sollte.

  • Die Handelskosten werden nicht berücksichtigt, sondern die Parameter anhand der tatsächlichen Kosten angepasst.

  • Kann Signale für kurzfristige Trades entwickeln, um Multi-Timeframe-Strategien umzusetzen.

Optimierungsrichtlinien

  • Filterbedingungen hinzufügen:

    • Grundsätzliche Daten wie Einkommen, Nachrichten

    • Indikatoren wie Volumen, ATR-Stopp

  • Optimierung der Parameter:

    • Zeiträume für die Berechnung von Unterstützungs-/Widerstandsraten

    • Zeitrahmen für die Tendenzbestimmung

  • Strategieumfang erweitern:

    • Entwicklung von kurzfristigen Handelsstrategien

    • Erwägen Sie kurzfristige Möglichkeiten

    • Marktübergreifende Spreads

  • Verbesserung des Risikomanagements:

    • Optimierung der Positionsgröße nach Volatilität und Größe

    • Verbessern Sie Stop-Loss-Strategien wie Moving/Bracket Stops

    • Einführung risikobereinigter Kennzahlen

  • Verbesserte Ausführungslogik:

    • Auswahl des Eintrittszeitpunkts

    • Einträge in teilweiser Größe

    • Optimierung der Stop-Loss-Bewegung

Schlussfolgerung

Diese Strategie entwarf ein relativ robustes Breakout-System, indem sie Trends über mehrere Zeitrahmen hinweg analysierte. Im Vergleich zu einfachen Filtern wie gleitenden Durchschnitten zeigte sie höhere Gewinnraten und Risiko-Belohnungsquoten. Aber es gibt einige Bereiche, die verbessert werden können, wie den Mangel an soliden Risikomanagementmechanismen und die Berücksichtigung von Fundamentalen. Mit weiterer Optimierung kann es zu einer sehr praktischen Trendfolgestrategie werden. Insgesamt ist das Strategiedesign solide, verbessert die Genauigkeit durch Multi-Zeitrahmen-Analyse und lohnt sich für weitere Forschung und Anwendung.


/*backtest
start: 2023-10-24 00:00:00
end: 2023-10-26 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4

// Revision:        1
// Author:          @millerrh
// Strategy:  Enter long when recent swing high breaks out, using recent swing low as stop level.  Move stops up as higher lows print to act
// as trailing stops.  Ride trend as long as it is there and the higher lows aren't breached.  
// The difference between this one and the previous Breakout Trend Follower is that this one uses higher timeframe higher highs/higher lows as a filter instead 
// of an arbitrary Moving Average.  I wanted to test out whether waiting for longer term actual trend changes produced better stats than just the moving average.
// Conditions/Variables 
//    1. Manually configure which dates to back test
//    2. Can add a filter to only take setups that are above (or below for shorts) user-defined larger timeframe trends (helps avoid trading counter trend) 

// === CALL STRATEGY/STUDY, PROGRAMATICALLY ENTER STRATEGY PARAMETERS HERE SO YOU DON'T HAVE TO CHANGE THEM EVERY TIME YOU RUN A TEST ===
// (STRATEGY ONLY) - Comment out srategy() when in a study() 
strategy("Breakout Trend Follower V2", overlay=true, initial_capital=10000, currency='USD', 
   default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1)
// (STUDY ONLY) - Comment out study() when in a strategy() 
//study("Breakout Trend Follower V2", overlay=true)

// === BACKTEST RANGE ===
Start = input(defval = timestamp("01 Jan 2019 06:00 +0000"), title = "Backtest Start Date", type = input.time, group = "Backtest Range")
Finish = input(defval = timestamp("01 Jan 2100 00:00 +0000"), title = "Backtest End Date", type = input.time, group = "Backtest Range")

// == USER INPUTS ==
tableLocation = input(defval="Top", options=["Top", "Bottom"], title = "Info Table Location", group = "Display",
  tooltip = "Place information table on the top of the pane or the bottom of the pane.")
lookback = input(defval = 3, title = "Pivot Lookback Period", group = "Pivot Points",
  tooltip = "Looks for pivot points within this number of bars both left and right.")
showPivotPoints = input(title = "Show Historical Pivot Points?", type = input.bool, defval = false, group = "Pivot Points",
  tooltip = "Toggle this on to see the historical pivot points that were used.  Change the Lookback Period to adjust the frequency of these points.
  The pivot points are only shown for the current chart timeframe - to see the Daily pivot pionts, use the Daily timeframe, etc.")
trendFilter = input(defval="1st Timeframe", options=["1st Timeframe", "Both Timeframes", "None"], title = "Use HTF Trend for Filtering?", group = "Higher Timeframe Levels",
  tooltip = "Signals will be ignored when price is not aligned with the higher timeframe trend(s).  The intent is to keep you out of bear periods and only buying when 
  price is showing strength and you are trading with the trend.")
twoSet = input(defval="D", title="1st High Timeframe", type=input.resolution, group = "Higher Timeframe Levels",
  tooltip = "Allows you to set two different time frames for looking at the trend.")
threeSet = input(defval="W", title="2nd High Timeframe", type=input.resolution, group = "Higher Timeframe Levels")
showMTFLevels = input(title = "Show Multiple Timeframe S/R Levels?", type = input.bool, defval = true, group = "Higher Timeframe Levels",
  tooltip = "Displays the pivot highs and lows of higher timeframes to use as support/resistance levels. When these levels break, the trend
  will change on these higher timeframes.")
currentColorS = input(color.new(color.orange,50), title = "Current Timeframe    Support", type = input.color, group = "Higher Timeframe Levels", inline = "MTF1")
currentColorR = input(color.new(color.blue,50), title = " Resistance", type = input.color, group = "Higher Timeframe Levels", inline = "MTF1")
oneColorS = input(color.new(color.yellow,50), title = "1st High Timeframe   Support", type = input.color, group = "Higher Timeframe Levels", inline = "MTF2")
oneColorR = input(color.new(color.yellow,50), title = " Resistance", type = input.color, group = "Higher Timeframe Levels", inline = "MTF2")
twoColorS = input(color.new(color.white,50), title = "2nd High Timeframe    Support", type = input.color, group = "Higher Timeframe Levels", inline = "MTF3")
twoColorR = input(color.new(color.white,50), title = " Resistance", type = input.color, group = "Higher Timeframe Levels", inline = "MTF3")

//  == DEFINE FUNCTIONS FOR USE IN MULTIPLE TIMEFRAMES (USING A TUPLE TO AVOID SO MANY SECURITY CALLS) ==  
f_getHTF() =>
    ph = pivothigh(high, lookback, lookback)
    pl = pivotlow(low, lookback, lookback)
    highLevel = valuewhen(ph, high[lookback], 0)
    lowLevel = valuewhen(pl, low[lookback], 0)
    barsSinceHigh = barssince(ph) + lookback
    barsSinceLow = barssince(pl) + lookback
    timeSinceHigh = time[barsSinceHigh]
    timeSinceLow = time[barsSinceLow]
    [ph, pl, highLevel, lowLevel, barsSinceHigh, barsSinceLow, timeSinceHigh, timeSinceLow]
    
[ph_01, pl_01, hL_01, lL_01, bsSH_01, bsSL_01, tSH_01, tSL_01] = security(syminfo.tickerid, "", f_getHTF())
[ph_02, pl_02, hL_02, lL_02, bsSH_02, bsSL_02, tSH_02, tSL_02] = security(syminfo.tickerid, twoSet, f_getHTF())
[ph_03, pl_03, hL_03, lL_03, bsSH_03, bsSL_03, tSH_03, tSL_03] = security(syminfo.tickerid, threeSet, f_getHTF())

// Plot historical pivot points for debugging and configuring the lookback period.
plot(showPivotPoints ? ph_01 : na, style=plot.style_cross, linewidth=3, color=color.new(color.yellow,50), offset=-lookback)
plot(showPivotPoints ? pl_01 : na, style=plot.style_cross, linewidth=3, color=color.new(color.yellow,50), offset=-lookback)

// == PLOT SUPPORT/RESISTANCE LINES ON THE HIGHER TIMEFRAMES ==
// Use a function to define the lines
f_line(x1, y1, y2, _color) =>
    var line id = na
    // line.delete(id)
    // id := line.new(x1, y1, time, y2, xloc.bar_time, extend.right, _color)

// 1st Timeframe
highLine1 = showMTFLevels ? f_line(tSH_01, hL_01, hL_01, currentColorR) : na
lowLine1 = showMTFLevels ? f_line(tSL_01, lL_01, lL_01, currentColorS) : na 
// 2nd Timeframe
highLine2 = showMTFLevels ? f_line(tSH_02, hL_02, hL_02, oneColorR) : na
lowLine2 = showMTFLevels ? f_line(tSL_02, lL_02, lL_02, oneColorS) : na
// 3rd Timeframe
highLine3 = showMTFLevels ? f_line(tSH_03, hL_03, hL_03, twoColorR) : na
lowLine3 = showMTFLevels ? f_line(tSL_03, lL_03, lL_03, twoColorS) : na

// == TREND CALCULATIONS (USING A TUPLE TO CONSOLIDATE REPETATIVE CODE AND GENERATE MULTIPE VARIABLES WITH ONE FUNCTION ==
f_signal(highLevel, lowLevel) =>
    uptrendSignal    = high > highLevel
    downtrendSignal  = low < lowLevel
    inUptrend        = bool(na)
    inDowntrend      = bool(na) 
    inUptrend       := uptrendSignal[1] ? true : downtrendSignal[1] ? false : inUptrend[1]
    inDowntrend     := not inUptrend
    [uptrendSignal, downtrendSignal, inUptrend, inDowntrend]

[uptrendSignal1, downtrendSignal1, inUptrend1, inDowntrend1] = f_signal(hL_01, lL_01)  // 1st Timeframe
[uptrendSignal2, downtrendSignal2, inUptrend2, inDowntrend2] = f_signal(hL_02, lL_02)  // 2nd Timeframe
[uptrendSignal3, downtrendSignal3, inUptrend3, inDowntrend3] = f_signal(hL_03, lL_03)  // 3rd Timeframe

// == TREND TABLE PLOTTING ==
tablePos = tableLocation == "Top" ? position.top_right : position.bottom_right
var table trendTable = table.new(tablePos, 3, 1, border_width = 3)
upColor = color.rgb(38, 166, 154)
downColor = color.rgb(240, 83, 80)

f_fillCell(_column, _row, _cellText, _c_color) =>
    table.cell(trendTable, _column, _row, _cellText, bgcolor = color.new(_c_color, 70), text_color = _c_color, width = 6)

if barstate.islast or barstate.islastconfirmedhistory
    f_fillCell(0, 0, inUptrend1 ? "▲" : "▼", inUptrend1 ? upColor : downColor)
    f_fillCell(1, 0, inUptrend2 ? "▲ " + twoSet : "▼ " + twoSet, inUptrend2 ? upColor : downColor)
    f_fillCell(2, 0, inUptrend3 ? "▲ " + threeSet : "▼ " + threeSet, inUptrend3 ? upColor : downColor)

// Conditions for entry and exit
buyConditions =  true
buySignal = high > hL_01 and buyConditions // Code to act like a stop-buy for the Study
sellSignal = low < lL_01 // Code to act like a stop-loss for the Study

// (STRATEGY ONLY) Comment out for Study
strategy.entry("Long", strategy.long, stop = hL_01, when = buyConditions)
// strategy.entry("Long", strategy.long, stop = buyLevel2, when = time > Start and time < Finish and high > maFilterCheck)
strategy.exit("Exit Long", from_entry = "Long", stop=lL_01)



Mehr