- Symbols and timeframes
- Technical aspects of timeseries organization and storage
- Getting characteristics of price arrays
- Number of available bars (Bars/iBars)
- Search bar index by time (iBarShift)
- Overview of Copy functions for obtaining arrays of quotes
- Getting quotes as an array of MqlRates structures
- Separate request for arrays of prices, volumes, spreads, time
- Reading price, volume, spread, and time by bar index
- Finding the maximum and minimum values in a timeseries
- Working with real tick arrays in MqlTick structures
Finding the maximum and minimum values in a timeseries
Among the group of functions for working with time series of quotes, there are two that provide the simplest aggregate processing: searching for the maximum and minimum values of the series at a given interval, respectively iHighest and iLowest.
int iHighest(const string symbol, ENUM_TIMEFRAMES timeframe, ENUM_SERIESMODE type, int count = WHOLE_ARRAY, int offset = 0)
int iLowest(const string symbol, ENUM_TIMEFRAMES timeframe, ENUM_SERIESMODE type, int count = WHOLE_ARRAY, int offset = 0)
The functions return the index of the largest/smallest value for a specific timeseries type, which is specified by a pair of symbol/timeframe parameters, as well as the ENUM_SERIESMODE enumeration element (it describes the quote fields already familiar to us).
Identifier |
Description |
---|---|
MODE_OPEN |
Opening price |
MODE_LOW |
High price |
MODE_HIGH |
Low price |
MODE_CLOSE |
Closing price |
MODE_VOLUME |
Tick volume |
MODE_REAL_VOLUME |
Real volume |
MODE_SPREAD |
Spread |
The offset parameter specifies the index at which to start the search. Numbering is carried out as in a timeseries, that is, the increase in offset results in a shift to the past, and the 0-th index means the current bar (this is the default value). The number of analyzed bars is specified in the count parameter (WHOLE_ARRAY by default).
In case of an error, the functions return -1. Use GetLastError to find the error code.
To demonstrate how one of these functions works (iHighest), let's modify the example from the previous section on estimating the real sizes of spreads by bars and compare the results. Of course, they must match. The new version of the script is attached in the file SeriesSpreadHighest.mq5.
The changes affected the structure SpreadPerBar and the work cycle inside OnStart.
Fields have been added to the structure that allow you to understand how the new function works. Due to the nature of the algorithm, they are not obligatory.
struct SpreadPerBar
|
The main transformations affected OnStart, but they are localized inside the loop (all other code fragments remained unchanged).
for(int i = 0; i < BarCount; ++i)
|
The borders of the current bar, prev and next, are defined as before. However, instead of copying the timeseries elements between these labels into its own array spreads, and the subsequent call of ArrayMaximum for it, we determine the indexes and the number of M1 bars that form the current bar of the higher timeframe. This is done in the following way.
The iBarShift function allows you to find out the offset (variable p) in the history of M1, where the right border of the bar with time next - 1 is located. The bars function calculates the number of M1 bars (variable n) falling between prev and next - 1. These two values become parameters in the iHighest function call made to find the maximum value of type MODE_SPREAD, among n M1 bars, starting from the index p. If the maximum is found without problems (m > -1), it remains for us to take the corresponding value using iSpread and place it in a structure.
const int p = iBarShift(WorkSymbol, PERIOD_M1, next - 1);
|
When outputting the array with the results to the log, we will now additionally see the indexes of M1 bars, where the bar of the higher timeframe "begins" and where the maximum spread was found in it. The word "begins" is in quotation marks, because as new M1 bars arrive, these indexes will increase, and the virtual "beginning" of each will shift, although the opening times of historical bars, of course, remain constant.
Maximal speeds per intraday bar
|
For example, at the time the script was launched, the bar with the label 2021.10.12 14:00 started from the 67th bar M1 (i.e. it was opened 67 minutes ago), and the M1 bar with the maximum spread inside this H1 bar was found under the index 89. Obviously, this index should be less than the number of the M1 bar where the previous H1 bar started: 2021.10.12 13:00 it was marked 127 minutes ago. In this H1 bar, in turn, the maximum spread for the 181 index was found. And this is less than the index 187 for an even older bar 2021.10.12 12:00.
Indexes in the pos and max columns are constantly increasing because we walk around the bars in order from the present to the past. The num column will almost have 60 since most H1 bars are made up of 60 M1 bars. But this is not always the case. For example, below are incomplete hourly bars, consisting of fewer minutes: this can be either the consequences of an earlier market close due to the holiday schedule, or real gaps in trading activity (lack of liquidity).
...
|