Intentando programar un indicador de patrones de vela, hammer, doji, engulfing, etc..

 

Hola a todos, estoy empezando con MQL4 y ante la dificultad de encontrar un buen indicador de patrones de velas, decidí aventurarme a programar uno.

Tengo hecho el código que pego abajo, pero no me funciona y ya estoy estancado.

He comenzado por intentar detectar un patrón de hammer.

Alguien puede echarme una mano con esto. Gracias.

//+------------------------------------------------------------------+
//|                                         PatronesDeCambio.mq4     |
//|                                   Copyright 2024, Juan Martínez  |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red

//---- input parameters
extern double HammerUpperShadowPercent = 50; // Porcentaje máximo permitido de la sombra superior en relación con el cuerpo de la vela
extern double HammerLowerShadowPercent = 66.66; // Porcentaje mínimo permitido de la sombra inferior en relación con la diferencia entre el precio máximo y el precio mínimo

//---- buffers
double HammerBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0, HammerBuffer);
   SetIndexStyle(0, DRAW_ARROW);
   SetIndexArrow(0, 233);
   IndicatorDigits(Digits + 1);
   IndicatorShortName("Hammer Pattern");
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   int limit = MathMax(rates_total - 350, 0); // Limitamos la iteración a las últimas 350 velas
   int counted_bars = IndicatorCounted();
   
   if (counted_bars < 0) 
       return(-1);

   for(int i = rates_total - 1; i >= limit; i--)
   {
      bool isHammer = false;

      // Verificar si la vela actual es alcista
      if (open[i] < close[i]) {
         // Calcular el tamaño del cuerpo de la vela alcista
         double bodySize = close[i] - open[i];
         
         // Calcular el tamaño de la sombra superior e inferior en pips
         double upperShadow = high[i] - MathMax(close[i], open[i]);
         double lowerShadow = MathMin(close[i], open[i]) - low[i];  // CORRECCIÓN: Debe ser precio máximo y mínimo
         
         // Calcular el porcentaje de la sombra superior e inferior en relación con el cuerpo de la vela
         double upperShadowPercent = upperShadow / bodySize * 100;
         double lowerShadowPercent = lowerShadow / (high[i] - low[i]) * 100;  // CORRECCIÓN: Debe ser la diferencia entre precio máximo y mínimo
         
         // Verificar si se cumple la condición del Hammer
         if (upperShadowPercent <= HammerUpperShadowPercent &&
             lowerShadowPercent >= HammerLowerShadowPercent) 
         {
            isHammer = true;
         }
      }
      
      if(isHammer) 
      {
         HammerBuffer[i] = low[i] - 2 * Point; // Dibujar flecha hacia arriba debajo del hammer
         ObjectCreate("HammerLabel_" + IntegerToString(i), OBJ_LABEL, 0, 0, 0);
         ObjectSet("HammerLabel_" + IntegerToString(i), OBJPROP_CORNER, 0);
         ObjectSet("HammerLabel_" + IntegerToString(i), OBJPROP_XDISTANCE, 10);
         ObjectSet("HammerLabel_" + IntegerToString(i), OBJPROP_YDISTANCE, 20);
         ObjectSetText("HammerLabel_" + IntegerToString(i), "Hammer", 10, "Arial", Red);
      }
      else
      {
         HammerBuffer[i] = EMPTY_VALUE;
         ObjectDelete("HammerLabel_" + IntegerToString(i));
      }
   }
   
   return(0);
}
//+------------------------------------------------------------------+
Razón de la queja: