Estrategia de arbitraje estadístico adaptativo de seguimiento del impulso

El autor:¿ Qué pasa?, Fecha: 2023-12-11 16:41:27
Las etiquetas:

img

Resumen general

Esta estrategia construye una envolvente de volatilidad dinámica basada en el método de regresión del núcleo de Nadaraya-Watson para generar señales comerciales de compra baja y venta alta mediante el seguimiento de las situaciones de cruce entre el precio y las bandas de envolvente.

Estrategia lógica

El núcleo de la estrategia es calcular la envolvente dinámica del precio. En primer lugar, mediante el uso de una ventana de retroceso personalizada, se construyen las curvas de regresión del núcleo de Nadaraya-Watson del precio (cerca, alto, bajo) para obtener una estimación de precio suavizada. Luego se calcula el ATR basado en una longitud ATR personalizada, y se forman las bandas de envolvente superior e inferior con factores cercanos y lejanos. Cuando el precio se rompe en el sobre desde abajo, se genera una señal de compra. Cuando el precio se rompe del sobre desde arriba, se activa una señal de venta. Al rastrear la relación dinámica entre el precio y las propiedades estadísticas relacionadas con la volatilidad, la estrategia ajusta sus decisiones comerciales de manera adaptativa.

Ventajas

  1. Basado en modelos matemáticos con parámetros controlables, menos probabilidad de sobreajuste.
  2. Adaptarse a los cambios del mercado aprovechando la relación dinámica entre el precio y la volatilidad para aprovechar las oportunidades comerciales.
  3. La escala de log funciona bien con diferentes marcos de tiempo e instrumentos con magnitudes de volatilidad variables.
  4. Parámetros personalizables para ajustar la sensibilidad de la estrategia.

Los riesgos

  1. La naturaleza teórica de los modelos matemáticos, puede tener un rendimiento inferior en el comercio en vivo.
  2. Los parámetros clave requieren experiencia, configuraciones inadecuadas pueden perjudicar la rentabilidad.
  3. El retraso en la emisión puede causar la pérdida de algunas oportunidades comerciales.
  4. Vulnerable a los golpes en los mercados altamente volátiles.

La optimización adecuada, las pruebas de retroceso suficientes, la comprensión de los factores clave y el tamaño prudente de las posiciones en el comercio en vivo podrían ayudar a mitigar estos riesgos.

Direcciones de mejora

  1. Optimice los parámetros para encontrar la mejor combinación.
  2. Aplicar métodos de aprendizaje automático para seleccionar automáticamente los parámetros óptimos.
  3. Añadir filtros para activar la estrategia en ciertos entornos de mercado.
  4. Incorporar otros indicadores para filtrar las señales engañosas.
  5. Prueba diferentes algoritmos de modelos matemáticos.

Conclusión

La estrategia incorpora análisis estadístico y análisis de indicadores técnicos para generar señales de negociación mediante el seguimiento dinámico de la relación entre el precio y la volatilidad. Los parámetros se pueden ajustar en función de las condiciones del mercado y las necesidades personales. En general, a pesar de la sólida base teórica, su rendimiento real todavía necesita mayor verificación. Uno debe tratarlo con prudencia y comerciar con precaución.


/*backtest
start: 2022-12-04 00:00:00
end: 2023-12-10 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// © Julien_Eche
//@version=5

strategy("Nadaraya-Watson Envelope Strategy", overlay=true, pyramiding=1, default_qty_type=strategy.percent_of_equity, default_qty_value=20)

// Helper Functions
getEnvelopeBounds(_atr, _nearFactor, _farFactor, _envelope) => 
    _upperFar = _envelope + _farFactor*_atr
    _upperNear = _envelope + _nearFactor*_atr
    _lowerNear = _envelope - _nearFactor*_atr
    _lowerFar = _envelope - _farFactor*_atr
    _upperAvg = (_upperFar + _upperNear) / 2
    _lowerAvg = (_lowerFar + _lowerNear) / 2 
    [_upperNear, _upperFar, _upperAvg, _lowerNear, _lowerFar, _lowerAvg]

customATR(length, _high, _low, _close) =>
    trueRange = na(_high[1])? math.log(_high)-math.log(_low) : math.max(math.max(math.log(_high) - math.log(_low), math.abs(math.log(_high) - math.log(_close[1]))), math.abs(math.log(_low) - math.log(_close[1])))
    ta.rma(trueRange, length)

customKernel(x, h, alpha, x_0) =>
    sumWeights = 0.0
    sumXWeights = 0.0
    for i = 0 to h
        weight = math.pow(1 + (math.pow((x_0 - i), 2) / (2 * alpha * h * h)), -alpha)
        sumWeights := sumWeights + weight
        sumXWeights := sumXWeights + weight * x[i]
    sumXWeights / sumWeights

// Custom Settings
customLookbackWindow = input.int(8, 'Lookback Window (Custom)', group='Custom Settings')
customRelativeWeighting = input.float(8., 'Relative Weighting (Custom)', step=0.25, group='Custom Settings')
customStartRegressionBar = input.int(25, "Start Regression at Bar (Custom)", group='Custom Settings')

// Envelope Calculations
customEnvelopeClose = math.exp(customKernel(math.log(close), customLookbackWindow, customRelativeWeighting, customStartRegressionBar))
customEnvelopeHigh = math.exp(customKernel(math.log(high), customLookbackWindow, customRelativeWeighting, customStartRegressionBar))
customEnvelopeLow = math.exp(customKernel(math.log(low), customLookbackWindow, customRelativeWeighting, customStartRegressionBar))
customEnvelope = customEnvelopeClose
customATRLength = input.int(60, 'ATR Length (Custom)', minval=1, group='Custom Settings')
customATR = customATR(customATRLength, customEnvelopeHigh, customEnvelopeLow, customEnvelopeClose)
customNearATRFactor = input.float(1.5, 'Near ATR Factor (Custom)', minval=0.5, step=0.25, group='Custom Settings')
customFarATRFactor = input.float(2.0, 'Far ATR Factor (Custom)', minval=1.0, step=0.25, group='Custom Settings')
[customUpperNear, customUpperFar, customUpperAvg, customLowerNear, customLowerFar, customLowerAvg] = getEnvelopeBounds(customATR, customNearATRFactor, customFarATRFactor, math.log(customEnvelopeClose))

// Colors
customUpperBoundaryColorFar = color.new(color.red, 60)
customUpperBoundaryColorNear = color.new(color.red, 80)
customBullishEstimatorColor = color.new(color.teal, 50)
customBearishEstimatorColor = color.new(color.red, 50)
customLowerBoundaryColorNear = color.new(color.teal, 80)
customLowerBoundaryColorFar = color.new(color.teal, 60)

// Plots
customUpperBoundaryFar = plot(math.exp(customUpperFar), color=customUpperBoundaryColorFar, title='Upper Boundary: Far (Custom)')
customUpperBoundaryAvg = plot(math.exp(customUpperAvg), color=customUpperBoundaryColorNear, title='Upper Boundary: Average (Custom)')
customUpperBoundaryNear = plot(math.exp(customUpperNear), color=customUpperBoundaryColorNear, title='Upper Boundary: Near (Custom)') 
customEstimationPlot = plot(customEnvelopeClose, color=customEnvelope > customEnvelope[1] ? customBullishEstimatorColor : customBearishEstimatorColor, linewidth=2, title='Custom Estimation')
customLowerBoundaryNear = plot(math.exp(customLowerNear), color=customLowerBoundaryColorNear, title='Lower Boundary: Near (Custom)')
customLowerBoundaryAvg = plot(math.exp(customLowerAvg), color=customLowerBoundaryColorNear, title='Lower Boundary: Average (Custom)') 
customLowerBoundaryFar = plot(math.exp(customLowerFar), color=customLowerBoundaryColorFar, title='Lower Boundary: Far (Custom)')

// Fills
fill(customUpperBoundaryFar, customUpperBoundaryAvg, color=customUpperBoundaryColorFar, title='Upper Boundary: Farmost Region (Custom)')
fill(customUpperBoundaryNear, customUpperBoundaryAvg, color=customUpperBoundaryColorNear, title='Upper Boundary: Nearmost Region (Custom)')
fill(customLowerBoundaryNear, customLowerBoundaryAvg, color=customLowerBoundaryColorNear, title='Lower Boundary: Nearmost Region (Custom)')
fill(customLowerBoundaryFar, customLowerBoundaryAvg, color=customLowerBoundaryColorFar, title='Lower Boundary: Farmost Region (Custom)')


longCondition = ta.crossover(close, customEnvelopeLow)
if (longCondition)
    strategy.entry("Buy", strategy.long)

exitLongCondition = ta.crossover(customEnvelopeHigh, close)
if (exitLongCondition)
    strategy.close("Buy")


Más.