Problem Description
Solution
To sort an array of numbers in MQL4, you primarily use the built-in ArraySort() function. This function is highly optimized and sorts the first dimension of a numeric array.
Below is a complete script that demonstrates three key concepts:
- Basic Sorting: Sorting a simple array to find the minimum and maximum values.
- Median Calculation: Calculating the median value (robust against outliers).
- Tracking Indices: Using a multi-dimensional array to sort values while keeping track of which "item" (e.g., a specific Order Ticket or Magic Number) belongs to that value.
MQL4 Implementation
//+------------------------------------------------------------------+
//| SortAndAnalyze.mq4 |
//| Copyright 2023, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
#property script_show_inputs
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
// --- EXAMPLE 1: Basic Sorting and Median Calculation ---
Print("=== EXAMPLE 1: Basic Statistics ===");
// 1. Define and initialize an array with random performance data
double performanceData[];
ArrayResize(performanceData, 9); // Odd number of elements for easy median example
performanceData[0] = 10.5;
performanceData[1] = -5.0;
performanceData[2] = 22.1;
performanceData[3] = 0.0;
performanceData[4] = 105.4; // Outlier
performanceData[5] = 3.3;
performanceData[6] = 8.8;
performanceData[7] = -1.2;
performanceData[8] = 15.0;
// 2. Create a copy to preserve the original order (Optional but recommended)
double sortedData[];
ArrayCopy(sortedData, performanceData);
// 3. Sort the array in Ascending order
// MODE_ASCEND is default. Use MODE_DESCEND for reverse.
ArraySort(sortedData, WHOLE_ARRAY, 0, MODE_ASCEND);
// 4. Find Min and Max (Top/Bottom performers)
int total = ArraySize(sortedData);
double minValue = sortedData[0]; // First element after ascending sort
double maxValue = sortedData[total - 1]; // Last element after ascending sort
Print("Minimum Value: ", DoubleToString(minValue, 2));
Print("Maximum Value: ", DoubleToString(maxValue, 2));
// 5. Calculate Median
double median = CalculateMedian(sortedData);
Print("Median Value: ", DoubleToString(median, 2));
// --- EXAMPLE 2: Sorting while keeping track of IDs (2D Array) ---
Print("=== EXAMPLE 2: Top Performers with IDs ===");
// Imagine Column 0 is Profit, Column 1 is Ticket Number
double tradeData[5][2];
// Fill data: [Profit, Ticket#]
tradeData[0][0] = 50.0; tradeData[0][1] = 1001;
tradeData[1][0] = 120.0; tradeData[1][1] = 1002;
tradeData[2][0] = -20.0; tradeData[2][1] = 1003;
tradeData[3][0] = 300.0; tradeData[3][1] = 1004;
tradeData[4][0] = 10.0; tradeData[4][1] = 1005;
// ArraySort sorts by the FIRST dimension (Column 0 - Profit)
// We sort Descending to put the highest profit at index 0
ArraySort(tradeData, WHOLE_ARRAY, 0, MODE_DESCEND);
Print("Top 3 Performing Tickets:");
for(int i = 0; i < 3; i++)
{
Print("Rank ", i+1, ": Ticket #", (int)tradeData[i][1],
" with Profit $", DoubleToString(tradeData[i][0], 2));
}
}
//+------------------------------------------------------------------+
//| Helper function to calculate Median from a SORTED array |
//+------------------------------------------------------------------+
double CalculateMedian(double &array[])
{
int size = ArraySize(array);
if(size == 0) return 0.0;
// If size is odd, return the middle element
if(size % 2 != 0)
{
return array[size / 2];
}
// If size is even, return the average of the two middle elements
else
{
int midIndex = size / 2;
return (array[midIndex - 1] + array[midIndex]) / 2.0;
}
}
Key Functions Explained
-
ArraySort(array, count, start, direction)- This is the core function.
array: The numeric array to sort.count: Number of elements to sort (usuallyWHOLE_ARRAY).start: Starting index (usually0).direction:MODE_ASCEND(default, lowest to highest) orMODE_DESCEND(highest to lowest).
-
Median Logic
- The median is the "middle" value. It is often preferred over the Average (Mean) in trading because it filters out extreme outliers (like one massive news-spike profit).
- Prerequisite: The array must be sorted first.
- Odd count: The element at index
size / 2. - Even count: The average of the elements at
size / 2and(size / 2) - 1.
-
2D Arrays for Identification
- A common problem in MQL4 is sorting an array of profits (e.g.,
{10, 50, -5}) and losing track of which trade generated which profit. - Solution: Use a multi-dimensional array
double data[][2]. - Store the value to sort by in the first dimension (index
[x][0]). - Store the ID (Ticket, MagicNumber, Symbol Index) in the second dimension (index
[x][1]). ArraySortalways sorts based on the first dimension, but it moves the entire "row" together, keeping the ID attached to the value.
- A common problem in MQL4 is sorting an array of profits (e.g.,
Q&A: MQL4 Array Sorting
Q: Can I sort an array of Strings in MQL4?
A: No, ArraySort only works on numeric arrays (double, int, etc.). To sort strings, you would need to implement a custom sorting algorithm (like Bubble Sort or Quick Sort) manually within your code.
Q: Does ArraySort change the original array?
A: Yes, it sorts the array "in place." If you need to keep the original order of data for other calculations (like a time-series moving average), you must use ArrayCopy to create a duplicate array before sorting.
Q: How do I find the index of the maximum value without sorting?
A: You can use ArrayMaximum(array). This returns the index of the highest value. Similarly, ArrayMinimum(array) returns the index of the lowest value. This is faster if you only need the single best/worst item and don't need the median or a ranked list.