Problem Description
Solution
To find the highest high over the last 20 bars in MQL4, the most efficient method is to use the built-in iHighest() function. This function is specifically designed to search timeseries arrays (like High[], Low[], Open[], Close[]) and return the index (shift) of the highest value.
Here is the proper way to handle this using both the built-in function and a manual array iteration method.
Method 1: Using iHighest (Recommended)
This is the standard and fastest way to retrieve extreme values from price history.
void OnTick()
{
// --- Parameters ---
int lookbackPeriod = 20; // Number of bars to check
int startBar = 1; // 1 = Start from the last closed bar (0 = current forming bar)
// --- Step 1: Find the index (shift) of the highest high ---
// iHighest returns the shift (e.g., 5 bars ago), not the price itself.
int highestIndex = iHighest(NULL, 0, MODE_HIGH, lookbackPeriod, startBar);
// --- Step 2: Error Checking ---
if(highestIndex == -1)
{
Print("Error finding highest high. Error code: ", GetLastError());
return;
}
// --- Step 3: Retrieve the actual price using the index ---
double highestPrice = High[highestIndex];
// --- Output for verification ---
Print("The Highest High over the last ", lookbackPeriod,
" bars is at index ", highestIndex,
" with price: ", highestPrice);
}
Explanation of Parameters:
NULL: Uses the current chart symbol.0: Uses the current chart timeframe.MODE_HIGH: Specifies that we are searching theHigh[]array.lookbackPeriod: How many bars to scan (20).startBar: Where to begin. Using 1 is standard to avoid "repainting" (values changing as the current bar moves). Using 0 includes the currently forming bar.
Method 2: Manual Array Iteration (For Custom Logic)
If you need to perform complex logic (e.g., finding the highest high but excluding bars with specific volume), you can iterate through the High[] array manually.
double GetHighestHighManual(int count, int start)
{
double maxPrice = 0.0;
// Loop from the start bar backwards into history
for(int i = start; i < start + count; i++)
{
// Check if the current iteration's high is greater than our stored max
if(High[i] > maxPrice)
{
maxPrice = High[i];
}
}
return(maxPrice);
}
void OnTick()
{
// Call the function for the last 20 bars starting from index 1
double highest = GetHighestHighManual(20, 1);
Print("Manual Calculation: Highest High is ", highest);
}
Key Concepts for MQL4 Arrays
- Timeseries Indexing: MQL4 price arrays (
High[],Low[], etc.) are indexed in reverse.High[0]is the current, active bar.High[1]is the most recently closed bar.High[20]is the bar that occurred 20 periods ago.
- Array Range: Always ensure you do not try to access a bar index larger than
Bars - 1. If you try to accessHigh[10000]on a chart with only 5000 bars, the EA will crash or throw an "Array out of range" error. - Efficiency:
iHighestis significantly faster than a manualforloop because it is optimized at the engine level of MetaTrader 4.
Q&A: MQL4 Array Handling
Q: Why do I get different results using startBar = 0 vs startBar = 1?
A: startBar = 0 includes the currently forming candle. Since the price moves up and down during the bar's life, the "Highest High" might change tick-by-tick. startBar = 1 looks only at fully closed candles, ensuring the value remains static until a new bar opens.
Q: Can I use ArrayMaximum instead of iHighest?
A: ArrayMaximum is a generic function for any array. While you can use it, iHighest is specifically designed for timeseries data (Open, High, Low, Close) and is generally preferred for readability and specific handling of chart data in MQL4.
Q: How do I find the lowest low over the last 20 bars?
A: You simply swap the function to iLowest and the mode to MODE_LOW.
int lowestIndex = iLowest(NULL, 0, MODE_LOW, 20, 1);
double lowestPrice = Low[lowestIndex];