Stratégie de rupture de volatilité dynamique


Date de création: 2023-11-13 11:26:50 Dernière modification: 2023-11-13 11:26:50
Copier: 1 Nombre de clics: 750
1
Suivre
1617
Abonnés

Stratégie de rupture de volatilité dynamique

Aperçu

Cette stratégie utilise la dynamique de la bande de Brin pour faire plus lorsque le prix franchit la bande de Brin et plus lorsque le prix franchit la bande de Brin. Contrairement à la stratégie de rupture traditionnelle, la bande de Brin change de dynamique en fonction de la volatilité historique, ce qui permet de mieux juger de l’état de survente du marché.

Principe de stratégie

La stratégie repose principalement sur la rupture des prix de l’indicateur de la ceinture de Brin. La ceinture de Brin comprend trois lignes:

  1. moyenne mobile sur n jours
  2. En haut: ligne médiane + k * n jours d’écart standard
  3. Basse piste: ligne médiane - k * n jours de différence standard

Lorsque la hausse des prix dépasse la hausse, considérez que le marché est en survente, et vous pouvez faire plus. Lorsque la baisse des prix dépasse la baisse, considérez que le marché est en survente, et vous devriez faire un pari.

Cette stratégie permet de personnaliser les paramètres de la bande de Bryn: la longueur de la ligne médiane n et le multiple de l’écart-type k. La longueur de la ligne médiane par défaut est de 20 jours et le multiple de l’écart-type est de 2.

Après la clôture de chaque jour, il vérifie si le prix de clôture de la journée a franchi la trajectoire supérieure. Si c’est le cas, il exécute un signal de plus lors de l’ouverture du lendemain. Après avoir fait plus, il surveille en temps réel si le prix a franchi la trajectoire inférieure, et si elle est franchie, elle est à plat.

La stratégie a également introduit un filtre linéaire, qui ne génère des signaux multiples que lorsque le prix est supérieur à la ligne moyenne. Il est possible de choisir de tracer la ligne moyenne sur la période actuelle ou plus élevée pour contrôler le moment d’entrée.

La méthode de stop loss offre également deux options: un stop loss à pourcentage fixe ou un suivi du train de descente de la ceinture de Brin. Ce dernier offre une plus grande marge de manœuvre pour les bénéfices.

Avantages stratégiques

  • Le marché est jugé à l’aide de la courbe de Brin
  • Filtrage uniforme pour éviter les échanges négatifs
  • Des paramètres de bande de Bryn personnalisables pour s’adapter à différents cycles
  • Deux options de réduction de la perte
  • Prise en charge des paramètres d’optimisation de la rétroanalyse et des stratégies de vérification en direct

Risque stratégique

  • Le Blinky n’est pas tout à fait à même de juger les sur-achats et les sur-venteurs.
  • Le filtrage linéaire peut manquer une percée plus rapide
  • Les stop-loss fixes peuvent être trop conservateurs et les stop-loss de suivi peuvent être trop radicaux
  • Paramètres à optimiser pour différentes variétés et cycles
  • Il n’y a pas de limite à la taille des pertes, il faut tenir compte de la gestion des fonds

Optimisation de la stratégie

  • Tester différentes combinaisons de paramètres de moyenne
  • Essayez différents paramètres de la bande de Bryn
  • Comparaison des taux de rendement des arrêts de pourcentage fixes et des arrêts de suivi sous la voie
  • Ajout d’un module de gestion des fonds pour limiter les pertes individuelles
  • En combinaison avec d’autres indicateurs de vérification du signal de la bande de Bryn

Résumer

La stratégie utilise la dynamique des bandes de Brin pour juger des sur-achats et des survente, des signaux de filtrage en ligne uniforme, des fonds de protection contre les pertes. Comparée à la rupture de la trajectoire fixe traditionnelle, elle est plus adaptée aux fluctuations du marché.

Code source de la stratégie
/*backtest
start: 2022-11-06 00:00:00
end: 2023-11-12 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5

// Revision:        1
// Author:          @millerrh
// Strategy:  
//      Entry: Buy when price breaks out of upper Bollinger Band
//      Exit: Trail a stop with the lower Bollinger Band 
// Conditions/Variables:
//    1. Can add a filter to only take setups that are above a user-defined moving average on current timeframe and/or longer timeframe (helps avoid trading counter trend) 
//    2. Manually configure which dates to back test
//    3. User-Configurable Bollinger Band Settings
//    4. Optionally use a tighter initial stop level.  Once Bollinger Band catches up, trail with lower Bollinger Band to give more breathing room.

// strategy('Donchian Breakout', overlay=true, initial_capital=100000, currency='USD', default_qty_type=strategy.percent_of_equity, calc_on_every_tick = true,
//   default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1)

strategy('Bollinger Breakout', overlay=true, initial_capital=100000, currency='USD', default_qty_type=strategy.percent_of_equity,
  default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.0, calc_on_order_fills=true)

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

// == INPUTS ==
// Bollinger Band Inputs
bbLength = input.int(20, minval=1, group = "Bollinger Band Settings", title="Bollinger Band Length",
  tooltip = "Bollinger Band moving average length.")
bbMultTop = input.float(2.0, minval=0.001, maxval=50, title="Standard Deviation (Top)")
bbMultBot = input.float(2.0, minval=0.001, maxval=50, title="Standard Deviation (Bottom)")

useTightStop = input.bool(title='Use Fixed Percentage for Initial Stop?', defval=false, group = "order entry",
  tooltip = "'Keep your losers small and let winners run' is the saying.  This will allow you to use a tight initial stop
  until the lower Bollinger Band catches up.")
percStop = input.int(title="Stop", defval=8, group = "order entry", inline = "perc")
trigInput = input.string(title='Execute Trades On...', defval='Wick', options=['Wick', 'Close'], group = "order entry",
  tooltip = "Useful for comparing standing stop orders at the Bollinger Band boundary (executing on the wick) vs. waiting for candle closes prior to taking action")

// Moving Average Filtering Inputs
useMaFilter = input.bool(title='Use Moving Average for Filtering (Current Timeframe)?', defval=false, group = "moving average filtering",
  tooltip = "Signals will be ignored when price is under this moving average.  The intent is to keep you out of bear periods and only buying when 
             price is showing strength.")
maType = input.string(defval='SMA', options=['EMA', 'SMA'], title='MA Type For Filtering', group = "moving average filtering")
maLength = input.int(defval=50, title="Moving Average:    Length", minval=1, group = "moving average filtering", inline = "1ma")
ma1Color = input.color(color.new(color.green, 50), title = " Color", group = "moving average filtering", inline = "1ma")
useMaFilter2 = input.bool(title='Use Moving Average for Filtering (High Timeframe)?', defval=false, group = "moving average filtering")
tfSet = input.timeframe(defval="D", title="Timeframe of Moving Average", group = "moving average filtering",
  tooltip = "Allows you to set a different time frame for a moving average filter.  Trades will be ignored when price is under this moving average.
  The idea is to keep your eye on the larger moves in the market and stay on the right side of the longer term trends and help you be pickier about 
  the stocks you trade.")
ma2Type = input.string(defval='SMA', options=['EMA', 'SMA'], title='MA Type For Filtering', group = "moving average filtering")
ma2Length = input.int(defval=50, title="Moving Average:    Length", minval=1, group = "moving average filtering", inline = "2ma")
ma2Color = input.color(color.new(color.white, 50), title = " Color", group = "moving average filtering", inline = "2ma")


// === THE BOLLINGER BAND ===
// Logic
bbBasis = ta.sma(close, bbLength)
bbUpper = bbBasis + bbMultTop * ta.stdev(close, bbLength)
bbLower = bbBasis - bbMultBot * ta.stdev(close, bbLength)

// Plotting
plot(bbBasis, "Basis", color=color.new(color.white, 50))
p1 = plot(bbUpper, color=color.new(color.blue, 50), linewidth=1, title='Upper Bollinger Band')
p2 = plot(bbLower, color=color.new(color.blue, 50), linewidth=1, title='Lower Bollinger Band')
fill(p1, p2, title = "Background", color=color.rgb(33, 150, 243, 95))

// == FILTERING LOGIC ==
// Declare function to be able to swap out EMA/SMA
ma(maType, src, length) =>
    maType == 'EMA' ? ta.ema(src, length) : ta.sma(src, length)  //Ternary Operator (if maType equals EMA, then do ema calc, else do sma calc)
maFilter = ma(maType, close, maLength)
maFilter2 = request.security(syminfo.tickerid, tfSet, ma(ma2Type, close, ma2Length))

// Plotting
plot(useMaFilter ? maFilter : na, title='Trend Filter MA - CTF', color=ma1Color, linewidth=2, style=plot.style_line)
plot(useMaFilter2 ? maFilter2 : na, title='Trend Filter MA - HTF', color=ma2Color, linewidth=2, style=plot.style_line)


// == ENTRY AND EXIT CRITERIA ==
// Trigger stop based on candle close or High/Low (i.e. Wick)
trigResistance = trigInput == 'Close' ? close : trigInput == 'Wick' ? high : na
trigSupport = trigInput == 'Close' ? close : trigInput == 'Wick' ? low : na
buySignal = trigResistance >= bbUpper 

buyConditions = (useMaFilter ? bbUpper > maFilter : true) and
  (useMaFilter2 ? bbUpper > maFilter2 : true) 
  
// == STOP AND PRICE LEVELS ==
// Configure initial stop level
inPosition = strategy.position_size > 0
stopLevel = strategy.position_avg_price - (strategy.position_avg_price * percStop/100)
posStop = stopLevel > bbLower ? stopLevel : bbLower


// Check if using stop vs. not
stop = useTightStop ? posStop : bbLower
plot(inPosition ? stop : na, style=plot.style_linebr, color=color.new(color.red, 40), linewidth = 1, title = "Stop Levels", trackprice=false)

sellSignal = trigSupport <= stop

// == STRATEGY ENTRIES & EXITS ==
// This string of code enters and exits at the candle close
if trigInput == 'Close'
    strategy.entry('Long', strategy.long, when=buyConditions and buySignal)
    strategy.close('Long', when=sellSignal)

// This string of code enters and exits at the wick (i.e. with pre-set stops)
if trigInput == 'Wick'
    strategy.entry('Long', strategy.long, stop=bbUpper, when=buyConditions)
    strategy.exit('Exit Long', from_entry='Long', stop=stop)
strategy.cancel('Long',when= not(buyConditions)) // Resets stop level once buyConditions aren't true anymore