English Русский Deutsch 日本語
preview
Características del Wizard MQL5 que debe conocer (Parte 44): Indicador técnico Average True Range (ATR)

Características del Wizard MQL5 que debe conocer (Parte 44): Indicador técnico Average True Range (ATR)

MetaTrader 5Probador | 27 junio 2025, 08:03
31 0
Stephen Njuki
Stephen Njuki

Introducción

El rango verdadero promedio (Average True Range, ATR) es un indicador de volatilidad común y popular que, posiblemente, para los operadores de divisas, es lo más parecido a los datos de volumen. Desarrollado como un indicador destinado a seguir el rango de la barra de precios sin descuidar los cambios de precios dentro de la barra, se ha convertido en un referente en el sector, no solo para filtrar las señales de entrada, sino también para orientar sobre el tamaño de las posiciones. Analizamos este indicador descomponiéndolo en posibles patrones, tal y como hemos hecho en los artículos anteriores sobre indicadores, con la diferencia principal de que examinamos patrones fuera de la clase de señales personalizadas, teniendo en cuenta también la clase de gestión del dinero personalizada para los asesores expertos creados por el asistente.

Sin embargo, antes de entrar en eso, terminaremos con el indicador que habíamos comenzado la última vez, el ADX.


Reversión del ADX

El patrón 6 para el ADX es la reversión que se caracteriza por una caída en el soporte principal del ADX al final de una tendencia prominente. Para hacer un breve resumen del ADX, mide la fuerza de una tendencia, con picos o aumentos en el buffer principal del oscilador que indican la fuerza de la tendencia predominante. Además, hay dos buffers adicionales, el DI+ y el DI-, que también cuantifican la fuerza de las subidas y bajadas de precios respectivamente.

Entonces, una señal alcista está marcada por una fuerte tendencia bajista que ha estado ocurriendo por algún tiempo más una caída en las lecturas del buffer del oscilador principal desde por encima del nivel 50 a por debajo de 4 en aproximadamente 2 a 3 barras de precios. El argumento detrás de esto es que, dado que el ADX mide la fuerza de la tendencia, la tendencia actual se está debilitando y, por lo tanto, está a punto de producirse una reversión de la misma, que en este caso es una tendencia alcista. Por el contrario, una señal bajista está marcada por una fuerte tendencia alcista que también presencia una caída similar en el buffer principal ADX por debajo de 40 desde una cifra elevada. Implementamos esto en la clase de señal de la siguiente manera:

//+------------------------------------------------------------------+
//| Check for Pattern 6.                                             |
//+------------------------------------------------------------------+
bool CSignalADX::IsPattern_6(ENUM_POSITION_TYPE T)
{  if(Base(X()+3) >= 50 && Base(X()) <= 40)
   {  if(T == POSITION_TYPE_BUY && Close(StartIndex()) > Close(StartIndex() + m_ma_period))
      {  return(true);
      }
      else if(T == POSITION_TYPE_SELL && Close(StartIndex()) < Close(StartIndex() + m_ma_period))
      {  return(true);
      }
   }
   return(false);
}

Y probando exclusivamente este patrón, al tener el parámetro de entrada 'Patterns Used' asignado al valor entero 64, nos da los siguientes resultados:

adx_r6


ADX y ruptura de soporte/resistencia

El patrón 7, que es el octavo y penúltimo de los patrones ADX que estamos considerando, combina picos en el búfer ADX principal con rupturas de los niveles de soporte o resistencia. Dado que la interpretación de las líneas de soporte y resistencia es más problemática en el código que en el trading manual, nos basaremos en un indicador secundario, las bandas de Bollinger, para ayudar a definirlas mejor. Hay soluciones más matizadas para esto, que he considerado en los últimos artículos sobre RSI y bandas de Bollinger, y el lector puede consultarlas para redefinir lo que hemos decidido utilizar aquí.

Nuestras rupturas de soporte y resistencia se marcarán simplemente al atravesar los límites inferior y superior del indicador de bandas de Bollinger. Por lo tanto, una señal alcista se caracteriza por un aumento del principal indicador ADX por encima del nivel 25 y también por un repunte del precio por encima de las bandas de Bollinger superiores, mientras que una señal bajista se caracteriza por un aumento similar del ADX y una caída del precio por debajo de la banda inferior de las bandas. Implementamos esto en MQL5 de la siguiente manera:

//+------------------------------------------------------------------+
//| Check for Pattern 7.                                             |
//+------------------------------------------------------------------+
bool CSignalADX::IsPattern_7(ENUM_POSITION_TYPE T)
{  if(Base(X()+2) < 25 && Base(X()) > 25)
   {  if(T == POSITION_TYPE_BUY && Close(StartIndex()) >= Upper(StartIndex()))
      {  return(true);
      }
      else if(T == POSITION_TYPE_SELL && Close(StartIndex()) <= Lower(StartIndex()))
      {  return(true);
      }
   }
   return(false);
}

Al probar el asesor experto ensamblado por el asistente que utiliza únicamente este patrón, con el parámetro de entrada para Patrones utilizados establecido en 128, obtenemos los siguientes resultados:

adx_r7


ADX con confirmación RSI

Nuestro patrón final, el 8, combina el ADX con un indicador que ya hemos visto, el RSI. Dado que el ADX es un indicador que mide la tendencia y el RSI se utiliza a menudo para marcar los puntos de sobrecompra y sobreventa, la combinación de estos dos desde el punto de vista del ADX deberá tener en cuenta las tendencias alcistas o importantes, y no su final. Hasta ahora, nos hemos centrado en los cruces del RSI en el nivel 50, no en que alcance los umbrales de 70/30.

La señal alcista se marca, por lo tanto, por un cruce del RSI de por debajo de 50 a por encima de 50, junto con un aumento del búfer principal del ADX de por debajo de 25 a por encima de 25. Por el contrario, la señal bajista se indica mediante una caída del RSI desde un nivel superior a 50 hasta por debajo de este, con un nuevo aumento del valor del ADX por encima de la marca de 25. Implementamos esto en MQL5 de la siguiente manera:

//+------------------------------------------------------------------+
//| Check for Pattern 8.                                             |
//+------------------------------------------------------------------+
bool CSignalADX::IsPattern_8(ENUM_POSITION_TYPE T)
{  if(Base(X()+1) < 25 && Base(X()) > 25)
   {  if(T == POSITION_TYPE_BUY && RSI(StartIndex()) > 50 && RSI(StartIndex() + 1) < 50)
      {  return(true);
      }
      else if(T == POSITION_TYPE_SELL && RSI(StartIndex()) < 50 && RSI(StartIndex() + 1) > 50)
      {  return(true);
      }
   }
   return(false);
}

Al probar solo este patrón, asignando el entero de entrada de los patrones utilizados a 256, obtenemos los siguientes resultados:

adx_r8


Optimización para patrones ADX ideales

Nuestro asistente ha creado un asesor experto, sobre el que hay artículos explicativos aquí y aquí sobre cómo hacerlo con el código adjunto al final de este artículo, que también se puede utilizar con todos los patrones ADX que hemos visto hasta ahora, aunque con diferentes ponderaciones. Como he mencionado anteriormente, esto no es necesariamente ideal, ya que se tiende a tener diferentes patrones que se anulan entre sí, lo que significa que, a partir de las ejecuciones de optimización, se tiende a obtener resultados que se «ajustan a la curva» y, a menudo, se tiene dificultad para replicar su rendimiento en datos fuera de la muestra. Dicho esto, aquí están algunos resultados de pruebas obtenidos al combinar los nueve patrones del ADX que hemos considerado hasta ahora.

adx_r_all

adx_c_all


El ATR

El oscilador de rango verdadero promedio, como ya se presentó anteriormente, mide la volatilidad, lo cual es crucial para los operadores de Forex dada la falta de datos de volumen. Por lo tanto, veamos también sus patrones, algunos de los cuales son aplicables fuera de nuestra clase de señal personalizada típica.


Señal de ruptura de volatilidad

Cuando el valor actual del ATR aumenta significativamente por encima de su promedio reciente, puede indicar una ruptura de la volatilidad. Esto, a su vez, implica una estrategia comercial en la que la entrada en una operación en la dirección de la ruptura cuando el ATR aumenta significativamente, indica que es probable que el mercado experimente grandes movimientos de precios en esa dirección. Los indicadores complementarios, como la media móvil, el MACD, etc., también pueden determinar la dirección de la operación. Implementamos esto en MQL5 de la siguiente manera:

//+------------------------------------------------------------------+
//| Check for Pattern 0.                                             |
//+------------------------------------------------------------------+
bool CSignalATR::IsPattern_0(ENUM_POSITION_TYPE T)
{  if(ATR(X()) > ATR(X() + 1) && ATR(X() + 1) > ATR(X() + 2) && ATR(X() + 2) > ATR(X() + 3))
   {  if(T == POSITION_TYPE_BUY && Close(X()) > Close(X() + 1) && Close(X() + 1) > Close(X() + 2) && Close(X() + 2) > Close(X() + 3))
      {  return(true);
      }
      else if(T == POSITION_TYPE_SELL && Close(X()) < Close(X() + 1) && Close(X() + 1) < Close(X() + 2) && Close(X() + 2) < Close(X() + 3))
      {  return(true);
      }
   }
   return(false);
}

Al probar este patrón en solitario concreto con la entrada para Patrones utilizados (Used Pattern) asignada a 1, obtenemos los siguientes informes como uno de los muchos resultados favorables de una breve sesión de optimización. Estamos optimizando el par EURUSD para el año 2022, en el marco temporal horario.

tar_r0


Umbral ATR para la confirmación de la ruptura

Las confirmaciones de ruptura con el ATR son fundamentales, dado que el ATR es una medida de volatilidad. Al asignar un valor al rango medio (máximos menos mínimos) durante un periodo determinado, ayuda a los operadores a determinar cuánto suele variar el precio con cada nueva barra. Se produce una ruptura cuando el precio supera un nivel de soporte o resistencia definido. Por lo tanto, el ATR puede servir como filtro para falsas rupturas, utilizando umbrales de volatilidad para confirmar el movimiento.

Un problema habitual con las rupturas es que los precios pueden superar un nivel brevemente, solo para volver a retroceder. El umbral ATR, cuando se complementa con estas brechas, ayuda a filtrar esto confirmando la ruptura si el precio se mueve un porcentaje específico por encima/por debajo del nivel clave, en relación con el valor ATR. Por ejemplo, si el ATR es de 20 pips, una ruptura podría considerarse válida si el precio se mueve más allá de un nivel de soporte/resistencia en al menos 1,5 veces o 2 veces los 20 pips, lo que indicaría un cambio real en el impulso en lugar de ruido. Por lo tanto, estas lecturas del ATR son muy sensibles, por lo que se puede utilizar un período ATR más bajo (por ejemplo, 7 o 10 en lugar del valor típico de 14) para mercados más rápidos o estrategias a corto plazo, lo que proporciona una mejor adaptabilidad a la volatilidad. Sin embargo, con el swing trading, un periodo ATR más largo (por ejemplo, 14 o 20) suaviza el ruido y proporciona una señal de confirmación de ruptura más estable.

Sin embargo, nuestra implementación en MQL5 utiliza un enfoque ligeramente diferente, ya que hacemos un seguimiento de las oscilaciones de precios con respecto a un valor ATR absoluto. Si se producen cambios de precio en una dirección concreta con un movimiento ATR razonable que supere un umbral optimizado, se activa una nueva señal en la dirección de la tendencia del precio. Esto lo codificamos de la siguiente manera:

//+------------------------------------------------------------------+
//| Check for Pattern 1.                                             |
//+------------------------------------------------------------------+
bool CSignalATR::IsPattern_1(ENUM_POSITION_TYPE T)
{  if(ATR(X()) >= m_threshold_points*m_symbol.Point())
   {  if(T == POSITION_TYPE_BUY && Close(X()) > Close(X() + 1) && Close(X() + 1) > Close(X() + 2) && Close(X() + 2) > Close(X() + 3))
      {  return(true);
      }
      else if(T == POSITION_TYPE_SELL && Close(X()) < Close(X() + 1) && Close(X() + 1) < Close(X() + 2) && Close(X() + 2) < Close(X() + 3))
      {  return(true);
      }
   }
   return(false);
}

Una prueba realizada con optimizaciones utilizando solo este patrón nos da los siguientes resultados:

tar_r1


ATR como señal de salida

La medida de volatilidad del mercado de ATR lo convierte en una herramienta eficaz para determinar puntos de salida dinámicos basados en las condiciones actuales del mercado. A diferencia de las estrategias de salida con pip o punto fijo, las salidas basadas en el ATR se adaptan a la volatilidad del mercado, lo que garantiza que las salidas se produzcan en niveles significativos en lugar de en umbrales arbitrarios. Un aumento repentino de los valores ATR podría indicar un evento significativo en el mercado (actas de la Fed, etc.) o una posible reversión. Por lo tanto, los operadores podrían optar por salir de una posición cuando el ATR se expanda más allá de un umbral determinado, lo que indicaría un aumento de la volatilidad que podría conducir al agotamiento de la tendencia o a reversiones. Esta inversión pendiente, por lo tanto, sí que constituye una señal.

Los operadores de swing pueden utilizar además el ATR para salir de posiciones en niveles de precios clave conocidos/identificados, sumando o restando un múltiplo del ATR a los máximos o mínimos recientes del swing. Esto les permite tener en cuenta el movimiento medio de los precios y salir cerca de puntos clave de reversión. Esta forma de salida, basada en los niveles ATR por parte de los operadores de swing, reduce la exposición a excursiones adversas o caídas injustificadas, especialmente durante períodos de mayor volatilidad que pueden indicar una reversión inminente o una fase de consolidación.

Además, en mercados con rangos de precios limitados, el ATR tiende a ser bajo, por lo tanto, cuando el ATR aumenta repentinamente, podría indicar una posible ruptura o una mayor volatilidad. Los traders podrían usar este aumento como señal de salida si estuvieran posicionados dentro del rango. La regla de oro aquí es que evitar salidas de baja volatilidad de manera sistemática ayuda a los operadores a evitar quedar atrapados en mercados volátiles y laterales, manteniendo así un perfil de riesgo/recompensa favorable en sus operaciones. Sin embargo, nuestra implementación en MQL5 es un poco simplista porque estamos construyendo una clase de señal personalizada y estamos buscando una entrada. Así es como codificamos el patrón 2:

//+------------------------------------------------------------------+
//| Check for Pattern 2.                                             |
//+------------------------------------------------------------------+
bool CSignalATR::IsPattern_2(ENUM_POSITION_TYPE T)
{  if(ATR(X()) >= 2.0 * m_threshold_points*m_symbol.Point())
   {  if(T == POSITION_TYPE_SELL && Close(X()) > Close(X() + 1) && Close(X() + 1) > Close(X() + 2) && Close(X() + 2) > Close(X() + 3))
      {  return(true);
      }
      else if(T == POSITION_TYPE_BUY && Close(X()) < Close(X() + 1) && Close(X() + 1) < Close(X() + 2) && Close(X() + 2) < Close(X() + 3))
      {  return(true);
      }
   }
   return(false);
}

Nuestro enfoque aquí básicamente exige una reversión de la tendencia cuando los valores de ATR son demasiado altos, más del doble de un umbral optimizado. Este ciertamente no es el mejor enfoque para explotar esto, ya que los lectores pueden haber notado que hemos mencionado formas "más interesantes" de capitalizar las salidas anteriormente. Sin embargo, como siempre, el código fuente adjunto se puede modificar para tener un enfoque alternativo. Una prueba realizada a partir de un breve período de optimización para el par EURCHF para el año 2022 en el marco temporal de 1 hora nos arroja el siguiente informe:

atr_r2


Señal de contracción de la volatilidad

La contracción del ATR también puede servir como señal para prepararse para una expansión de la volatilidad, la calma antes de la tormenta. Los periodos de baja volatilidad suelen preceder a un aumento repentino de los precios o a algún episodio de volatilidad. Algunos operadores suelen vigilar la contracción del ATR para anticipar cuándo es probable que se produzca una ruptura, posicionándose para el movimiento que se avecina. Un aumento repentino del ATR tras un periodo así suele ser una confirmación clara de que se ha producido una ruptura. Por lo tanto, los operadores pueden utilizar la contracción del ATR para entrar en operaciones una vez que la volatilidad comience a expandirse de nuevo, alineándose así con la tendencia.

Otra ventaja de las contracciones del ATR tiene que ver con las salidas con límite de tiempo. Algunos operadores salen de sus posiciones tras un determinado periodo de tiempo, por lo que utilizar el ATR como guía para saber cuándo cerrar posiciones que se están estancando puede resultar muy útil en este sentido. Otra ventaja de las contracciones del ATR tiene que ver con las salidas con límite de tiempo. Algunos operadores salen de sus posiciones tras un determinado periodo de tiempo, por lo que utilizar el ATR como guía para saber cuándo cerrar posiciones que se están estancando puede resultar muy útil en este sentido. Esto puede brindar a los seguidores de tendencias la oportunidad de prepararse para posibles reversiones o realizar algunas operaciones de toma de ganancias. Para los operadores que siguen las tendencias, una salida temporal puede tener sentido.

Para los operadores de swing, la contracción del ATR puede indicar que el precio se encuentra estancado en una fase de consolidación, lo que sugiere que es momento de salir de las posiciones y evitar quedar atrapado en un movimiento lateral. Por el contrario, una vez que finaliza la contracción, los operadores a corto plazo pueden buscar puntos de entrada cuando la volatilidad comience a aumentar de nuevo. Por otra parte, los operadores a corto plazo pueden utilizar la contracción del ATR para identificar mercados con rangos definidos, con el fin de operar dentro de ese rango comprando en el soporte y vendiendo en la resistencia hasta que se produzca una ruptura al alza o a la baja.

Además, cabe destacar, especialmente en los mercados de divisas opacos, que la contracción del ATR suele producirse junto con una disminución de los volúmenes de negociación, lo que normalmente implica que los participantes en el mercado se muestran indecisos. Cuando el volumen aumenta y el ATR se expande, podría sugerir una posible ruptura a medida que nueva liquidez ingresa al mercado. La combinación de una contracción del ATR con un aumento posterior del volumen es una confirmación útil para los operadores de ruptura que buscan entrar durante la expansión de la volatilidad. En este artículo, la contracción de la volatilidad como señal de entrada se utiliza para detectar reversiones. Estas reversiones pendientes definen entonces nuestra dirección de precios anticipada. Si ATR disminuye después de una tendencia bajista, anticipamos un retroceso y, por lo tanto, tenemos una señal alcista. Por otro lado, si esta caída en ATR ocurre hacia el final de un ciclo alcista, lo tomaríamos como una señal bajista. Nuestro código para este efecto se proporciona a continuación:

//+------------------------------------------------------------------+
//| Check for Pattern 3.                                             |
//+------------------------------------------------------------------+
bool CSignalATR::IsPattern_3(ENUM_POSITION_TYPE T)
{  if(ATR(X()) < ATR(X() + 1) && ATR(X() + 1) < ATR(X() + 2) && ATR(X() + 2) < ATR(X() + 3))
   {  if(T == POSITION_TYPE_SELL && Close(X() + 3) > Close(X() + 4) && Close(X() + 4) > Close(X() + 5) && Close(X() + 5) > Close(X() + 6))
      {  return(true);
      }
      else if(T == POSITION_TYPE_BUY && Close(X() + 3) < Close(X() + 4) && Close(X() + 4) < Close(X() + 5) && Close(X() + 5) < Close(X() + 6))
      {  return(true);
      }
   }
   return(false);
}

La ejecución de pruebas de algunos de los resultados de optimización que utilizan solo el patrón 3 con el parámetro de entrada para los patrones utilizados como 8, nos da los siguientes resultados:

atr_r3


Canal ATR (Bandas ATR)

Los canales ATR (también conocidos como bandas ATR) son bandas dinámicas basadas en la volatilidad que se pueden trazar por encima y por debajo del precio utilizando un múltiplo del rango verdadero promedio (ATR). Al igual que las Bandas de Bollinger, ayudan a crear un canal alrededor del precio, que en este caso particular puede ser útil para reflejar la volatilidad del mercado.

Y al igual que las Bandas, estas se expanden y contraen según la volatilidad del precio, lo que proporciona a los operadores una idea de cuánto se mueve normalmente el precio con respecto a su media dentro de un período de tiempo determinado. Además, las bandas superior e inferior actúan como un nivel de soporte y resistencia dinámico respectivamente, de modo que a medida que el precio tiende a fluctuar dentro de estas bandas y el toque o la ruptura de estos "niveles", se pueden generar señales para posibles reversiones o continuación. A diferencia de los niveles de soporte/resistencia estáticos, estos seguramente serán más dinámicos, lo que los hace más sensibles a las condiciones predominantes del mercado.

Entonces, las señales de estas bandas son cuando tenemos una ruptura de precio por encima de la banda ATR superior para una tendencia alcista o una mayor presión de compra, mientras que una ruptura por debajo de la banda inferior puede indicar una tendencia bajista o presión de venta. Para un operador manual, será necesario implementar un indicador personalizado que trace físicamente estas bandas, pero en nuestro caso, dado que utilizamos asesores expertos ensamblados por un asistente (con guías aquí y aquí para los nuevos lectores), no tenemos que preocuparnos por eso. Dado que estamos automatizando nuestro proceso de negociación, podemos tomar las dos lecturas separadas del indicador de la media móvil del precio y el ATR y sumarlas para definir estas bandas en cada nueva barra. Implementamos el patrón en MQL5 de la siguiente manera:

//+------------------------------------------------------------------+
//| Check for Pattern 4.                                             |
//+------------------------------------------------------------------+
bool CSignalATR::IsPattern_4(ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY && Close(X()) > MA(X()) + 2.0 * ATR(X()))
   {  return(true);
   }
   else if(T == POSITION_TYPE_SELL && Close(X()) < MA(X()) - 2.0 * ATR(X()))
   {  return(true);
   }
   return(false);
}

Estas bandas pueden asumir funciones adicionales, como filtrar falsas rupturas cuando se utilizan con otros indicadores, como las bandas de Bollinger o los canales de Keltner, al confirmar que la ruptura es lo suficientemente significativa. Otras aplicaciones del canal ATR se solapan un poco con lo que hemos mencionado anteriormente, pero aún así merecen ser mencionadas. Los canales ATR pueden ayudar a identificar la fuerza y la dirección de una tendencia. Cuando el precio se mueve constantemente cerca de la banda superior del ATR, esto indica una fuerte tendencia alcista. Del mismo modo, un precio que se mueve a lo largo de la banda inferior indica una fuerte tendencia bajista. Esta detección de tendencias puede resultar útil en algunos mercados que parecen estar sometidos a fuertes oscilaciones en marcos temporales amplios. Por el contrario, si el precio tiene dificultades para salir de las bandas ATR o toca con frecuencia las bandas sin seguir adelante, esto podría indicar un agotamiento de la tendencia o una pérdida de impulso.

Los operadores también utilizan las bandas ATR para identificar oportunidades de reversión a la media, especialmente en mercados con rangos limitados. Cuando el precio alcanza la banda superior o inferior, puede indicar que el activo está sobrecomprado o sobrevendido, y es probable que se produzca una reversión hacia la media (precio promedio). Por lo tanto, dependiendo del marco temporal considerado, cuando el precio rebota en la banda superior o inferior del ATR sin romperla, esto puede indicar a los operadores que deben tomar ganancias o revertir sus posiciones.

Al utilizar una toma de ganancias basada en la volatilidad, estas bandas pueden proporcionar niveles dinámicos en función de la volatilidad. Una toma de ganancias colocada justo fuera de la banda ATR puede ayudar a proteger las operaciones del ruido normal del mercado, lo que dejaría dinero sobre la mesa, al permitir espacio para fluctuaciones de precios dentro de la banda. Esto no se consideró en nuestra implementación del patrón 4 ya que estamos haciendo una clase de señal personalizada; sin embargo, puede aparecer en una clase de seguimiento personalizada de otro Asesor Experto ensamblado por asistente. Las pruebas se ejecutan a partir de un período de optimización, con configuraciones similares a las que hemos utilizado anteriormente de EURCHF, marco de tiempo horario, año 2022, se presentan de la siguiente manera:

atr_r4

Luego realizamos una optimización en todas estas señales y cuando las combinamos en una, con distintos pesos, obtenemos las siguientes ejecuciones de prueba de una de las ejecuciones de optimización favorables.

atr_r_all

atr_c_all


ATR en la clase Trailing

Hemos analizado cómo se puede utilizar el ATR para generar señales de entrada y salida para un Asesor Experto, aunque este no sea siempre su objetivo o uso principal. Principalmente, ATR se utiliza en la colocación de stops o, como mucho, en el dimensionamiento de posiciones; por lo tanto, los analizamos en clases personalizadas que aún se pueden ensamblar dentro de un Asesor Experto a través del Asistente MQL5.

Mantenemos nuestra implementación aquí sencilla, por lo que para definir un nivel de stop dinámico, simplemente incrementamos un índice de referencia en un múltiplo del ATR. Nuestro punto de referencia, para nuestros propósitos, puede adoptar tres formas. Precio bruto, precio promedio móvil y niveles de precios del indicador SAR. Cada uno de ellos, en su parte, nos proporciona un patrón que indexamos 0, 1 y 2 y codificamos de la siguiente manera:

//+------------------------------------------------------------------+
//| Check for Pattern 0.                                             |
//+------------------------------------------------------------------+
void CTrailingATR::IsPattern_0(double &Price, ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY)
   {  Price -= (m_stop_level * ATR(StartIndex()));
   }
   else if(T == POSITION_TYPE_SELL)
   {  Price += (m_stop_level * ATR(StartIndex()));
   }
}
//+------------------------------------------------------------------+
//| Check for Pattern 1.                                             |
//+------------------------------------------------------------------+
void CTrailingATR::IsPattern_1(double &Price, ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY)
   {  Price = (MA(StartIndex()) - (m_stop_level * ATR(StartIndex())));
   }
   else if(T == POSITION_TYPE_SELL)
   {  Price = (MA(StartIndex()) + (m_stop_level * ATR(StartIndex())));
   }
}
//+------------------------------------------------------------------+
//| Check for Pattern 2.                                             |
//+------------------------------------------------------------------+
void CTrailingATR::IsPattern_2(double &Price, ENUM_POSITION_TYPE T)
{  if(T == POSITION_TYPE_BUY && SAR(StartIndex()) < Low(StartIndex()))
   {  Price = (SAR(StartIndex()) - (m_stop_level * ATR(StartIndex())));
   }
   else if(T == POSITION_TYPE_SELL && SAR(StartIndex()) > High(StartIndex()))
   {  Price = (SAR(StartIndex()) + (m_stop_level * ATR(StartIndex())));
   }
}

La optimización y las ejecuciones de prueba se pueden realizar patrón por patrón, como lo hicimos anteriormente. Sin embargo, para ser breves, solo haremos una única ejecución que busca optimizar el uso de todos los patrones con diferentes pesos. Los resultados de estos se presentan a continuación:

atr_t_all

atr_c_t_all


ATR en la gestión del dinero

Los gaps de stop loss pueden ser útiles para establecer el tamaño de la posición. Esto se debe a que el argumento es que si uno tiene una posición abierta, entonces el stop loss es lo que limitaría la pérdida máxima que sufriría en la posición, si la operación sale en su contra. Por lo tanto, al medir el valor del tick de una brecha de stop loss, uno puede obtener un valor nocional del tamaño de una posición en lotes que no activaría más que ese porcentaje establecido de su margen libre en ese momento.

Una vez armados con un nivel de stop loss y un porcentaje de riesgo máximo, podemos obtener los lotes que en teoría limitarían nuestras pérdidas. En teoría, esto se debe a que los stops no garantizan el precio. Sólo se activan si ese precio está disponible, motivo por el cual enero de 2015 fue devastador para los traders del CHF. ¿Cuál es entonces el mejor seguro? Dimensionamiento de posición mínimo y responsable. Si adoptamos los mismos 3 métodos diferentes de stop loss posibles que teníamos anteriormente con el trailing stop, así es como implementaríamos 3 patrones paralelos para una clase de administración de dinero personalizada:

//+------------------------------------------------------------------+
//| Getting lot size for open long position.                         |
//+------------------------------------------------------------------+
double CMoneyATR::CheckOpenLong(double price, double sl)
{  if(m_symbol == NULL)
      return(0.0);
//--- select lot size
   double lot;
   if(price == 0.0)
      lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_BUY, m_symbol.Ask(), m_percent);
   else
      lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_BUY, price, m_percent);
//---
   double result  = 0.0, results = 0.0;
   price =m_symbol.Bid();
//--- if the model 0 is used and "ATR-Based Stop Loss"
   if(((m_patterns_usage & 0x01) != 0))
   {  IsPattern_0(price, POSITION_TYPE_BUY);
      result += m_pattern_0 * price;
      results += m_pattern_0;
   }
//--- if the model 1 is used and "ATR-MA-Channel Stop Loss"
   if(((m_patterns_usage & 0x02) != 0))
   {  IsPattern_1(price, POSITION_TYPE_BUY);
      result += m_pattern_1 * price;
      results += m_pattern_1;
   }
//--- if the model 2 is used and "ATR-SAR-Channel Stop Loss"
   if(((m_patterns_usage & 0x04) != 0))
   {  IsPattern_2(price, POSITION_TYPE_BUY);
      result += m_pattern_2 * price;
      results += m_pattern_2;
   }
//---
   if(results > 0)
   {  result /= results;
      double _risk = (fabs(m_symbol.Bid()-result)/m_symbol.Point())*(m_symbol.TickSize()/m_symbol.Point())*m_symbol.TickValue();
      _risk /= m_account.FreeMargin();
      _risk *= 100.0;
      double _risk_lots = m_percent/_risk;// where m_percent is also max risk
      lot = fmin(2.0*lot, fmax(_risk_lots, m_symbol.LotsMin()));
   }
//--- return trading volume
   return(Optimize(lot));
}
//+------------------------------------------------------------------+
//| Getting lot size for open short position.                        |
//+------------------------------------------------------------------+
double CMoneyATR::CheckOpenShort(double price, double sl)
{  if(m_symbol == NULL)
      return(0.0);
//--- select lot size
   double lot;
//---
   if(price == 0.0)
      lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_SELL, m_symbol.Bid(), m_percent);
   else
      lot = m_account.MaxLotCheck(m_symbol.Name(), ORDER_TYPE_SELL, price, m_percent);
//---
   double result  = 0.0, results = 0.0;
   price =m_symbol.Ask();
//--- if the model 0 is used and "ATR-Based Stop Loss"
   if(((m_patterns_usage & 0x01) != 0))
   {  IsPattern_0(price, POSITION_TYPE_SELL);
      result += m_pattern_0 * price;
      results += m_pattern_0;
   }
//--- if the model 1 is used and "ATR-MA-Channel Stop Loss"
   if(((m_patterns_usage & 0x02) != 0))
   {  IsPattern_1(price, POSITION_TYPE_SELL);
      result += m_pattern_1 * price;
      results += m_pattern_1;
   }
//--- if the model 2 is used and "ATR-SAR-Channel Stop Loss"
   if(((m_patterns_usage & 0x04) != 0))
   {  IsPattern_2(price, POSITION_TYPE_SELL);
      result += m_pattern_2 * price;
      results += m_pattern_2;
   }
//---
   if(results > 0)
   {  result /= results;
      double _risk = (fabs(result-m_symbol.Ask())/m_symbol.Point())*(m_symbol.TickSize()/m_symbol.Point())*m_symbol.TickValue();
      _risk /= m_account.FreeMargin();
      _risk *= 100.0;
      double _risk_lots = m_percent/_risk;// where m_percent is also max risk
      lot = fmin(2.0*lot, fmax(_risk_lots, m_symbol.LotsMin()));
   }
//--- return trading volume
   return(Optimize(lot));
}

Este enfoque, además de tener la debilidad de depender excesivamente de que el precio del stop loss esté disponible, de vez en cuando corre el riesgo de asignar tamaños de lotes excesivamente grandes, en casos en que la brecha del stop loss es muy pequeña. Es por eso que normalizamos los lotes para no exceder el doble de los lotes que obtendríamos con el porcentaje de riesgo predeterminado del margen libre. Por lo tanto, este porcentaje de riesgo (m_percent) tiene dos propósitos: uno, define el techo de nuestros lotes si vamos a comprar lotes y lo utiliza como porcentaje del margen libre; en segundo lugar, también define el porcentaje máximo nocional del margen libre que perderíamos si nuestro stop loss estuviera en un nivel establecido.

Las pruebas realizadas con algunos de los mejores resultados de optimización, nuevamente con configuraciones similares a las anteriores, nos brindan los siguientes resultados:

atr_m_r_all

atr_m_c_all

Una vez más, no hicimos pruebas por patrón, sino que simplemente optimizamos nuestro Asesor Experto para usar todos los patrones, aunque con diferentes pesos, como fue el caso anterior con los trailing stops.


Conclusión

Hemos finalizado nuestro análisis del indicador ADX que habíamos considerado en el último artículo, y también hemos comenzado y concluido el indicador ATR. En este artículo se han presentado bastantes ideas e implementaciones diferentes del ATR; sin embargo, no se han codificado ni probado para mayor brevedad. Por lo tanto, el lector puede llevarlos más allá y realizar sus propias implementaciones y pruebas, idealmente en una variedad aún más amplia de símbolos y en más datos históricos, para tener una mejor idea de lo que es adecuado a sus circunstancias.

Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/16213

Archivos adjuntos |
MoneyWZ_44.mqh (13.81 KB)
TrailingWZ_44.mqh (11.24 KB)
SignalWZ_44.mqh (15.63 KB)
wz_44_signal.mq5 (7.47 KB)
wz_44_trail.mq5 (8.35 KB)
wz_trail_mm_44.mq5 (9.07 KB)
Utilizando redes neuronales en MetaTrader Utilizando redes neuronales en MetaTrader
En el artículo se muestra la aplicación de las redes neuronales en los programas de MQL, usando la biblioteca de libre difusión FANN. Usando como ejemplo una estrategia que utiliza el indicador MACD se ha construido un experto que usa el filtrado con red neuronal de las operaciones. Dicho filtrado ha mejorado las características del sistema comercial.
Estudiamos el indicador de perfil de mercado Market Profile: ¿Qué es y cómo se estructura? Estudiamos el indicador de perfil de mercado Market Profile: ¿Qué es y cómo se estructura?
Hoy nos familiarizaremos con el "Perfil de mercado". Además, averiguaremos qué hay detrás de este nombre, trataremos de entender los principios de trabajo con el Perfil y analizaremos su versión presentada en el terminal bajo el nombre MarketProfile.
Particularidades del trabajo con números del tipo double en MQL4 Particularidades del trabajo con números del tipo double en MQL4
En estos apuntes hemos reunido consejos para resolver los errores más frecuentes al trabajar con números del tipo double en los programas en MQL4.
Redes neuronales en el trading: Transformer parámetro-eficiente con atención segmentada (Final) Redes neuronales en el trading: Transformer parámetro-eficiente con atención segmentada (Final)
En artículos anteriores, revisamos los aspectos teóricos del framework PSformer, que incluye dos importantes innovaciones en la arquitectura del Transformer clásico: el mecanismo de compartición de parámetros (PS) y la atención a los segmentos espaciotemporales (SegAtt). En este artículo, continuaremos el trabajo sobre la implementación de los enfoques propuestos mediante MQL5.