Стратегия инверсии спящего диапазона использует периоды снижения волатильности в качестве сигналов входа и направлена на получение прибыли, когда волатильность снова набирает обороты. Она определяет ситуации, когда цена содержится в узком спящем диапазоне и фиксирует предстоящую ценовую тенденцию. Эта стратегия хорошо работает, когда текущая волатильность низкая, но ожидается прорыв.
Стратегия сначала идентифицирует спящий диапазон, когда цена содержится в диапазоне цен предыдущего торгового дня. Это указывает на то, что волатильность снизилась по сравнению с несколькими днями назад. Мы проверяем, является ли текущий день высокий < высокий n дней назад (обычно 4 дня) и текущий день низкий > низкий n дней назад, чтобы квалифицироваться как спящий диапазон.
После того, как дремлющий диапазон идентифицирован, стратегия размещает два ожидающих ордера - стоп покупки в верхней части диапазона и стоп продажи в нижней части диапазона. Затем она ждет, пока цена не выйдет из диапазона либо вверх, либо вниз. Если цена проходит вверх, ордер покупки запускается на длинный. Если цена проходит вниз, ордер продажи запускается на короткий.
После входа, ордера на остановку потерь и получение прибыли размещаются. Стоп-лосс контролирует риск снижения, а получение прибыли закрывает торговлю с целью получения прибыли. Стоп-лосс размещается на расстоянии % от цены входа, как определено в параметрах риска. Прибыль размещается на расстоянии, равном размеру спящего диапазона, поскольку мы ожидаем, что цена будет двигаться аналогично предыдущей волатильности.
Наконец, фиксированная фракционная модель размещения позиций управляет размером сделки. Она увеличивает размер прибыли и уменьшает размер убытков для улучшения корректированной по риску доходности.
Преимущества этой стратегии:
Захватывает предстоящую тенденцию, используя снижение волатильности в качестве сигнала.
Двухнаправленные ордера улавливают восходящий или нисходящий тренд.
Стоп-лосс и прибыль контролируют риск одной сделки.
Фиксированное дробление увеличивает эффективность капитала.
Простая логика, легко реализуемая.
Риски, которые следует учитывать:
Неправильное направление прорыва, если прорыв диапазона неясен.
Прорыв может быть просто кратковременным изменением, а не длительным трендом.
Риск быть выведенным огромными движениями.
Фиксированный размер фракции может увеличить убытки при добавлении к проигрышным сделкам.
Плохая производительность, если параметры не установлены правильно.
Некоторые способы улучшения стратегии:
Добавьте фильтры, такие как дивергенция, чтобы избежать ложных прорывов.
Улучшить стоп-лосс с задержкой или ордером стоп-лосса.
Добавьте фильтр тренда, чтобы избежать записей, противоречащих тренду.
Оптимизировать соотношение фиксированной доли для сбалансированного соотношения риска и прибыли.
Посмотрите на несколько временных рамок для улучшения преимущества.
Использование машинного обучения для автоматической оптимизации параметров.
Стратегия реверсии спящего диапазона имеет четкую логику и потенциал прибыли. Тонкая настройка с помощью оптимизации, управления рисками и фильтрации сигналов может еще больше улучшить последовательность. Но все средние стратегии реверсии несут в себе неотъемлемые риски, и размещение позиций необходимо контролировать.
/*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)