Indexing Direction in Arrays, Buffers and Timeseries
数组、缓冲区和时间序列的索引方向
所有数组和指标缓冲区的默认索引方向是从左到右。第一个元素的索引始终为零。因此,数组或指标缓冲区中索引为0的第一个元素默认位于最左边的位置,而最后一个元素位于最右边的位置。
指标缓冲区是一个类型为double的动态数组,其大小由客户端终端管理,以确保它始终与计算指标所基于的条形数相对应。通常使用SetIndexBuffer()函数将类型为double的动态数组指定为指标缓冲区。指标缓冲区不需要使用ArrayResize()函数设置其大小——这将由终端的执行系统完成。
时间序列是反向索引的数组,即时间序列的第一个元素位于最右边的位置,最后一个元素位于最左边的位置。由于时间序列用于存储历史价格数据并包含时间信息,我们可以说最新的数据位于时间序列的最右边,而最旧的数据位于最左边。
因此,索引为0的时间序列元素包含有关符号最新报价的信息。如果时间序列包含每日时间框架的数据,当前未完成日的数据位于零位置,而索引为1的位置包含昨天的数据。
改变索引方向
ArraySetAsSeries()函数允许改变访问动态数组元素的方法;但计算机内存中数据的物理顺序不会改变。此函数只是改变了数组元素的寻址方法,因此当使用ArrayCopy()函数将一个数组复制到另一个数组时,接收数组的内容不会依赖于源数组的索引方向。
对于静态分布的数组,无法改变索引方向。即使数组作为参数传递给函数,尝试在该函数内部改变索引方向也不会产生效果。
对于指标缓冲区,就像对于普通数组一样,索引方向也可以设置为反向(如时间序列那样),即引用指标缓冲区的零位置将意味着引用指标缓冲区的最后一个值,这将对应于最新条形上的指标值。不过,指标条形的物理位置将保持不变。
在指标中接收价格数据
每个自定义指标都必须包含OnCalculate()函数,用于传递计算指标缓冲区中值所需的价格数据。可以使用ArrayGetAsSeries()函数确定这些传递数组的索引方向。
传递给函数的数组反映了价格数据,即这些数组具有时间序列的符号,当检查这些数组时,ArrayIsSeries()函数将返回true。然而,无论如何,索引方向应仅通过ArrayGetAsSeries()函数进行检查。
为了不依赖默认值,对于将要使用的数组,应无条件调用ArraySetAsSeries()并设置所需的索引方向。
接收价格数据和指标值
在专家顾问、指标和脚本中,所有数组的默认索引方向是从左到右。如果需要,在任何mql4程序中都可以请求任何符号和时间框架上的时间序列值,以及任何符号和时间框架上计算的指标值。
为此目的使用Copy…()函数:
- CopyRates – 将价格历史复制到MqlRates结构数组;
- CopyTime – 将时间值复制到datetime类型数组;
- CopyOpen – 将开盘价复制到double类型数组;
- CopyHigh – 将高价复制到double类型数组;
- CopyLow – 将低价复制到double类型数组;
- CopyClose – 将收盘价复制到double类型数组;
- CopyTickVolume – 将tick量复制到long类型数组;
- 所有这些函数的工作方式类似。以CopyOpen()为例,说明数据获取机制。这意味着请求数据的索引方向是时间序列的,而索引为0的位置存储当前未完成条形的数据。为了访问这些数据,我们需要将所需的数据量复制到接收数组,例如复制到数组缓冲区。

在复制时,需要指定源数组中开始的位置,从该位置将数据复制到接收数组。如果成功,指定数量的元素将从源数组(在这种情况下是从指标缓冲区)复制到接收数组。无论接收数组中设置了什么索引值,复制总是按照上图所示的方式进行。