this is a strategy that speacilize in consilidation times:



#property copyright "Copyright 2023, Your Name"
#property link      "https://www.mql5.com"
#property version   "1.04"
#property strict


enum ENUM_LENGTH
{
   LENGTH_1 = 1,
   LENGTH_7 = 7,
   LENGTH_21 = 21,
   LENGTH_50 = 50,
   LENGTH_100 = 100,
   LENGTH_150 = 150,
   LENGTH_200 = 200
};

// Input parameters
input string   Symbol = "EURUSD";     // Trading symbol
input double   GridSpreadPips = 60;   // Grid spread in pips
input int      MaxTradesOpen = 20;    // Maximum number of open trades
input int      MagicNumber = 11223344585; // Magic number for identifying bot trades
input double   RiskPercentage = 100.0; // Total account risk percentage
input ENUM_LENGTH ADXPeriod = LENGTH_1;        // ADX indicator period
input double   ADXThreshold = 25;     // ADX threshold for closing trades
input ENUM_TIMEFRAMES ADXTimeframe = PERIOD_CURRENT; // ADX indicator timeframe

// Global variables
double GridSpreadPoints;
double MiddleOfGrid;
double GridLevels[];
double LotSize;
int ADXHandle;
bool TradingAllowed = true;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   // Convert pips to points
   GridSpreadPoints = GridSpreadPips * 10 * SymbolInfoDouble(Symbol, SYMBOL_POINT);
   
   // Calculate lot size
   LotSize = CalculateLotSize();
   
   // Initialize grid
   MiddleOfGrid = SymbolInfoDouble(Symbol, SYMBOL_BID);
   UpdateGridLevels();
   
   // Initialize ADX indicator
   ADXHandle = iADX(Symbol, ADXTimeframe, ADXPeriod);
   if(ADXHandle == INVALID_HANDLE)
   {
      Print("Error creating ADX indicator: ", GetLastError());
      return(INIT_FAILED);
   }
   
   // Open initial trades if ADX allows
   if(CheckADX())
   {
      OpenBuyOrder(MiddleOfGrid + GridSpreadPoints);
      OpenSellOrder(MiddleOfGrid - GridSpreadPoints);
   }
   
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   // Close all positions if needed
   if(MessageBox("Do you want to close all trades?", "Close Trades", MB_YESNO) == IDYES)
   {
      CloseAllPositions();
   }
   
   // Release the ADX indicator handle
   IndicatorRelease(ADXHandle);
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   if(!CheckADX())
   {
      if(TradingAllowed)
      {
         CloseAllPositions();
         TradingAllowed = false;
         Print("ADX above threshold. Closing all trades and pausing trading.");
      }
      return;
   }
   
   if(!TradingAllowed)
   {
      TradingAllowed = true;
      Print("ADX below threshold. Resuming trading.");
   }
   
   double currentPrice = (SymbolInfoDouble(Symbol, SYMBOL_BID) + SymbolInfoDouble(Symbol, SYMBOL_ASK)) / 2;
   
   if(currentPrice <= GridLevels[0] || currentPrice >= GridLevels[2])
   {
      if(PositionsTotal() + 2 <= MaxTradesOpen)
      {
         Print("Opening new positions... ", Symbol);
         OpenBuyOrder(currentPrice + GridSpreadPoints);
         OpenSellOrder(currentPrice - GridSpreadPoints);
      }
      else
      {
         CloseAllPositions();
      }
      
      MiddleOfGrid = currentPrice;
      UpdateGridLevels();
   }
}

//+------------------------------------------------------------------+
//| Check ADX value                                                  |
//+------------------------------------------------------------------+
bool CheckADX()
{
   double ADXBuffer[];
   ArraySetAsSeries(ADXBuffer, true);
   
   if(CopyBuffer(ADXHandle, 0, 0, 1, ADXBuffer) != 1)
   {
      Print("Error copying ADX buffer: ", GetLastError());
      return false;
   }
   
   return (ADXBuffer[0] < ADXThreshold);
}

//+------------------------------------------------------------------+
//| Calculate lot size based on risk and max trades                  |
//+------------------------------------------------------------------+
double CalculateLotSize()
{
   double accountBalance = AccountInfoDouble(ACCOUNT_BALANCE);
   double leverage = AccountInfoInteger(ACCOUNT_LEVERAGE);
   double includingLeverage = accountBalance * leverage;
   
   string baseCurrency = StringSubstr(Symbol, 0, 3);
   string accountCurrency = AccountInfoString(ACCOUNT_CURRENCY);
   double conversionRate = 1;
   
   if(baseCurrency != accountCurrency)
   {
      string conversionPair = baseCurrency + accountCurrency;
      conversionRate = SymbolInfoDouble(conversionPair, SYMBOL_BID);
      if(conversionRate == 0) // If direct conversion is not available, try inverse
      {
         conversionPair = accountCurrency + baseCurrency;
         conversionRate = 1 / SymbolInfoDouble(conversionPair, SYMBOL_BID);
      }
   }
   
   double lotValueInAccountCurrency = 100000 * conversionRate;
   double lotsInAccount = (includingLeverage * RiskPercentage/100) / lotValueInAccountCurrency;
   
   double lotSizePerTrade = NormalizeDouble(lotsInAccount / MaxTradesOpen, 2);
   
   // Ensure lot size is within allowed limits
   double minLot = SymbolInfoDouble(Symbol, SYMBOL_VOLUME_MIN);
   double maxLot = SymbolInfoDouble(Symbol, SYMBOL_VOLUME_MAX);
   lotSizePerTrade = MathMax(minLot, MathMin(maxLot, lotSizePerTrade));
   
   Print("Calculated Lot Size per trade: ", lotSizePerTrade);
   return lotSizePerTrade;
}

//+------------------------------------------------------------------+
//| Update grid levels                                               |
//+------------------------------------------------------------------+
void UpdateGridLevels()
{
   ArrayResize(GridLevels, 3);
   GridLevels[0] = MiddleOfGrid - GridSpreadPoints;
   GridLevels[1] = MiddleOfGrid;
   GridLevels[2] = MiddleOfGrid + GridSpreadPoints;
}

//+------------------------------------------------------------------+
//| Open a buy order                                                 |
//+------------------------------------------------------------------+
void OpenBuyOrder(double takeProfit)
{
   MqlTradeRequest request = {};
   MqlTradeResult result = {};
   
   request.action = TRADE_ACTION_DEAL;
   request.symbol = Symbol;
   request.volume = LotSize;
   request.type = ORDER_TYPE_BUY;
   request.price = SymbolInfoDouble(Symbol, SYMBOL_ASK);
   request.tp = takeProfit;
   request.magic = MagicNumber;
   
   if(!OrderSend(request, result))
   {
      Print("OrderSend error: ", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Open a sell order                                                |
//+------------------------------------------------------------------+
void OpenSellOrder(double takeProfit)
{
   MqlTradeRequest request = {};
   MqlTradeResult result = {};
   
   request.action = TRADE_ACTION_DEAL;
   request.symbol = Symbol;
   request.volume = LotSize;
   request.type = ORDER_TYPE_SELL;
   request.price = SymbolInfoDouble(Symbol, SYMBOL_BID);
   request.tp = takeProfit;
   request.magic = MagicNumber;
   
   if(!OrderSend(request, result))
   {
      Print("OrderSend error: ", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Close all positions                                              |
//+------------------------------------------------------------------+
void CloseAllPositions()
{
   for(int i = PositionsTotal() - 1; i >= 0; i--)
   {
      ulong ticket = PositionGetTicket(i);
      if(PositionSelectByTicket(ticket))
      {
         MqlTradeRequest request = {};
         MqlTradeResult result = {};
         
         request.action = TRADE_ACTION_DEAL;
         request.position = ticket;
         request.symbol = PositionGetString(POSITION_SYMBOL);
         request.volume = PositionGetDouble(POSITION_VOLUME);
         request.type = PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
         request.price = PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY ? SymbolInfoDouble(Symbol, SYMBOL_BID) : SymbolInfoDouble(Symbol, SYMBOL_ASK);
         request.magic = MagicNumber;
         
         if(!OrderSend(request, result))
         {
            Print("OrderSend error: ", GetLastError());
         }
      }
   }
   LotSize = CalculateLotSize();
}





and this is an indicator that speacalizes in detecting consolidating:
//+------------------------------------------------------------------+
//|                            consilidation X3.mq5                  |
//|                                                                  |
//|                              Copyright 2024, Your Name           |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024"
#property link      ""
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 6
#property indicator_plots   6

//--- Enums for MA types
enum ENUM_MA_TYPE {
    MA_SMA,     // Simple
    MA_EMA,     // Exponential
    MA_SMMA,    // Smoothed
    MA_LWMA     // Linear Weighted
};

//--- plot Ratio1
#property indicator_label1  "Ratio1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

//--- plot Threshold1
#property indicator_label2  "Threshold1"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrRed
#property indicator_style2  STYLE_DASH
#property indicator_width2  1

//--- plot Ratio2
#property indicator_label3  "Ratio2"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrMediumSeaGreen
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1

//--- plot Threshold2
#property indicator_label4  "Threshold2"
#property indicator_type4   DRAW_LINE
#property indicator_color4  clrOrange
#property indicator_style4  STYLE_DASH
#property indicator_width4  1

//--- plot Ratio3
#property indicator_label5  "Ratio3"
#property indicator_type5   DRAW_LINE
#property indicator_color5  clrMagenta
#property indicator_style5  STYLE_SOLID
#property indicator_width5  1

//--- plot Threshold3
#property indicator_label6  "Threshold3"
#property indicator_type6   DRAW_LINE
#property indicator_color6  clrGray
#property indicator_style6  STYLE_DASH
#property indicator_width6  1

//--- input parameters
input int           Period1 = 21;              // Period 1
input ENUM_MA_TYPE  MAType1 = MA_SMA;         // MA Type 1
input double        Threshold1 = 0.25;          // Threshold 1
input int           Period2 = 52;              // Period 2
input ENUM_MA_TYPE  MAType2 = MA_EMA;         // MA Type 2
input double        Threshold2 = 0.15;          // Threshold 2
input int           Period3 = 120;              // Period 3
input ENUM_MA_TYPE  MAType3 = MA_SMMA;        // MA Type 3
input double        Threshold3 = 0.1;          // Threshold 3
input int           SmoothingPeriod = 3;       // Smoothing Period
input ENUM_MA_TYPE  SmoothingMAType = MA_EMA;  // Smoothing MA Type
input color         RectangleColor = clrGreen; // Rectangle Color
input double        RectangleOpacity = 0.2;    // Rectangle Opacity (0.0-1.0)

//--- indicator buffers
double         Ratio1Buffer[];
double         Threshold1Buffer[];
double         Ratio2Buffer[];
double         Threshold2Buffer[];
double         Ratio3Buffer[];
double         Threshold3Buffer[];
double         TempBuffer[];  // Additional buffer for smoothing calculations

//--- Global variables for rectangle drawing
string         rectPrefix = "ConsolidationRect_";
datetime       consolidationStart = 0;
bool           inConsolidation = false;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                           |
//+------------------------------------------------------------------+
int OnInit() {
    //--- indicator buffers mapping
    SetIndexBuffer(0, Ratio1Buffer, INDICATOR_DATA);
    SetIndexBuffer(1, Threshold1Buffer, INDICATOR_DATA);
    SetIndexBuffer(2, Ratio2Buffer, INDICATOR_DATA);
    SetIndexBuffer(3, Threshold2Buffer, INDICATOR_DATA);
    SetIndexBuffer(4, Ratio3Buffer, INDICATOR_DATA);
    SetIndexBuffer(5, Threshold3Buffer, INDICATOR_DATA);
    
    //--- Set drawing begin
    PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, Period1);
    PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, Period2);
    PlotIndexSetInteger(4, PLOT_DRAW_BEGIN, Period3);
    
    //--- set accuracy
    IndicatorSetInteger(INDICATOR_DIGITS, 4);
    
    //--- set empty values
    PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetDouble(3, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetDouble(4, PLOT_EMPTY_VALUE, 0.0);
    PlotIndexSetDouble(5, PLOT_EMPTY_VALUE, 0.0);
    
    //--- set indicator name
    string short_name = "Triple Consolidation Ratio (Smoothed)";
    IndicatorSetString(INDICATOR_SHORTNAME, short_name);
    
    // Delete any existing rectangles
    DeleteAllRectangles();
    
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                         |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
    DeleteAllRectangles();
}

//+------------------------------------------------------------------+
//| Calculate MA based on type                                         |
//+------------------------------------------------------------------+
double CalculateMA(const double &values[], int position, int period, ENUM_MA_TYPE maType) {
    if(position < period - 1) return 0;
    
    double ma = 0;
    double sum = 0;
    double weight = 0;
    double weightSum = 0;
    
    switch(maType) {
        case MA_SMA: {
            for(int i = 0; i < period; i++)
                sum += values[position - i];
            ma = sum / period;
            break;
        }
        
        case MA_EMA: {
            double alpha = 2.0 / (period + 1.0);
            ma = values[position];
            for(int i = 1; i < period; i++)
                ma = (values[position - i] * alpha) + (ma * (1.0 - alpha));
            break;
        }
        
        case MA_SMMA: {
            double alpha = 1.0 / period;
            ma = values[position];
            for(int i = 1; i < period; i++)
                ma = (values[position - i] * alpha) + (ma * (1.0 - alpha));
            break;
        }
        
        case MA_LWMA: {
            for(int i = 0; i < period; i++) {
                weight = period - i;
                sum += values[position - i] * weight;
                weightSum += weight;
            }
            ma = sum / weightSum;
            break;
        }
    }
    
    return ma;
}

//+------------------------------------------------------------------+
//| Calculate consolidation ratio for given period and MA type         |
//+------------------------------------------------------------------+
double CalculateRatio(const double &open[], const double &close[], int position, 
                     int period, ENUM_MA_TYPE maType) {
    if(position < period) return 0;
    
    double ranges[];
    ArrayResize(ranges, period);
    ArrayInitialize(ranges, 0);
    
    // Calculate ranges
    for(int i = 0; i < period; i++) {
        ranges[i] = MathAbs(open[position-i] - close[position-i]);
    }
    
    // Calculate average range using specified MA type
    double avgRange = CalculateMA(ranges, period-1, period, maType);
    if(avgRange == 0) return 0;
    
    // Calculate expected total range
    double expectedRange = avgRange * period;
    
    // Calculate actual price change
    double actualChange = MathAbs(close[position] - close[position - period]);
    
    // Return ratio
    return actualChange / expectedRange;
}

//+------------------------------------------------------------------+
//| Delete all rectangles drawn by the indicator                       |
//+------------------------------------------------------------------+
void DeleteAllRectangles() {
    ObjectsDeleteAll(0, rectPrefix);
}

//+------------------------------------------------------------------+
//| Check if all ratios indicate consolidation                         |
//+------------------------------------------------------------------+
bool IsConsolidating(int position) {
    if(position < 0) return false;
    
    return Ratio1Buffer[position] < Threshold1 &&
           Ratio2Buffer[position] < Threshold2 &&
           Ratio3Buffer[position] < Threshold3;
}

//+------------------------------------------------------------------+
//| Draw or update consolidation rectangle                             |
//+------------------------------------------------------------------+
void ManageConsolidationRectangle(const datetime &time[], const double &high[], const double &low[], 
                                 int position, bool isConsolidating) {
    if(position < 0) return;
    
    long chartId = ChartID();
    
    if(isConsolidating) {
        if(!inConsolidation) {
            consolidationStart = time[position];
            inConsolidation = true;
        }
        
        string rectName = rectPrefix + TimeToString(consolidationStart);
        
        if(ObjectFind(chartId, rectName) < 0) {
            ObjectCreate(chartId, rectName, OBJ_RECTANGLE, 0, 
                        consolidationStart, high[position], 
                        time[position], low[position]);
            
            uint alpha = (uint)(255 * RectangleOpacity);
            color rectColorWithAlpha = (RectangleColor & 0xFFFFFF) | (alpha << 24);
            
            ObjectSetInteger(chartId, rectName, OBJPROP_COLOR, rectColorWithAlpha);
            ObjectSetInteger(chartId, rectName, OBJPROP_FILL, true);
            ObjectSetInteger(chartId, rectName, OBJPROP_BACK, true);
            ObjectSetInteger(chartId, rectName, OBJPROP_SELECTABLE, false);
            ObjectSetInteger(chartId, rectName, OBJPROP_HIDDEN, true);
        }
        else {
            double currentHigh = ObjectGetDouble(chartId, rectName, OBJPROP_PRICE, 0);
            double currentLow = ObjectGetDouble(chartId, rectName, OBJPROP_PRICE, 1);
            
            ObjectSetDouble(chartId, rectName, OBJPROP_PRICE, 0, MathMax(high[position], currentHigh));
            ObjectSetDouble(chartId, rectName, OBJPROP_PRICE, 1, MathMin(low[position], currentLow));
            ObjectSetInteger(chartId, rectName, OBJPROP_TIME, 1, time[position]);
        }
    }
    else {
        inConsolidation = false;
        consolidationStart = 0;
    }
}

//+------------------------------------------------------------------+
//| 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 minimum rates
    int maxPeriod = MathMax(MathMax(Period1, Period2), Period3);
    if(rates_total <= maxPeriod) return(0);
    
    //--- calculate starting position
    int start = (prev_calculated > 0) ? prev_calculated - 1 : 0;
    
    //--- Initialize arrays if first calculation
    if(prev_calculated <= 0) {
        ArrayInitialize(Ratio1Buffer, 0.0);
        ArrayInitialize(Ratio2Buffer, 0.0);
        ArrayInitialize(Ratio3Buffer, 0.0);
        ArrayInitialize(Threshold1Buffer, Threshold1);
        ArrayInitialize(Threshold2Buffer, Threshold2);
        ArrayInitialize(Threshold3Buffer, Threshold3);
    }
    
    //--- main calculation loop
    for(int i = start; i < rates_total && !IsStopped(); i++) {
        // Calculate ratios
        double ratio1 = CalculateRatio(open, close, i, Period1, MAType1);
        double ratio2 = CalculateRatio(open, close, i, Period2, MAType2);
        double ratio3 = CalculateRatio(open, close, i, Period3, MAType3);
        
        // Apply smoothing only if we have enough data
        if(i >= SmoothingPeriod) {
            Ratio1Buffer[i] = ratio1;
            Ratio2Buffer[i] = ratio2;
            Ratio3Buffer[i] = ratio3;
            
            if(SmoothingPeriod > 1) {
                ArrayCopy(TempBuffer, Ratio1Buffer);
                Ratio1Buffer[i] = CalculateMA(TempBuffer, i, SmoothingPeriod, SmoothingMAType);
                
                ArrayCopy(TempBuffer, Ratio2Buffer);
                Ratio2Buffer[i] = CalculateMA(TempBuffer, i, SmoothingPeriod, SmoothingMAType);
                
                ArrayCopy(TempBuffer, Ratio3Buffer);
                Ratio3Buffer[i] = CalculateMA(TempBuffer, i, SmoothingPeriod, SmoothingMAType);
            }
        }
        
        // Set threshold values
        Threshold1Buffer[i] = Threshold1;
        Threshold2Buffer[i] = Threshold2;
        Threshold3Buffer[i] = Threshold3;
        
        // Check consolidation and manage rectangle
        bool isConsolidating = IsConsolidating(i);
        ManageConsolidationRectangle(time, high, low, i, isConsolidating);
    }
    
    //--- return value of prev_calculated for next call
    return(rates_total);
}
//+------------------------------------------------------------------+


can you combine integrate them to one another?