Стратегия тренда ATR средней реверсии

Автор:Чао Чжан, Дата: 2023-09-21 11:42:06
Тэги:

Обзор

Эта стратегия использует максимумы и минимумы волатильности цен для определения времени входа и выхода позиций.

Логика стратегии

  1. Используйте индикатор ATR для измерения волатильности цен. Вычислите ATR за последние 20 периодов и получите его скользящую среднюю величину и стандартное отклонение. Если текущее значение ATR превышает среднее плюс одно стандартное отклонение, волатильность цен считается высокой.

  2. Используйте логарифмический курс изменения цены первого порядка для определения тренда цены. Вычислите логарифмический курс изменения цены за последние 20 периодов, получите его скользящую среднюю величину. Если текущий курс изменения превышает средний за 3 дня подряд и является положительным, цена считается в восходящем тренде.

  3. Когда волатильность цены высока, и цена показывает восходящий тренд, идти длинный. Когда цена тянет назад и стоп-лосс запускается, закрыть позицию. Стоп-лосс цена регулируется динамически, чтобы оставаться ниже самой низкой цены минус 2 раза ATR.

Анализ преимуществ

  1. Использование волатильности цен и тенденции для определения длинного/короткого времени, избегание переоценки на различных рынках.

  2. Динамическая остановка убытков избегает чрезмерных потерь от слишком широких остановок.

  3. Отзывы показывают, что годовая доходность составляет 159% в течение 2015-2021 годов, что намного превышает 120% от покупки и удержания.

Анализ рисков

  1. Слишком агрессивные параметры ATR могут привести к слишком малому количеству возможностей для входа.

  2. Индикатор тренда может генерировать ложные сигналы, противоречащие фактическому тренду.

  3. Для проверки надежности необходимо увеличить количество образцов, чтобы избежать перегрузки.

  4. Невозможно оценить производительность в экстремальных условиях, таких как сбой вспышки, требуется ручное вмешательство или программа остановки.

Руководство по оптимизации

  1. Добавьте больше индикаторов подтверждения тренда, таких как MACD, KDJ, чтобы улучшить точность тренда.

  2. Настройка параметров ATR на основе различных продуктов и рыночных режимов для оптимизации индикатора волатильности.

  3. Добавьте логику прорыва и факторы ускорения тренда, чтобы оценить прорывы.

  4. Проверьте различные типы стоп-лосса, такие как процент, волатильность стоп-лосса на производительности.

  5. Оцените на таких показателях, как частота торговли, стабильность кривой, максимальное снижение для обеспечения надежности.

Резюме

Эта стратегия сочетает в себе преимущества измерения волатильности и тренда для определения возможных точек обратного поворота для входа в усиленную волатильность и использует динамические остановки для контроля риска. Бактэст показывает приличную альфу. Но 6-летняя выборка ограничена, ключевые параметры нуждаются в рыночной настройке, и для уменьшения ложных сигналов требуется больше подтверждающих факторов. Перед применением к живой торговле также требуется всеобъемлющая проверка надежности. В целом это дает представление о среднем обратном повороте волатильности, но все еще требует уточнения и строгой проверки, чтобы стать надежной количественной стратегией.


/*backtest
start: 2022-09-14 00:00:00
end: 2023-09-20 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 (kevinhhl)

//@version=4
strategy("Mean Reversion (ATR) Strategy [KL]",overlay=true,pyramiding=1)
ENUM_LONG = "Long"

// Timeframe {
backtest_timeframe_start = input(defval = timestamp("01 Apr 2000 13:30 +0000"), title = "Backtest Start Time", type = input.time)
USE_ENDTIME = input(false,title="Define backtest end-time (If false, will test up to most recent candle)")
backtest_timeframe_end = input(defval = timestamp("01 May 2021 19:30 +0000"), title = "Backtest End Time (if checked above)", type = input.time)
within_timeframe = true
// }

// Trailing stop loss {
ATR_X2_TSL = atr(input(14,title="Length of ATR for trailing stop loss")) * input(2.0,title="ATR Multiplier for trailing stop loss",type=input.float)
TSL_source = low
var stop_loss_price = float(0)
TSL_line_color = color.green, TSL_transp = 100
if strategy.position_size == 0 or not within_timeframe
    TSL_line_color := color.black
    stop_loss_price := TSL_source - ATR_X2_TSL 
else if strategy.position_size > 0
    stop_loss_price := max(stop_loss_price, TSL_source - ATR_X2_TSL)
    TSL_transp := 0
plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp))
// }

// Variables for confirmations of entry {
_len_volat = input(20,title="Length of ATR to determine volatility")
_ATR_volat = atr(_len_volat)
_avg_atr = sma(_ATR_volat, _len_volat)
_std_volat = stdev(_ATR_volat,_len_volat)
signal_diverted_ATR = _ATR_volat > (_avg_atr + _std_volat) or _ATR_volat < (_avg_atr - _std_volat)

_len_drift = input(20,title="Length of Drift")//default set to const: _len_vol's default value
_prcntge_chng = log(close/close[1])
_drift = sma(_prcntge_chng, _len_drift) - pow(stdev(_prcntge_chng, _len_drift),2)*0.5
_chg_drift = _drift/_drift[1]-1
signal_uptrend = (_drift > _drift[1] and _drift > _drift[2]) or _drift > 0

entry_signal_all = signal_diverted_ATR and signal_uptrend
// }

alert_per_bar(msg)=>
    prefix = "[" + syminfo.root + "] "
    suffix = "(P=" + tostring(close) + "; atr=" + tostring(_ATR_volat) + ")"
    alert(tostring(prefix) + tostring(msg) + tostring(suffix), alert.freq_once_per_bar)

// MAIN {
if within_timeframe

    if strategy.position_size > 0 and strategy.position_size[1] > 0 and (stop_loss_price/stop_loss_price[1]-1) > 0.005
        alert_per_bar("TSL raised to " + tostring(stop_loss_price))

    // EXIT:
	if strategy.position_size > 0 and TSL_source <= stop_loss_price
	    exit_msg = close <= strategy.position_avg_price ? "stop loss" : "take profit"
        strategy.close(ENUM_LONG, comment=exit_msg)
    // ENTRY:
    else if entry_signal_all and (strategy.position_size == 0 or (strategy.position_size > 0 and close > stop_loss_price))
		entry_msg = strategy.position_size > 0 ? "adding" : "initial"
		strategy.entry(ENUM_LONG, strategy.long, comment=entry_msg)

if strategy.position_size == 0
    stop_loss_price := float(0)
// }


Больше