Estrategia de tendencia ATR de reversión media

El autor:¿ Qué pasa?, Fecha: 2023-09-21 11:42:06
Las etiquetas:

Resumen general

Esta estrategia utiliza los máximos y mínimos de la volatilidad de los precios para determinar el momento de las entradas y salidas de las posiciones.

Estrategia lógica

  1. Utilice el indicador ATR para medir la volatilidad de los precios. Calcule el ATR en los últimos 20 períodos y obtenga su promedio móvil y desviación estándar. Si el valor actual del ATR excede el promedio más una desviación estándar, la volatilidad de los precios se considera alta.

  2. Utilice la tasa de cambio de precio logarítmica de primer orden para determinar la tendencia de precios. Calcule la tasa de cambio de precio cercano logarítmico en los últimos 20 períodos, obtenga su promedio móvil. Si la tasa de cambio actual excede el promedio durante 3 días consecutivos y es positiva, el precio se considera en una tendencia alcista.

  3. Cuando la volatilidad del precio es alta y el precio muestra una tendencia alcista, ir largo. Cuando el precio retrocede y se activa la stop loss, la posición de cierre. El precio de stop loss se ajusta dinámicamente para mantenerse por debajo del precio más bajo menos 2 veces ATR.

Análisis de ventajas

  1. Utilizar la volatilidad de los precios y la tendencia para determinar el tiempo largo/corto, evitar el exceso de negociación en mercados variados.

  2. La pérdida de parada dinámica evita pérdidas excesivas por paradas demasiado amplias.

  3. La prueba de retroceso muestra un rendimiento anual del 159% durante 2015-2021, muy superior al 120% de la compra y retención.

Análisis de riesgos

  1. Los parámetros de ATR demasiado agresivos pueden resultar en muy pocas oportunidades de entrada.

  2. El indicador de tendencia puede generar señales falsas que contradicen la tendencia real.

  3. Necesitamos una muestra más grande y una comprobación de robustez para evitar el sobreajuste.

  4. Incapaz de evaluar el rendimiento en condiciones extremas como choques de flash.

Direcciones de optimización

  1. Añadir más indicadores de confirmación de tendencia como MACD, KDJ para mejorar la precisión de la tendencia.

  2. Ajustar los parámetros ATR de forma adaptativa en función de diferentes productos y regímenes de mercado para optimizar el indicador de volatilidad.

  3. Agregue la lógica de la ruptura y los factores de aceleración de tendencia para medir las rupturas.

  4. Prueba diferentes tipos de stop loss como el porcentaje, volatilidad stop en el rendimiento.

  5. Evaluar en métricas como la frecuencia del comercio, la estabilidad de la curva, la extracción máxima para garantizar la robustez.

Resumen de las actividades

Esta estrategia combina las ventajas de medir la volatilidad y la tendencia para determinar posibles puntos de reversión para entrar en la volatilidad amplificada, y utiliza paradas dinámicas para controlar el riesgo. La prueba de retroceso muestra un alfa decente generado. Pero la muestra de 6 años es limitada, los parámetros clave necesitan ajuste específico del mercado y se necesitan más factores de confirmación para reducir las señales falsas. También se requiere una comprobación de robustez integral antes de aplicarla al comercio en vivo. En general, esto proporciona una idea de la reversión media en la volatilidad, pero aún necesita refinamiento y verificación rigurosa para convertirse en una estrategia cuantitativa robusta.


/*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)
// }


Más.