日历的基本概念
在处理经济日历时,我们将运用若干概念,MQL5 为这些概念的规范描述定义了特殊类型的结构体。
首先,日历事件与特定国家/地区相关联,使用 MqlCalendarCountry 结构体来描述每个国家/地区。
struct MqlCalendarCountry
|
我们将在下一节中了解如何以 MqlCalendarCountry 结构体数组的形式获取日历中可用的国家/地区列表及其特性。
目前,我们只需关注其 id 字段。该字段之所以重要,是因为它是确定日历事件是否属于特定国家/地区的关键。在每个国家/地区(或注册的国家/地区联盟,如欧盟),都存在一个国际公认的、会影响市场并因此被纳入日历的经济指标类型和信息事件类型列表。
每种事件类型均由 MqlCalendarEvent 结构体定义,其中 country_id 字段将事件唯一地关联到对应国家/地区。我们稍后会探讨所使用的枚举类型。
struct MqlCalendarEvent
|
重要的是要理解,MqlCalendarEvent 结构体描述的正是事件的类型(例如,消费者价格指数 CPI 的发布),而不是可能每季度、每月或按其他时间表发生的某个具体事件。它包含了事件的通用特性,包括重要性、频率、与经济板块的关系、计量单位、名称以及信息来源。至于实际指标和预测指标,这些将在针对此类特定事件的日历条目中提供:这些条目以 MqlCalendarValue 结构体的形式存储,我们稍后会讨论。用于查询支持的事件类型的函数将在后续章节介绍。
type 字段中的事件类型被指定为 ENUM_CALENDAR_EVENT_TYPE 枚举值之一。
标识符 |
说明 |
---|---|
CALENDAR_TYPE_EVENT |
事件(会议、演讲等) |
CALENDAR_TYPE_INDICATOR |
经济指标 |
CALENDAR_TYPE_HOLIDAY |
假日(周末) |
事件所属的经济板块则从 ENUM_CALENDAR_EVENT_SECTOR 枚举中选择。
标识符 |
说明 |
---|---|
CALENDAR_SECTOR_NONE |
未设置部门 |
CALENDAR_SECTOR_MARKET |
市场、交易所 |
CALENDAR_SECTOR_GDP |
国内生产总值 (GDP) |
CALENDAR_SECTOR_JOBS |
劳动力市场 |
CALENDAR_SECTOR_PRICES |
价格 |
CALENDAR_SECTOR_MONEY |
资金 |
CALENDAR_SECTOR_TRADE |
交易 |
CALENDAR_SECTOR_GOVERNMENT |
政府 |
CALENDAR_SECTOR_BUSINESS |
企业 |
CALENDAR_SECTOR_CONSUMER |
消费 |
CALENDAR_SECTOR_HOUSING |
住房 |
CALENDAR_SECTOR_TAXES |
税收 |
CALENDAR_SECTOR_HOLIDAYS |
假日 |
事件的频率通过 ENUM_CALENDAR_EVENT_FREQUENCY 枚举在 frequency 字段中显示。
标识符 |
说明 |
---|---|
CALENDAR_FREQUENCY_NONE |
未设置发布频率 |
CALENDAR_FREQUENCY_WEEK |
每周 |
CALENDAR_FREQUENCY_MONTH |
每月 |
CALENDAR_FREQUENCY_QUARTER |
每季度 |
CALENDAR_FREQUENCY_YEAR |
每年 |
CALENDAR_FREQUENCY_DAY |
每日 |
事件持续时间 (time_mode) 可以用 ENUM_CALENDAR_EVENT_TIMEMODE 枚举中的一个元素来描述。
标识符 |
说明 |
---|---|
CALENDAR_TIMEMODE_DATETIME |
事件的具体时间是已知的 |
CALENDAR_TIMEMODE_DATE |
事件持续一整天 |
CALENDAR_TIMEMODE_NOTIME |
时间未发布 |
CALENDAR_TIMEMODE_TENTATIVE |
只有日期是事先知道的,但事件的确切时间不知道(时间是事后指定的)。 |
事件的重要性通过 ENUM_CALENDAR_EVENT_IMPORTANCE 枚举在 importance 字段中指定。
标识符 |
说明 |
---|---|
CALENDAR_IMPORTANCE_NONE |
未设置 |
CALENDAR_IMPORTANCE_LOW |
低 |
CALENDAR_IMPORTANCE_MODERATE |
中 |
CALENDAR_IMPORTANCE_HIGH |
高 |
作为 ENUM_CALENDAR_EVENT_UNIT 枚举的一个成员,事件值所使用的度量单位在 unit 字段中定义。
标识符 |
说明 |
---|---|
CALENDAR_UNIT_NONE |
未设置单位 |
CALENDAR_UNIT_PERCENT |
利息 (%) |
CALENDAR_UNIT_CURRENCY |
本国货币 |
CALENDAR_UNIT_HOUR |
小时数 |
CALENDAR_UNIT_JOB |
工作场所数量 |
CALENDAR_UNIT_RIG |
钻机 |
CALENDAR_UNIT_USD |
美元 |
CALENDAR_UNIT_PEOPLE |
人数 |
CALENDAR_UNIT_MORTGAGE |
按揭贷款数量 |
CALENDAR_UNIT_VOTE |
投票数 |
CALENDAR_UNIT_BARREL |
桶数 |
CALENDAR_UNIT_CUBICFEET |
体积(立方英尺) |
CALENDAR_UNIT_POSITION |
合约投机仓位净额 |
CALENDAR_UNIT_BUILDING |
建筑物数量 |
在某些情况下,经济指标的数值需要根据 ENUM_CALENDAR_EVENT_MULTIPLIER 枚举中的某一元素使用 multiplier。
标识符 |
说明 |
---|---|
CALENDAR_MULTIPLIER_NONE |
未设置乘数 |
CALENDAR_MULTIPLIER_THOUSANDS |
千倍 |
CALENDAR_MULTIPLIER_MILLIONS |
百万倍 |
CALENDAR_MULTIPLIER_BILLIONS |
十亿倍 |
CALENDAR_MULTIPLIER_TRILLIONS |
万亿倍 |
至此,我们已了解所有用于描述 MqlCalendarEvent 结构体中事件类型的特殊数据类型。
每个独立的日历条目则由 MqlCalendarValue 结构体表示。其详细描述如下,但首先请注意一个关键点:MqlCalendarValue 包含一个 event_id 字段,该字段指向事件类型的标识符,即 MqlCalendarEvent 结构体中某个 id 的值。
如前所述,MqlCalendarEvent 结构体又通过 country_id 字段与 MqlCalendarCountry 关联。因此,一旦特定国家/地区或事件类型的信息录入日历数据库,便可为其注册任意数量的同类事件。当然,数据库的填充工作由信息提供方负责,而非开发者。
简而言之,系统分别维护着三个内部数据表:
- MqlCalendarCountry 结构体表:描述国家/地区信息
- MqlCalendarEvent 结构体表:描述事件类型
- MqlCalendarValue 结构体表:存储各类具体事件的指标
通过引用事件类型标识符,可以有效避免在具体事件记录中重复信息。例如,月度发布的 CPI 值都只引用同一个包含该事件类型通用特性的 MqlCalendarEvent 结构体。如果不是采用这种分表方式,那么就必须在每个 CPI 日历条目中重复相同的特性。这种使用标识符字段在数据表之间建立关系的方法被称为 relational,我们将在关于 SQLite的章节中再次讨论。所有这些都在下图中有所说明。
结构体间通过标识符字段链接的示意图
所有这些表都存储在内部日历数据库中,该数据库在终端连接到服务器期间会持续保持最新状态。
日历条目(即具体事件)是 MqlCalendarValue 结构体。它们也通过其 id 字段中的唯一编号进行标识(这三个核心表各自都有自己的 id 字段)。
struct MqlCalendarValue
|
对于每个事件,除了其发布时间 (time) 外,还存储了以下四个值:
- 实际值 (actual_value),在新闻发布后即刻知晓
- 前次值 (prev_value),在上次同类新闻发布时知晓
- 前次指标的修正值 (revised_prev_value)(如果自上次发布后有所修改)
- 预测值 (forecast_value)
显而易见,并非所有字段都必须填写。因此,对于未来的事件,当前值是缺失的(尚未知晓),而过去值的修正也并非一定发生。此外,这四个字段仅对量化指标有意义,而日历中还反映了监管机构的演讲、会议和假日。
空字段(无值)由常量 LONG_MIN (-9223372036854775808) 表示。如果字段中的值已指定(不等于 LONG_MIN),则它对应于指标真实值乘以一百万后的结果,也就是说,要获得常规(真实)形式的指标,需要将字段值除以 1,000,000。
为了方便程序员,该结构体定义了 4 个 Has 方法用于检查字段是否已填充,以及 4 个 Get 方法用于返回已转换为实数的相应字段值,如果字段未填充,则方法将返回 NaN (Not A Number,非数字)。
有时,为了获取绝对值(如果算法需要),额外分析 MqlCalendarEvent 结构体中的 multiplier 特性非常重要,因为某些值是根据 ENUM_CALENDAR_EVENT_MULTIPLIER 枚举以倍数单位指定的。此外,MqlCalendarEvent 拥有 digits 字段,它指定了接收值的有效小数位数,用于后续的正确格式化(例如,在调用 NormalizeDouble 时)。
报告期(即已发布指标的计算周期)在 period 字段中设置为该周期的第一天。例如,如果指标是按月计算的,那么日期 '2022.05.01 00:00:00' 表示五月份。报告期的时长(例如,月、季度、年)则在关联的 MqlCalendarEvent 结构体的 frequency 字段中定义:该字段的类型是前面与其他枚举一起描述过的特殊枚举 ENUM_CALENDAR_EVENT_FREQUENCY。
特别值得关注的是 impact_type 字段,在新闻发布后,该字段会通过比较当前值和预测值,自动设置相应货币对汇率的影响方向。这种影响可能是积极的(货币预期升值),也可能是消极的(货币预期贬值)。例如,销售额降幅大于预期将被标记为具有消极影响,而失业率降幅大于预期则为积极影响。但并非所有事件的这种特性都能被明确解读(某些经济指标被认为是矛盾的),此外,还应注意变化的相对数值。
事件对本国货币汇率的潜在影响使用 ENUM_CALENDAR_EVENT_IMPACT 枚举表示。
标识符 |
说明 |
---|---|
CALENDAR_IMPACT_NA |
未说明影响 |
CALENDAR_IMPACT_POSITIVE |
积极影响 |
CALENDAR_IMPACT_NEGATIVE |
消极影响 |
经济日历的另一个重要概念是其“变更”这一事实。遗憾的是,并没有一个专门的结构体来描述变更。变更唯一的特性是其独特的 ID,这是一个整数,在内部日历库每次发生更改时由系统分配。
我们知道,信息提供者会不断修改日历:新的即将发生的事件会被添加进来,而已发布的指标和预测也可能被修正。因此,跟踪任何编辑的发生至关重要,通过检测周期性递增的变更编号可以实现这一点。
具有特定标识符的编辑时间及其具体内容在 MQL5 中是不可获取的。如果需要,MQL 程序应自行实现定期的日历状态查询和记录分析。
一系列 MQL5 函数允许获取关于国家/地区、事件类型、具体日历条目及其变更的信息。我们将在后续章节中对此进行探讨。
注意!首次访问日历时(如果之前未在终端工具栏中打开过“日历”选项卡),内部日历数据库与服务器之间的同步可能需要几秒钟的时间。