在时间序列中查找最大值和最小值
在处理报价时间序列的函数组中,有两个提供最简单聚合处理的函数:用于查找给定时间区间内序列的最大值和最小值,分别为 iHighest和 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)
这两个函数将返回特定时间序列类型中最大值/最小值的索引,时间序列类型由 symbol/timeframe参数对以及 ENUM_SERIESMODE 枚举元素(用于描述我们已熟知的报价字段)共同指定。
标识符 |
说明 |
|---|---|
MODE_OPEN |
开盘价 |
MODE_LOW |
最高价 |
MODE_HIGH |
最低价 |
MODE_CLOSE |
收盘价 |
MODE_VOLUME |
分时报价成交量 |
MODE_REAL_VOLUME |
实际成交量 |
MODE_SPREAD |
点差 |
offset参数用于指定开始搜索的索引位置。编号方式与时间序列一致,即offset增大意味着向历史方向移动,而 0 号索引代表当前柱线(此为默认值)。分析的柱线数量通过 count参数指定(默认值为 WHOLE_ARRAY)。
如果出现错误,函数将返回 -1。使用 GetLastError 获取错误代码。
为了演示其中一个函数 (iHighest) 的工作原理,我们将修改上一节中通过柱线估算点差实际大小的示例,并对结果进行比较。当然,它们必须匹配。脚本的新版本附在文件 SeriesSpreadHighest.mq5中。
这些变化影响了 SpreadPerBar结构体以及 OnStart 内部的工作循环。
该结构体中添加了一些字段,这些字段允许你了解新函数的工作原理。由于算法的特性,这些字段不是必填字段。
struct SpreadPerBar
|
主要修改影响了 OnStart,但这些修改都位于循环内部(所有其他代码片段保持不变)。
for(int i = 0; i < BarCount; ++i)
|
当前柱线的边界(prev和next)的定义与之前相同。不过,我们不再将这些标签之间的时间序列元素复制到自有数组 spreads中,也不再随后对其调用ArrayMaximum 函数,而是确定构成更高时间范围当前柱线的 M1 柱线的索引及数量。这可以按以下方式完成。
iBarShift函数允许你确定 M1 历史数据中的偏移量(变量 p),该偏移量指向时间为next - 1 的柱线右边界所在位置。bars函数用于计算介于 prev 和 next - 1 之间的 M1 柱线数量(变量n)这两个值将作为参数传入 iHighest函数调用中,用于在从索引 p 开始的n 个 M1 柱线中,找出 MODE_SPREAD 类型的最大值。如果能够顺利找到最大值 (m > -1),我们只需使用 iSpread 获取相应值并将其存入结构体即可。
const int p = iBarShift(WorkSymbol, PERIOD_M1, next - 1);
|
将包含结果的数组输出到日志时,我们现在还会看到 M1 柱线的索引,其中包括更高时间范围柱线“起始”的位置,以及在该柱线中找到的最大点差的位置。“起始”一词之所以加上引号,是因为随着新的 M1 柱线不断生成,这些索引会逐渐递增,每条柱线的虚拟“起始位置”也会随之移动,不过历史柱线的开盘时间当然是保持不变的。
Maximal speeds per intraday bar
|
例如,在脚本启动时,标签为 2021.10.12 14:00 的柱线是从第 67 根 M1 柱线开始的(即它在 67 分钟前开盘),而在该 H1 柱线内具有最大点差的 M1 柱线的索引为 89。显然,该索引应小于前一个 H1 柱线起始位置的 M1 柱线编号:2021.10.12 13:00 - 其标记为 127 分钟前开盘。在该 H1 柱线中,又发现索引 181 处存在最大点差。而该数值小于更早的 2021.10.12 12:00 柱线所对应的索引 187。
pos和max 列中的索引值会持续递增,这是因为我们按照从当前到过去的时间顺序遍历柱线数据。num列中的值几乎均为 60,因为大多数 H1 柱线都是由 60 个 M1 柱线构成。但实际情况并非总是如此。例如,以下是不完整的小时柱线,由不足一小时的数据构成:这可能是由于节假日导致市场提前休市,或是交易活动出现缺口(流动性不足)所致。
...
|