创建对象
要创建对象,需要一组所有类型通用的最小特性集。每种类型特有的附加特性可在对象创建后进行设置或修改。必需特性包括要创建对象的图表标识符、对象名称、窗口/子窗口编号、第一个锚点的两个坐标,即时间和价格。
虽然存在基于屏幕坐标定位的对象组,但创建时仍需传入两个值(通常为零,因其实际未被使用)。
通常,ObjectCreate函数原型如下:
bool ObjectCreate(long chartId, const string name, ENUM_OBJECT type, int window,
datetime time1, double price1, datetime time2 = 0, double price2 = 0, ...)
chartId值为 0 表示当前图表。name参数在整个图表(包括子窗口)中必须唯一,且长度不超过 63 个字符。
此前章节已介绍 type参数对应的对象类型,即 ENUM_OBJECT 枚举中的元素。
如我们所知,window参数的窗口/子窗口编号从 0 开始(0 表示主图表窗口)。如果为子窗口指定较大的索引值,则该子窗口必须存在,否则函数将以错误终止并返回 false。
需要提醒的是,返回的成功标志 (true) 仅表示创建对象的命令已成功加入队列。其执行结果并非立即可知。这是采用异步调用提升性能所带来的固有特性。
要检查执行结果,可使用 ObjectFind 函数或任何 ObjectGet 函数查询对象特性。但需注意,此类函数会等待整个图表命令队列执行完毕,才会返回实际结果(对象状态)该过程可能需要一些时间,期间 MQL 程序代码会暂停执行。换言之,与创建和修改对象的函数不同,检查对象状态的函数是同步执行的。
从第二个锚点开始,其他附加锚点为可选参数。允许的锚点数量最多 30 个(供未来扩展使用),当前对象类型中使用的锚点不超过 5 个。
需特别注意,调用ObjectCreate函数时,如果使用已存在的对象名称,该函数仅会修改锚点坐标(如果自上次调用后坐标发生了变更)。这一特性便于编写统一代码,无需根据对象是否存在而编写条件分支。换言之,只要不关心对象是否已存在,无条件调用ObjectCreate即可确保对象存在。但需注意一个细节。调用 ObjectCreate时,如果对象类型或子窗口索引与现有对象不同,相关数据将保持不变,且不会产生错误。
调用 ObjectCreate时,可以将所有锚点保留为默认值 (null),前提是在该指令后调用具有相应 OBJPROP_TIME 和 OBJPROP_PRICE 特性的 ObjectSet 函数。
对于某些对象类型,锚点的指定顺序可能很重要。例如,对于 OBJ_REGRESSION(线性回归通道)和 OBJ_STDDEVCHANNEL(标准差通道)等通道,必须满足time1<time2的条件。否则,尽管会成功创建对象,但将无法正常构建通道。
以 ObjectSimpleShowcase.mq5脚本为例,该脚本在图表最新柱线位置创建多个不同类型的对象,且仅需一个锚点。
所有对象操作示例均使用ObjectPrefix.mqh头文件,该文件包含对象名称的通用前缀字符串。因而,在需要时,我们可以更便捷地从图表中清除“自有”对象。
const string ObjNamePrefix = "ObjShow-"; |
在 OnStart函数中,定义一个包含对象类型的数组。
void OnStart()
|
接下来,通过循环遍历数组元素,在主窗口创建对象,并传入第 i 根柱线的时间和收盘价。
const int n = ArraySize(types);
|
脚本执行后可能的结果如下:

最新柱线收盘价位置显示的简单类型对象
本示例中启用了Close价绘制线条和网格显示。我们将在后续章节学习如何调整对象的大小、颜色及其他特性。特别说明,大数图标对象的锚点默认位于顶边中点,因此视觉上会显示在价格线下方。但卖出图标显示在价格线上方,因为其锚点始终位于底边中点。
请注意,通过编程创建的对象默认不会显示在同名对话框的对象列表中。要查看这些对象,需点击 All按钮。