English Русский 中文 Deutsch 日本語 Português
preview
Encontrando patrones de velas con la ayuda de MQL5

Encontrando patrones de velas con la ayuda de MQL5

MetaTrader 5Trading | 25 julio 2023, 15:55
996 0
Mohamed Abdelmaaboud
Mohamed Abdelmaaboud

Introducción

Las velas japonesas son muy importantes para el análisis técnico, pero solo si las usamos correctamente. Las velas pueden formar ciertos patrones o modelos en el gráfico; al analizar estos, podemos determinar el movimiento potencial de un instrumento financiero. Los patrones se pueden dividir en dos tipos: patrones que constan de una sola vela y patrones que constan de una combinación de velas. En este artículo, aprenderemos cómo podemos usar MQL5 para encontrar patrones en MetaTrader 5 de forma automática. Para ello, analizaremos los siguientes puntos:

Tenga en cuenta que cualquier patrón debe utilizarse junto con otras herramientas técnicas para obtener señales significativas. Por consiguiente, en este artículo, analizaremos los principios básicos de la búsqueda de patrones de velas utilizando las herramientas de MQL5 para que dichos patrones puedan incluirse en los sistemas comerciales.

¡Atención! Toda la información del presente artículo se ofrece «tal cual», únicamente con fines ilustrativos, y no supone ningún tipo de recomendación. El artículo no garantiza ningún resultado en absoluto. Todo lo que ponga en práctica usando este artículo como base, lo hará bajo su propia cuenta y riesgo; el autor no garantiza resultado alguno.

Patrones de velas individuales

Veamos dos ejemplos de patrones populares que constan de una sola vela. Estas velas pueden aparecer en cualquier marco temporal; debemos analizar su posición en relación con la acción del precio. Estos son los patrones Doji y Martillo.

Vela Doji:

En esencia, es una vela, pero pertenece a los patrones. Esta vela tiene casi los mismos precios de apertura y cierre, lo cual da como resultado un cuerpo muy pequeño con una sombra superior e inferior, o incluso sin sombra. Aquí tenemos un ejemplo de una vela de este tipo:

doji

Una vela Doji de este tipo indica que existe un equilibrio entre compradores y vendedores, y que ninguna fuerza domina el mercado ni desplaza el precio hacia arriba o hacia abajo durante el periodo en que aparece dicha vela. Dicha situación puede indicar una reversión o corrección en el mercado, y puede aparecer antes de una corrección o al final de una tendencia. El patrón se considera más significativo en los marcos temporales mayores. Existen muchos tipos y formaciones para esta vela, como libélula, piernas largas, etc. Cada uno de ellos porta cierta información que se puede usar para el comercio.

Lo que debemos lograr es que el programa detecte el patrón Doji determinando el precio y el tiempo de la última vela en cada tick y comparando estos valores para determinar la formación. Si el precio de apertura es igual al precio de cierre, el programa debería retornar una señal indicando que se trata de un patrón de velas Doji.

Veamos cómo podemos crear un programa capaz de encontrar dicho patrón. Analizaremos este proceso paso a paso:

Primero crearemos una función para determinar Doji (getDoji). La llamaremos en OnTick() para verificar cada tick si existe este patrón.

void OnTick()
  {
   getDoji();
  }

Luego crearemos la función (getDoji), tendremos una variable integer.

int getDoji()

Definiremos la función determinando el tiempo, los precios de apertura, el máximo, el mínimo y el cierre de la última vela.

Para ello, utilizaremos las funciones: iTime, que retorna el tiempo de apertura de la vela; iOpen, que retorna el precio de apertura de la vela; iHigh, que retorna el precio máximo; iLow, que retorna el precio mínimo; e iClose, que retorna el precio de cierre de la vela. Todos los parámetros serán iguales:

  • symbol — nombre del símbolo; nosotros tendremos "_Symbol", es decir, calcularemos el indicador según el símbolo del gráfico actual.
  • timeframe — marco temporal para los cálculos, indicaremos PERIOD_CURRENT para trabajar en el marco temporal del gráfico actual.
  • shift — índice de la vela para la que retornaremos los valores; usaremos 1, la última vela formada.
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);

A continuación, definiremos las condiciones para buscar Doji usando la declaración if

if(open==close)

Si se cumple esta condición, nuestro programa creará un objeto basado en la función createObj. Para crear un objeto, usaremos ciertos parámetros de tiempo, precio, código de flecha, color y texto. Después finalizaremos la función y retornaremos 1.

   if(open==close)
     {
      createObj(time,low,217, clrBlack,"Doji");
        {
         return 1;
        }
     }

Para finalizar la función getDoji, retornaremos 0

   return 0;

A continuación, añadiremos la función createObj con los parámetros time, price, arrowcode, clr y txt usando la función void

void createObj(datetime time, double price, int arrawCode, color clr, string txt)

Luego crearemos la variable de cadena objName y le asignaremos el valor " "

string objName=" ";

Después concatenaremos las cadenas para asignarlas a la variable objName usando la función StringConcatenate, que forma una cadena de parámetros transmitidos ​​y retorna el tamaño de la cadena formada. Parámetros de la función:

  • string_var — cadena que se formará después de la concatenación (objName).
  • argument1 — parámetro de tipo simple, especificaremos el texto "Signal at " para mostrar la señal.
  • argument2 — determina el tiempo de la vela encontrada, tendremos este tiempo de una variable predefinida.
  • argument3 — en tercer lugar, añadiremos el texto " at ".
  • argument4 — luego añadiremos un precio redondeado al texto usando DoubleToString, que convierte un valor double en string.
  • argument5 — añadiremos nuevamente el texto "(".
  • argument6 — asignaremos un valor a una variable entera predefinida (arrowcode). Los códigos se pueden encontrar buscando Wingdings en la guía de ayuda de mql5.
  • argument7 — completaremos el texto ")".
StringConcatenate(objName, "Signal at ",time, " at ",DoubleToString(price,_Digits)," (",arrawCode,")");

A continuación, añadiremos una condición para definir el patrón utilizando la instrucción if y la función ObjectCreate como expresión. La función ObjectCreate crea un objeto utilizando el nombre objName predefinido. Aquí tenemos sus parámetros:

  • chart_id — define el gráfico, usaremos 0 para el gráfico actual.
  • name — nombre del objeto, usaremos el objName predefinido.
  • type — tipo de objeto, nosotros tendremos OBJ_ARROW.
  • nwin — número de la subventana del gráfico en la que trabajaremos, 0 será la ventana principal del gráfico.
  • time1 — tiempo de anclaje, usaremos la variable predefinida time.
  • price1 — precio de anclaje, usaremos la variable price predefinida.
if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))

Si se cumple esta condición, crearemos un objeto. Para hacer esto, deberemos establecer sus propiedades y su forma, además de determinar el código de flecha y su color utilizando la función ObjectSetInteger, que establece el valor de la propiedad del objeto. Parámetros de la función:

  • chart_id — define el gráfico, usaremos 0 para el gráfico actual.
  • name — nombre del objeto, usaremos el objName predefinido.
  • prop_id — identificador de propiedad del objeto, usaremos el valor de la enumeración ENUM_OBJECT_PROPERTY_INTEGER: OBJPROP_ARROWCODE para seleccionar el tipo de objeto y OBJPROP_COLOR para el color.
  • prop_value — valor de la propiedad, arrawCode para el código de flecha y la variable predefinida (clr) para el color.
ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);

Después de eso, crearemos un texto que mostrará información sobre la vela. Luego crearemos la variable de tipo string candleName con las variables predefinidas objName y txt asignadas.

string candleName=objName+txt;

A continuación, crearemos un objeto de texto y usaremos la instrucción if y la función ObjectCreate como expresión, mientras que usaremos el operador ObjectSetString para establecer el valor de cadena de la propiedad del objeto y ObjectSetInteger para determinar el color del objeto de texto.

      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);

Ahora echemos un vistazo a lo que ha ocurrido. El código completo del asesor se ve así:

//+------------------------------------------------------------------+
//|                                        Doji pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
void OnTick()
  {
   getDoji();
  }
int getDoji()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
//Doji
   if(open==close)
     {
      createObj(time,low,217, clrBlack,"Doji");
        {
         return 1;
        }
     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal at ",time, " at ",DoubleToString(price,_Digits)," (",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

Compilamos el código. En este caso, no debería haber errores. Después de ello, el programa aparecerá en el Navegador en el terminal. Lo arrastraremos al gráfico para iniciarlo y obtendremos las señales. El asesor detectará y mostrará el patrón Doji en el gráfico. Aquí tenemos un ejemplo de prueba:

Ejemplo de Doji

Como podemos ver, tenemos un objeto con una flecha negra debajo de la vela y el texto "Doji" que define el patrón de la vela.

Patrón "Martillo"

El martillo es un patrón de velas muy popular que también puede ocurrir en diferentes marcos temporales. Su nombre proviene de su forma: tiene una sombra alargada y un cuerpo pequeño, semejantes a un martillo. Dependiendo de la posición del cuerpo pequeño, existen dos tipos de patrones: el martillo y el martillo invertido. Si tiene una sombra inferior larga y el cuerpo de la vela es más alto, tendremos un martillo, que puede ser alcista o bajista dependiendo del precio de apertura y cierre. Las siguientes figuras son ejemplos del Martillo:

  • Martillo alcista

Martillo alcista

Este patrón indica que el vendedor ha tratado de bajar el precio, pero el comprador tiene el control del mercado. La vela se cierra por encima de la apertura, lo cual indica la fuerza de los compradores.

  • Martillo bajista

Martillo bajista

Este patrón indica que el vendedor ha tratando de bajar el precio y el comprador ha cerrado cerca del precio de apertura, lo cual significa que el comprador todavía está en el juego.

Si una vela tiene una sombra superior larga y su cuerpo se encuentra abajo, tendremos un patrón de martillo invertido y también podrá ser alcista o bajista dependiendo de la posición de los precios de apertura y cierre. Ejemplos de martillo invertido:

  • Martillo invertido alcista

Martillo invertido alcista

Indica que el comprador ha tratado de subir los precios, pero el vendedor ha cerrado la vela alrededor de la apertura y el mínimo, lo cual significa que el vendedor todavía está en el juego a pesar de la fuerza del comprador.

  • Martillo invertido bajista

Martillo invertido bajista

Este patrón indica que el comprador ha tratado de bajar el precio, pero el vendedor tiene el control del mercado. La vela cierra por debajo de la apertura, lo cual indica la fuerza del vendedor.

Este patrón, como todos los patrones de velas japonesas, resultará más significativo al combinarse con otros instrumentos técnicos. 

Para buscar un patrón, determinaremos el precio, el tiempo y el tamaño de la vela, y compararemos el tamaño del cuerpo y las sombras. Si se detecta un patrón de martillo o martillo invertido, en el gráfico se mostrarán una flecha roja o verde y el nombre del patrón.

El código completo del programa tiene el aspecto que sigue:

//+------------------------------------------------------------------+
//|                                      Hammer pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
void OnTick()
  {
   getHammer(0.07,0.7);
  }
int getHammer(double smallShadowRatio, double longShadowRatio)
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double candleSize=high-low;
   if(open<close)
     {
      if(high-close < candleSize*smallShadowRatio)
        {
         if(open-low>candleSize*longShadowRatio)
            createObj(time,low,217, clrGreen,"Hammer");
           {
            return 1;
           }
        }
     }
   if(open>close)
     {
      if(high-open<candleSize*smallShadowRatio)
        {
         if(close-low>candleSize*longShadowRatio)
            createObj(time,high,218,clrRed,"Hammer");
           {
            return 1;
           }
        }
     }
   if(open<close)
     {
      if(open-low < candleSize*smallShadowRatio)
        {
         if(high-close>candleSize*longShadowRatio)
            createObj(time,low,217, clrGreen,"Inverted Hammer");
           {
            return -1;
           }
        }
     }
   if(open>close)
     {
      if(close-low < candleSize*smallShadowRatio)
        {
         if(high-open>candleSize*longShadowRatio)
            createObj(time,high,218, clrRed,"Inverted Hammer");
           {
            return -1;
           }
        }
     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

Cuáles son las diferencias en este código:

Aquí llamaremos a la función getHammer en OnTick() con los parámetros requeridos smallShadowRatio y longShadowRatio definidos.

void OnTick()
  {
   getHammer(0.07,0.7);
  }

Luego crearemos la función getHammer con los parámetros de las dos variables de tipo double smallShadowRatio y longShadowRatio

int getHammer(double smallShadowRatio, double longShadowRatio)

y crearemos una variable double para el tamaño de la vela candleSize que se usará para la comparación

double candleSize=high-low;

Condiciones del patrón "Martillo":

En el caso del martillo alcista (la apertura es menor que el cierre), la última vela deberá ser alcista; la sombra superior de la vela (máximo-cierre) deberá ser menor que el índice de la sombra corta (0,07), mientras que la sombra inferior (apertura-mínimo) deberá ser superior a la proporción de sombra larga (0,7). Después crearemos una flecha verde con el código 217 de Wingdings y un objeto de texto con la etiqueta "Martillo" en el gráfico debajo del mínimo de la vela martillo y finalizaremos la función.

   if(open<close)
     {
      if(high-close < candleSize*smallShadowRatio)
        {
         if(open-low>candleSize*longShadowRatio)
            createObj(time,low,217, clrGreen,"Hammer");
           {
            return 1;
           }
        }
     }

En el caso del martillo bajista (la apertura es más alta que el cierre), la última vela deberá ser bajista; la sombra superior de la vela (máximo-apertura) deberá ser menor que el índice de la sombra corta (0,07), mientras que la sombra inferior (cierre-mínimo) deberá ser mayor que la proporción de la sombra larga (0,7). Luego dibujaremos una flecha roja con el código 218 de Wingdings y un objeto de texto con la etiqueta "Martillo" en el gráfico sobre el máximo de la vela martillo y finalizaremos la función.

   if(open>close)
     {
      if(high-open<candleSize*smallShadowRatio)
        {
         if(close-low>candleSize*longShadowRatio)
            createObj(time,high,218,clrRed,"Hammer");
           {
            return 1;
           }
        }
     }

En el caso de un martillo invertido alcista (la apertura es más baja que el cierre), la última vela deberá ser alcista; la sombra inferior de la vela (apertura-mínimo) deberá ser menor que la proporción de la sombra corta (0,07), mientras que la sombra superior (máximo-cierre) deberá ser mayor que la proporción de la sombra larga (0.7). Después dibujaremos una flecha verde con el código 217 de Wingdings y un objeto de texto con la etiqueta "Martillo invertido" en el gráfico debajo del mínimo de la vela del martillo y finalizaremos la función.

   if(open<close)
     {
      if(open-low < candleSize*smallShadowRatio)
        {
         if(high-close>candleSize*longShadowRatio)
            createObj(time,low,217, clrGreen,"Inverted Hammer");
           {
            return -1;
           }
        }
     }

En el caso del martillo invertido bajista (la apertura es más alta que el cierre), la última vela deberá ser bajista; la sombra inferior de la vela (cierre-mínimo) deberá ser menor que la proporción de la sombra corta (0,07), mientras que la sombra superior (máximo-apertura) deberá ser mayor que la proporción de la sombra larga (0.7). Luego dibujaremos una flecha roja con el código 218 de Wingdings y un objeto de texto con la etiqueta "Martillo invertido" en el gráfico sobre el máximo de la vela martillo y finalizaremos la función.

   if(open>close)
     {
      if(close-low < candleSize*smallShadowRatio)
        {
         if(high-open>candleSize*longShadowRatio)
            createObj(time,high,218, clrRed,"Inverted Hammer");
           {
            return -1;
           }
        }
     }

Editaremos la posición de la flecha y su color dependiendo del tipo de vela usando el operador (if): la expresión será el color, mientras que el operador, si es verdadero, será la posición de la flecha a través de la función ObjectSetInteger.

Si hay una flecha verde debajo de la vela

      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);

Si arriba la vela es roja

      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);

Luego compilaremos el código del asesor y este aparecerá en la ventana del navegador en el terminal, desde donde lo iniciaremos en el gráfico. A continuación, le mostramos un ejemplo de cómo funciona:

  • Martillo alcista:

Ejemplo de martillo alcista

Como podemos ver, tenemos una flecha verde y un objeto de texto verde "Martillo" en el gráfico debajo del mínimo del martillo alcista.

  • Martillo bajista:

Ejemplo de martillo bajista

Aquí se muestra una flecha roja y un objeto de texto rojo "Martillo" en el gráfico sobre el máximo del martillo bajista.

  • Martillo invertido alcista:

Ejemplo de martillo invertido alcista

El gráfico muestra una flecha verde y un objeto de texto verde "Martillo invertido" debajo del mínimo del patrón de martillo alcista.

  • Martillo invertido bajista:

Ejemplo de martillo invertido bajista

Se añadirán una flecha roja y un objeto de texto rojo "Martillo invertido" en el gráfico sobre el máximo del martillo bajista.

Patrones de dos velas

En esta parte, veremos otro tipo de patrones de velas: patrones que constan de dos velas. Analizaremos dos patrones populares: "Envolvente" (alcista y bajista), y "Patrón penetrante" alcista, con el patrón bajista opuesto "Cubierta de nube oscura".

Patrón "Envolvente":

Este patrón de velas es muy popular en el análisis técnico, y se compone de dos velas, una de las cuales absorbe a la otra, es decir tenemos una vela pequeña seguida de una vela grande, y esta vela grande cubre completamente a la pequeña.

El tipo de vela envolvente dependerá del color y la dirección de la misma:

  • Envolvente alcista:

Consta de una pequeña vela bajista seguida de una gran vela alcista, y esta vela alcista engulle por completo a la más pequeña:

Envolvente alcista

Puede indicar que el comprador controla el mercado y el precio puede seguir ascendiendo después de esa vela.

  • Envolvente bajista:

Consta de una pequeña vela alcista seguida de una gran vela bajista, y esta vela bajista engulle por completo a la más pequeña:

Envolvente bajista

Puede indicar que el vendedor tiene el control del mercado y que el precio puede seguir descendiendo después de esa vela.

Ahora vamos a crear un programa para la búsqueda automática de este patrón. Necesitaremos determinar la hora de la última vela y los precios de las dos últimas velas. Para hacer esto, en cada tick verificaremos estos valores y determinaremos las posiciones de las velas entre sí. En base a esto, determinaremos la presencia del tipo de patrón envolvente necesario. Si se detecta un patrón envolvente, mostraremos una señal específica en el gráfico, que consistirá en una flecha de color y un objeto de texto según el tipo de patrón (alcista o bajista).

A continuación, le mostramos el código completo para crear este programa:

//+------------------------------------------------------------------+
//|                                   Engulfing pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
void OnTick()
  {
   getEngulfing();
  }
int getEngulfing()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   if(open<close)
     {
      if(open2>close2)
        {
         if(high>high2&&low<low2)
           {
            if(close>open2&&open<close2)
              {
               createObj(time,low,217, clrGreen,"Bullish Engulfing");
                 {
                  return 1;
                 }
              }
           }
        }
     }
   if(open>close)
     {
      if(open2<close2)
        {
         if(high>high2&&low<low2)
           {
            if(close<open2&&open>close2)
              {
               createObj(time,high,218, clrRed,"Bearish Engulfing");
                 {
                  return -1;
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

Diferencias en este código:

Creamos variables double para la hora de la última vela y el precio de las dos últimas velas para usar en la función getEngulfing. Los parámetros time, open, high, low y close se utilizan para la última vela, mientras que open2, high2, low2 y close2 se utilizan para la penúltima vela.

   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);

Condiciones para identificar este tipo de patrón de velas japonesas

En el caso de la envolvente alcista, la última vela deberá ser alcista (open < close), la penúltima vela deberá ser bajista (open2 > open2), el máximo de la última (high) deberá ser mayor que el máximo de la penúltima (high2), mientras que el mínimo de la última (low) deberá ser menor que el mínimo de la penúltima (low2). Además, el cierre de la última (close) deberá ser mayor que la apertura de la penúltima (open2), mientras que la apertura de la penúltima (open) deberá ser menor que el cierre de la penúltima (close2). Después de definir dicha vela, crearemos un objeto basado en la función creada (createObj) con los siguientes parámetros:

  • time — tiempo de la última vela, predefinido por la variable.
  • price — mínimo de la última vela bajo la cual se reflejará nuestro objeto.
  • arrowCode — flecha con el código 217 Wingdings.
  • clr — color clrGreen.
  • txt — texto "Bullish Engulfing".

Luego finalizaremos la función.

   if(open<close)
     {
      if(open2>close2)
        {
         if(high>high2&&low<low2)
           {
            if(close>open2&&open<close2)
              {
               createObj(time,low,217, clrGreen,"Bullish Engulfing");
                 {
                  return 1;
                 }
              }
           }
        }
     }

En el caso de la envolvente bajista, la última vela deberá bajista (open > close), la penúltima vela deberá ser alcista (open2 < close2), high deberá encontrarse por encima de high2, low deberá estar por debajo de low2, y close deberá estar por debajo de open2, mientras que open deberá encontrarse por encima de close2. Después de definir dicha vela, crearemos un objeto basado en la función creada (createObj) con los siguientes parámetros:

  • time — tiempo de la última vela, predefinido por la variable.
  • price — máximo de la última vela por encima de la cual se reflejará nuestro objeto.
  • arrowCode — flecha con el código 218 Wingdings.
  • clr — color clrRed.
  • txt — texto "Bearish Engulfing".

Luego finalizaremos la función.

   if(open>close)
     {
      if(open2<close2)
        {
         if(high>high2&&low<low2)
           {
            if(close<open2&&open>close2)
              {
               createObj(time,high,218, clrRed,"Bearish Engulfing");
                 {
                  return -1;
                 }
              }
           }
        }
     }

Luego compilaremos el código del asesor y este aparecerá en la ventana del navegador en el terminal, desde donde lo iniciaremos en el gráfico. A continuación, le mostraremos un ejemplo de su funcionamiento:

  • Envolvente alcista:

Ejemplo de envolvente alcista

En el gráfico, tenemos una flecha verde y el texto "Bullish Engulfing" debajo del mínimo de la última vela del patrón.

  • Envolvente bajista:

Ejemplo de envolvente bajista

En el gráfico, vemos una flecha roja y el texto "Bearish Engulfing" por encima del máximo de la última vela del patrón.

"Patrón penetrante" / "Cubierta de nube oscura"

  • "Patrón penetrante"

Este es un patrón alcista que consta de dos velas. La primera es bajista, seguida de una vela alcista con apertura a la baja, luego sube y cierra por encima de la mitad de la primera vela bajista. Aquí tenemos un ejemplo de tal patrón:

Piercing line (Patrón penetrante)

Este patrón indica que el comprador se está volviendo más fuerte y que va controlando el mercado, reemplazando el control del vendedor. Por lo tanto, se refiere a un cambio de la fuerza de la venta a la fuerza de la compra, ya que el comprador ha podido empujar el precio por encima de la mitad de la vela bajista anterior a pesar de que la apertura era más baja.

  • "Cubierta de nube oscura"

El patrón es opuesto al "patrón penetrante". Se trata de un patrón bajista que tiene una estructura de dos velas, la primera de las cuales es alcista, seguida de una vela bajista con una brecha de apertura y un cierre por debajo de la mitad de la primera alcista. Aquí vemos esa vela en el gráfico:

Cubierta de nube oscura

Este patrón indica que el vendedor se está volviendo más fuerte y que va controlando el mercado, reemplazando el control del comprador. Entonces, esta es una transición del poder de los compradores hacia al poder de los vendedores: el vendedor ha podido impulsar el precio por debajo de la mitad de la vela alcista anterior a pesar de que la apertura era más alta.

Ahora vamos a crear un programa para la búsqueda automática de este patrón. Para ello, comprobaremos la hora y los precios de la primera vela (time, open, high, low y close) y los precios de la segunda vela (open2, high2, low2 y close2), así como el tamaño de la primera (candleSize2) y la mitad de la segunda (velaMidPoint2). El programa verificará constantemente estos valores y determinará su posición relativa entre sí. Luego retornaremos una señal determinada que tomará como base ciertas condiciones basadas en un sentimiento alcista o bajista.

A continuación, le mostramos el código completo para crear este programa:

//+------------------------------------------------------------------+
//|                      Piercing && Dark Cloud pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
void OnTick()
  {
   getPiercing();  
  }
int getPiercing()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double candleSize2=high2-low2;
   double candleMidPoint2=high2-(candleSize2/2);
   if(open<close)
     {
      if(open2>close2)
        {
         if(open<low2)
           {
            if(close>candleMidPoint2&&close<high2)
              {
               createObj(time,low,217, clrGreen,"Piercing");
                 {
                  return 1;
                 }
              }
           }
        }
     }
   if(open>close)
     {
      if(open2<close2)
        {
         if(open>high2)
           {
            if(close<candleMidPoint2&&close>low2)
              {
               createObj(time,high,218, clrRed,"Dark Cloud");
                 {
                  return -1;
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

Qué hemos añadido en el código siguiente

La definición de CandleSize2 y CandleMidPoint2

   double candleSize2=high2-low2;
   double candleMidPoint2=high2-(candleSize2/2);

Las condiciones del patrón

En el caso del "Patrón penetrante"

Si la última vela es alcista (open < close), y además open2 es mayor que close2, open es menor que low2 y close es mayor que candleMidPoint2, mientras que close es menor que high2, dibujaremos una flecha verde en el gráfico con el texto "Piercing" debajo de la parte inferior del patrón, después de lo cual finalizaremos la función.

   if(open<close)
     {
      if(open2>close2)
        {
         if(open<low2)
           {
            if(close>candleMidPoint2&&close<high2)
              {
               createObj(time,low,217, clrGreen,"Piercing");
                 {
                  return 1;
                 }
              }
           }
        }
     }

En el caso del patrón "Cubierta de nube oscura":

Si la última vela es bajista (la apertura es más alta que el cierre), y además open2 es menor que close2, open es mayor que high2 y close es menor que CandleMidPoint2, mientras que close es mayor que low2, dibujaremos un objeto en forma de una flecha roja con el texto en el gráfico "Dark cloud" sobre el máximo del patrón, y luego saldremos de la función.

   if(open>close)
     {
      if(open2<close2)
        {
         if(open>high2)
           {
            if(close<candleMidPoint2&&close>low2)
              {
               createObj(time,high,218, clrRed,"Dark Cloud");
                 {
                  return -1;
                 }
              }
           }
        }
     }

Luego compilaremos el código del asesor y este aparecerá en la ventana del navegador en el terminal, desde donde lo iniciaremos en el gráfico. A continuación, le mostraremos un ejemplo de su funcionamiento:

  • "Patrón penetrante"

Ejemplo de "Patrón penetrante"

En el gráfico anterior, tenemos una flecha verde y el texto "Piercing" debajo del mínimo del patrón, que es lo que esperábamos.

  • "Cubierta de nube oscura"

Ejemplo de patrón "Cubierta de nube oscura"

El gráfico ahora tendrá una flecha roja y el texto "Dark cloud" sobre el máximo del patrón, como esperábamos.

Patrones de tres velas

Ahora veremos dos ejemplos de patrones mixtos, el patrón de estrella (matutina y vespertina) y el patrón de tres velas internas (ascendente, descendente).

Patrón de estrella

  • Estrella matutina:

Esta es una estructura de tres velas que consta de una pequeña vela entre dos velas mayores, la primera de las cuales es bajista larga, mientras que la segunda es alcista larga. Aquí vemos esa vela en el gráfico:

Lucero del alba

Este patrón indica un cambio en la fuerza de los vendedores hacia la fuerza de los compradores, ya que el comprador controla el mercado e impulsa el precio hacia arriba después de que haya descendido bajo la presión del vendedor.

  • Patrón de estrella vespertina
Se trata de una estructura de tres velas que consta de una pequeña vela entre dos velas mayores, la primera de las cuales es alcista larga, mientras que la segunda es bajista larga. Aquí vemos una vela así en el gráfico:

Evening star (estrella vespertina)

Este patrón indica un cambio en el poder de los compradores hacia el poder de los vendedores: el vendedor controla el mercado y empuja el precio hacia abajo tras un repunte bajo la presión del comprador.

Vamos a crear un programa que busque automáticamente este patrón. Para hacer esto, deberemos determinar el tiempo y el precio de la última vela y los precios de las dos velas anteriores, y también determinar el tamaño de las últimas tres velas y compararlas entre sí para determinar su relación. En base a esto, determinaremos la presencia del tipo de patrón necesario.

A continuación, le mostramos el código completo para crear este programa:

//+------------------------------------------------------------------+
//|                                        Star pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
void OnTick()
  {
   getStar(0.5);
  }
int getStar(double middleCandleRatio)
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double open3=iOpen(_Symbol,PERIOD_CURRENT,3);
   double high3=iHigh(_Symbol,PERIOD_CURRENT,3);
   double low3=iLow(_Symbol,PERIOD_CURRENT,3);
   double close3=iClose(_Symbol,PERIOD_CURRENT,3);
   double candleSize=high-low;
   double candleSize2=high2-low2;
   double candleSize3=high3-low3;
   if(open<close)
     {
      if(open3>close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj(time,low,217, clrGreen,"Morning Star");
              {
               return 1;
              }
           }
        }

     }
   if(open>close)
     {
      if(open3<close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj(time,high,218, clrRed,"Evening Star");
              {
               return -1;
              }
           }
        }

     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

Qué hemos añadido en el código siguiente

Función getStar con el parámetro middleCandleRatio

int getStar(double middleCandleRatio)

Variables de tiempo para la última vela y los datos de precio (open, high, low, close) y el tamaño de vela para las últimas tres velas (candleSize, candleSize2 y candleSize3)

   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double open3=iOpen(_Symbol,PERIOD_CURRENT,3);
   double high3=iHigh(_Symbol,PERIOD_CURRENT,3);
   double low3=iLow(_Symbol,PERIOD_CURRENT,3);
   double close3=iClose(_Symbol,PERIOD_CURRENT,3);
   double candleSize=high-low;
   double candleSize2=high2-low2;
   double candleSize3=high3-low3;

Las condiciones del patrón

En el caso del patrón Lucero del alba:

Si la última vela es alcista (open < close), la tercera es bajista (open3 > close3), CandleSize2 es menor que el valor de middleCandleRatio de CandleSize, que es 0,5, y al mismo tiempo CandleSize2 es menor que middleCandleRatio de CandleSize3, mostraremos un objeto de flecha verde y el texto "Morning star" debajo del mínimo del patrón, y luego finalizaremos la función.

   if(open<close)
     {
      if(open3>close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj(time,low,217, clrGreen,"Morning Star");
              {
               return 1;
              }
           }
        }
     }

En el caso del patrón Estrella vespertina:

Si la última vela es alcista (open > close), la tercera es bajista (open3 > close3), CandleSize2 es menor que el valor de la proporción de middleCandleRatio de CandleSize, que es 0,5, y CandleSize2 es menor que la proporción de middleCandleRatio de CandleSize3, mostraremos una flecha roja y el texto "Morning star" sobre el máximo del patrón, y luego finalizaremos la función.

   if(open>close)
     {
      if(open3<close3)
        {
         if(candleSize2<candleSize*middleCandleRatio && candleSize2<candleSize3*middleCandleRatio)
           {
            createObj(time,high,218, clrRed,"Evening Star");
              {
               return -1;
              }
           }
        }
     }

Compilación del código del asesor. Después de eso, aparecerá en la ventana del Navegador en el terminal, y desde allí lo iniciaremos en el gráfico. A continuación, le mostraremos un ejemplo de su funcionamiento:

  • Estrella matutina:

Ejemplo de Lucero del alba

El patrón ha sido detectado y también se ha mostrado el objeto necesario en el gráfico:

  • Estrella vespertina:

Ejemplo de estrella vespertina

El patrón ha sido detectado y también se ha mostrado el objeto necesario en el gráfico:

Como nota al margen para el patrón de estrella, la formación del patrón alternativo tiene una brecha con la vela pequeña del medio, podemos añadir esto como una condición adicional al código.

Patrón "Tres velas internas"

  • Tres velas internas hacia arriba:

Este también es un patrón de tres velas: la primera vela es una vela bajista larga, la segunda es una vela alcista pequeña que se negocia dentro de la primera, mientras que la tercera es una vela alcista larga que cierra por encima del máximo de la primera. Aquí tenemos el patrón en el gráfico:

Tres velas internas hacia arriba:

El patrón indica un potencial sentimiento alcista bajo el control del comprador.

  • Tres velas internas hacia abajo:

Este también es un patrón de tres velas: la primera vela es alcista larga, la segunda es una vela bajista pequeña que se negocia dentro de la primera, mientras que la tercera es una vela bajista larga que cierra por debajo del mínimo de la primera. Aquí tenemos el patrón en el gráfico:

Tres velas internas hacia abajo

El patrón indica un posible comportamiento bajista por parte del vendedor. Vamos a crear ahora un programa para buscar automáticamente este patrón. En esencia, determinaremos el tiempo de la última vela y los precios de las últimas tres velas. Para hacer esto, en cada tick verificaremos estos valores y determinaremos sus posiciones entre sí. En base a esto, determinaremos la presencia del tipo de patrón necesario. El código del programa será el que sigue:
//+------------------------------------------------------------------+
//|                                Three inside pattern detector.mq5 |
//|                                  Copyright 2023, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"
void OnTick()
  {
   getthreeInside();
  }
int getthreeInside()
  {
   datetime time=iTime(_Symbol,PERIOD_CURRENT,1);
   double open=iOpen(_Symbol,PERIOD_CURRENT,1);
   double high=iHigh(_Symbol,PERIOD_CURRENT,1);
   double low=iLow(_Symbol,PERIOD_CURRENT,1);
   double close=iClose(_Symbol,PERIOD_CURRENT,1);
   double open2=iOpen(_Symbol,PERIOD_CURRENT,2);
   double high2=iHigh(_Symbol,PERIOD_CURRENT,2);
   double low2=iLow(_Symbol,PERIOD_CURRENT,2);
   double close2=iClose(_Symbol,PERIOD_CURRENT,2);
   double open3=iOpen(_Symbol,PERIOD_CURRENT,3);
   double high3=iHigh(_Symbol,PERIOD_CURRENT,3);
   double low3=iLow(_Symbol,PERIOD_CURRENT,3);
   double close3=iClose(_Symbol,PERIOD_CURRENT,3);
   if(open3>close3)
     {
      if(open2<close2)
        {
         if(open2>low3&&close2<high3)
           {
            if(open<close&&open>open2&&open<close2)
              {
               if(close>high3)
                 {
                  createObj(time,low,217, clrGreen,"3 Inside Up");
                    {
                     return 1;
                    }
                 }
              }
           }
        }

     }
   if(open3<close3)
     {
      if(open2>close2)
        {
         if(open2<high3&&close2>low3)
           {
            if(open>close&&open<open2&&open>close2)
              {
               if(close<low3)
                 {
                  createObj(time,high,218, clrRed,"3 Inside Down");
                    {
                     return -1;
                    }
                 }
              }
           }
        }
     }
   return 0;
  }
void createObj(datetime time, double price, int arrawCode, color clr, string txt)
  {
   string objName=" ";
   StringConcatenate(objName, "Signal@",time, "at",DoubleToString(price,_Digits),"(",arrawCode,")");
   if(ObjectCreate(0,objName,OBJ_ARROW,0,time,price))
     {
      ObjectSetInteger(0,objName,OBJPROP_ARROWCODE,arrawCode);
      ObjectSetInteger(0,objName,OBJPROP_COLOR,clr);
      if(clr==clrGreen)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_TOP);
      if(clr==clrRed)
         ObjectSetInteger(0,objName,OBJPROP_ANCHOR,ANCHOR_BOTTOM);
     }
   string candleName=objName+txt;
   if(ObjectCreate(0,candleName,OBJ_TEXT,0,time,price))
     {
      ObjectSetString(0,candleName,OBJPROP_TEXT," "+txt);
      ObjectSetInteger(0,candleName,OBJPROP_COLOR,clr);
     }
  }

El código se distingue por las condiciones del patrón.

En el caso de "Tres velas internas hacia arriba"

   if(open3>close3)
     {
      if(open2<close2)
        {
         if(open2>low3&&close2<high3)
           {
            if(open<close&&open>open2&&open<close2)
              {
               if(close>high3)
                 {
                  createObj(time,low,217, clrGreen,"3 Inside Up");
                    {
                     return 1;
                    }
                 }
              }
           }
        }

     }

En el caso de "Tres velas internas hacia abajo"

   if(open3<close3)
     {
      if(open2>close2)
        {
         if(open2<high3&&close2>low3)
           {
            if(open>close&&open<open2&&open>close2)
              {
               if(close<low3)
                 {
                  createObj(time,high,218, clrRed,"3 Inside Down");
                    {
                     return -1;
                    }
                 }
              }
           }
        }
     }

Después de compilar el código del asesor, este aparecerá en la ventana del Navegador en el terminal, y lo ejecutaremos en el gráfico. A continuación, le mostraremos un ejemplo de su funcionamiento:

  • Tres velas internas hacia arriba:

Ejemplo de tres velas internas hacia arriba

El patrón ha sido detectado y se muestra en el gráfico.

  • Tres velas internas hacia abajo:

Ejemplo de tres velas internas hacia abajo

Aquí también se detecta el patrón y se muestra este en el gráfico.

Conclusión

Bien, en este artículo, hemos descubierto cómo escribir el código necesario para buscar patrones de velas en sus diversas formaciones, a saber, patrones de velas simples, patrones de dos velas y patrones de tres velas:

  • Patrones de velas simples: cómo encontrar velas Doji y Martillo.
  • Patrones de velas dobles: hemos aprendido a encontrar los patrones Envolvente, Patrón Penetrante y Cubierta de nube oscura.
  • Patrones de tres velas: hemos creado programas para buscar los patrones "Estrella" y "Tres velas internas".

Espero que el artículo le haya resultado útil y le ayude a alcanzar sus objetivos comerciales.

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

Implementando el factor Janus en MQL5 Implementando el factor Janus en MQL5
Gary Anderson desarrolló un método de análisis de mercado basado en una teoría que denominó el factor Janus. La teoría describe un conjunto de indicadores que se pueden usar para identificar tendencias y evaluar el riesgo de mercado. En este artículo, implementaremos dichas herramientas en MQL5.
Teoría de Categorías en MQL5 (Parte 5): Ecualizadores Teoría de Categorías en MQL5 (Parte 5): Ecualizadores
La teoría de categorías es un apartado diverso y en expansión de las matemáticas, que solo recientemente ha comenzado a ser trabajado por la comunidad MQL5. Esta serie de artículos tiene por objetivo repasar algunos de sus conceptos para crear una biblioteca abierta y seguir usando este maravilloso apartado en la creación de estrategias comerciales.
Redes neuronales: así de sencillo (Parte 37): Atención dispersa (Sparse Attention) Redes neuronales: así de sencillo (Parte 37): Atención dispersa (Sparse Attention)
En el artículo anterior, analizamos los modelos relacionales que utilizan mecanismos de atención en su arquitectura. Una de las características de dichos modelos es su mayor uso de recursos informáticos. Este artículo propondrá uno de los posibles mecanismos para reducir el número de operaciones computacionales dentro del bloque Self-Attention o de auto-atención, lo cual aumentará el rendimiento del modelo en su conjunto.
Desarrollo de un sistema de repetición — Simulación de mercado (Parte 06): Primeras mejoras (I) Desarrollo de un sistema de repetición — Simulación de mercado (Parte 06): Primeras mejoras (I)
En este artículo empezaremos a estabilizar todo el sistema, porque sin eso corremos el riesgo de no poder cumplir los siguientes pasos.