Timeseries and Indicators Access
访问时间序列和指标数据
这些是用于处理时间序列和指标的函数。时间序列与常规数据数组的不同之处在于其反向排序——时间序列的元素是从数组的末尾到开头进行索引的(从最新数据到最旧数据)。要复制时间序列值和指标数据,建议使用动态数组のみ,因为复制函数旨在分配接收值所需的数组大小。
这里有一个重要的例外:如果经常需要复制时间序列和指标值,例如在每个OnTick()调用中在专家顾问或每个OnCalculate()调用中在指标中,在这种情况下,最好使用静态分布数组,因为动态数组的内存分配操作需要额外的时间,这在测试和优化过程中会有影响。
在使用访问时间序列和指标值的函数时,应考虑索引方向。这在数组、缓冲区和时间序列中的索引方向部分中有描述。
无论请求的数据是否已准备好(所谓的异步访问),都可以访问指标和时间序列数据。这对于自定义指标的计算至关重要,因此如果没有数据,Copy…()类型的函数会立即返回错误。然而,当从专家顾问和脚本访问时,会在小暂停期间尝试多次接收数据,这是为了提供下载所需时间序列或计算指标值所需的时间。
如果请求的数据(符号名称和/或时间框架与当前不同)来自其他图表,则有可能相应的图表未在客户端终端中打开,必须向服务器请求必要的数据。在这种情况下,错误ERR_HISTORY_WILL_UPDATED(4066 - 请求的历史数据正在更新)将放在last_error变量中,并且需要重新请求(参见ArrayCopySeries()的示例)。

历史上公认的是,对数组中的价格数据的访问是从数据的末尾开始的。实际上,新数据总是写在数组的末尾,但数组的索引始终为零。时间序列数组中的0索引表示当前条形图的数据,即与该时间框架中未完成的时间间隔相对应的条形图。
时间框架是形成单个价格条形的时间段。有几种预定义的标准时间框架。
| 函数 | 操作 |
|---|---|
| SeriesInfoInteger | 返回有关历史数据状态的信息 |
| RefreshRates | 刷新预定义变量和序列数组中的数据 |
| CopyRates | 将Rates结构的历史数据获取到指定符号和期间内的数组中 |
| CopyTime | 将指定符号和期间内的条形图开盘时间历史数据获取到数组中 |
| CopyOpen | 将指定符号和期间内的条形图开盘价格历史数据获取到数组中 |
| CopyHigh | 将指定符号和期间内的条形图最高价格历史数据获取到数组中 |
| CopyLow | 将指定符号和期间内的条形图最低价格历史数据获取到数组中 |
| CopyClose | 将指定符号和期间内的条形图收盘价历史数据获取到数组中 |
| CopyTickVolume | 将指定符号和期间内的刻度体积历史数据获取到数组中 |
| Bars | 返回指定符号和期间内的历史条形图数量 |
| iBars | 返回指定图表上的条形图数量 |
| iBarShift | 返回覆盖指定时间的条形图的索引 |
| iClose | 返回具有时间框架和偏移的指定符号的条形图的收盘价 |
| iHigh | 返回具有时间框架和偏移的指定符号的条形图最高价 |
| iHighest | 返回特定数量条形图上最大值的偏移 |
| iLow | 返回具有时间框架和偏移的指定符号的条形图最低价 |
| iLowest | 返回特定数量条形图上最低值的偏移 |
| iOpen | 返回具有时间框架和偏移的指定符号的条形图开盘价 |
| iTime | 返回具有时间框架和偏移的指定符号的条形图时间值 |
| iVolume | 返回具有时间框架和偏移的指定符号的条形图刻度体积 |
尽管使用ArraySetAsSeries()函数可以在数组中设置时间序列中类似元素的访问,但应记住数组元素在物理上存储在同一顺序中——只是索引方向发生了变化。为了证明这一点,让我们执行一个示例:
datetime TimeAsSeries[];
//--- set access to the array like to a timeseries
ArraySetAsSeries(TimeAsSeries,true);
ResetLastError();
int copied=CopyTime(NULL,0,0,10,TimeAsSeries);
if(copied<=0)
{
Print("The copy operation of the open time values for last 10 bars has failed");
return;
}
Print("TimeCurrent =",TimeCurrent());
Print("ArraySize(Time) =",ArraySize(TimeAsSeries));
int size=ArraySize(TimeAsSeries);
for(int i=0;i<size;i++)
{
Print("TimeAsSeries["+i+"] =",TimeAsSeries[i]);
}
datetime ArrayNotSeries[];
ArraySetAsSeries(ArrayNotSeries,false);
ResetLastError();
copied=CopyTime(NULL,0,0,10,ArrayNotSeries);
if(copied<=0)
{
Print("The copy operation of the open time values for last 10 bars has failed");
return;
}
size=ArraySize(ArrayNotSeries);
for(int i=size-1;i>=0;i--)
{
Print("ArrayNotSeries["+i+"] =",ArrayNotSeries[i]);
}结果我们将得到如下输出:
TimeCurrent = 2009.06.11 14:16:23
ArraySize(Time) = 10
TimeAsSeries[0] = 2009.06.11 14:00:00
TimeAsSeries[1] = 2009.06.11 13:00:00
TimeAsSeries[2] = 2009.06.11 12:00:00
TimeAsSeries[3] = 2009.06.11 11:00:00
TimeAsSeries[4] = 2009.06.11 10:00:00
TimeAsSeries[5] = 2009.06.11 09:00:00
TimeAsSeries[6] = 2009.06.11 08:00:00
TimeAsSeries[7] = 2009.06.11 07:00:00
TimeAsSeries[8] = 2009.06.11 06:00:00
TimeAsSeries[9] = 2009.06.11 05:00:00
ArrayNotSeries[9] = 2009.06.11 14:00:00
ArrayNotSeries[8] = 2009.06.11 13:00:00
ArrayNotSeries[7] = 2009.06.11 12:00:00
ArrayNotSeries[6] = 2009.06.11 11:00:00
ArrayNotSeries[5] = 2009.06.11 10:00:00
ArrayNotSeries[4] = 2009.06.11 09:00:00
ArrayNotSeries[3] = 2009.06.11 08:00:00
ArrayNotSeries[2] = 2009.06.11 07:00:00
ArrayNotSeries[1] = 2009.06.11 06:00:00
ArrayNotSeries[0] = 2009.06.11 05:00:00从输出中可以看出,随着TimeAsSeries数组的索引增加,索引的时间值减少,即我们从现在移动到过去。对于普通数组ArrayNotSeries,结果是不同的——随着索引增长,我们是从过去移动到现在。
另请参阅
ArrayIsDynamic(), ArrayGetAsSeries(), ArraySetAsSeries(), ArrayIsSeries()