La stratégie d'inversion de la fourchette dormante utilise des périodes de diminution de la volatilité comme signaux d'entrée et vise à tirer profit lorsque la volatilité reprend. Elle identifie les situations où le prix est contenu dans une fourchette dormante étroite et capte la tendance des prix à venir. Cette stratégie fonctionne bien lorsque la volatilité actuelle est faible mais qu'une rupture est attendue.
La stratégie identifie d'abord une fourchette dormante, c'est-à-dire lorsque le prix est contenu dans la fourchette de prix de la journée de négociation précédente. Cela indique que la volatilité a diminué par rapport à il y a quelques jours. Nous vérifions si le haut de la journée courante < le haut de n jours auparavant (généralement 4 jours) et le bas de la journée courante > le bas de n jours auparavant pour être considéré comme une fourchette dormante.
Une fois qu'une fourchette dormante est identifiée, la stratégie place deux ordres en attente - un buy stop près du haut de la fourchette et un sell stop près du bas de la fourchette. Elle attend ensuite que le prix dépasse la fourchette soit vers le haut ou vers le bas. Si le prix dépasse vers le haut, l'ordre d'achat est déclenché pour aller long. Si le prix dépasse vers le bas, l'ordre de vente est déclenché pour aller court.
Après l'entrée, les ordres stop loss et take profit sont placés. Le stop loss contrôle le risque à la baisse et le take profit ferme le commerce pour le profit. Le stop loss est placé à une distance de % du prix d'entrée tel que défini dans les paramètres de risque. Le take profit est placé à une distance égale à la taille de la plage dormante car nous nous attendons à ce que le prix se déplace de manière similaire à la volatilité précédente.
Enfin, un modèle de taille de position fractionnée fixe gère la taille des transactions.
Les avantages de cette stratégie sont les suivants:
Capture la tendance à venir en utilisant la volatilité diminuée comme signal.
Les ordres bidirectionnels sont des ordres de prise de tendance haussière ou de baisse.
Le risque de stop loss et de prise de bénéfices est contrôlé par un seul métier.
La taille fractionnée fixe améliore l'efficacité du capital.
Une logique simple, facile à mettre en œuvre.
Les risques à prendre en considération sont les suivants:
Fausse direction de fuite si la fuite de portée n'est pas claire.
L'éclatement est peut-être juste un court renversement, pas une tendance durable.
Le risque d'être éliminé par des mouvements énormes.
La taille des fractions fixes peut amplifier les pertes lorsqu'elles s'ajoutent à des transactions perdantes.
Faibles performances si les paramètres ne sont pas réglés correctement.
Quelques moyens pour améliorer la stratégie:
Ajoutez des filtres comme la divergence pour éviter les fausses fuites.
Améliorer le stop-loss avec des stop-loss de suivi ou d'ordre.
Ajouter un filtre de tendance pour éviter les entrées contre tendance.
Optimiser les ratios de fraction fixe pour un risque/rendement équilibré.
Regardez à plusieurs délais pour améliorer l'avantage.
Utiliser l'apprentissage automatique pour l'optimisation automatisée des paramètres.
La stratégie d'inversion de plage en sommeil a une logique et un potentiel de profit clairs. Le réglage fin par l'optimisation, la gestion des risques et le filtrage des signaux peut améliorer encore la cohérence. Mais toutes les stratégies de réversion moyennes comportent des risques inhérents et la taille des positions doit être contrôlée.
/*backtest start: 2023-09-29 00:00:00 end: 2023-10-29 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/ // © gsanson66 //This code is based on the Narrow Range strategy //Interactive Broker fees are applied on this strategy //@version=5 strategy("NARROW RANGE BACKTESTING", shorttitle="NR BACKTESTING", overlay=true, initial_capital=1000, default_qty_type=strategy.fixed, commission_type=strategy.commission.percent, commission_value=0.18) //--------------------------------FUNCTIONS------------------------------------// //@function to print label debugLabel(txt, color) => label.new(bar_index, high, text = txt, color=color, style = label.style_label_lower_right, textcolor = color.black, size = size.small) //@function which looks if the close date of the current bar falls inside the date range inBacktestPeriod(start, end) => (time >= start) and (time <= end) //--------------------------------USER INPUTS------------------------------------// //Narrow Range Length nrLength = input.int(4, minval=2, title="Narrow Range Length", group="Strategy parameters") //Risk Management stopLossInput = input.float(0.5, title="Stop Loss (in percentage of reference range)", group="Strategy parameters") //Money Management fixedRatio = input.int(defval=400, minval=1, title="Fixed Ratio Value ($)", group="Money Management") increasingOrderAmount = input.int(defval=200, minval=1, title="Increasing Order Amount ($)", group="Money Management") //Backtesting period startDate = input(title="Start Date", defval=timestamp("1 Janv 2020 00:00:00"), group="Backtesting Period") endDate = input(title="End Date", defval=timestamp("1 July 2024 00:00:00"), group="Backtesting Period") //--------------------------------VARIABLES INITIALISATION--------------------------// strategy.initial_capital = 50000 bool nr = na var bool long = na var bool short = na var float stopPriceLong = na var float stopLossLong = na var float takeProfitLong = na var float stopPriceShort = na var float stopLossShort = na var float takeProfitShort = na var float takeProfit = na var float stopLoss = na bool inRange = na int closedtrades = strategy.closedtrades equity = math.abs(strategy.equity - strategy.openprofit) var float capital_ref = strategy.initial_capital var float cashOrder = strategy.initial_capital * 0.95 //------------------------------CHECKING SOME CONDITIONS ON EACH SCRIPT EXECUTION-------------------------------// //Checking if the date belong to the range inRange := true //Checking performances of the strategy if equity > capital_ref + fixedRatio spread = (equity - capital_ref)/fixedRatio nb_level = int(spread) increasingOrder = nb_level * increasingOrderAmount cashOrder := cashOrder + increasingOrder capital_ref := capital_ref + nb_level*fixedRatio if equity < capital_ref - fixedRatio spread = (capital_ref - equity)/fixedRatio nb_level = int(spread) decreasingOrder = nb_level * increasingOrderAmount cashOrder := cashOrder - decreasingOrder capital_ref := capital_ref - nb_level*fixedRatio //We check if a trade has been closed to cancel all previous orders if closedtrades > closedtrades[1] strategy.cancel("Long") strategy.cancel("Short") stopPriceLong := na stopPriceShort := na //Checking if we close all trades in case where we exit the backtesting period if strategy.position_size!=0 and not inRange debugLabel("END OF BACKTESTING PERIOD : we close the trade", color=color.rgb(116, 116, 116)) strategy.close_all() long := na short := na stopPriceLong := na stopLossLong := na takeProfitLong := na stopPriceShort := na stopLossShort := na takeProfitShort := na takeProfit := na stopLoss := na //----------------------------------FINDING NARROW RANGE DAY------------------------------------------// // We find the Narrow Range Day if low > low[nrLength] and high < high[nrLength] nr := true //------------------------------------STOP ORDERS--------------------------------------------// // We handle plotting of stop orders and cancellation of other side order if one order is triggered if strategy.position_size > 0 and not na(stopPriceLong) and not na(stopPriceShort) long := true strategy.cancel("Short") stopPriceLong := na stopPriceShort := na takeProfit := takeProfitLong stopLoss := stopLossLong if strategy.position_size < 0 and not na(stopPriceLong) and not na(stopPriceShort) short := true strategy.cancel("Long") stopPriceLong := na stopPriceShort := na takeProfit := takeProfitShort stopLoss := stopLossShort //------------------------------------STOP LOSS & TAKE PROFIT--------------------------------// // If an order is triggered we plot TP and SL if not na(takeProfit) and not na(stopLoss) and long if high >= takeProfit and closedtrades == closedtrades[1] + 1 takeProfit := na stopLoss := na long := na if low <= stopLoss and closedtrades == closedtrades[1] + 1 takeProfit := na stopLoss := na long := na if not na(takeProfit) and not na(stopLoss) and short if high >= stopLoss and closedtrades == closedtrades[1] + 1 takeProfit := na stopLoss := na short := na if low <= takeProfit and closedtrades == closedtrades[1] + 1 takeProfit := na stopLoss := na short := na //-----------------------------LONG/SHORT CONDITION-------------------------// // Conditions to create two stop orders (one for Long and one for Short) and SL & TP calculation if nr and inRange and strategy.position_size == 0 stopPriceLong := high[4] takeProfitLong := high[4] + (high[4] - low[4]) stopLossLong := high[4] - (high[4] - low[4])*stopLossInput qtyLong = cashOrder/stopPriceLong strategy.entry("Long", strategy.long, qtyLong, stop=stopPriceLong) strategy.exit("Exit Long", "Long", limit=takeProfitLong ,stop=stopLossLong) stopPriceShort := low[4] takeProfitShort := low[4] - (high[4] - low[4]) stopLossShort := low[4] + (high[4] - low[4])*stopLossInput qtyShort = cashOrder/stopPriceShort strategy.entry("Short", strategy.short, qtyShort, stop=stopPriceShort) strategy.exit("Exit Short", "Short", limit=takeProfitShort ,stop=stopLossShort) //--------------------------PLOTTING ELEMENT----------------------------// plotshape(nr, "NR", shape.arrowdown, location.abovebar, color.rgb(255, 132, 0), text= "NR4", size=size.huge) plot(stopPriceLong, "Stop Order", color.blue, 3, plot.style_linebr) plot(stopPriceShort, "Stop Order", color.blue, 3, plot.style_linebr) plot(takeProfit, "Take Profit", color.green, 3, plot.style_linebr) plot(stopLoss, "Stop Loss", color.red, 3, plot.style_linebr)