Características del Wizard MQL5 que debe conocer (Parte 56): Fractales de Bill Williams
Introducción
Bill Williams’ fractal indicator is a pivotal and important indicator amongst the collection habits known for. Identifica principalmente los puntos de reversión en la acción del precio de los símbolos negociados. Basado en el concepto de fractales, como un patrón repetitivo de 5 barras que a menudo se marca como bajista si la barra central de las 5 tiene el máximo más alto, o alcista en los casos en que la barra central tiene el mínimo más bajo. Analizamos algunos de los patrones de este indicador que pueden utilizar los operadores, tal y como hemos hecho anteriormente con los artículos sobre el asistente MQL5.
Fractales consecutivos en la misma dirección
Para nuestro primer patrón, el patrón 0, se define una formación alcista cuando se forma una serie de mínimos fractales alcistas en el mínimo anterior o cerca de él. Generalmente esto se interpreta como que el mercado encontró soporte en ese punto. Es importante tener en cuenta que, por mínimos fractales consecutivos, lo que se quiere decir es que no hay ningún máximo fractal entre los mínimos. Este es un indicador importante porque los patrones típicos son fractales altos que siguen a fractales bajos, en alternancia. Sin embargo, en el caso del patrón alcista, se considera que indica que diferentes compradores ingresan al mercado a niveles de precios similares, lo que refuerza la tesis de una fase de acumulación que precede a un movimiento ascendente.
Por el contrario, múltiples máximos fractales bajistas consecutivos pueden trazar un nivel de resistencia que el precio no puede superar. Este fuerte rechazo (o rechazo repetido en períodos de tiempo amplios) a menudo indica una fuerte presión de venta y una probable continuación o comienzo de una tendencia bajista.
Implementamos el Patrón-0 (Pattern-0) en MQL5 de la siguiente manera:
//+------------------------------------------------------------------+ //| Check for Pattern 0. | //+------------------------------------------------------------------+ bool CSignalFractals::IsPattern_0(ENUM_POSITION_TYPE T) { if(T == POSITION_TYPE_BUY && FractalLow(X() + 1) != 0.0 && FractalLow(X()) != 0.0) { return(true); } else if(T == POSITION_TYPE_SELL && FractalHigh(X() + 1) != 0.0 && FractalHigh(X()) != 0.0) { return(true); } return(false); }
De forma predeterminada, se proporciona un indicador fractal de Bill Williams entre el conjunto de indicadores incorporados. También requiere algunos ajustes, ya que muchos de sus valores para los buffers Upper/Highs y Lower/Lows producen NaN en el uso inicial. Por lo tanto, creamos una versión modificada de esto introduciendo 2 funciones: FractalHigh y FractalLow. El código para ambos se detalla a continuación:
double FractalHigh(int ind) { // m_high.Refresh(-1); if(m_high.MaxIndex(ind, 5) == ind) { return(m_high.GetData(ind)); } return(0.0); }
double FractalLow(int ind) { // m_low.Refresh(-1); if(m_low.MinIndex(ind, 5) == ind) { return(m_low.GetData(ind)); } return(0.0); }
En la función patrón-0, simplemente llamamos a la función FractalLow en 2 barras consecutivas anteriores cuando buscamos una señal alcista o al fractal máximo en la misma cuando buscamos un patrón bajista. El lector puede personalizar este número de barras consecutivas aumentándolo si es necesario filtrar más señales falsas. Sin embargo, como suele ocurrir, pocas configuraciones de trading requieren pruebas durante períodos más largos para que resulten fiables. Realizamos todas las pruebas de patrones de este indicador en el símbolo GBP/USD, en un marco temporal de 4 horas, para el año 2024, tras haber optimizado los patrones para el año 2023. El recorrido hacia adelante para el patrón 0 nos da el siguiente informe.

El patrón 0 indica una fuerte continuación de tendencia. Por lo tanto, puede ayudar a reabrir posiciones en una tendencia predominante si se ha tomado una ganancia.
Ruptura de tendencia fractal
El patrón 1, nuestro segundo patrón, define su formación alcista en primer lugar con un fractal bajista que había servido como resistencia. Una formación alcista ocurre cuando el precio, yendo contra la corriente, rompe decisivamente por encima de este fractal alto. Esta ruptura se interpreta entonces como que los compradores dominan a los vendedores, de modo que el nivel de resistencia anterior se transforma en un soporte, lo que indica una reversión de la tendencia. Esta también podría ser una fuerte continuación de tendencia si ocurriera dentro de una tendencia alcista mucho más amplia que se hubiera vuelto menos evidente en marcos temporales pequeños.
Una versión bajista del patrón 1, como era de esperar, sería lo opuesto. Un fractal bajo alcista sería seguido por una ruptura del precio por debajo de la marca del fractal bajo. Esta ruptura se toma como una indicación de que los vendedores están tomando el control y preparando el escenario para una tendencia bajista. Implementamos esto de la siguiente manera en MQL5:
//+------------------------------------------------------------------+ //| Check for Pattern 1. | //+------------------------------------------------------------------+ bool CSignalFractals::IsPattern_1(ENUM_POSITION_TYPE T) { if(T == POSITION_TYPE_BUY && FractalHigh(X() + 1) != 0.0 && Close(X()) > FractalHigh(X() + 1)) { return(true); } else if(T == POSITION_TYPE_SELL && FractalLow(X() + 1) != 0.0 && Close(X()) < FractalLow(X() + 1)) { return(true); } return(false); }
En nuestro código anterior, buscamos puntos fractales en la barra anterior y luego comparamos el precio de cierre actual con ese precio fractal. Como se argumenta en la lógica, el fractal alto (el fractal bajista) es pertinente al patrón alcista y el fractal bajo también es importante para el patrón bajista.
El avance hacia el año 2024 a partir de la optimización de los umbrales de apertura y cierre para el año 2023 nos presenta el siguiente informe:

El patrón 1 se destaca porque, a diferencia del patrón 0, que es una continuación, este puede servir como una reversión. Por eso, siempre es una buena idea usarlo con otros indicadores.
Fractales internos (máximos más bajos, mínimos más altos)
El patrón 2 tiene su formación alcista definida cuando los fractales alcistas (mínimos oscilantes) se forman cerca del rango de un fractal anterior más amplio. La acción del precio a menudo se comprime dentro de este rango, y los fractales bajos casi forman una línea recta. Entonces, cuando se produce un movimiento por encima de este rango estrecho, eso confirmaría un sesgo alcista ya que los compradores estarían empujando el precio fuera de una zona de consolidación.
Por otro lado, con una formación fractal bajista, si los máximos oscilantes forman un grupo dentro de los límites de un rango fractal bajista anterior, esto también marcaría un período de indecisión. Una vez que el precio cae por debajo del límite inferior de este rango y el soporte falla, esta ruptura a la baja confirmaría un movimiento bajista. Así es como implementamos esto en MQL5:
//+------------------------------------------------------------------+ //| Check for Pattern 2. | //+------------------------------------------------------------------+ bool CSignalFractals::IsPattern_2(ENUM_POSITION_TYPE T) { CArrayDouble _buffer; if(T == POSITION_TYPE_BUY) { for(int i = 0; i < m_periods; i++) { if(FractalLow(X() + i) != 0.0) { _buffer.Add(FractalLow(X() + i)); } } if(_buffer[_buffer.Maximum(0, _buffer.Total())] - _buffer[_buffer.Minimum(0, _buffer.Total())] <= fabs(Close(X()) - Close(X() + 10))) { return(true); } } else if(T == POSITION_TYPE_SELL) { for(int i = 0; i < m_periods; i++) { if(FractalHigh(X() + i) != 0.0) { _buffer.Add(FractalHigh(X() + i)); } } if(_buffer[_buffer.Maximum(0, _buffer.Total())] - _buffer[_buffer.Minimum(0, _buffer.Total())] <= fabs(Close(X()) - Close(X() + 10))) { return(true); } } return(false); }
La implementación de este patrón requiere, según nuestro enfoque, el uso de una clase estándar de matriz. Esto se debe a que estamos buscando puntos fractales durante un período fijo y el número que recuperaremos es incierto. Con esto también necesitamos tener una idea de la desviación estándar de estos puntos fractales.
Debido a que nuestra clase de matriz no proporciona la función de desviación estándar como el tipo de datos vectoriales y debido a que también requiere un uso intensivo de recursos computacionales, optamos por tomar el rango de estos puntos en su lugar. Para tener una idea de que su rango está comprimido, lo comparamos con la magnitud de la tendencia en el precio de cierre y si es menor, tenemos la confirmación.
Estrictamente hablando, esta es una evaluación burda, ya que se puede ver fácilmente que en los mercados con tendencia, cuando la magnitud del cambio del precio de cierre se vuelve bastante grande, cualquier conjunto de puntos fractales pasará esta prueba. Por esta razón puede ser una buena idea que los lectores realicen cambios que indiquen comparar el rango de puntos fractales o su desviación estándar con un valor absoluto. Este valor podría ajustarse mediante optimización.
Una ejecución hacia adelante después de optimizar nuestro Asesor Experto ensamblado por el asistente, con el par USDJPY en un marco temporal de 4 horas, nos da estos resultados:

El patrón 2 es un patrón de compresión que indica potencial de ruptura. En marcos temporales múltiples, cuando se forman fractales más pequeños dentro de otros más grandes, eso generalmente sugiere una compresión antes de una expansión.
Divergencia fractal con acción del precio
La divergencia con la acción del precio es nuestro patrón 3. En este patrón se observa una divergencia alcista cuando el precio forma un mínimo más bajo (una indicación de presión bajista sostenida), sin embargo los fractales alcistas correspondientes (los mínimos oscilantes) están por encima de los del movimiento anterior. Esta divergencia se interpreta como alcista con el argumento de que, a pesar de la caída de los precios, el soporte subyacente se está fortaleciendo, lo que sugiere una inminente reversión alcista.
Una divergencia bajista, por otro lado, es cuando el precio forma un máximo más alto mientras que los máximos fractales bajistas son más bajos que los anteriores. Esta configuración generalmente indica que, aunque el precio está subiendo, la resistencia está comprimiendo el precio, lo que podría ser un presagio de pérdida de poder adquisitivo y una reversión a la baja. Implementamos esto en MQL5 de la siguiente manera:
//+------------------------------------------------------------------+ //| Check for Pattern 3. | //+------------------------------------------------------------------+ bool CSignalFractals::IsPattern_3(ENUM_POSITION_TYPE T) { CArrayDouble _buffer; if(T == POSITION_TYPE_BUY) { for(int i = 0; i < m_periods; i++) { if(FractalLow(X() + i) != 0.0) { _buffer.Add(FractalLow(X() + i)); } if(_buffer.Total() >= 2) { break; } } if(_buffer[0] > _buffer[1] && Low(X()) < Low(X() + 1)) { return(true); } } else if(T == POSITION_TYPE_SELL) { for(int i = 0; i < m_periods; i++) { if(FractalHigh(X() + i) != 0.0) { _buffer.Add(FractalHigh(X() + i)); } if(_buffer.Total() >= 2) { break; } } if(_buffer[0] < _buffer[1] && High(X()) > High(X() + 1)) { return(true); } } return(false); }
La codificación de nuestro patrón 3 también requiere el uso de la clase de matriz estándar que está disponible en el IDE MQL5. Esto se debe principalmente a las razones ya mencionadas en el patrón 2, sin embargo, en este caso estamos buscando solo 2 puntos fractales en lugar de una colección durante un período establecido por el parámetro de entrada 'm_periods'. Utilizamos los 2 puntos fractales junto con los 2 puntos de precio extremos para establecer nuestra señal potencial, como ya se argumentó anteriormente.
Una optimización posterior al avance para un símbolo, marco temporal y período de prueba similares a los patrones anteriores nos presenta el siguiente informe:

Fractales opuestos gemelos (zonas de reversión)
Los fractales gemelos opuestos forman nuestro patrón 4. La formación alcista de este patrón implica dos fractales ubicados de forma idéntica, uno alcista (en los mínimos) y otro bajista (en los máximos). El cruce de estos dos crea una zona de indecisión. Cuando el precio rebota en el fractal alcista y sube por encima del fractal bajista, se confirma una señal alcista.
Con la formación bajista, la secuencia es un fractal alcista seguido inmediatamente de otro fractal bajista. Si el precio rebota en el fractal bajista (máximo) y cae por debajo del fractal alcista, también se confirma una señal de venta. Codificamos esto en MQL5 de la siguiente manera:
//+------------------------------------------------------------------+ //| Check for Pattern 4. | //+------------------------------------------------------------------+ bool CSignalFractals::IsPattern_4(ENUM_POSITION_TYPE T) { bool _1 = (FractalHigh(X() + 1) != 0.0 && FractalLow(X() + 1) != 0.0); bool _2 = (FractalHigh(X() + 2) != 0.0 && FractalLow(X() + 2) != 0.0); if(_1 || _2) { if(T == POSITION_TYPE_BUY) { if((_1 && Close(X()) > FractalHigh(X() + 1)) || (_2 && Close(X()) > FractalHigh(X() + 2))) { return(true); } } else if(T == POSITION_TYPE_SELL) { if((_1 && Close(X()) < FractalLow(X() + 1)) || (_2 && Close(X()) < FractalLow(X() + 2))) { return(true); } } } return(false); }
Nuestro código utiliza dos valores booleanos para verificar el patrón fractal gemelo. Hemos optado por utilizar 2 valores booleanos porque los efectos de este patrón único podrían arrastrarse ligeramente (en lugar de retrasarse). Cada valor marca la última barra completa o la barra anterior. Si se encuentra el patrón, procedemos simplemente a verificar si el precio de cierre rompió alguno de sus niveles clave, como ya se explicó anteriormente.
Un avance de optimización posterior para este patrón nos arroja el siguiente informe:

La aparición consecutiva de fractales alcistas y bajistas también resalta otro punto de indecisión en los mercados. Las rupturas en ambos lados, entonces, son lo que se utiliza como señales para el patrón 4.
Confirmación fractal de máximos y mínimos oscilantes
Para este patrón, Patrón-5, observamos la acción del precio a lo largo de una serie de barras en relación con los puntos de referencia fractales. La formación alcista se define cuando se establece un fractal alcista (que a menudo es un nivel de soporte potencial) y la acción del precio posterior no cae significativamente por debajo de este nivel. Si el precio continúa rebotando desde este nivel, reforzará la tesis de que es una zona de soporte alcista.
Por el contrario, se establece una formación/swing bajista si se establece un máximo fractal y después de la acción del precio posterior, el precio no excede el punto de referencia alto del fractal. El argumento aquí es que la incapacidad persistente de romper al alza el fractal refuerza su papel como área de resistencia y, por lo tanto, una señal para el sentimiento bajista. Implementamos esto en MQL5 de la siguiente manera:
//+------------------------------------------------------------------+ //| Check for Pattern 5. | //+------------------------------------------------------------------+ bool CSignalFractals::IsPattern_5(ENUM_POSITION_TYPE T) { vector _std; _std.Init(5); _std.Fill(0.0); if(T == POSITION_TYPE_BUY && FractalLow(X() + m_periods) != 0.0) { if(_std.CopyRates(m_symbol.Name(), m_period, 4, 0, m_periods) && _std.Std() <= fabs(Close(X()) - Close(X() + m_periods))) { return(true); } } else if(T == POSITION_TYPE_SELL && FractalHigh(X() + m_periods)) { if(_std.CopyRates(m_symbol.Name(), m_period, 2, 0, m_periods) && _std.Std() <= fabs(Close(X()) - Close(X() + m_periods))) { return(true); } } return(false); }
Nuestro código anterior utiliza un vector no solo para copiar el buffer de tasas que necesitamos, sino también para recuperar de manera eficiente su desviación estándar. Comparamos esta desviación con la magnitud de la tendencia prevaleciente en el precio de cierre, como hicimos con el patrón 2. Por lo tanto, los inconvenientes y precauciones planteados en el patrón 2 se aplican aquí, por lo que el lector tiene la libertad de realizar modificaciones en el código adjunto.
Una ejecución de avance después de optimizar con un símbolo, ventanas y marco de tiempo similares a los anteriores nos da el siguiente informe:

No había estado haciendo caminatas hacia adelante en estas series, pero como las ventanas de prueba son muy pequeñas, ahora las incluimos como estándar. Lo que faltará serán las ejecuciones de optimización durante el período de entrenamiento porque tener ambas hará que el artículo esté demasiado lleno.
Swing fractal fallido
El patrón 6 se centra en el «fracaso» de la acción del precio para romper los niveles fractales. Para los alcistas, después de un swing fractal alcista, si el precio intenta romper aún más a la baja y este intento fracasa, es decir, el nuevo mínimo es rechazado por una rápida reversión al alza, esto suele indicar que los vendedores están agotados y que los compradores deben intervenir.
Por el contrario, para los bajistas, cuando se forma un máximo fractal y el precio intenta subir por encima de este fractal, pero fracasa, este «fracaso del swing» se toma como una indicación de que los vendedores están al mando y que es probable que el precio se encamine hacia una tendencia bajista. Implementación en MQL5 como sigue:
//+------------------------------------------------------------------+ //| Check for Pattern 6. | //+------------------------------------------------------------------+ bool CSignalFractals::IsPattern_6(ENUM_POSITION_TYPE T) { if(T == POSITION_TYPE_BUY && FractalLow(X() + 2) != 0.0) { if(Low(X() + 1) <= FractalLow(X() + 2) && Close(X()) >= High(X() + 2)) { return(true); } } else if(T == POSITION_TYPE_SELL && FractalHigh(X() + 2) != 0.0) { if(High(X() + 1) >= FractalHigh(X() + 2) && Close(X()) <= Low(X() + 2)) { return(true); } } return(false); }
Este es uno de nuestros patrones más sencillos en lo que respecta a la codificación. Como se ha argumentado anteriormente, simplemente estamos comparando los precios bajos anteriores con el mínimo fractal anterior y, a continuación, el precio de cierre con el precio alto de hace dos barras en la tendencia alcista. Seguimos lo contrario en el caso bajista. El lector puede decidir hasta dónde quiere remontarse en la historia.
Un avance tras la optimización, como fue el caso de los patrones 0-5 para los umbrales de apertura y cierre de este patrón, nos presenta el siguiente informe:

Un máximo (o mínimo) fractal que no es superado por las velas posteriores suele servir como rechazo. Es una señal clara de agotamiento de la tendencia.
Agrupación de fractales alrededor de las medias móviles
Nuestro octavo patrón, Patrón-7, combina el indicador fractal con la media móvil. En el caso de una configuración alcista, cuando una serie de mínimos fractales se agrupan cerca de una media móvil (por ejemplo, la media móvil de 50), esto se interpreta como una indicación de que la media móvil está actuando como un fuerte nivel de soporte. Por lo tanto, estos mínimos fractales tienden a ofrecer oportunidades de entrada para los compradores y, una vez que el precio se mueve de forma decisiva por encima del nivel de resistencia más cercano o incluso de la propia media móvil, esto confirma la tesis alcista.
Del mismo modo, una formación bajista se produce cuando múltiples fractales altos se agrupan alrededor de la media móvil, que actuaría como resistencia en ese momento. El rechazo recurrente del precio en estos niveles y un movimiento decisivo por debajo del soporte o la media móvil confirmarían una tendencia bajista. La implementación de esto en MQL5 es la siguiente:
//+------------------------------------------------------------------+ //| Check for Pattern 7. | //+------------------------------------------------------------------+ bool CSignalFractals::IsPattern_7(ENUM_POSITION_TYPE T) { CArrayDouble _buffer; if(T == POSITION_TYPE_BUY) { for(int i = 1; i < m_periods; i++) { if(FractalLow(X() + i) != 0.0) { _buffer.Add(fabs(FractalLow(X() + i) - MA(X() + i))); } } if(_buffer[_buffer.Maximum(0, _buffer.Total())] <= fabs(Close(X() + 1) - Close(X() + m_periods)) && Close(X() + 1) <= MA(X() + 1) && Close(X()) > MA(X())) { return(true); } } else if(T == POSITION_TYPE_SELL) { for(int i = 1; i < m_periods; i++) { if(FractalHigh(X() + i) != 0.0) { _buffer.Add(fabs(FractalHigh(X() + i) - MA(X() + i))); } } if(_buffer[_buffer.Maximum(0, _buffer.Total())] <= fabs(Close(X() + 1) - Close(X() + m_periods)) && Close(X() + 1) >= MA(X() + 1) && Close(X()) < MA(X())) { return(true); } } return(false); }
El patrón 7, al igual que el patrón 2 y el patrón 3, también utiliza la clase array, pero en esta ocasión para registrar la magnitud de la diferencia entre el punto fractal y la media móvil. Como se ha argumentado anteriormente, buscamos situaciones en las que esta diferencia sea lo más pequeña posible y, por eso, tomamos su valor máximo de todos los puntos de diferencia que entran en el búfer. Una vez más, estamos comparando esta magnitud con la tendencia predominante, por lo que se recuerda al lector que debe realizar ajustes al respecto, tal y como se ha mencionado anteriormente con otros patrones, como el patrón 6.
Al avanzar con los ajustes de entrada obtenidos al optimizar el mismo símbolo utilizado en los patrones anteriores, obtenemos el siguiente informe:

Cuando muchos fractales se consolidan cerca de una media móvil, esto sugiere una zona de pivote con una ruptura del grupo que confirma una continuación o una reversión.
Patrón fractal con gap
Para el patrón 8, la señal alcista se produce cuando un mínimo fractal alcista se encuentra cerca de un gap de precios (normalmente en una acción del precio con alta volatilidad o impulsada por noticias). En esta situación, el gap actúa como zona de soporte. La presencia de un fractal en el gap se interpreta entonces como que los compradores ven esta zona como una oportunidad. Una vez que el gap se «llene» o se mantenga, es probable que se produzca un movimiento alcista.
La formación bajista también se produce cuando aparece un máximo fractal bajista cerca o en la ubicación de un gap alcista que se ha abierto al alza. En este escenario, el gap representaría un nivel de resistencia. La presencia del fractal indicaría que los vendedores están defendiendo el nivel y, si el precio comenzara una tendencia bajista, la tendencia bajista se consolidaría. Implementamos esto en MQL5 de la siguiente manera:
//+------------------------------------------------------------------+ //| Check for Pattern 8. | //+------------------------------------------------------------------+ bool CSignalFractals::IsPattern_8(ENUM_POSITION_TYPE T) { if(T == POSITION_TYPE_BUY && FractalLow(X() + 2) != 0.0) { if(Low(X() + 1) > High(X() + 2) && Close(X()) >= High(X() + 2)) { return(true); } } else if(T == POSITION_TYPE_SELL && FractalHigh(X() + 2) != 0.0) { if(High(X() + 1) < Low(X() + 2) && Close(X()) <= Low(X() + 2)) { return(true); } } return(false); }
Para el patrón 8, solo nos interesa la diferencia de precios, por lo que nuestra implementación anterior es casi tan sencilla como la del patrón 6.
A continuación se muestra una proyección con un símbolo y una configuración del entorno de prueba similares a los que hemos tenido anteriormente para el par USDJPY en un marco temporal de 4 horas en el año 2023:

La coincidencia de gaps de precios y rupturas fractales siempre amplifica el movimiento de los precios. Sin embargo, estas configuraciones son más comunes en eventos relacionados con las noticias.
Alineación fractal con los niveles de Fibonacci
Nuestro patrón final combina el fractal con los niveles de Fibonacci. Una alineación alcista se produce cuando un fractal bajo coincide con un nivel clave de retroceso de Fibonacci. Esta confluencia entre el soporte identificado por el fractal y el nivel de Fibonacci refuerza la solidez de la zona de soporte. Por lo tanto, esta doble confirmación sirve como una sólida señal alcista, si el precio se mantiene en este nivel. Por lo general, podría ser una señal de un rebote o de la continuación de la tendencia.
En una formación bajista, el fractal alto se alinea con un nivel crítico de retroceso de Fibonacci. Esta alineación refuerza entonces la resistencia en ese punto. Si el precio tiene dificultades para superar la zona de Fibonacci y, en cambio, revierte a la baja desde esta zona de confluencia, esto confirma una señal bajista. Ambas configuraciones se codifican de la siguiente manera en MQL5:
//+------------------------------------------------------------------+ //| Check for Pattern 9. | //+------------------------------------------------------------------+ bool CSignalFractals::IsPattern_9(ENUM_POSITION_TYPE T) { if(T == POSITION_TYPE_BUY && FractalLow(X()) != 0.0) { if(Is_Fibo_Level(X())) { return(true); } } else if(T == POSITION_TYPE_SELL && FractalHigh(X()) != 0.0) { if(Is_Fibo_Level(X())) { return(true); } } return(false); }
El código para nuestro patrón final fue un poco complicado de concebir, ya que lo que siempre es evidente y obvio en el trading manual no suele serlo cuando se trata de automatizarlo. ¿Cómo «trazaríamos» y marcaríamos los niveles de Fibonacci? Para ayudarnos con esto, hemos creado una función rudimentaria que hemos llamado «Is_Fibo_Level()». Su código se muestra a continuación:
bool Is_Fibo_Level(int ind) { double _r=0.0; vector _h,_l; int _size = 3 * PeriodSeconds(PERIOD_MN1) / PeriodSeconds(m_period); _h.Init(_size); _l.Init(_size); if(_h.CopyRates(m_symbol.Name(),m_period,2,0,_size) && _l.CopyRates(m_symbol.Name(),m_period,4,0,_size)) { _r = _h.Max()-_l.Min(); if(_l.Min()-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+ATR(ind)) { return(true); } else if(_l.Min()+(0.236*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.236*_r)+ATR(ind)) { return(true); } else if(_l.Min()+(0.382*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.382*_r)+ATR(ind)) { return(true); } else if(_l.Min()+(0.5*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.5*_r)+ATR(ind)) { return(true); } else if(_l.Min()+(0.618*_r)-ATR(ind) <= Close(ind) && Close(ind) <= _l.Min()+(0.618*_r)+ATR(ind)) { return(true); } else if(_h.Max()-ATR(ind) <= Close(ind) && Close(ind) <= _h.Max()+ATR(ind)) { return(true); } } return(false); }
Esta función simplemente toma muestras de los precios de los últimos tres meses, un período arbitrario que, obviamente, no refleja los niveles de precios clave como lo haría una configuración manual. Siempre se dice que la prueba del pudín está en comerlo, por lo que quizá obsesionarse demasiado con cómo vemos las cosas manualmente no se traduce necesariamente en rendimiento comercial, y por eso lo desarrollamos en el patrón 9, donde simplemente buscamos una coincidencia entre los puntos fractales y los niveles de esta función. El ATR también se utiliza de forma muy rudimentaria para establecer la amplitud de nuestros niveles, por lo que, en caso de que el periodo de tres meses registre una baja volatilidad, es probable que se produzcan muchos solapamientos. Esto podría ser un punto de partida para el lector interesado a la hora de realizar modificaciones.
Un avance como el que hemos hecho con los otros cinco patrones nos da este informe:

Por lo tanto, este patrón sirve para confirmar las zonas clave de reversión. En esta serie, cada vez que hemos analizado los patrones, también hemos considerado la opción de utilizar no solo un patrón, como ha sido el caso hasta ahora en los nueve patrones anteriores, sino también utilizar todos los patrones juntos.
Combinación de los patrones
El código adjunto para nuestros 9 patrones tiene la forma de una clase de señal personalizada. Usamos esta clase en un asistente MQL5 para ensamblar asesores expertos. Hay guías aquí y aquí sobre cómo hacerlo. Las optimizaciones de patrones individuales y las pruebas que hemos realizado anteriormente se basaron en asignar a los mapas de parámetros de entrada utilizados un índice especial que tiene la forma 2 elevado al índice del patrón. Así, con el patrón 5, el resultado era 2^5, es decir, 32; con el 7, era 128, y así sucesivamente. Sin embargo, cuando se opera con múltiples patrones, esta entrada sirve como un mapa en lugar de como un indicador de un patrón específico. Tenemos 9 patrones, por lo que el valor máximo de nuestro parámetro para los mapas utilizados es 2^9, que es 512 menos uno (ya que empezamos a contar desde cero).
Si optimizamos para obtener la mejor combinación de patrones en los umbrales de apertura y cierre estándar, nuestros mejores ajustes de entrada son los siguientes:

Una prueba realizada con los datos de entrenamiento nos da el siguiente informe:


Y un avance hacia el año 2024 nos da los siguientes resultados:


Creo que estos resultados reflejan lo que se ha destacado en artículos anteriores, es decir, que la combinación de patrones requiere conocimientos especializados por parte del operador. Necesita ser muy específico al combinar patrones. No debería buscar respuestas en las ejecuciones de optimización. Tenemos patrones individuales arriba que pudieron avanzar. Esto fue el resultado de 1 año de pruebas, por lo que ciertamente se justifican períodos de prueba más largos y, como siempre, el desempeño pasado no indica resultados futuros. Sin embargo, esto habla de la importancia de adoptar un enfoque centrado al seleccionar patrones para una señal en lugar de promediar.
Importancia de los marcos temporales
La interpretación fractal es muy subjetiva al marco temporal utilizado. Los marcos temporales superiores H4, diario y semanal proporcionan señales más sólidas y fiables, ya que tienden a filtrar gran parte del ruido del mercado. Los fractales en estos marcos temporales suelen marcar niveles clave de soporte y resistencia a los que prestan atención las instituciones y los operadores a largo plazo. Las señales se generan muy lentamente, lo que puede resultar frustrante para muchos operadores, pero cuando se forman, suelen ser configuraciones de alta confianza.
Por otro lado, los marcos temporales más bajos de M15, M20 y M30 aparecen con mayor frecuencia, pero pueden ser menos fiables debido a las fluctuaciones de precios a corto plazo. Son más adecuados para estrategias de scalping, en las que se premia más la rapidez de reacción. Sin embargo, por regla general, son más propensos a falsas rupturas y requieren filtros adicionales para mejorar la precisión.
También hay marcos temporales intermedios H1, H2, y estos, en teoría, deberían proporcionar un término medio entre los dos. Se invita al lector a explorar la veracidad de esto; sin embargo, las mejores prácticas indican que funcionan bien cuando se combinan con fractales en marcos temporales más amplios.
Conclusión
Los fractales suelen ser incondicionales en mercados con alta liquidez y fuerte interés institucional. Los picos de precios de bajo volumen tienden a crear fractales falsos que rápidamente se invalidan, por lo que el análisis de volumen o los gráficos de huella pueden utilizarse para añadir confianza a las decisiones basadas en fractales.
Dicho esto, hemos considerado nueve patrones distintos de este indicador tan «fundamental» y, aunque presenta importantes inconvenientes en los marcos temporales más pequeños, cuando se utiliza con paciencia en los marcos temporales más amplios puede arrojar resultados interesantes, ya que hemos podido avanzar a partir de un año de pruebas en algunos de los patrones.
| Archivo | Descripción |
|---|---|
| SignalWZ_56.mqh | Archivo de clase. |
| WZ_56.mq5 | Archivo de expertos que muestra los datos incluidos. |
Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/17334
Advertencia: todos los derechos de estos materiales pertenecen a MetaQuotes Ltd. Queda totalmente prohibido el copiado total o parcial.
Este artículo ha sido escrito por un usuario del sitio web y refleja su punto de vista personal. MetaQuotes Ltd. no se responsabiliza de la exactitud de la información ofrecida, ni de las posibles consecuencias del uso de las soluciones, estrategias o recomendaciones descritas.
Kit de herramientas de negociación MQL5 (Parte 8): Cómo implementar y utilizar la librería History Manager en sus proyectos
Desarrollamos un asesor experto multidivisas (Parte 24): Añadimos una nueva estrategia (I)
Desarrollo de un kit de herramientas para el análisis de la acción del precio (Parte 15): Introducción a la teoría de los cuartos (I) - Dibujando la teoría de cuartos
Análisis de múltiples símbolos con Python y MQL5 (Parte 3): Tipos de cambio triangulares
- Aplicaciones de trading gratuitas
- 8 000+ señales para copiar
- Noticias económicas para analizar los mercados financieros
Usted acepta la política del sitio web y las condiciones de uso