Problem Description
Solution
The fastest way to find a specific value within a large, sorted array in MQL4 is to use the built-in ArrayBsearch() function.
This function implements a Binary Search algorithm. Unlike a linear search (which iterates through every element one by one with $O(n)$ complexity), a binary search repeatedly divides the search interval in half. This results in a time complexity of $O(\log n)$, making it exponentially faster for large datasets.
Key Features of ArrayBsearch
- Speed: Extremely fast for large arrays (e.g., finding a value in 1,000,000 elements takes roughly 20 comparisons).
- Prerequisite: The array must be sorted (either ascending or descending). If the array is not sorted, the result is unpredictable.
- Return Value: It returns the index of the found element. If the exact value doesn't exist, it returns the index of the nearest value.
MQL4 Implementation
Below is a script demonstrating how to correctly use ArrayBsearch to find a specific price within a sorted data array. It handles both exact matches and "nearest neighbor" logic.
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
// 1. Create a sample array (simulating a large dataset)
double priceData[];
int dataSize = 10000;
ArrayResize(priceData, dataSize);
// Fill array with simulated sorted data (Ascending)
// Example: 1.0000, 1.0002, 1.0004...
for(int i = 0; i < dataSize; i++)
{
priceData[i] = 1.0000 + (i * 0.0002);
}
// 2. Define the target value to find
double targetValue = 1.5000; // This value exists in our logic (index 2500)
// 3. Perform the Binary Search
// Parameters: Array, Value to find, Count (default whole), Start (default 0), Direction
ulong startTime = GetMicrosecondCount();
int foundIndex = ArrayBsearch(priceData, targetValue, WHOLE_ARRAY, 0, MODE_ASCEND);
ulong endTime = GetMicrosecondCount();
// 4. Validate the result
// ArrayBsearch returns the NEAREST index if exact match isn't found.
// We must check if the value at the returned index matches our target.
// Define a small tolerance for double comparison
double tolerance = 0.0000001;
if(MathAbs(priceData[foundIndex] - targetValue) < tolerance)
{
PrintFormat("SUCCESS: Found exact value %.4f at index %d.", priceData[foundIndex], foundIndex);
}
else
{
PrintFormat("NOTE: Exact value not found. Nearest value is %.4f at index %d.", priceData[foundIndex], foundIndex);
}
PrintFormat("Search time: %d microseconds", endTime - startTime);
}
Important Considerations
-
Sorting Direction:
By default,ArrayBsearchassumes the array is sorted in Ascending order. If your array is sorted in Descending order, you must explicitly passMODE_DESCENDas the last parameter:int index = ArrayBsearch(data, value, WHOLE_ARRAY, 0, MODE_DESCEND); -
Nearest Neighbor Behavior:
ArrayBsearchdoes not return -1 if the value is not found. It returns the index of the element with the value closest to the search key. You must always comparearray[index]with yourtarget_valueif you strictly require an exact match. -
Price Data Context:
Standard chart arrays likeClose[]orOpen[]are sorted by time, not by price value.- To find a specific Time: Use
iBarShift(). - To find a specific Price in history: You must first copy the prices to a dynamic array, sort them using
ArraySort(), and then useArrayBsearch().
- To find a specific Time: Use
Q&A: Quantitative Development in MQL4
Q: Can I use ArrayBsearch on string arrays?
A: No, ArrayBsearch only works on numeric arrays (double, float, long, int, short, char). For strings, you must implement your own binary search algorithm or use a linear search.
Q: What happens if I use ArrayBsearch on an unsorted array?
A: The result will be undefined and likely incorrect. The binary search algorithm relies on the structural logic that the data is ordered; without order, the "divide and conquer" logic fails.
Q: Is ArraySort fast enough to justify sorting just to use ArrayBsearch?
A: ArraySort uses the QuickSort algorithm ($O(n \log n)$).
- If you are searching once, a linear search ($O(n)$) is faster than Sorting + Binary Search.
- If you are searching multiple times on the same dataset, Sorting once ($O(n \log n)$) followed by multiple Binary Searches ($O(\log n)$) is significantly more efficient.