按时间查找柱线索引 (iBarShift)
iBarShift函数用于获取指定时间对应的柱线编号。这里的柱线编号始终采用时间序列中的编号规则,即索引 0 对应最右侧最新的柱线,随着从右向左移动(向过去回溯),索引值逐渐递增。
int iBarShift(const string symbol, ENUM_TIMEFRAMES timeframe, datetime time, bool exact = false)
该函数返回指定 symbol/timeframe参数对的时间序列中包含time 参数值的柱线索引。每个柱线由开盘时间和该时间序列柱线统一的持续时间(即周期)来界定。例如,在小时时间范围上,开盘时间标记为 13:00 的柱线从 13:00:00 持续到 13:59:59(包括整个最后一分钟和最后一秒)。
如果指定时间没有对应的柱线(例如时间处于非交易时段或非交易日),则该函数将根据参数值采取不同处理方式:如果 precise = true,函数将返回 -1;如果exact=false,函数将返回开盘时间早于指定时间的最邻近柱线索引。若不存在这样的柱线,即指定时间之前没有历史数据,函数将返回 -1。但这里有一个细微差别。
注意!如果iBarShift函数返回一个具体的柱线编号(即非 -1 的值),这并不意味着后续通过该索引访问时间序列时一定能获取该柱线的价格或其他特性。特别是当请求的柱线索引超过终端窗口中的柱线限制 (TerminalInfoInteger(TERMINAL_MAXBARS)) 时,就可能发生这种情况。这种情况可能在新柱线形成时出现:较早的柱线可能会向左移动超出限制范围,位于可见窗口之外,尽管在名义上它们仍可能会在内存中保留一段时间。开发者必须始终检查此类情况。
我们将使用脚本 SeriesBars.mq5检查 Bars/iBars 和(见 上一节)iBarShift函数的性能。
void OnStart()
|
在这里我们遇到了另一个新函数 ChartTimeOnDropped (后续将详细说明):该函数可返回(活动图表中)在Navigator中通过鼠标将脚本拖放到特定柱线的时间。首先,让我们将脚本拖放至图表上有报价的区域。
日志中将创建如下条目(具体数值将根据你的设置、操作及当前时间而有所不同):
ChartTimeOnDropped()=2021.10.01 09:00:00 / ok
|
在本例中,脚本被拖放至时间为 2021.10.01 09:00 的柱线(使用的是小时时间范围)。根据 iBarShift,该时间对应柱线编号 125。
从鼠标所在柱线到最新柱线(当前时间)的柱线数量为 126 根。这一点需要结合柱线编号 125 来考虑,因为编号是从 0 开始的。
通过不同方式获取的图表上的柱线总数(iBars、不带日期范围的 Bars 以及包含从 0 到当前时刻 TimeCurrent 完整时间段的Bars)均为 10004 根。终端设置的柱线限制为 10000 根,但在会话期间额外形成了 4 根小时柱线。
对于已存在的交易品种和时间范围,当 exact = false时,当前时间对应的柱线编号iBarShift(..., TimeCurrent()) 始终为 0。如果exact = true,则有时可能返回 -1,因为当所有市场金融工具的分时报价到来时服务器时间会增加,而当前交易品种可能暂时没有交易。此时服务器时间可能会提前多个柱线周期,导致 TimeCurrent没有完全对应的新柱线。
如果将脚本拖放至最后一根柱线右侧的空白区域(即未来时间区域),将出现以下情况:
ChartTimeOnDropped()=2021.10.09 02:30:00 / ok
|
iBarShift函数在搜索任意前一根柱线的模式下 (exact = false) 返回 0,因为当前柱线是距离未来时间点最近的。然而,精确搜索 (exact = true) 时会返回结果 -1。此外,用于计算从当前时间到“目标”未来时间范围内柱线数量的 Bars函数此时返回 0(该区域尚无柱线)。
iBarShift函数在编写多货币 MQL 程序时特别有用。由于不同金融工具的交易时间表往往不一致,因此对于特定时间点,某个交易品种可能存在对应的柱线,而另一个交易品种可能不存在。通过iBarShift函数的最近(前一个)柱线搜索模式,你始终可以获取到同一时刻不同交易品种的有效价格对应的柱线索引。通常,即使是外汇交易品种,同一时间的历史柱线索引也可能不同。
例如,以下指令将在小时时间范围(MQ 模拟服务器)下,记录三个交易品种(EURUSD、XAUUSD、USDRUB)在同一日期范围内的不同柱线数量及其编号:
PRTF(Bars("EURUSD", PERIOD_H1, D'2021.05.01', D'2021.09.01')); // 2087
|