Code for lateralization zones

 

Does anyone know a code that identifies sideways trading zones on the chart? It would be for EURUSD and USDXJPY.

The moderator has applied automatic translation. On the English forum, please write in English.

 
lcdeus87:

Does anyone know a code that identifies sideways trading zones on the chart? It would be for EURUSD and USDXJPY.

Code Base

ATR Cycles

Ryan L Johnson, 2025.11.08 14:29

A volatility filter based on 3 ATR's: a fast ATR, a middle ATR, and a slow ATR

 
lcdeus87:

Does anyone know a code that identifies sideways trading zones on the chart? It would be for EURUSD and USDXJPY.

I thought this was a great idea so I quickly coded it up for you and the community!

It's an MQL5 indicator that automatically detects and draws sideways zones on your chart, works great for EURUSD and USDJPY. It uses ADX to group consecutive ranging candles into clean zones with support and resistance lines, fully visible across history.

Key settings:

  • InpADXThresh — lower = stricter zones (10–15 for really flat ranges)
  • InpMinBars — minimum candles needed to qualify as a zone
  • InpPeriod — ADX period (20 works well on every timeframe)

//+------------------------------------------------------------------+
//|        Sideways Zone Detector v2 - MQL5                          |
//+------------------------------------------------------------------+
#property copyright   "Thomas Eduard at your service"
#property version     "2.00"
#property indicator_chart_window
#property indicator_buffers 0
#property indicator_plots   0

// --- Inputs ---
input int    InpPeriod    = 20;             // ADX periode
input double InpADXThresh = 25.0;          // ADX drempel (onder = sideways)
input color  InpZoneColor = clrDodgerBlue; // Zone vulkleur
input color  InpResColor  = clrRed;        // Weerstandslijn
input color  InpSupColor  = clrLime;       // Steunlijn
input int    InpMinBars   = 5;             // Minimaal bars per zone
input int    InpMaxZones  = 100;           // Max zones in geschiedenis

int adxHandle;

//+------------------------------------------------------------------+
int OnInit()
  {
   adxHandle = iADX(_Symbol, _Period, InpPeriod);
   if(adxHandle == INVALID_HANDLE)
     {
      Print("Fout: ADX handle aanmaken mislukt");
      return INIT_FAILED;
     }
   return INIT_SUCCEEDED;
  }

//+------------------------------------------------------------------+
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[])
  {
   if(rates_total < InpPeriod + 1) return 0;
   if(prev_calculated == rates_total) return rates_total;

   // --- Data kopiëren als series (index 0 = nieuwste bar) ---
   double adxBuf[], highArr[], lowArr[];
   datetime timeArr[];

   ArraySetAsSeries(adxBuf, true);
   if(CopyBuffer(adxHandle, 0, 0, rates_total, adxBuf) <= 0)
      return 0;

   ArrayCopy(highArr, high);
   ArrayCopy(lowArr,  low);
   ArrayCopy(timeArr, time);
   ArraySetAsSeries(highArr, true);
   ArraySetAsSeries(lowArr,  true);
   ArraySetAsSeries(timeArr, true);

   // --- Alle oude objecten verwijderen ---
   ObjectsDeleteAll(0, "sz_");

   // --- Zones detecteren en tekenen ---
   int zoneCount = 0;
   int i = 0;

   while(i < rates_total - InpPeriod && zoneCount < InpMaxZones)
     {
      if(adxBuf[i] < InpADXThresh)
        {
         // Begin van een sideways zone
         int    zoneEnd = i;
         double zHigh   = highArr[i];
         double zLow    = lowArr[i];

         // Alle opeenvolgende sideways-bars samenvoegen
         while(i < rates_total - InpPeriod && adxBuf[i] < InpADXThresh)
           {
            if(highArr[i] > zHigh) zHigh = highArr[i];
            if(lowArr[i]  < zLow)  zLow  = lowArr[i];
            i++;
           }
         int zoneStart = i - 1; // oudste bar van de zone

         int barCount = zoneStart - zoneEnd + 1;
         if(barCount >= InpMinBars)
           {
            datetime t1 = timeArr[zoneStart];                  // oudste tijd
            datetime t2 = timeArr[zoneEnd] + PeriodSeconds();  // nieuwste tijd + 1 bar

            string zName  = "sz_rect_"  + IntegerToString(zoneCount);
            string hName  = "sz_high_"  + IntegerToString(zoneCount);
            string lName  = "sz_low_"   + IntegerToString(zoneCount);
            string lbName = "sz_label_" + IntegerToString(zoneCount);

            // --- Gevulde zone rechthoek ---
            ObjectCreate(0, zName, OBJ_RECTANGLE, 0, t1, zLow, t2, zHigh);
            ObjectSetInteger(0, zName, OBJPROP_COLOR,      ColorToARGB(InpZoneColor, 40));
            ObjectSetInteger(0, zName, OBJPROP_FILL,       true);
            ObjectSetInteger(0, zName, OBJPROP_BACK,       true);
            ObjectSetInteger(0, zName, OBJPROP_SELECTED,   false);
            ObjectSetInteger(0, zName, OBJPROP_SELECTABLE, false);

            // --- Weerstandslijn (boven) ---
            ObjectCreate(0, hName, OBJ_TREND, 0, t1, zHigh, t2, zHigh);
            ObjectSetInteger(0, hName, OBJPROP_COLOR,      InpResColor);
            ObjectSetInteger(0, hName, OBJPROP_WIDTH,      2);
            ObjectSetInteger(0, hName, OBJPROP_STYLE,      STYLE_SOLID);
            ObjectSetInteger(0, hName, OBJPROP_RAY_RIGHT,  false);
            ObjectSetInteger(0, hName, OBJPROP_SELECTABLE, false);
            ObjectSetInteger(0, hName, OBJPROP_BACK,       false);

            // --- Steunlijn (onder) ---
            ObjectCreate(0, lName, OBJ_TREND, 0, t1, zLow, t2, zLow);
            ObjectSetInteger(0, lName, OBJPROP_COLOR,      InpSupColor);
            ObjectSetInteger(0, lName, OBJPROP_WIDTH,      2);
            ObjectSetInteger(0, lName, OBJPROP_STYLE,      STYLE_SOLID);
            ObjectSetInteger(0, lName, OBJPROP_RAY_RIGHT,  false);
            ObjectSetInteger(0, lName, OBJPROP_SELECTABLE, false);
            ObjectSetInteger(0, lName, OBJPROP_BACK,       false);

            // --- Label met aantal bars ---
            ObjectCreate(0, lbName, OBJ_TEXT, 0, t1, zHigh);
            ObjectSetString(0,  lbName, OBJPROP_TEXT,      "SIDEWAYS (" + IntegerToString(barCount) + " bars)");
            ObjectSetInteger(0, lbName, OBJPROP_COLOR,     clrWhite);
            ObjectSetInteger(0, lbName, OBJPROP_FONTSIZE,  7);
            ObjectSetInteger(0, lbName, OBJPROP_SELECTABLE,false);
            ObjectSetInteger(0, lbName, OBJPROP_BACK,      false);

            zoneCount++;
           }
        }
      else
        i++;
     }

   ChartRedraw(0);
   return rates_total;
  }

//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   ObjectsDeleteAll(0, "sz_");
   ChartRedraw(0);
  }
 
Thomas Eduard Van Der Jagt #:

I thought this was a great idea so I quickly coded it up for you and the community!

It's an MQL5 indicator that automatically detects and draws sideways zones on your chart, works great for EURUSD and USDJPY. It uses ADX to group consecutive ranging candles into clean zones with support and resistance lines, fully visible across history.

Key settings:

  • InpADXThresh — lower = stricter zones (10–15 for really flat ranges)
  • InpMinBars — minimum candles needed to qualify as a zone
  • InpPeriod — ADX period (20 works well on every timeframe)

Thank you so much! It worked! Speaking of which, do you have any code for the asset to operate in hard scalping during this period of sideways movement?

 
lcdeus87 #:
Muito obrigado! Funcionou! Falando nisso, você teria algum codigo para o ativo operar hard Scalp nesse periodo de lateralização?

No problem at all, glad it worked!

I personally don’t use or have any specific code for that kind of hard scalping strategy during sideways markets. But I’m pretty sure there are a lot of useful YouTube videos and resources out there that go into that in detail.

To be honest, I get most of my inspiration and ideas from YouTube as well 🙂

 
lcdeus87 #:
Muito obrigado! Funcionou! Falando nisso, você teria algum codigo para o ativo operar hard Scalp nesse periodo de lateralização?

Please write in English on the English forum. I will apply automatic translation to your second comment too, but I won't be doing this every time. Comments in a language other than English on the English forum may be deleted.