Эта стратегия использует гипотетическое тестирование, чтобы определить, отклоняется ли ATR от своего среднего значения. В сочетании с прогнозом ценовой тенденции, она реализует среднюю стратегию реверсии на основе ATR. Значительное отклонение ATR указывает на потенциальную аномальную волатильность на рынке. Если прогнозируется, что ценовая тенденция будет быстрой, можно установить длинную позицию.
Испытание гипотез
Провести t-тест на двух образцах между быстрым периодом ATR (atr_fast) и медленным периодом ATR (atr_slow).
Если статистика испытания превышает пороговый показатель (интервал доверия, указанный с помощью фактора reliability_factor), следует отклонить нулевую гипотезу, т.е. считается, что быстрая ATR значительно отклоняется от медленной ATR.
Прогноз ценового тренда
Движущаяся средняя логарифмической доходности рассчитывается как ожидаемая скорость дрейфа (дрейф).
Если дрейф увеличивается, текущая тенденция считается bullish.
Вход и выход с остановкой потерь
Пройти длинный курс, когда быстрый и медленный ATR значительно отличаются, а тренд - быстрый.
Постоянно корректируйте стоп-лосс с помощью ATR. Выходите из позиции, когда цена превышает стоп-лосс.
Использование гипотезных испытаний для определения отклонения ATR является более научным и адаптивным.
В сочетании с прогнозом ценового тренда избегается неправильная торговля, основанная исключительно на отклонении ATR.
Корректировка стоп-лосса постоянно управляет риском снижения.
Не в состоянии остановить убытки, когда цена падает.
Неправильное предсказание тренда может привести к покупке на вершине.
Неправильные настройки параметров могут пропустить правильный ввод или добавить ненужные сделки.
Подумайте о добавлении других показателей для многофакторного подтверждения, чтобы избежать ошибок.
Испытать различные комбинации параметров ATR для поиска более стабильных значений.
Добавить критерии прорыва ключевых уровней цен, чтобы избежать ложного прорыва.
Общая логика этой стратегии ясна. Использование гипотетического тестирования для выявления аномальной волатильности разумно. Однако отклонение ATR само по себе недостаточно для определения тренда. Для улучшения точности необходимы больше подтверждающих факторов. Правила стоп-лосса надежны, но неэффективны против крахов в стиле скалы. В будущем можно улучшить такие области, как критерии входа, выбор параметров, оптимизация стоп-лосса.
/*backtest start: 2022-10-16 00:00:00 end: 2023-10-16 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/ // © DojiEmoji //@version=5 strategy("Mean Reversion (ATR) Strategy v2 [KL] ", overlay=true, pyramiding=1) var string ENUM_LONG = "Long" var string GROUP_TEST = "Hypothesis testing" var string GROUP_TSL = "Stop loss" var string GROUP_TREND = "Trend prediction" backtest_timeframe_start = input(defval=timestamp("01 Apr 2000 13:30 +0000"), title="Backtest Start Time") within_timeframe = true // TSL: calculate the stop loss price. { ATR_TSL = ta.atr(input(14, title="Length of ATR for trailing stop loss", group=GROUP_TSL)) * input(2.0, title="ATR Multiplier for trailing stop loss", group=GROUP_TSL) TSL_source = low TSL_line_color = color.green TSL_transp = 100 var stop_loss_price = float(0) if strategy.position_size == 0 or not within_timeframe TSL_line_color := color.black stop_loss_price := TSL_source - ATR_TSL else if strategy.position_size > 0 stop_loss_price := math.max(stop_loss_price, TSL_source - ATR_TSL) TSL_transp := 0 plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp)) // } end of "TSL" block // Entry variables { // ATR diversion test via Hypothesis testing (2-tailed): // H0 : atr_fast equals atr_slow // Ha : reject H0 if z_stat is above critical value, say reliability factor of 1.96 for a 95% confidence interval len_fast = input(14,title="Length of ATR (fast) for diversion test", group=GROUP_TEST) atr_fast = ta.atr(len_fast) std_error = ta.stdev(ta.tr, len_fast) / math.pow(len_fast, 0.5) // Standard Error (SE) = std / sq root(sample size) atr_slow = ta.atr(input(28,title="Length of ATR (slow) for diversion test", group=GROUP_TEST)) test_stat = (atr_fast - atr_slow) / std_error reject_H0 = math.abs(test_stat) > input.float(1.645,title="Reliability factor", tooltip="Strategy uses 2-tailed test; Confidence Interval = Point Estimate (avg ATR) +/- Reliability Factor x Standard Error; i.e use 1.645 for a 90% confidence interval", group=GROUP_TEST) // main entry signal, subject to confirmation(s), gets passed onto the next bar var _signal_diverted_ATR = false if not _signal_diverted_ATR _signal_diverted_ATR := reject_H0 // confirmation: trend prediction; based on expected lognormal returns _prcntge_chng = math.log(close / close[1]) // Expected return (drift) = average percentage change + half variance over the lookback period len_drift = input(14, title="Length of drift", group=GROUP_TREND) _drift = ta.sma(_prcntge_chng, len_drift) - math.pow(ta.stdev(_prcntge_chng, len_drift), 2) * 0.5 _signal_uptrend = _drift > _drift[1] entry_signal_all = _signal_diverted_ATR and _signal_uptrend // main signal + confirmations // } end of "Entry variables" block // MAIN { // Update the stop limit if strategy holds a position if strategy.position_size > 0 and ta.change(stop_loss_price) strategy.exit(ENUM_LONG, comment="sl", stop=stop_loss_price) // Entry if within_timeframe and entry_signal_all strategy.entry(ENUM_LONG, strategy.long, comment=strategy.position_size > 0 ? "adding" : "initial") // Alerts _atr = ta.atr(14) alert_helper(msg) => prefix = "[" + syminfo.root + "] " suffix = "(P=" + str.tostring(close, "#.##") + "; atr=" + str.tostring(_atr, "#.##") + ")" alert(str.tostring(prefix) + str.tostring(msg) + str.tostring(suffix), alert.freq_once_per_bar) if strategy.position_size > 0 and ta.change(strategy.position_size) if strategy.position_size > strategy.position_size[1] alert_helper("BUY") else if strategy.position_size < strategy.position_size[1] alert_helper("SELL") // Clean up - set the variables back to default values once no longer in use if strategy.position_size == 0 stop_loss_price := float(0) if ta.change(strategy.position_size) _signal_diverted_ATR := false // } end of MAIN block