Esta estrategia utiliza pruebas de hipótesis para determinar si ATR se desvía de su valor medio. Combinado con la predicción de la tendencia del precio, implementa una estrategia de reversión media basada en ATR. Una desviación significativa de ATR indica una potencial volatilidad anormal en el mercado. Si se predice que la tendencia del precio será alcista, se puede establecer una posición larga.
Prueba de hipótesis
Se realizará una prueba t de dos muestras entre el período de ATR rápido (atr_fast) y el período de ATR lento (atr_slow).
Si la estadística de ensayo excede el umbral (intervalo de confianza especificado por el factor_fiabilidad), se rechazará la hipótesis nula, es decir, se considerará que el ATR rápido se desvía significativamente del ATR lento.
Pronóstico de la tendencia de precios
La media móvil de los rendimientos logarítmicos se calcula como la tasa de deriva esperada (drift).
Si la deriva está aumentando, la tendencia actual se considera alcista.
Entrada y salida de pérdidas de parada
Si el valor de la transacción es inferior al valor de la transacción, el valor de la transacción es igual al valor de la transacción.
Ajuste continuamente el stop loss utilizando ATR. Posición de salida cuando el precio se rompe por debajo del stop loss.
El uso de pruebas de hipótesis para determinar la desviación ATR es más científico y adaptativo.
La combinación con la predicción de la tendencia de los precios evita operaciones erróneas basadas únicamente en la desviación ATR.
El ajuste del stop loss gestiona continuamente el riesgo a la baja.
Incapaz de detener las pérdidas cuando el precio se desploma.
Una predicción de tendencia incorrecta puede resultar en comprar en la parte superior.
La configuración incorrecta de los parámetros puede no incluir la entrada correcta o agregar operaciones innecesarias.
Considere la posibilidad de añadir otros indicadores para la confirmación multifactorial para evitar errores.
Prueba diferentes combinaciones de parámetros ATR para encontrar valores más estables.
Añadir criterios sobre la ruptura de los niveles clave de precios para evitar una ruptura falsa.
La lógica general de esta estrategia es clara. El uso de pruebas de hipótesis para detectar volatilidad anormal es razonable. Sin embargo, la desviación de ATR por sí sola es insuficiente para determinar la tendencia. Se necesitan más factores de confirmación para mejorar la precisión. Las reglas de stop loss son confiables pero ineficaces contra choques de estilo acantilado. Se pueden hacer mejoras futuras en áreas como criterios de entrada, selección de parámetros, optimización de stop loss.
/*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