MQL4 range lookup

Find the highest and lowest bars in MQL4

iHighest and iLowest return a bar shift, not a price. Pass the symbol, timeframe, series type, number of bars, and starting shift; check for minus one; then read the corresponding iHigh, iLow, or other series value.

Open the Coding Agent, then choose MQL4 from the language menu.

HighestLowestRange.mq4.mq4
#property strict
#property script_show_inputs

input int Lookback = 20;

void OnStart()
  {
   if(Lookback < 1 || iBars(NULL, 0) <= Lookback)
     {
      Print("Not enough bars.");
      return;
     }

   int high_shift = iHighest(NULL, 0, MODE_HIGH, Lookback, 1);
   int low_shift  = iLowest(NULL, 0, MODE_LOW, Lookback, 1);

   if(high_shift < 0 || low_shift < 0)
     {
      Print("Range lookup failed. Error ", GetLastError());
      return;
     }

   double highest = iHigh(NULL, 0, high_shift);
   double lowest  = iLow(NULL, 0, low_shift);

   Print("Highest: ", DoubleToString(highest, Digits),
         " at shift ", high_shift);
   Print("Lowest: ", DoubleToString(lowest, Digits),
         " at shift ", low_shift);
  }
  • The result is a bar shift
  • Count is a number of bars
  • Start controls the first bar searched
  • Check minus one before reading data

Count and start describe the search window

A start value of zero includes the current bar. A start value of one begins with the most recently closed bar. Count is the number of bars searched from that starting shift, not the final index.

The type argument selects MODE_HIGH, MODE_LOW, MODE_OPEN, MODE_CLOSE, MODE_VOLUME, or another supported series identifier. The returned shift belongs to the symbol and timeframe passed to the function.

GoalTypeTypical start
Highest closed highMODE_HIGH1
Lowest closed lowMODE_LOW1
Largest current-window volumeMODE_VOLUME0 or 1 by rule

A valid shift still needs the correct series

If iHighest searched a different symbol or timeframe, read the value with iHigh for that same symbol and timeframe. Indexing the current chart High array with a foreign shift can return unrelated data.

History may be unavailable or shorter than requested. Check iBars and the returned shift, and distinguish unavailable data from a legitimate numeric zero.

  • Use one symbol and timeframe consistently across lookup and value access
  • Decide whether the current bar belongs in the window
  • Check the minimum history before searching
  • Treat a negative shift as failure

Tie handling depends on the series scan

Several bars can share the same high or low. The function returns one shift found by its series search; it does not return every tied bar.

If the application needs all ties, a custom loop should define equality tolerance and collect each matching shift explicitly.

Review the complete example

The script searches 20 closed bars starting at shift 1, then converts the returned shifts into price values. It excludes the still-forming current bar.

The example reads history only. A trading rule based on extremes still needs a defined bar-close policy and protection against missing or changing history.

HighestLowestRange.mq4.mq4
#property strict
#property script_show_inputs

input int Lookback = 20;

void OnStart()
  {
   if(Lookback < 1 || iBars(NULL, 0) <= Lookback)
     {
      Print("Not enough bars.");
      return;
     }

   int high_shift = iHighest(NULL, 0, MODE_HIGH, Lookback, 1);
   int low_shift  = iLowest(NULL, 0, MODE_LOW, Lookback, 1);

   if(high_shift < 0 || low_shift < 0)
     {
      Print("Range lookup failed. Error ", GetLastError());
      return;
     }

   double highest = iHigh(NULL, 0, high_shift);
   double lowest  = iLow(NULL, 0, low_shift);

   Print("Highest: ", DoubleToString(highest, Digits),
         " at shift ", high_shift);
   Print("Lowest: ", DoubleToString(lowest, Digits),
         " at shift ", low_shift);
  }
Where Pineify fits

Move from the rule to editable MQL4 source

Pineify can generate or revise one self-contained .mq4 file with MQL4-specific reference context. Its independent static checker returns MetaEditor diagnostics so you can repair source issues before testing in your own MT4 environment.

Open MQL4 Coding Agent

Static diagnostics do not prove runtime behavior, backtest results, broker compatibility, or live-trading safety.

Pineify MQL4 Coding Agent with MQL4 selected and an editable MetaTrader 4 code artifact

A practical workflow

  1. 1

    Define the window

    Choose symbol, timeframe, series type, count, and starting shift.

  2. 2

    Check history

    Confirm that the requested series contains enough bars.

  3. 3

    Request the shift

    Call iHighest or iLowest and reject a negative result.

  4. 4

    Read the value

    Use the matching iHigh, iLow, or series function with the returned shift.

Frequently asked questions

Does iHighest return the highest price?

No. iHighest returns the shift of the bar containing the highest requested series value.

How do I exclude the current bar?

Use a starting shift of 1 so the search begins with the latest closed bar.

What does count mean in iHighest?

Count is the number of bars to search from the starting shift.

What does iLowest return on failure?

It returns -1. Check that result before using it as a series index.

Can I search another timeframe?

Yes. Pass that timeframe to both the search function and the value-access function.

Last verified against the linked official references on . Compile and test the final source in the MetaTrader 4 build, broker, symbol, and account environment you plan to use.

Continue with one reviewable MQL4 file

Define the requirement, inspect the generated source, repair diagnostics, and test the behavior in your own MT4 environment.

Open Coding Agent