Stratégie de suivi de cassure


Date de création: 2024-01-31 17:06:36 Dernière modification: 2024-01-31 17:06:36
Copier: 0 Nombre de clics: 1280
1
Suivre
1617
Abonnés

Stratégie de suivi de cassure

Aperçu

L’idée principale de cette stratégie est d’identifier la direction de la tendance sur les plus grandes périodes de temps et de trouver des points d’entrée de rupture sur les plus petites périodes de temps, tandis que les arrêts de perte suivent les moyennes mobiles sur les plus grandes périodes de temps.

Principe de stratégie

La stratégie est basée sur trois critères principaux:

Premièrement, le calcul d’une moyenne mobile simple de X jours sur une période plus longue (comme la ligne solaire) ne permet de faire des achats que lorsque la moyenne mobile est à la station de prix. Cela peut être utilisé pour déterminer la direction de la tendance générale et éviter les périodes de volatilité des transactions.

Deuxièmement, calculer le Swing High le plus haut prix d’une période plus courte (par exemple 5 jours) et déclencher un signal d’achat lorsque le prix dépasse ce sommet. Combiné à un paramètre de retour sur le cycle lb, il est possible de trouver un point de rupture approprié.

Troisièmement, établir une ligne de stop-loss. Une fois en position, la ligne de stop-loss est verrouillée sur le prix le plus bas de lbStop d’une période donnée à partir du plus bas le plus proche. En même temps, définir une moyenne mobile (comme l’EMA de 10 jours de la ligne solaire) comme mécanisme d’exit et de sortie de position lorsque le prix est inférieur à cette moyenne mobile.

La stratégie impose également des valeurs d’ATR pour éviter d’acheter des points surdimensionnés. En outre, il existe d’autres conditions auxiliaires telles que la plage de temps de réévaluation.

L’interaction de ces trois indicateurs constitue la logique centrale de cette stratégie.

Analyse des forces stratégiques

Il s’agit d’une stratégie avancée de type tracking qui présente les avantages suivants:

  1. Utilisez deux périodes pour éviter d’être pris dans une fausse rupture de marché. La période plus longue permet de juger de la tendance générale et la période plus courte permet de trouver des points d’entrée spécifiques.

  2. Les points de rupture qui se forment à l’aide du swing high ont une certaine inertie et peuvent être facilement suivis. Les paramètres de la période lb peuvent être ajustés pour rechercher des ruptures vraiment efficaces.

  3. Le stop-loss est plus rigoureux, il suit les plus récents bas et laisse une certaine distance de sécurité pour éviter d’être bloqué.

  4. L’utilisation d’une moyenne mobile comme mécanisme d’exit permet une suspension flexible selon les circonstances.

  5. L’indicateur ATR évite les risques liés à une surdose.

  6. Il est possible de définir différentes combinaisons de paramètres pour tester l’efficacité, avec une plus grande marge d’optimisation.

Analyse des risques

Cette stratégie comporte aussi des risques:

  1. Il est facile d’être à plusieurs reprises mis en position d’entrée et de sortie lorsque les prix oscillent à proximité des moyennes mobiles, ce qui entraîne un risque de frais de commission plus élevés.

  2. Le risque de retrait est plus élevé lorsque le point d’achat est proche de la moyenne mobile.

  3. Il est possible de conserver une position trop longtemps sans tendance évidente, ce qui entraîne un risque de temps.

  4. Il est nécessaire de définir raisonnablement les paramètres ATR. Si l’ATR est trop petit, le filtrage est faible, si il est trop grand, les chances d’entrée sont réduites.

  5. Il est nécessaire de tester l’influence de différents paramètres lb sur les résultats. Des paramètres trop grands peuvent manquer certaines opportunités, et des paramètres trop petits peuvent identifier de fausses percées.

Comment gérer les risques:

  1. Ajustez les paramètres de la moyenne mobile de manière appropriée pour augmenter le filtrage.
  2. Optimisation des paramètres ATR et prise en compte de l’observation.
  3. Ajustez pour revenir à la période lb, en recherchant le paramètre optimal.
  4. La suspension des transactions en période de choc.

Orientation de l’optimisation de la stratégie

La stratégie peut également être optimisée dans les dimensions suivantes:

  1. Testez différentes combinaisons de paramètres de la moyenne mobile pour trouver le paramètre optimal.

  2. Essayez différents paramètres ATR pour équilibrer les chances d’entrée et le contrôle des risques.

  3. Optimiser les paramètres de révision du cycle lb pour identifier des percées plus efficaces.

  4. Essayez de mettre en place un stop-loss dynamique pour contrôler le risque en fonction de la volatilité et des retraits.

  5. L’efficacité de la percée est évaluée en fonction d’autres facteurs, tels que le volume des transactions.

  6. Développer des méthodes de recherche de points extrêmes tels que <, >, >, <, etc.

  7. Essayez d’entraîner les paramètres avec Machine Learning pour obtenir le paramètre optimal

Résumer

La stratégie dans son ensemble est une stratégie de suivi de rupture typique. Le jugement sur le double cadre de temps, Swing High identifie le moment d’entrée, la ligne d’arrêt et le mécanisme de sortie double assurance de la moyenne mobile, formant un système logique complet. Les caractéristiques de risque et de récompense de la stratégie sont assez claires et conviennent aux investisseurs de type suivi de ligne moyenne et longue. Bien que certains risques existent, le niveau de risque peut être réduit par l’optimisation des paramètres et l’optimisation des règles.

Code source de la stratégie
/*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.