时间序列组织与存储的技术要点
在探讨 MQL5 中用于处理时间序列的 API 函数的实际应用问题之前,我们需要先了解 MetaTrader 5 平台从服务器接收报价数据并进行存储的技术基础。
在价格数据被终端用于图表显示和传递给 MQL 程序之前,这些数据会从服务器下载并经过特殊预处理。无论数据请求是由用户在图表中导航时发起,还是通过 MQL5 语言以编程方式发起,服务器数据访问机制都是相同的。
从服务器传输的数据采用压缩格式传输:这些是经过高效打包的分钟柱线数据块,但并非通常的 M1 柱线。
从服务器接收的数据会自动解压缩,并以特殊的 HCC 中间格式保存。每个交易品种的数据会写入独立文件夹:{terminal_dir}/bases/{server_name}/history/{symbol_name}。例如,来自 MetaQuotes-Demo 交易服务器的 EURUSD 数据可能存储在以下文件夹中:C:/Program Files/MetaTrader 5/bases/MetaQuotes-Demo/history/EURUSD/。
数据被写入扩展名为 *.hcc 的文件中:每个文件存储为期一年的一分钟柱线数据。例如,EURUSD 文件夹中的 2021.hcc 文件包含 2021 年的 EURUSD 分钟柱线数据。这些文件用于为所有时间范围准备价格数据,不适合直接访问。
HCC 格式的服务文件充当绘制特定时间范围价格数据的数据源。这些文件仅在图表或 MQL 程序请求时创建,并以 *.hc 扩展名保存以供后续在文件中使用。
每个时间范围的数据都是独立生成的,与其他时间范围无关。所有时间范围(包括 M1)的数据生成和可用性规则均相同。也就是说,虽然 HCC 格式的数据存储单元是分钟柱线,但这些数据的存在并不意味着 HC 格式中也有同等数量的 M1 时间范围数据可用。
为节省资源,时间范围数据仅在需要时才会被加载并存储到 RAM 中:如果长时间没有数据访问,它们会从 RAM 中卸载(但仍保留在文件中)。这可能导致如果某个时间序列长时间未被使用,下一次请求时的执行时间延长。如果计算机资源充足,所有常用时间序列(特别是已打开图表对应的数据)几乎可以立即访问。
从服务器接收新数据后,会自动更新所有时间范围的 HC 格式价格数据,并重新计算所有依赖的 指标。
当 MQL 程序访问特定交易品种和时间周期的数据时,可能出现所需的时间序列尚未生成或尚未与交易服务器同步的情况(例如,服务器上已出现更新的价格)。在这种情况下,应通过某种形式实现数据就绪等待机制。
对于脚本,唯一的解决方案是使用循环,因为它们缺乏事件处理机制,没有其他选择。对于指标,强烈不建议使用此类算法(如任何等待循环),因为这会导致该交易品种的所有指标计算和其他价格数据处理暂停。
对于 EA 交易和指标,最好使用事件处理模型。如果在处理 OnTick 或 OnCalculate 事件时未能获取所需时间序列的全部数据,应退出事件处理程序,并在下一次调用处理程序时等待数据出现。
最大柱线数量
需要注意的是,为每个请求的交易品种/时间范围对计算的最大柱线数量,不会超过终端 Options对话框中Max. bars in chart 参数的值。因此,该参数不仅会限制任何时间范围的图表显示,也对所有 MQL 程序产生约束。
该限制主要用于节省系统资源。若将该参数设置为较大的值,需记住,如果较低时间范围存在足够深度的历史数据,存储时间序列和指标缓冲区的内存消耗量可能达到数百兆字节,甚至占满全部 RAM。
修改柱线限制仅在重启客户端终端后生效。该参数会影响从服务器请求的数据量,以构建工作时间范围所需数量的柱线。
参数设置的限制并非绝对,在特定情况下可能会被突破。例如,在会话开始时,如果特定时间范围的报价历史足以满足整个限制条件,则随着新柱线的形成,其数量可能会超过该参数的当前值。实际可用柱线数量可通过 Bars/iBars 函数获取。