//+------------------------------------------------------------------+
//|                                               Fractals_DD_DB.mq4 |
//|                                          Copyright 2022 mql5.com |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2022 mql5.com"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 2

//+------------------------------------------------------------------+
string Indi_ID = "Fractals_DD_DB";
double   dw[], up[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexStyle(0,DRAW_ARROW,0,3,clrBlue);
   SetIndexBuffer(0,dw);
   SetIndexArrow(0,233);
   SetIndexStyle(1,DRAW_ARROW,0,3,clrRed);
   SetIndexBuffer(1,up);
   SetIndexArrow(1,234);
   
//---
   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 = 0;

    // Handling first calculation or recalculation
    if (prev_calculated == 0) 
    {
        limit = rates_total - 1;  // Process all bars for the first time
    } 
    else 
    {
        limit = rates_total - prev_calculated;  // Process only new bars
    }
   
   for(int i=limit; i>=0; i--)
     {
      dw[i] = iFractals(NULL,0,MODE_LOWER,i);
      up[i] = iFractals(NULL,0,MODE_UPPER,i);
     }    
     
    int lastLowIndex = -1;
    int lastHighIndex = -1;

    if(IsNewBar(_Period))
     {
    // Loop through bars to find fractal lows and plot sections
    for(int i = limit - 1; i >= 0; i--)
    {
        double lowFractal = iFractals(NULL, 0, MODE_LOWER, i);

        if(lowFractal != 0.0)
        {
            if(lastLowIndex != -1)  // Check if we have a previous fractal low
            {
                double prevLowFractal = iFractals(NULL, 0, MODE_LOWER, lastLowIndex);
                if(lowFractal > prevLowFractal)  // Higher low found
                {
                    // Draw section between the two fractals
                    string lineName = Indi_ID+"_LowSection_" + IntegerToString(i);
                   if(ObjectFind(ChartID(),lineName)<0)
                    { 
                    if (!ObjectCreate(lineName, OBJ_TREND, 0, time[i], lowFractal, time[lastLowIndex], prevLowFractal))
                    {
                        Print("Error creating object: ", lineName);
                    }
                        // Set line properties
                        ObjectSetInteger(0, lineName, OBJPROP_RAY_RIGHT, false);
                        ObjectSetInteger(0, lineName, OBJPROP_COLOR, clrBlue);
                        ObjectSetInteger(0, lineName, OBJPROP_WIDTH, 2);
                        ObjectSetInteger(0, lineName, OBJPROP_STYLE, STYLE_SOLID);
                    }
                }
            }
            lastLowIndex = i;  // Update the lastLowIndex
        }
    }

    // Loop through bars to find fractal highs and plot sections
    for(int i = limit - 1; i >= 0; i--)
    {
        double highFractal = iFractals(NULL, 0, MODE_UPPER, i);

        if(highFractal != 0.0)
        {
            if(lastHighIndex != -1)  // Check if we have a previous fractal high
            {
                double prevHighFractal = iFractals(NULL, 0, MODE_UPPER, lastHighIndex);
                if(highFractal < prevHighFractal)  // Lower high found
                {
                    // Draw section between the two fractals
                    string lineName = Indi_ID+"_HighSection_" + IntegerToString(i);
                   if(ObjectFind(ChartID(),lineName)<0)
                    {
                    if (!ObjectCreate(lineName, OBJ_TREND, 0, time[i], highFractal, time[lastHighIndex], prevHighFractal))
                    {
                        Print("Error creating object: ", lineName);
                    }
                        // Set line properties
                        ObjectSetInteger(0, lineName, OBJPROP_RAY_RIGHT, false);
                        ObjectSetInteger(0, lineName, OBJPROP_COLOR, clrRed);
                        ObjectSetInteger(0, lineName, OBJPROP_WIDTH, 2);
                        ObjectSetInteger(0, lineName, OBJPROP_STYLE, STYLE_SOLID);
                    }
                }
            }
            lastHighIndex = i;  // Update the lastHighIndex
        }
    }
     }

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//----
               objectsDelete(Indi_ID);
//----
  }
//+------------------------------------------------------------------+
void objectsDelete(string name)
{
   int objTotal = ObjectsTotal();
   for(int i=objTotal-1; i>=0; i--)  
  {
      string objName = ObjectName(i);
      if(StringFind(objName,name,0) >= 0)
       ObjectDelete(0,objName);
   }
}
//+------------------------------------------------------------------+
bool IsNewBar(int per)
{ 
  static datetime Trend_Candle_prevTime1 = -1;
  
  if(Trend_Candle_prevTime1 != iTime(_Symbol,per,6))
  { 
   Trend_Candle_prevTime1 = iTime(_Symbol,per,6); 
       
   return(true);  
  } 

  return(false); 
}
//+------------------------------------------------------------------+
