//+------------------------------------------------------------------+
//|                                           EnhancedMPO_Consolidation.mq5 |
//|                                          ©2023 Your Name or Firm  |
//+------------------------------------------------------------------+
#property copyright "©2023 Your Name or Firm"
#property link      "yourwebsite.com"
#property version   "2.01"
#property description "Enhanced Market Phase Oscillator (MPO) for Consolidation Detection"

#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots   4
#property indicator_minimum 0

//--- Plot settings
#property indicator_label1  "MPO"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2

#property indicator_label2  "Bollinger Upper"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrGray
#property indicator_style2  STYLE_DOT
#property indicator_width2  1

#property indicator_label3  "Bollinger Lower"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrGray
#property indicator_style3  STYLE_DOT
#property indicator_width3  1

#property indicator_label4  "Consolidation"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  clrRed
#property indicator_style4  STYLE_SOLID
#property indicator_width4  2

//--- Arrow code for consolidation signals (Wingdings font)
#define ARROW_CODE  234  // Wingdings code for downward arrow

//--- Input parameters
input int InpPeriodADX      = 14;          // Period for ADX
input int InpPeriodATR      = 14;          // Period for ATR
input int InpPeriodBB       = 20;          // Period for Bollinger Bands
input double InpBBDeviation  = 2.0;         // Deviation for Bollinger Bands
input int InpPeriodRSI      = 14;          // Period for RSI
input int InpThresholdRSI   = 10;          // RSI Threshold range around 50 for consolidation
input ENUM_TIMEFRAMES InpTimeframe = PERIOD_CURRENT; // Timeframe

//--- Indicator buffers
double MPOBuffer[];
double BBUpperBuffer[];
double BBLowerBuffer[];
double ConsolidationBuffer[];

//--- Indicator handles
int ATR_Handle;
int ADX_Handle;
int BB_Handle;
int RSI_Handle;

//--- Arrays for indicator data
double ATRBuffer[];
double ADXBuffer[];
double BBUpperRaw[];
double BBLowerRaw[];
double RSIBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
   //--- Set buffers
   SetIndexBuffer(0, MPOBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, BBUpperBuffer, INDICATOR_DATA);
   SetIndexBuffer(2, BBLowerBuffer, INDICATOR_DATA);
   SetIndexBuffer(3, ConsolidationBuffer, INDICATOR_DATA);
   
   //--- Set Arrow properties for Consolidation
   SetIndexArrow(3, ARROW_CODE);
   PlotIndexSetInteger(3, PLOT_ARROW, 234); // Using Wingdings arrow code
   
   //--- Indicator properties
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
   
   //--- Create ATR handle
   ATR_Handle = iATR(_Symbol, InpTimeframe, InpPeriodATR);
   if(ATR_Handle == INVALID_HANDLE)
     {
      Print("Failed to create ATR indicator handle. Error: ", GetLastError());
      return(INIT_FAILED);
     }
   
   //--- Create ADX handle
   ADX_Handle = iADX(_Symbol, InpTimeframe, InpPeriodADX);
   if(ADX_Handle == INVALID_HANDLE)
     {
      Print("Failed to create ADX indicator handle. Error: ", GetLastError());
      IndicatorRelease(ATR_Handle);
      return(INIT_FAILED);
     }
   
   //--- Create Bollinger Bands handle (Upper buffer index = 0, Lower buffer index = 2)
   BB_Handle = iBands(_Symbol, InpTimeframe, InpPeriodBB, 0, InpBBDeviation, PRICE_CLOSE);
   if(BB_Handle == INVALID_HANDLE)
     {
      Print("Failed to create Bollinger Bands handle. Error: ", GetLastError());
      IndicatorRelease(ATR_Handle);
      IndicatorRelease(ADX_Handle);
      return(INIT_FAILED);
     }
   
   //--- Create RSI handle
   RSI_Handle = iRSI(_Symbol, InpTimeframe, InpPeriodRSI, PRICE_CLOSE);
   if(RSI_Handle == INVALID_HANDLE)
     {
      Print("Failed to create RSI handle. Error: ", GetLastError());
      IndicatorRelease(ATR_Handle);
      IndicatorRelease(ADX_Handle);
      IndicatorRelease(BB_Handle);
      return(INIT_FAILED);
     }
   
   //--- Set indicator levels (Optional: Add threshold lines)
   IndicatorSetInteger(INDICATOR_LEVELS, 2);
   IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, 15.0);
   IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, 30.0);
   IndicatorSetInteger(INDICATOR_LEVELCOLOR, 0, clrRed);
   IndicatorSetInteger(INDICATOR_LEVELCOLOR, 1, clrGreen);
   IndicatorSetInteger(INDICATOR_LEVELWIDTH, 0, 1);
   IndicatorSetInteger(INDICATOR_LEVELWIDTH, 1, 1);
   IndicatorSetInteger(INDICATOR_LEVELSTYLE, 0, STYLE_DASH);
   IndicatorSetInteger(INDICATOR_LEVELSTYLE, 1, STYLE_DASH);
   
   return(INIT_SUCCEEDED);
  }
  
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   //--- Release indicator handles
   if(ATR_Handle != INVALID_HANDLE)
      IndicatorRelease(ATR_Handle);
   if(ADX_Handle != INVALID_HANDLE)
      IndicatorRelease(ADX_Handle);
   if(BB_Handle != INVALID_HANDLE)
      IndicatorRelease(BB_Handle);
   if(RSI_Handle != INVALID_HANDLE)
      IndicatorRelease(RSI_Handle);
  }
  
//+------------------------------------------------------------------+
//| 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[])
  {
   //--- Check for sufficient bars
   int required_bars = MathMax(MathMax(InpPeriodADX, InpPeriodATR), MathMax(InpPeriodBB, InpPeriodRSI)) + 10; // Extra buffer
   if(rates_total < required_bars)
      return(0);
   
   //--- Determine the start position for calculation
   int start = 0;
   if(prev_calculated > 0)
      start = prev_calculated - 1;
   else
      start = required_bars;
   
   //--- Declare dynamic threshold variables
   double ADX_MA, ATR_MA;
   int threshold_period = InpPeriodADX; // Example period for MA
   
   //--- Calculate Moving Averages for dynamic thresholds
   //--- ADX Moving Average
   ADX_MA = 0.0;
   if(CopyBuffer(ADX_Handle, 0, 0, threshold_period, &ADXBuffer) > 0)
     {
      for(int i = 0; i < threshold_period; i++)
        {
         ADX_MA += ADXBuffer[i];
        }
      ADX_MA /= threshold_period;
     }
   else
     {
      Print("Failed to copy ADX buffer for MA calculation. Error: ", GetLastError());
      return(prev_calculated);
     }
   
   //--- ATR Moving Average
   ATR_MA = 0.0;
   if(CopyBuffer(ATR_Handle, 0, 0, threshold_period, &ATRBuffer) > 0)
     {
      for(int i = 0; i < threshold_period; i++)
        {
         ATR_MA += ATRBuffer[i];
        }
      ATR_MA /= threshold_period;
     }
   else
     {
      Print("Failed to copy ATR buffer for MA calculation. Error: ", GetLastError());
      return(prev_calculated);
     }
   
   //--- Copy Bollinger Bands Upper (buffer 0) and Lower (buffer 2)
   if(CopyBuffer(BB_Handle, 0, 0, rates_total, BBUpperRaw) <= 0)
     {
      Print("Failed to copy Bollinger Bands Upper. Error: ", GetLastError());
      return(prev_calculated);
     }
   
   if(CopyBuffer(BB_Handle, 2, 0, rates_total, BBLowerRaw) <= 0)
     {
      Print("Failed to copy Bollinger Bands Lower. Error: ", GetLastError());
      return(prev_calculated);
     }
   
   //--- Copy RSI data
   if(CopyBuffer(RSI_Handle, 0, 0, rates_total, RSIBuffer) <= 0)
     {
      Print("Failed to copy RSI data. Error: ", GetLastError());
      return(prev_calculated);
     }
   
   //--- Copy ADX data
   if(CopyBuffer(ADX_Handle, 0, 0, rates_total, ADXBuffer) <= 0)
     {
      Print("Failed to copy ADX data. Error: ", GetLastError());
      return(prev_calculated);
     }
   
   //--- Copy ATR data
   if(CopyBuffer(ATR_Handle, 0, 0, rates_total, ATRBuffer) <= 0)
     {
      Print("Failed to copy ATR data. Error: ", GetLastError());
      return(prev_calculated);
     }
   
   //--- Calculate MPO and Consolidation
   for(int i = start; i < rates_total; i++)
     {
      //--- Calculate MPO
      if(ATRBuffer[i] != 0.0)
         MPOBuffer[i] = (ADXBuffer[i] / ATRBuffer[i]) / 100.0;
      else
         MPOBuffer[i] = 0.0;
      
      //--- Assign Bollinger Bands
      BBUpperBuffer[i] = BBUpperRaw[i];
      BBLowerBuffer[i] = BBLowerRaw[i];
      
      //--- Consolidation Logic:
      // 1. MPO below a certain dynamic threshold (indicating low market phase)
      // 2. Bollinger Bands are narrow (low volatility)
      // 3. RSI is near the neutral level (e.g., between 50 - InpThresholdRSI/2 and 50 + InpThresholdRSI/2)
      // 4. ADX below a dynamic threshold
      
      bool isLowMPO = MPOBuffer[i] < (ADX_MA / ATR_MA) * 0.8; // Adjust multiplier as needed
      bool isNarrowBB = (BBUpperRaw[i] - BBLowerRaw[i]) < ATR_MA * 0.5; // Example: BB width less than half ATR MA
      bool isNeutralRSI = (RSIBuffer[i] > (50 - InpThresholdRSI/2)) && (RSIBuffer[i] < (50 + InpThresholdRSI/2));
      bool isADXLow = ADXBuffer[i] < ADX_MA * 1.2; // Adjust multiplier as needed
      
      if(isLowMPO && isNarrowBB && isNeutralRSI && isADXLow)
        {
         //--- Mark consolidation with an arrow below the bar
         ConsolidationBuffer[i] = low[i] - (ATRBuffer[i] * 0.2); // Position the arrow slightly below the low
        }
      else
        {
         ConsolidationBuffer[i] = EMPTY_VALUE;
        }
     }
   
   return(rates_total);
  }

//+------------------------------------------------------------------+


'consolidation.mq5'			1
'SetIndexArrow' - undeclared identifier	consolidation.mq5	83	4
',' - unexpected token	consolidation.mq5	83	19
'3' - some operator expected	consolidation.mq5	83	18
')' - unexpected token	consolidation.mq5	83	31
'ADXBuffer' - invalid array access	consolidation.mq5	190	55
'&' - illegal operation use	consolidation.mq5	190	54
'ADXBuffer' - class type expected	consolidation.mq5	190	55
'CopyBuffer' - no one of the overloads can be applied to the function call	consolidation.mq5	190	7
could be one of 3 function(s)	consolidation.mq5	190	7
   built-in: int CopyBuffer(int,int,int,int,double&[])	consolidation.mq5	190	7
   built-in: int CopyBuffer(int,int,datetime,int,double&[])	consolidation.mq5	190	7
   built-in: int CopyBuffer(int,int,datetime,datetime,double&[])	consolidation.mq5	190	7
'ATRBuffer' - invalid array access	consolidation.mq5	206	55
'&' - illegal operation use	consolidation.mq5	206	54
'ATRBuffer' - class type expected	consolidation.mq5	206	55
'CopyBuffer' - no one of the overloads can be applied to the function call	consolidation.mq5	206	7
could be one of 3 function(s)	consolidation.mq5	206	7
   built-in: int CopyBuffer(int,int,int,int,double&[])	consolidation.mq5	206	7
   built-in: int CopyBuffer(int,int,datetime,int,double&[])	consolidation.mq5	206	7
   built-in: int CopyBuffer(int,int,datetime,datetime,double&[])	consolidation.mq5	206	7
12 errors, 0 warnings		13	1


fix the errors and make it that it will make a rectangle n the chart where there is a consolidation