
Esta estrategia utiliza un método de prueba de hipótesis para determinar si el ATR está desviado de la media, en combinación con la predicción de la movilidad de los precios, para lograr una estrategia de negociación de retorno a la media basada en el ATR. Cuando el ATR se desvía significativamente, indica que el mercado puede tener una fluctuación anormal.
Pruebas de hipótesis
El ciclo ATR rápido (parameteratr_fast) y el ciclo ATR lento (parameteratr_slow) se realizan dos pruebas de t. La hipótesis de prueba, la hipótesis cero H0 es el promedio de las dos muestras sin diferencias significativas.
Si la estadística de prueba es superior al umbral (el intervalo de confianza especificado por el parámetro reliability_factor), se rechaza la hipótesis original de que el ATR rápido se ha desviado claramente del ATR lento.
Previsión de las tendencias de precios
Calcula el promedio móvil de la rentabilidad de la lógica como la tasa de deriva esperada (drift paramétrico).
Si la desviación aumenta, entonces la tendencia actual es la de la pesimismo.
Entradas y salidas con pérdidas
Cuando las diferencias en el ATR son significativas y las tendencias son positivas, haz más entradas.
Luego se utiliza el cálculo de ATR para ajustar continuamente la línea de parada. La parada se retira cuando el precio cae por debajo de la línea de parada.
El uso de pruebas hipotéticas para determinar si el ATR se desvía de forma anormal de lo más científico y los parámetros se adaptan.
La combinación de la predicción de la tendencia de los precios evita que se cometan transacciones erróneas solo por la desviación del ATR.
Ajuste continuo de los parados para reducir el riesgo de pérdidas.
El precio de la gasolina se ha disparado en los últimos meses, pero no se ha podido detener.
En el caso de las tendencias, hay errores que pueden comprarse en los puntos más altos.
Si los parámetros no están configurados correctamente, se perderá el momento de la transacción correcta o se agregarán transacciones innecesarias.
Se puede considerar la posibilidad de agregar otros indicadores a la confirmación multifactorial para evitar que un solo indicador cause transacciones erróneas.
Se pueden probar diferentes combinaciones de parámetros ATR para encontrar los más estables.
Aumentar el juicio sobre la brecha de la barrera de precios clave y evitar la compra de brechas falsas.
La estrategia general es clara y se puede usar la hipótesis de prueba para juzgar las fluctuaciones anormales. Sin embargo, la desviación de ATR no puede juzgar completamente la tendencia, se necesita aumentar la base de juicio para mejorar la precisión. La regla de parada de pérdidas es confiable, pero no puede hacer frente a la caída acantiladora. En el futuro, se pueden mejorar las condiciones de entrada, la selección de parámetros y la optimización de la parada de pérdidas.
/*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