
Die Hauptidee dieser Strategie ist es, die Richtung der Trends auf den größeren Zeitrahmen zu identifizieren und auf den kleineren Zeitrahmen die Eintrittspunkte zu finden, während der Stopp-Exit den Moving Averages auf den größeren Zeitrahmen verfolgt.
Die Strategie basiert auf drei Indikatoren:
Zuerst berechnet man einen X-Tage-Simple Moving Average für eine längere Periode (z.B. eine Sonnenlinie), der nur dann zum Kauf zugelassen ist, wenn der Moving Average auf der Preisstation steht. Dies kann verwendet werden, um die Richtung des allgemeinen Trends zu bestimmen und eine Periode der Handelsschwankungen zu vermeiden.
Zweitens berechnet man die höchsten Preise innerhalb eines kürzeren Zeitraums (z.B. 5 Tage), um ein Kaufsignal auszulösen, wenn der Preis diesen Höchstwert überschreitet. Hier wird ein Rückblick auf die Periodiparameter lb kombiniert, um einen geeigneten Bruchpunkt zu finden.
Drittens, eine Stop-Line zu erstellen. Nach dem Eintritt in die Position, die Stop-Line auf den niedrigsten Preis von lbStop in einem bestimmten Zeitraum von der nächsten Tiefe gesperrt. Gleichzeitig ein Moving Average (wie die 10-Tage-EMA der Tageslinie) als Exit-Mechanismus, der den Handel aus dem Handel, wenn der Preis unter dem Moving Average.
Die Strategie setzt gleichzeitig den ATR-Wert ein, um zu vermeiden, dass überhöhte Punkte gekauft werden. Zusätzlich gibt es weitere zusätzliche Bedingungen wie die Rückmesszeit.
Die Interaktionen dieser drei Indikatoren bilden die zentrale Logik der Strategie.
Es handelt sich um eine bahnbrechende Tracking-Strategie mit folgenden Vorteilen:
Verwenden Sie zwei Zeitrahmen, um zu vermeiden, dass Sie in einem wackligen Markt mit falschen Durchbrüchen gefangen sind. Die längeren Zeitrahmen beurteilen die allgemeinen Trends, die kürzeren suchen nach bestimmten Einstiegspunkten.
Durchschnittspunkte, die durch Swing Highs entstehen, sind inertial und leicht nachvollziehbar. Die Parameter lb können angepasst werden, um nach wirklich effektiven Durchbrüchen zu suchen.
Die Stop-Loss-Methode ist strenger und verfolgt die jüngsten Tiefststände und lässt eine gewisse Bufferdistanz zu, um zu vermeiden, dass sie aufgehängt werden.
Die Verwendung von Moving Averages als Exit-Mechanismus ermöglicht eine flexible Einstellung.
Die ATR-Anzeige verhindert die Gefahr einer Überstrahlung.
Es können verschiedene Parameterkombinationen eingestellt werden, um die Wirkung zu testen und zu optimieren.
Die Strategie birgt auch Risiken:
Wenn die Preise in der Nähe des Moving Averages auf und ab schwanken, ist es leicht, wiederholt in und aus der Position zu wechseln. Dies birgt das Risiko höherer Gebühren.
Wenn der Kaufpunkt in der Nähe des beweglichen Durchschnitts durchbrochen wird, besteht ein höheres Rücknahmerisiko. Dies ist eine Eigenschaft der Strategie selbst.
Wenn die Marktentwicklung sich nicht deutlich entwickelt, kann es zu lange dauern, und es besteht ein Zeitrisiko.
Es ist notwendig, die ATR-Parameter vernünftigerweise einzustellen. Wenn der ATR zu klein ist, ist die Filterwirkung schwach, wenn er zu groß ist, verringert sich die Eintrittschancen.
Es ist notwendig, die Auswirkungen verschiedener lb-Parameter auf die Ergebnisse zu testen. Zu große Parameter verpassen einige Chancen, zu kleine Parameter können falsche Durchbrüche erkennen.
Die Risiken können auf folgende Weise gelöst werden:
Die Strategie kann auch in folgenden Dimensionen optimiert werden:
Verschiedene Kombinationen von Moving Average-Parametern werden getestet, um die optimale Variante zu finden.
Versuchen Sie, verschiedene ATR-Parameter einzustellen, um die Eintrittschancen und die Risikokontrolle auszugleichen.
Optimierung der Rückblick-Periode lb-Parameter zur Identifizierung effizienterer Durchbrüche.
Versuchen Sie, dynamische Stop-Losses zu erstellen, um die Risiken aufgrund der Volatilität und der Rücknahme zu kontrollieren.
Die Effektivität des Durchbruchs wird in Kombination mit anderen Faktoren, wie beispielsweise dem Handelsvolumen, beurteilt.
Entwicklung von Methoden zur Suche nach Extreme als Referenzpunkte, wie z.B. >/‘,</,><
Versuchen Sie, die Parameter mit Machine Learning zu trainieren, um die optimalen Parameter zu erhalten
Die Strategie als Ganzes ist eine typische Breakthrough-Tracking-Strategie. Die Doppel-Zeitrahmen-Beschlüsse, die Swing High-Erkennung der Einstiegsmomente, die Stop-Line und die Doppel-Exit-Mechanismen des Moving Averages bilden ein vollständiges logisches System. Die Strategie weist eine eindeutige Risiko- und Ertragscharakteristik und ist für Investoren geeignet, die die Art von mittleren und langen Linien verfolgen.
/*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.