Qullamaggie Ausbruch Verfolgungsstrategie

Schriftsteller:ChaoZhang, Datum: 2024-01-31 17:06:36
Tags:

img

Übersicht

Die Hauptidee dieser Strategie besteht darin, die Trendrichtung auf einem größeren Zeitrahmen zu identifizieren und Ausbruchspunkte zu finden, um auf einem kleineren Zeitrahmen einzutreten.

Strategieprinzip

Diese Strategie stützt sich hauptsächlich auf drei Indikatoren.

Erstens berechnen Sie einen längeren Zyklus (z. B. täglich) X-Tage einfacher gleitender Durchschnitt. Erlauben Sie den Kauf nur, wenn der Preis über diesem gleitenden Durchschnitt liegt. Dies kann verwendet werden, um die allgemeine Trendrichtung zu bestimmen und schwankende Handelsperioden zu vermeiden.

Zweitens berechnen Sie den höchsten Preis Swing High in einem kürzeren Zyklus (z. B. 5 Tage). Wenn der Preis diesen höchsten Preis durchbricht, wird ein Kaufsignal ausgelöst.

Sie können die Position mit einem Stop-Loss-Linien-System aufbauen, das die Position auf dem niedrigsten Preis für einen bestimmten Zeitraum abschließt.

Die Strategie legt auch den ATR-Wert fest, um zu vermeiden, dass Punkte zu lange gekauft werden.

Die Interaktionsbeurteilung der drei oben genannten Indikatoren bildet die Kernlogik dieser Strategie.

Analyse der Vorteile

Als Breakout-Tracking-Strategie hat sie folgende Vorteile:

  1. Verwenden Sie zwei Zeitrahmen, um nicht in falsche Ausbrüche in schwankenden Märkten zu geraten.

  2. Diese Art von Breakout hat eine gewisse Trägheit und ist leicht zu verfolgen. Der Lb Lookback Period Parameter kann auch angepasst werden, um wirklich effektive Breakouts zu finden.

  3. Die Stop-Loss-Methode ist relativ streng und verfolgt den jüngsten Tiefpunkt mit einer bestimmten Pufferdistanz, um zu vermeiden, dass er abgeschraubt wird.

  4. Verwenden Sie den gleitenden Durchschnitt als Exit-Mechanismus, um nach Marktbedingungen flexibel Gewinne zu erzielen.

  5. Der ATR-Indikator vermeidet das Risiko eines übermäßigen Hebels.

  6. Für die Prüfung können verschiedene Parameterkombinationen mit großem Optimierungsraum festgelegt werden.

Risikoanalyse

Die Strategie birgt auch einige Risiken:

  1. Wenn der Preis um die gleitende Durchschnittslinie nach oben und unten schwingt, ist es leicht, zwischen Ein- und Ausstiegspositionen hin und her zu wechseln.

  2. Wenn der Einbruchspunkt nahe der gleitenden Durchschnittslinie liegt, besteht ein relativ großes Rückzugsrisiko.

  3. Wenn es keine offensichtliche Entwicklung auf dem Markt gibt, kann die Haltedauer zu lang sein, was ein zeitliches Risiko mit sich bringt.

  4. Der ATR-Parameter muss vernünftig eingestellt werden. Wenn der ATR zu klein ist, ist der Filtereffekt schwach. Wenn er zu groß ist, verringern sich die Eintrittsmöglichkeiten.

  5. Es ist notwendig, die Auswirkungen verschiedener Lb-Parameter auf die Ergebnisse zu testen.

Risikominderung:

  1. Anpassung der gleitenden Durchschnittsparameter, um die Filterfähigkeit zu erhöhen.
  2. Optimierung der ATR-Parameter, ergänzt durch visuelles Urteilen.
  3. Richten Sie die Lb-Back-Periode an, um die optimalen Parameter zu finden.
  4. Stoppen Sie den Handel während schwankender Märkte.

Optimierungsrichtlinien

Die Strategie kann auch in folgenden Dimensionen optimiert werden:

  1. Versuche verschiedene Kombinationen von gleitenden Durchschnittsparametern, um die optimalen Parameter zu finden.

  2. Versuchen Sie verschiedene ATR-Parameter, um die Eintrittsmöglichkeiten und die Risikokontrolle auszugleichen.

  3. Optimieren Sie den Parameter der Lb-Lookback-Periode, um effizientere Ausbrüche zu identifizieren.

  4. Versuchen Sie, einen dynamischen Stop-Loss auf der Grundlage von Volatilität und Drawdown zu erstellen, um das Risiko zu kontrollieren.

  5. Einbeziehen Sie andere Faktoren wie das Handelsvolumen, um die Wirksamkeit von Ausbrüchen zu bestimmen.

  6. Entwickeln Sie/,< und andere Methoden, um extreme Punkte als Referenzen zu finden.

  7. Versuchen Sie Machine Learning, um Parameter für optimale Parameter zu trainieren

Zusammenfassung

Insgesamt handelt es sich um eine typische Breakout-Tracking-Strategie. Gemessen an den doppelten Zeitrahmen bildet die Verwendung von Swing High zur Identifizierung des Eintrittszeitpunkts und der Verwendung von Stop-Loss-Linien und gleitenden Durchschnitts-Doppel-Versicherungsausstiegsmechanismen ein komplettes logisches System. Die Risiko- und Rendite-Eigenschaften dieser Strategie sind klar und eignen sich für mittelfristige und langfristige Tracking-Investoren. Obwohl es bestimmte Risiken gibt, können sie durch Optimierung von Parametern und Regeln reduziert werden. Die Strategie bietet viel Raum für Verbesserungen. Die Einbeziehung mehrer Indikatoren kann den Strategieeffekt weiter verbessern.


/*backtest
start: 2023-01-24 00:00:00
end: 2024-01-30 00:00:00
period: 1d
basePeriod: 1h
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/
// © millerrh

// The intent of this strategy is to buy breakouts with a tight stop on smaller timeframes in the direction of the longer term trend.
// Then use a trailing stop of a close below either the 10 MA or 20 MA (user choice) on that larger timeframe as the position 
// moves in your favor (i.e. whenever position price rises above the MA).
// Option of using daily ATR as a measure of finding contracting ranges and ensuring a decent risk/reward.
// (If the difference between the breakout point and your stop level is below a certain % of ATR, it could possibly find those consolidating periods.)

//@version=4
strategy("Qullamaggie Breakout", 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)
   
// === BACKTEST RANGE ===
Start = input(defval = timestamp("01 Jan 2019 06:00 +0000"), title = "Backtest Start Date", type = input.time)
Finish = input(defval = timestamp("01 Jan 2100 00:00 +0000"), title = "Backtest End Date", type = input.time)

// Inputs
lb = input(defval = 3, title = "Lookback Period for Swing High", minval = 1,
   tooltip = "Lookback period for defining the breakout level.")
lbStop = input(defval = 3, title = "Lookback Bars for Stop Level", minval = 1,
   tooltip = "Initial stop placement is the lowest low this many bars back. Allows for tighter stop placement than referencing swing lows.")  
htf = input(defval="D", title="Timeframe of Moving Averages", type=input.resolution,
  tooltip = "Allows you to set a different time frame for the moving averages. The default behavior is to identify good tightening setups on a larger timeframe
  (like daily) and enter the trade on a breakout occuring on a smaller timeframe, using the moving averages of the larger timeframe to trail your stop.")
maType = input(defval="SMA", options=["EMA", "SMA"], title = "Moving Average Type")
ma1Length = input(defval = 10, title = "1st Moving Average Length", minval = 1)
ma2Length = input(defval = 20, title = "2nd Moving Average Length", minval = 1)
ma3Length = input(defval = 50, title = "3rd Moving Average Length", minval = 1)
useMaFilter = input(title = "Use 3rd Moving Average for Filtering?", type = input.bool, defval = true,
  tooltip = "Signals will be ignored when price is under this slowest moving average.  The intent is to keep you out of bear periods and only
             buying when price is showing strength or trading with the longer term trend.")
trailMaInput = input(defval="2nd Moving Average", options=["1st Moving Average", "2nd Moving Average"], title = "Trailing Stop")

// MA Calculations
ma(maType, src, length) =>
    maType == "EMA" ? ema(src, length) : sma(src, length) //Ternary Operator (if maType equals EMA, then do ema calc, else do sma calc)
ma1 = security(syminfo.tickerid, htf, ma(maType, close, ma1Length))
ma2 = security(syminfo.tickerid, htf, ma(maType, close, ma2Length))
ma3 = security(syminfo.tickerid, htf, ma(maType, close, ma3Length))

plot(ma1, color=color.purple, style=plot.style_line, title="MA1", linewidth=2, transp = 60)
plot(ma2, color=color.yellow, style=plot.style_line, title="MA2", linewidth=2, transp = 60)
plot(ma3, color=color.white, style=plot.style_line, title="MA3", linewidth=2, transp = 60)

// === USE ATR FOR FILTERING ===
// The idea here is that you want to buy in a consolodating range for best risk/reward. So here you can compare the current distance between 
// support/resistance vs.the ATR and make sure you aren't buying at a point that is too extended from normal.
useAtrFilter = input(title = "Use ATR for Filtering?", type = input.bool, defval = false,
  tooltip = "Signals will be ignored if the distance between support and resistance is larger than a user-defined percentage of Daily ATR. 
             This allows the user to ensure they are not buying something that is too extended and instead focus on names that are consolidating more.")
atrPerc = input(defval = 100, title = "% of Daily ATR Value", minval = 1)
atrValue = security(syminfo.tickerid, "D", atr(14))*atrPerc*.01

// === PLOT SWING HIGH/LOW AND MOST RECENT LOW TO USE AS STOP LOSS EXIT POINT ===
// Change these values to adjust the look back and look forward periods for your swing high/low calculations
pvtLenL = lb
pvtLenR = lb

// Get High and Low Pivot Points
pvthi_ = pivothigh(high, pvtLenL, pvtLenR)
pvtlo_ = pivotlow(low, pvtLenL, pvtLenR)

// Force Pivot completion before plotting.
Shunt = 1 //Wait for close before printing pivot? 1 for true 0 for flase
maxLvlLen = 0 //Maximum Extension Length
pvthi = pvthi_[Shunt]
pvtlo = pvtlo_[Shunt]

// Count How many candles for current Pivot Level, If new reset.
counthi = barssince(not na(pvthi))
countlo = barssince(not na(pvtlo))
 
pvthis = fixnan(pvthi)
pvtlos = fixnan(pvtlo)
hipc = change(pvthis) != 0 ? na : color.maroon
lopc = change(pvtlos) != 0 ? na : color.green

// Display Pivot lines
plot((maxLvlLen == 0 or counthi < maxLvlLen) ? pvthis : na, color=hipc, transp=0, linewidth=1, offset=-pvtLenR-Shunt, title="Top Levels")
// plot((maxLvlLen == 0 or countlo < maxLvlLen) ? pvtlos : na, color=lopc, transp=0, linewidth=1, offset=-pvtLenR-Shunt, title="Bottom Levels")
plot((maxLvlLen == 0 or counthi < maxLvlLen) ? pvthis : na, color=hipc, transp=0, linewidth=1, offset=0, title="Top Levels 2")
// plot((maxLvlLen == 0 or countlo < maxLvlLen) ? pvtlos : na, color=lopc, transp=0, linewidth=1, offset=0, title="Bottom Levels 2")

// BUY CONDITIONS
stopLevelCalc = valuewhen(pvtlo_, low[pvtLenR], 0) //Stop Level at Swing Low
buyLevel = valuewhen(pvthi_, high[pvtLenR], 0) //Buy level at Swing High
plot(buyLevel, style=plot.style_line, color=color.blue, title = "Current Breakout Level", show_last=1, linewidth=1, transp=50, trackprice=true)

// Conditions for entry and exit
stopLevel = float(na) // Define stop level here as "na" so that I can reference it in the inPosition 
  // variable and the ATR calculation before the stopLevel is actually defined.
buyConditions = (useMaFilter ? buyLevel > ma3 : true) and
  (useAtrFilter ? (buyLevel - stopLevel[1]) < atrValue : true)
// buySignal = high > buyLevel and buyConditions
buySignal = crossover(high, buyLevel) and buyConditions
trailMa = trailMaInput == "1st Moving Average" ? ma1 : ma2
sellSignal = crossunder(close, trailMa)
// sellSignal = security(syminfo.tickerid, htf, close < trailMa) and security(syminfo.tickerid, htf, close[1] < trailMa)


// STOP AND PRICE LEVELS
inPosition = bool(na)
inPosition := buySignal[1] ? true : sellSignal[1] ? false : low <= stopLevel[1] ? false : inPosition[1]

lowDefine = lowest(low, lbStop)
stopLevel := inPosition ? stopLevel[1] : lowDefine
// plot(stopLevel)

buyPrice = buyLevel
buyPrice := inPosition ? buyPrice[1] : buyLevel
plot(stopLevel, style=plot.style_line, color=color.orange, title = "Current Stop Level", show_last=1, linewidth=1, transp=50, trackprice=true)
plot(inPosition ? stopLevel : na, style=plot.style_circles, color=color.orange, title = "Historical Stop Levels", transp=50, trackprice=false)
// plot(buyPrice, style=plot.style_line, color=color.blue, linewidth=1, transp=50, trackprice=true)

// (STRATEGY ONLY) Comment out for Study
strategy.entry("Long", strategy.long, stop = buyLevel, when = buyConditions)
strategy.exit("Exit Long", from_entry = "Long", stop=stopLevel[1])
if (low[1] > trailMa)
    strategy.close("Long", when = sellSignal)
// if (low[1] > trailMa)
//     strategy.exit("Exit Long", from_entry = "Long", stop=trailMa) //to get this to work right, I need to reference highest highs instead of swing highs
    //because it can have me buy right back in after selling if the stop level is above the last registered swing high point.

Mehr