En la carga de los recursos... Cargando...

Estrategia de media móvil adaptativa del canal de Gauss

El autor:¿ Qué pasa?, Fecha: 2024-03-28 18:08:18
Las etiquetas:

img

Resumen general

La Estrategia de promedio móvil adaptativo del canal de Gauss es una estrategia de negociación cuantitativa que utiliza técnicas de filtrado de Gauss y ajustes de parámetros adaptativos. Basada en la teoría del filtro de Gauss propuesta por John Ehlers, esta estrategia genera señales comerciales suaves y adaptativas aplicando múltiples cálculos de promedio móvil exponencial a los datos de precios. El núcleo de la estrategia es construir un canal de precios ajustado dinámicamente, con bandas superiores e inferiores obtenidas agregando y restando el rango verdadero filtrado del precio filtrado de Gauss. Cuando el precio se rompe por encima de la banda superior, se ingresa una posición larga, y cuando se rompe por debajo de la banda inferior, se ingresa una posición corta. Además, la estrategia introduce parámetros de período de tiempo, lo que permite ajustes flexibles para los tiempos de inicio y final de la ejecución de la estrategia, mejorando su practicidad.

Principios de estrategia

Los principios de la estrategia de media móvil adaptativa del canal de Gauss son los siguientes:

  1. Calcular el valor del filtro gaussiano del precio. Basándose en el período de muestreo definido por el usuario y el número de polos, se calculan los parámetros Beta y Alpha, y luego los datos de precio se someten a un filtro gaussiano de varios niveles para obtener una serie de precios suavizada.
  2. Calcular el valor del filtro gaussiano del rango real El mismo proceso de filtración gaussiano se aplica al rango real del precio, dando como resultado una serie de rango suavizado.
  3. Construir el canal de Gauss. El precio filtrado por Gauss sirve como banda media, la banda superior se forma agregando el producto del rango verdadero filtrado y un multiplicador definido por el usuario a la banda media, y la banda inferior se forma restando este valor de la banda media, creando un canal dinámico.
  4. Generar señales comerciales: cuando el precio se rompe por encima de la banda superior del canal, se genera una señal de compra; cuando el precio se rompe por debajo de la banda inferior, se genera una señal de venta.
  5. Introducir parámetros de período de tiempo. Los usuarios pueden configurar los tiempos de inicio y final para la ejecución de la estrategia, y la estrategia solo operará en función de las señales comerciales dentro de este período de tiempo especificado.

Análisis de ventajas

La estrategia de media móvil adaptativa del canal de Gauss tiene las siguientes ventajas:

  1. La estrategia utiliza parámetros ajustados dinámicamente que pueden adaptarse a las diferentes condiciones del mercado e instrumentos comerciales sin necesidad de ajustes manuales frecuentes.
  2. Buena capacidad de seguimiento de tendencias: mediante la construcción de canales de precios, la estrategia puede capturar y seguir eficazmente las tendencias del mercado, evitando señales falsas en mercados agitados.
  3. La técnica de filtrado gaussiano se utiliza para suavizar los datos de precios varias veces, eliminando la mayoría del ruido del mercado y haciendo que las señales comerciales sean más confiables.
  4. Los usuarios pueden ajustar los parámetros de la estrategia de acuerdo con sus necesidades, como el período de muestreo, el número de polos, el multiplicador de rango, etc., para optimizar el rendimiento de la estrategia.
  5. La introducción de parámetros de período de tiempo permite que la estrategia se ejecute dentro de un intervalo de tiempo especificado, lo que facilita la aplicación en el mundo real y la investigación de backtesting.

Análisis de riesgos

A pesar de sus muchas ventajas, la estrategia de la media móvil adaptativa del canal de Gauss todavía conlleva ciertos riesgos:

  1. La configuración inadecuada de los parámetros puede llevar a la ineficacia de la estrategia o a un bajo rendimiento, lo que requiere pruebas y optimización repetidas en aplicaciones prácticas.
  2. Riesgo de eventos repentinos: ante ciertos eventos repentinos y importantes, la estrategia puede no ser capaz de reaccionar correctamente y de manera oportuna, lo que resulta en pérdidas.
  3. Si los parámetros se ajustan demasiado a los datos históricos, la estrategia puede tener un mal rendimiento en el futuro, lo que hace necesario considerar el rendimiento tanto dentro como fuera de la muestra.
  4. El riesgo de arbitraje: la estrategia es principalmente adecuada para mercados de tendencia, y el comercio frecuente en mercados agitados puede enfrentar riesgos de arbitraje significativos.

Direcciones de optimización

Las direcciones de optimización para la estrategia de media móvil adaptativa del canal de Gauss incluyen:

  1. Optimización de parámetros dinámicos: mediante la introducción de aprendizaje automático y otras técnicas, lograr la optimización automática y el ajuste dinámico de los parámetros de estrategia para mejorar la adaptabilidad.
  2. Fusión multifactor: Combina otros indicadores técnicos o factores efectivos con el canal gaussiano para formar señales comerciales más sólidas.
  3. Optimización de la gestión de posiciones: Incorporar en la estrategia normas razonables de gestión de posiciones y gestión de fondos para controlar las reducciones y los riesgos.
  4. Coordinación de múltiples instrumentos: ampliar la estrategia a múltiples instrumentos de negociación diferentes y diversificar los riesgos mediante la asignación de activos y el análisis de correlación.

Resumen de las actividades

La Estrategia de promedio móvil adaptativo de canal gaussiano es una estrategia de negociación cuantitativa basada en el filtrado gaussiano y los parámetros adaptativos, que genera señales comerciales suaves y confiables mediante la construcción dinámica de canales de precios. La estrategia tiene ventajas como una fuerte adaptabilidad, buena capacidad de seguimiento de tendencias, alta suavidad, gran flexibilidad y gran practicidad. Sin embargo, también enfrenta riesgos como el establecimiento de parámetros, eventos repentinos, sobreajuste y arbitraje.


/*backtest
start: 2023-03-22 00:00:00
end: 2024-03-27 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy(title="Gaussian Channel Strategy v1.0", overlay=true, calc_on_every_tick=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1)

// Date condition inputs
startDate = input(title="Date Start", type=input.time, defval=timestamp("1 Jan 2018 00:00 +0000"), group="Dates")
endDate = input(title="Date End", type=input.time, defval=timestamp("31 Dec 2060 23:59 +0000"), group="Dates")
timeCondition = true

// This study is an experiment utilizing the Ehlers Gaussian Filter technique combined with lag reduction techniques and true range to analyze trend activity.
// Gaussian filters, as Ehlers explains it, are simply exponential moving averages applied multiple times.
// First, beta and alpha are calculated based on the sampling period and number of poles specified. The maximum number of poles available in this script is 9.
// Next, the data being analyzed is given a truncation option for reduced lag, which can be enabled with "Reduced Lag Mode".
// Then the alpha and source values are used to calculate the filter and filtered true range of the dataset.
// Filtered true range with a specified multiplier is then added to and subtracted from the filter, generating a channel.
// Lastly, a one pole filter with a N pole alpha is averaged with the filter to generate a faster filter, which can be enabled with "Fast Response Mode". 

//Custom bar colors are included.

//Note: Both the sampling period and number of poles directly affect how much lag the indicator has, and how smooth the output is.
//      Larger inputs will result in smoother outputs with increased lag, and smaller inputs will have noisier outputs with reduced lag.
//      For the best results, I recommend not setting the sampling period any lower than the number of poles + 1. Going lower truncates the equation.

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Updates:
// Huge shoutout to @e2e4mfck for taking the time to improve the calculation method!
// -> migrated to v4
// -> pi is now calculated using trig identities rather than being explicitly defined.
// -> The filter calculations are now organized into functions rather than being individually defined.
// -> Revamped color scheme.

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Functions - courtesy of @e2e4mfck
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
 
//Filter function 
f_filt9x (_a, _s, _i) => 
    int _m2 = 0, int _m3 = 0, int _m4 = 0, int _m5 = 0, int _m6 = 0, 
    int _m7 = 0, int _m8 = 0, int _m9 = 0, float _f = .0, _x = (1 - _a)
    // Weights. 
    // Initial weight _m1 is a pole number and equal to _i
    _m2 := _i == 9 ? 36  : _i == 8 ? 28 : _i == 7 ? 21 : _i == 6 ? 15 : _i == 5 ? 10 : _i == 4 ? 6 : _i == 3 ? 3 : _i == 2 ? 1 : 0
    _m3 := _i == 9 ? 84  : _i == 8 ? 56 : _i == 7 ? 35 : _i == 6 ? 20 : _i == 5 ? 10 : _i == 4 ? 4 : _i == 3 ? 1 : 0
    _m4 := _i == 9 ? 126 : _i == 8 ? 70 : _i == 7 ? 35 : _i == 6 ? 15 : _i == 5 ? 5  : _i == 4 ? 1 : 0
    _m5 := _i == 9 ? 126 : _i == 8 ? 56 : _i == 7 ? 21 : _i == 6 ? 6  : _i == 5 ? 1  : 0 
    _m6 := _i == 9 ? 84  : _i == 8 ? 28 : _i == 7 ? 7  : _i == 6 ? 1  : 0 
    _m7 := _i == 9 ? 36  : _i == 8 ? 8  : _i == 7 ? 1  : 0 
    _m8 := _i == 9 ? 9   : _i == 8 ? 1  : 0 
    _m9 := _i == 9 ? 1   : 0
    // filter
    _f :=   pow(_a, _i) * nz(_s) + 
      _i  *     _x      * nz(_f[1])      - (_i >= 2 ? 
      _m2 * pow(_x, 2)  * nz(_f[2]) : 0) + (_i >= 3 ? 
      _m3 * pow(_x, 3)  * nz(_f[3]) : 0) - (_i >= 4 ? 
      _m4 * pow(_x, 4)  * nz(_f[4]) : 0) + (_i >= 5 ? 
      _m5 * pow(_x, 5)  * nz(_f[5]) : 0) - (_i >= 6 ? 
      _m6 * pow(_x, 6)  * nz(_f[6]) : 0) + (_i >= 7 ? 
      _m7 * pow(_x, 7)  * nz(_f[7]) : 0) - (_i >= 8 ? 
      _m8 * pow(_x, 8)  * nz(_f[8]) : 0) + (_i == 9 ? 
      _m9 * pow(_x, 9)  * nz(_f[9]) : 0)

//9 var declaration fun
f_pole (_a, _s, _i) =>
    _f1 =            f_filt9x(_a, _s, 1),      _f2 = (_i >= 2 ? f_filt9x(_a, _s, 2) : 0), _f3 = (_i >= 3 ? f_filt9x(_a, _s, 3) : 0)
    _f4 = (_i >= 4 ? f_filt9x(_a, _s, 4) : 0), _f5 = (_i >= 5 ? f_filt9x(_a, _s, 5) : 0), _f6 = (_i >= 6 ? f_filt9x(_a, _s, 6) : 0)
    _f7 = (_i >= 2 ? f_filt9x(_a, _s, 7) : 0), _f8 = (_i >= 8 ? f_filt9x(_a, _s, 8) : 0), _f9 = (_i == 9 ? f_filt9x(_a, _s, 9) : 0)
    _fn = _i == 1 ? _f1 : _i == 2 ? _f2 : _i == 3 ? _f3 :
      _i == 4     ? _f4 : _i == 5 ? _f5 : _i == 6 ? _f6 :
      _i == 7     ? _f7 : _i == 8 ? _f8 : _i == 9 ? _f9 : na
    [_fn, _f1]

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Inputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------

//Source
src = input(defval=hlc3, title="Source")

//Poles
int N = input(defval=4, title="Poles", minval=1, maxval=9)

//Period
int per = input(defval=144, title="Sampling Period", minval=2)

//True Range Multiplier
float mult = input(defval=1.414, title="Filtered True Range Multiplier", minval=0)

//Lag Reduction
bool modeLag  = input(defval=false, title="Reduced Lag Mode")
bool modeFast = input(defval=false, title="Fast Response Mode")

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Definitions
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------

//Beta and Alpha Components
beta  = (1 - cos(4*asin(1)/per)) / (pow(1.414, 2/N) - 1)
alpha = - beta + sqrt(pow(beta, 2) + 2*beta)

//Lag
lag = (per - 1)/(2*N)

//Data
srcdata = modeLag ? src + (src - src[lag]) : src
trdata  = modeLag ? tr(true) + (tr(true) - tr(true)[lag]) : tr(true)

//Filtered Values
[filtn, filt1]     = f_pole(alpha, srcdata, N)
[filtntr, filt1tr] = f_pole(alpha, trdata,  N)

//Lag Reduction
filt   = modeFast ? (filtn + filt1)/2 : filtn
filttr = modeFast ? (filtntr + filt1tr)/2 : filtntr

//Bands
hband = filt + filttr*mult
lband = filt - filttr*mult

// Colors
color1   = #0aff68
color2   = #00752d
color3   = #ff0a5a
color4   = #990032
fcolor   = filt > filt[1] ? #0aff68 : filt < filt[1] ? #ff0a5a : #cccccc
barcolor = (src > src[1]) and (src > filt) and (src < hband) ? #0aff68 : (src > src[1]) and (src >= hband) ? #0aff1b : (src <= src[1]) and (src > filt) ? #00752d : 
           (src < src[1]) and (src < filt) and (src > lband) ? #ff0a5a : (src < src[1]) and (src <= lband) ? #ff0a11 : (src >= src[1]) and (src < filt) ? #990032 : #cccccc

//-----------------------------------------------------------------------------------------------------------------------------------------------------------------
//Outputs
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------

//Filter Plot
filtplot = plot(filt, title="Filter", color=fcolor, linewidth=3)

//Band Plots
hbandplot = plot(hband, title="Filtered True Range High Band", color=fcolor)
lbandplot = plot(lband, title="Filtered True Range Low Band", color=fcolor)

//Channel Fill
fill(hbandplot, lbandplot, title="Channel Fill", color=fcolor, transp=80)

//Bar Color
barcolor(barcolor)


longCondition = crossover(close, hband) and timeCondition
closeAllCondition = crossunder(close, hband) and timeCondition

if longCondition
    strategy.entry("long", strategy.long)

if closeAllCondition
    strategy.close("long")

Más.