跳至内容
Timeseries and Indicators Access

Timeseries and Indicators Access

访问时间序列和指标数据

这些是用于处理时间序列和指标的函数。时间序列与常规数据数组的不同之处在于其反向排序——时间序列的元素是从数组的末尾到开头进行索引的(从最新数据到最旧数据)。要复制时间序列值和指标数据,建议使用动态数组のみ,因为复制函数旨在分配接收值所需的数组大小。

这里有一个重要的例外:如果经常需要复制时间序列和指标值,例如在每个OnTick()调用中在专家顾问或每个OnCalculate()调用中在指标中,在这种情况下,最好使用静态分布数组,因为动态数组的内存分配操作需要额外的时间,这在测试和优化过程中会有影响。

在使用访问时间序列和指标值的函数时,应考虑索引方向。这在数组、缓冲区和时间序列中的索引方向部分中有描述。

无论请求的数据是否已准备好(所谓的异步访问),都可以访问指标和时间序列数据。这对于自定义指标的计算至关重要,因此如果没有数据,Copy…()类型的函数会立即返回错误。然而,当从专家顾问和脚本访问时,会在小暂停期间尝试多次接收数据,这是为了提供下载所需时间序列或计算指标值所需的时间。

如果请求的数据(符号名称和/或时间框架与当前不同)来自其他图表,则有可能相应的图表未在客户端终端中打开,必须向服务器请求必要的数据。在这种情况下,错误ERR_HISTORY_WILL_UPDATED(4066 - 请求的历史数据正在更新)将放在last_error变量中,并且需要重新请求(参见ArrayCopySeries()的示例)。

时间序列和普通数组中的索引方向

历史上公认的是,对数组中的价格数据的访问是从数据的末尾开始的。实际上,新数据总是写在数组的末尾,但数组的索引始终为零。时间序列数组中的0索引表示当前条形图的数据,即与该时间框架中未完成的时间间隔相对应的条形图。

时间框架是形成单个价格条形的时间段。有几种预定义的标准时间框架

函数操作
SeriesInfoInteger返回有关历史数据状态的信息
RefreshRates刷新预定义变量和序列数组中的数据
CopyRatesRates结构的历史数据获取到指定符号和期间内的数组中
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()

最后更新于