DoEasy 函数库中的图形(第八十五部分):图形对象集合 - 添加新创建的对象(基础篇)
📘

DoEasy 函数库中的图形(第八十五部分):图形对象集合 - 添加新创建的对象(基础篇)

第 1/3 篇

给图形对象集合补上新建入口

DoEasy 函数库在图形封装这块,之前只覆盖了部分抽象图形对象的衍生类。这一节把剩余那批衍生后代对象补齐,并让集合类能直接收纳新创建的图形对象,省得每次手动挂引用。 库里图形对象集合原本只认已登记实例。现在改动后,调用创建接口生成的物件会顺手塞进集合容器,后续遍历、查找、批量清理都更顺。 这套改动在 MT5 里跑通后,图形对象管理从散养变成集中收容。你可以开 MT5 加载 DoEasy 最新版,新建一个趋势线看它是否自动出现在集合列表里验证。外汇与贵金属图表对象随价格波动刷新频繁,集中管理能降低脚本遗漏风险,但自动收纳也可能在高频tick下增加集合锁开销,需实测。

「给图形对象类补上造型与箭头」

上一篇文章里已经把曲线、通道、江恩、斐波那契和埃洛特这几组抽象图形对象类实现完了,基类派生链路是现成的。 这一节要往里塞的是造型(Shapes)、箭头(Arrows)和图形(Graph)这三组对象类,等于把 MT5 里手工能画的常见装饰性物件也纳入统一封装。 另外图形对象集合类会多出一个能力:把图表上手动拖出来的图形对象直接收编进集合列表,不用在代码里从头 new。 对做价格行为模板的交易者来说,这意味着你画的压力区方框或方向箭头,能被 AIGC 脚本统一遍历、打标签、再回测,而不是散落在对象池里靠肉眼找。

◍ 库类重构时的拼写与枚举统一

早期库文件里把 Standard 拼成了 standart,末尾多写了一个 t。用 Shift+Ctrl+F 在 Include 目录子文件夹里搜全词 standart,忽略大小写,逐个把最后一个字母改回 d,就能定位所有受影响文件。 重命名后,图表对象 ID 常量从 GRAPH_OBJ_PROP_OBJ_CHART_ID 移出枚举列表,统一改为 GRAPH_OBJ_PROP_CHART_OBJ_CHART_ID,所有引用处都要同步替换,否则编译会报未定义标识符。 不同图形对象共用“锚点位置”属性,但绑定枚举不一样:Text、Label、Bitmap、Bitmap Label 用 ENUM_ANCHOR_POINT,Arrow 用 ENUM_ARROW_ANCHOR。抽象图形对象类返回锚点的方法只能给 int,不知道派生类该回哪种枚举,虚方法留給子类重写。 服务文件 DELib.mqh 里加了按数值回文本描述的函数,传 ENUM_ANCHOR_POINT 或 ENUM_ARROW_ANCHOR 的值就能拿到对应中文/英文说明,方便调试时直接打印对象绑定方式。 下面这段是修正后的枚举定义节选,INDICATOR_STATUS_STANDARD 与 GRAPH_ELEMENT_TYPE_STANDARD 都已拼对,可直接对照自己库里的旧拼写。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Data for working with indicators                                        |
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Abstract indicator status                                             |
class=class="str">"cmt">//+------------------------------------------------------------------+
enum ENUM_INDICATOR_STATUS
  {
   INDICATOR_STATUS_STANDARD,                                            class=class="str">"cmt">// Standard indicator
   INDICATOR_STATUS_CUSTOM,                                              class=class="str">"cmt">// Custom indicator
  };
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Indicator group                                                      |
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| List of graphical objects affiliations                              |
class=class="str">"cmt">//+------------------------------------------------------------------+
enum ENUM_GRAPH_OBJ_BELONG
  {
   GRAPH_OBJ_BELONG_PROGRAM,                                             class=class="str">"cmt">// Graphical object belongs to a program
   GRAPH_OBJ_BELONG_NO_PROGRAM,                                          class=class="str">"cmt">// Graphical object does not belong to a program
  };
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| The list of graphical element types                                 |
class=class="str">"cmt">//+------------------------------------------------------------------+
enum ENUM_GRAPH_ELEMENT_TYPE
  {
   GRAPH_ELEMENT_TYPE_STANDARD,                                          class=class="str">"cmt">// Standard graphical object
   GRAPH_ELEMENT_TYPE_ELEMENT,                                           class=class="str">"cmt">// Element
   GRAPH_ELEMENT_TYPE_SHADOW_OBJ,                                        class=class="str">"cmt">// Shadow object
   GRAPH_ELEMENT_TYPE_FORM,                                              class=class="str">"cmt">// Form
   GRAPH_ELEMENT_TYPE_WINDOW,                                            class=class="str">"cmt">// Window
  };

图形对象的通用属性枚举

在 MT5 的底层对象模型里,不同图形对象共享一组通用属性枚举,写自定义指标或脚本时直接引用这些常量就能统一控制外观与行为。 下面这段枚举列出了时间坐标、颜色、线型、线宽、填充、只读、水平层数及每层线色/线型/线宽等 24 个关键项,覆盖了从趋势线到斐波那契弧的常见可调维度。 实际盯盘里若用 AIGC 批量标注形态,靠 GRAPH_OBJ_PROP_RAY_LEFT / RAY_RIGHT 控制射线方向、用 LEVELS 配合 LEVELCOLOR 做多档止损带,会比手动画线省掉约 70% 的重复操作。 注意外汇与贵金属杠杆高、滑点大,任何对象属性自动化修改都先在策略测试器跑一遍,避免实盘误触全图射线导致视觉干扰。

MQL5 / C++
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Graphical object group                                            |
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//--- Properties belonging to different graphical objects
  GRAPH_OBJ_PROP_TIME,                                                   class=class="str">"cmt">// Time coordinate
  GRAPH_OBJ_PROP_COLOR,                                                  class=class="str">"cmt">// Color
  GRAPH_OBJ_PROP_STYLE,                                                  class=class="str">"cmt">// Style
  GRAPH_OBJ_PROP_WIDTH,                                                  class=class="str">"cmt">// Line width
  GRAPH_OBJ_PROP_FILL,                                                   class=class="str">"cmt">// Object class="type">class="kw">color filling
  GRAPH_OBJ_PROP_READONLY,                                               class=class="str">"cmt">// Ability to edit text in the Edit object
  GRAPH_OBJ_PROP_LEVELS,                                                 class=class="str">"cmt">// Number of levels
  GRAPH_OBJ_PROP_LEVELCOLOR,                                             class=class="str">"cmt">// Level line class="type">class="kw">color
  GRAPH_OBJ_PROP_LEVELSTYLE,                                             class=class="str">"cmt">// Level line style
  GRAPH_OBJ_PROP_LEVELWIDTH,                                             class=class="str">"cmt">// Level line width
  GRAPH_OBJ_PROP_ALIGN,                                                  class=class="str">"cmt">// Horizontal text alignment in the Edit object(OBJ_EDIT)
  GRAPH_OBJ_PROP_FONTSIZE,                                               class=class="str">"cmt">// Font size
  GRAPH_OBJ_PROP_RAY_LEFT,                                               class=class="str">"cmt">// Ray goes to the left
  GRAPH_OBJ_PROP_RAY_RIGHT,                                              class=class="str">"cmt">// Ray goes to the right
  GRAPH_OBJ_PROP_RAY,                                                    class=class="str">"cmt">// Vertical line goes through all windows of a chart
  GRAPH_OBJ_PROP_ELLIPSE,                                                class=class="str">"cmt">// Display the full ellipse of the Fibonacci Arc object
  GRAPH_OBJ_PROP_ARROWCODE,                                              class=class="str">"cmt">// Arrow code for the "Arrow" object
  GRAPH_OBJ_PROP_ANCHOR,                                                 class=class="str">"cmt">// Position of the binding point of the graphical object
  GRAPH_OBJ_PROP_XDISTANCE,                                              class=class="str">"cmt">// Distance from the base corner along the X axis in pixels
  GRAPH_OBJ_PROP_YDISTANCE,                                             class=class="str">"cmt">// Distance from the base corner along the Y axis in pixels

「图形对象整数属性的收尾定义」

上面这段枚举收掉了标准图形对象整数属性的最后一批成员,从甘恩线趋势方向到按钮按下/弹起状态,再到内嵌图表对象的周期与坐标偏移,都是 MT5 图形系统里可直接读写的底层字段。 其中 GRAPH_OBJ_PROP_CHART_OBJ_CHART_ID 这类带底色标记的,专门指向 OBJ_CHART 内嵌图表的对象 ID,做多图表联动时绕不开。 宏定义给出硬数据:整数属性总量 GRAPH_OBJ_PROP_INTEGER_TOTAL 为 52,排序时跳过的 GRAPH_OBJ_PROP_INTEGER_SKIP 为 0,说明这 52 个属性全部参与对象枚举排序。 后面 MSG_GRAPH_OBJ_PROP_GROUP 系列是图形对象分组的实数属性入口,把对象按「组 / 线 / 通道」归类,方便在属性面板里折叠管理。外汇与贵金属图表加载这类对象时波动剧烈,属性读写需考虑高频刷新下的性能开销。

MQL5 / C++
  GRAPH_OBJ_PROP_DIRECTION,                                          class=class="str">"cmt">// Gann object trend
  GRAPH_OBJ_PROP_DEGREE,                                              class=class="str">"cmt">// Elliott wave marking level
  GRAPH_OBJ_PROP_DRAWLINES,                                           class=class="str">"cmt">// Display lines for Elliott wave marking
  GRAPH_OBJ_PROP_STATE,                                               class=class="str">"cmt">// Button state(pressed/released)
  GRAPH_OBJ_PROP_CHART_OBJ_CHART_ID,                                  class=class="str">"cmt">// Chart object ID(OBJ_CHART).
  GRAPH_OBJ_PROP_CHART_OBJ_PERIOD,                                    class=class="str">"cmt">// Chart object period
  GRAPH_OBJ_PROP_CHART_OBJ_DATE_SCALE,                                class=class="str">"cmt">// Time scale display flag for the Chart object
  GRAPH_OBJ_PROP_CHART_OBJ_PRICE_SCALE,                               class=class="str">"cmt">// Price scale display flag for the Chart object
  GRAPH_OBJ_PROP_CHART_OBJ_CHART_SCALE,                               class=class="str">"cmt">// Chart object scale
  GRAPH_OBJ_PROP_XSIZE,                                               class=class="str">"cmt">// Object width along the X axis in pixels.
  GRAPH_OBJ_PROP_YSIZE,                                               class=class="str">"cmt">// Object height along the Y axis in pixels.
  GRAPH_OBJ_PROP_XOFFSET,                                             class=class="str">"cmt">// X coordinate of the upper-left corner of the visibility area.
  GRAPH_OBJ_PROP_YOFFSET,                                             class=class="str">"cmt">// Y coordinate of the upper-left corner of the visibility area.
  GRAPH_OBJ_PROP_BGCOLOR,                                             class=class="str">"cmt">// Background class="type">class="kw">color for OBJ_EDIT, OBJ_BUTTON, OBJ_RECTANGLE_LABEL
  GRAPH_OBJ_PROP_CORNER,                                              class=class="str">"cmt">// Chart corner for binding a graphical object
  GRAPH_OBJ_PROP_BORDER_TYPE,                                         class=class="str">"cmt">// Border type for "Rectangle border"
  GRAPH_OBJ_PROP_BORDER_COLOR,                                        class=class="str">"cmt">// Border class="type">class="kw">color for OBJ_EDIT and OBJ_BUTTON
  };
class="macro">#define GRAPH_OBJ_PROP_INTEGER_TOTAL(class="num">52)                             class=class="str">"cmt">// Total number of integer properties
class="macro">#define GRAPH_OBJ_PROP_INTEGER_SKIP(class="num">0)                              class=class="str">"cmt">// Number of integer properties not used in sorting
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| Real properties of a standard graphical object                   |
class=class="str">"cmt">//+------------------------------------------------------------------+
  MSG_GRAPH_OBJ_PROP_GROUP,                                           class=class="str">"cmt">// Graphical object group
  MSG_GRAPH_OBJ_PROP_GROUP_LINES,                                     class=class="str">"cmt">// Lines
  MSG_GRAPH_OBJ_PROP_GROUP_CHANNELS,                                  class=class="str">"cmt">// Channels

◍ 对象属性分组与锚点枚举的收尾定义

在 MT5 的图形对象消息枚举收口处,先列出属性分组类别:LINE/CHANNEL/GANN/FIBO/ELLIOTT/SHAPES/ARROWS/GRAPHICAL,共 8 类,对应对象属性对话框里的分组标签。 锚点相关枚举覆盖了从顶部、底部到九宫格定位的 11 种情形,例如 MSG_GRAPH_OBJ_TEXT_ANCHOR_LEFT_UPPER 表示锚点在左上角,MSG_GRAPH_OBJ_TEXT_ANCHOR_CENTER 表示在正中心。写自定义指标面板时,用这些常量能直接拿到本地化后的界面文案。 两段失败提示枚举值得留意:MSG_GRAPH_OBJ_FAILED_GET_ADDED_OBJ_LIST 与 MSG_GRAPH_OBJ_FAILED_DETACH_OBJ_FROM_LIST,分别指向新增对象列表获取失败、对象从列表移除失败。若你的 EA 在运行时动态挂对象并偶发报错,可优先排查这两处返回。 外汇与贵金属图表上挂大量图形对象时,这类枚举返回的字符串不会随品种变化,但对象过多可能拖慢终端响应,属高风险环境下的性能隐患,建议实盘前在策略测试器里压一遍。

MQL5 / C++
  MSG_GRAPH_OBJ_PROP_GROUP_GANN,                 class=class="str">"cmt">// Gann
  MSG_GRAPH_OBJ_PROP_GROUP_FIBO,                 class=class="str">"cmt">// Fibo
  MSG_GRAPH_OBJ_PROP_GROUP_ELLIOTT,              class=class="str">"cmt">// Elliott
  MSG_GRAPH_OBJ_PROP_GROUP_SHAPES,               class=class="str">"cmt">// Shapes
  MSG_GRAPH_OBJ_PROP_GROUP_ARROWS,               class=class="str">"cmt">// Arrows
  MSG_GRAPH_OBJ_PROP_GROUP_GRAPHICAL,            class=class="str">"cmt">// Graphical objects

  MSG_GRAPH_OBJ_TEXT_CLICK_COORD,                class=class="str">"cmt">// (Chart click coordinate)
  MSG_GRAPH_OBJ_TEXT_ANCHOR_TOP,                 class=class="str">"cmt">// Arrow anchor point is located at the top
  MSG_GRAPH_OBJ_TEXT_ANCHOR_BOTTOM,              class=class="str">"cmt">// Arrow anchor point is located at the bottom

  MSG_GRAPH_OBJ_TEXT_ANCHOR_LEFT_UPPER,          class=class="str">"cmt">// Anchor point at the upper left corner
  MSG_GRAPH_OBJ_TEXT_ANCHOR_LEFT,                class=class="str">"cmt">// Anchor point at the left center
  MSG_GRAPH_OBJ_TEXT_ANCHOR_LEFT_LOWER,          class=class="str">"cmt">// Anchor point at the lower left corner
  MSG_GRAPH_OBJ_TEXT_ANCHOR_LOWER,               class=class="str">"cmt">// Anchor point at the bottom center
  MSG_GRAPH_OBJ_TEXT_ANCHOR_RIGHT_LOWER,         class=class="str">"cmt">// Anchor point at the lower right corner
  MSG_GRAPH_OBJ_TEXT_ANCHOR_RIGHT,               class=class="str">"cmt">// Anchor point at the right center
  MSG_GRAPH_OBJ_TEXT_ANCHOR_RIGHT_UPPER,         class=class="str">"cmt">// Anchor point at the upper right corner
  MSG_GRAPH_OBJ_TEXT_ANCHOR_UPPER,               class=class="str">"cmt">// Anchor point at the upper center
  MSG_GRAPH_OBJ_TEXT_ANCHOR_CENTER,              class=class="str">"cmt">// Anchor point at the very center of the object

  MSG_GRAPH_OBJ_FAILED_GET_ADDED_OBJ_LIST,       class=class="str">"cmt">// Failed to get the list of newly added objects
  MSG_GRAPH_OBJ_FAILED_DETACH_OBJ_FROM_LIST,     class=class="str">"cmt">// Failed to remove a graphical object from the list

};
class=class="str">"cmt">//+------------------------------------------------------------------+
  MSG_GRAPH_OBJ_PROP_GROUP,                      class=class="str">"cmt">// Graphical object group
  MSG_GRAPH_OBJ_PROP_GROUP_LINES,                class=class="str">"cmt">// Lines
  MSG_GRAPH_OBJ_PROP_GROUP_CHANNELS,             class=class="str">"cmt">// Channels
  MSG_GRAPH_OBJ_PROP_GROUP_GANN,                 class=class="str">"cmt">// Gann
  MSG_GRAPH_OBJ_PROP_GROUP_FIBO,                 class=class="str">"cmt">// Fibo
  MSG_GRAPH_OBJ_PROP_GROUP_ELLIOTT,              class=class="str">"cmt">// Elliott
  MSG_GRAPH_OBJ_PROP_GROUP_SHAPES,               class=class="str">"cmt">// Shapes

常见问题

在集合类里补一个接收对象指针的添加方法,创建后直接压入内部数组即可,避免在外面手动维护列表。
容易漏掉锚点相关的枚举和整数属性收尾定义,导致箭头端点或造型位置读不到,建类时顺手把分组枚举补全。
可以,小布能扫一遍你的对象类和枚举命名,标出不一致的地方,省去人工逐文件比对。
后期调用属性时容易传错类型,建议把通用属性和整数属性分组放,并在注释里写清取值边界。
写个遍历所有枚举值的打印脚本,跑一遍看是否每个分组都能正常输出,缺项会直接报错或留白。