DoEasy 库中的其他类(第六十八部分):图表窗口对象类和图表窗口中的指标对象类(基础篇)
◍ DoEasy 里的图表窗口与指标对象类
DoEasy 库从第六十八部分起,把图表窗口抽象成一个独立类,并在其内部挂接指标对象类,让脚本能直接按窗口维度管理指标实例,而不是散落在全局图表对象里。 原文示例发布于 2021 年 6 月 14 日 08:51,截至统计显示有 1 872 次查看、9 条讨论,说明这套封装在实际搬砖中有人真正跑过。 对于做价格行为复盘的读者,这种类结构意味着你可以在 MT5 里用统一接口遍历主图与子窗口的指标,再交给小布类的 AIGC 工具做特征提取,外汇与贵金属品种波动大、杠杆高,验证前先用模拟盘跑通逻辑。
「先补齐窗口与指标的对象骨架」
上篇已经搭起图表对象的第一版,能拿窗口尺寸、切子窗口显隐,但还没法直接摸到某个子窗口里挂了哪些指标。今天要补两个底层对象:一个是窗口里的指标对象,只存识别用的参数;另一个是窗口对象,记着自己高度和挂在其上的指标对象列表。 主图窗口和子窗口在结构上是平级的,都归图表对象管。拿到窗口对象后,就能拉出它的指标列表、取句柄,后面做批量处理才顺手。 现在直接写图表对象集合类还早,得先把图表、窗口、指标这三层对象各自打磨完。层次理清了,后续同时操控多图表、多子窗口、多指标才不会乱。 外汇和贵金属品种在 MT5 上子窗口指标数量差异很大,动手前建议在终端里开两个不同品种对照窗口数验证一下。
把图表子窗口和指标句柄收进对象里
做 MT5 底层封装时,图表主窗口和子窗口的属性常被忽略。原文在 DoEasy 库里专门补了三类:子窗口可见性、指标子窗口上框相对主窗口上框的 Y 轴像素距离、以及以像素为单位的图表高度。这些不是装饰参数,而是你后续用 ChartSetInteger() 动态调整子窗口高度、或按句柄抓指标时必须先读出来的底料。 整数型属性枚举从 62 扩到 67,字符串型从 4 到 5,多出来的就是窗口级和指标级常量。CWndInd 类只存四样东西:图表 ID、指标短名、所在窗口索引(0 是主窗)、指标句柄。短名 + 句柄足以在 CArrayObj 列表里唯一定位一个指标,不用把指标所有参数都搬进来。 CChartWnd 类持有该窗口的指标指针列表和子窗口索引。要注意 CHART_WINDOW_YDISTANCE 是只读属性,只能取不能设;而窗口高度可用 ChartSetInteger() 写,写完后必须强制 ChartRedraw(),否则得干等报价或鼠标事件才刷新。外汇和贵金属多窗口盯盘时乱刷屏容易漏信号,这点要留心。 指标句柄有引用计数陷阱。用 ChartIndicatorGet() 按短名拿句柄后,终端内部计数器 +1;若不再用却不 ReleaseIndicator(),以后就抓不回“丢失”的句柄。所以在建列表拿到短名和句柄后应立即释放。更新列表时先删实际不存在的,再补新出现的,保持对象描述和终端真实状态一致。
◍ 遍历图表子窗口与指标枚举的坑
给图表对象类做扩展时,循环里遇到“指标句柄”和“窗口中的指标索引”这类属性要直接跳过——它们挂在指标内部,跟图表对象本身没关系。若碰到“图表高度像素”属性,就调显示所有窗口属性的方法;若是“窗口中的指标名称”,则调显示该窗口附加指标描述的方法。 日志输出也做了细化:简述方法现在会打印子窗口数量,没有就提示无子窗口。遍历所有图表窗口时,每取到一个窗口对象,就打印它附着的指标描述(传 true 让指标前带连字符)和窗口参数描述。 按子窗口索引取对象的方法,是在窗口总数循环里逐个比对象索引,命中就返回指针,跑完没命中返回 NULL。设置子窗口可见性只需给主窗口加只读属性;取 Y 轴像素距离或高度像素时,按索引拿对象返属性值,拿不到返 -1,设高度失败返 false。 下面这段枚举和本地化字符串定义了窗口与指标相关的消息标识,以及图表整型属性起点。注意 CHART_PROP_ID 从 0 开始,CHART_PROP_IS_OBJECT 用来区分 OBJ_CHART 对象,写 EA 调试面板时可以直接复用这些常量。外汇与贵金属波动剧烈,用这类接口读窗口状态只作辅助诊断,实盘仍需严格风控。
MSG_CHART_OBJ_CHART_WINDOW, <span class="comment">class=class="str">"cmt">// Main chart window</span> <span style="background-class="type">class="kw">color:rgb(class="num">255, class="num">246, class="num">200);"> MSG_CHART_OBJ_CHART_SUBWINDOW, <span class="comment">class=class="str">"cmt">// Chart subwindow</span> MSG_CHART_OBJ_CHART_SUBWINDOWS_NUM, <span class="comment">class=class="str">"cmt">// Subwindows</span> MSG_CHART_OBJ_INDICATORS_MW_NAME_LIST, <span class="comment">class=class="str">"cmt">// Indicators in the main chart window</span> MSG_CHART_OBJ_INDICATORS_SW_NAME_LIST, <span class="comment">class=class="str">"cmt">// Indicators in the chart window</span> MSG_CHART_OBJ_INDICATOR, <span class="comment">class=class="str">"cmt">// Indicator</span> MSG_CHART_OBJ_INDICATORS_TOTAL, <span class="comment">class=class="str">"cmt">// Indicators</span> MSG_CHART_OBJ_WINDOW_N, <span class="comment">class=class="str">"cmt">// Window</span> MSG_CHART_OBJ_INDICATORS_NONE, <span class="comment">class=class="str">"cmt">// No indicators</span></span> }; <span class="comment">class=class="str">"cmt">//+------------------------------------------------------------------+</span> {"<span class="class="type">class="kw">string">Главное окно графика</span>","<span class="class="type">class="kw">string">Main chart window</span>"}, <span style="background-class="type">class="kw">color:rgb(class="num">216, class="num">232, class="num">194);"> {"<span class="class="type">class="kw">string">Подокно графика</span>","<span class="class="type">class="kw">string">Chart subwindow</span>"}, {"<span class="class="type">class="kw">string">Подокон</span>","<span class="class="type">class="kw">string">Subwindows</span>"}, {"<span class="class="type">class="kw">string">Индикаторы в главном окне графика</span>","<span class="class="type">class="kw">string">Indicators in the main chart window</span>"}, {"<span class="class="type">class="kw">string">Индикаторы в окне графика</span>","<span class="class="type">class="kw">string">Indicators in the chart window</span>"}, {"<span class="class="type">class="kw">string">Индикатор</span>","<span class="class="type">class="kw">string">Indicator</span>"}, {"<span class="class="type">class="kw">string">Индикаторов</span>","<span class="class="type">class="kw">string">Indicators total</span>"}, {"<span class="class="type">class="kw">string">Окно</span>","<span class="class="type">class="kw">string">Window</span>"}, {"<span class="class="type">class="kw">string">Отсутствуют</span>","<span class="class="type">class="kw">string">No indicators</span>"},</span> }; <span class="comment">class=class="str">"cmt">//+---------------------------------------------------------------------+</span> <span class="comment">class=class="str">"cmt">//+------------------------------------------------------------------+</span> <span class="comment">class=class="str">"cmt">//| Chart integer class="kw">property |</span> <span class="comment">class=class="str">"cmt">//+------------------------------------------------------------------+</span> <span class="keyword">enum</span> ENUM_CHART_PROP_INTEGER { CHART_PROP_ID = <span class="number">class="num">0</span>, <span class="comment">class=class="str">"cmt">// Chart ID</span> CHART_PROP_TIMEFRAME, <span class="comment">class=class="str">"cmt">// Chart timeframe</span> CHART_PROP_SHOW, <span class="comment">class=class="str">"cmt">// Price chart drawing</span> CHART_PROP_IS_OBJECT, <span class="comment">class=class="str">"cmt">// Chart object(OBJ_CHART) identification attribute</span> CHART_PROP_BRING_TO_TOP, <span class="comment">class=class="str">"cmt">// Show chart above all others</span>
「图表交互与显示属性的枚举清单」
MT5 图表对象有一组 CHART_PROP_* 枚举,专门控制交互权限和视觉呈现。把它们摸熟,你写 EA 或指标时才不会在右键菜单、十字光标、滚轮事件上跟终端默认行为打架。 CHART_PROP_CONTEXT_MENU 控制右键菜单是否可呼出;CHART_PROP_CROSSHAIR_TOOL 管中键十字光标;CHART_PROP_MOUSE_SCROLL 决定左键能否横向拖图。若要做自定义鼠标逻辑,先把这几个关掉,否则你的 OnChartEvent 会和原生操作抢事件。 CHART_PROP_EVENT_MOUSE_WHEEL 与 CHART_PROP_EVENT_MOUSE_MOVE 决定滚轮和鼠标移动消息是否广播给图表上所有 MQL5 程序。实测若不开启,EA 收不到 CHARTEVENT_MOUSE_WHEEL,量价联动悬浮窗就废了。 显示层方面,CHART_PROP_MODE 切蜡烛/柱线/折线;CHART_PROP_SCALE 系列(SCALEFIX、SCALEFIX_11、SCALE_PT_PER_BAR)控制缩放锚定;CHART_PROP_SHOW_TICKER、SHOW_OHLC、SHOW_BID_LINE 分别管左上角符号、OHLC 和买价横线的显隐。外汇与贵金属波动剧烈,图表属性误设可能造成误读,属高风险操作环境。
CHART_PROP_CONTEXT_MENU, class=class="str">"cmt">// Enable/disable access to the context menu class="kw">using the right click CHART_PROP_CROSSHAIR_TOOL, class=class="str">"cmt">// Enable/disable access to the Crosshair tool class="kw">using the middle click CHART_PROP_MOUSE_SCROLL, class=class="str">"cmt">// Scroll the chart horizontally class="kw">using the left mouse button CHART_PROP_EVENT_MOUSE_WHEEL, class=class="str">"cmt">// Send messages about mouse wheel events(CHARTEVENT_MOUSE_WHEEL) to all MQL5 programs on a chart CHART_PROP_EVENT_MOUSE_MOVE, class=class="str">"cmt">// Send messages about mouse button click and movement events(CHARTEVENT_MOUSE_MOVE) to all MQL5 programs on a chart CHART_PROP_EVENT_OBJECT_CREATE, class=class="str">"cmt">// Send messages about the graphical object creation event(CHARTEVENT_OBJECT_CREATE) to all MQL5 programs on a chart CHART_PROP_EVENT_OBJECT_DELETE, class=class="str">"cmt">// Send messages about the graphical object destruction event(CHARTEVENT_OBJECT_DELETE) to all MQL5 programs on a chart CHART_PROP_MODE, class=class="str">"cmt">// Type of the chart(candlesticks, bars or line(ENUM_CHART_MODE)) CHART_PROP_FOREGROUND, class=class="str">"cmt">// Price chart in the foreground CHART_PROP_SHIFT, class=class="str">"cmt">// Mode of shift of the price chart from the right border CHART_PROP_AUTOSCROLL, class=class="str">"cmt">// The mode of automatic shift to the right border of the chart CHART_PROP_KEYBOARD_CONTROL, class=class="str">"cmt">// Allow managing the chart class="kw">using a keyboard CHART_PROP_QUICK_NAVIGATION, class=class="str">"cmt">// Allow the chart to intercept Space and Enter key strokes to activate the quick navigation bar CHART_PROP_SCALE, class=class="str">"cmt">// Scale CHART_PROP_SCALEFIX, class=class="str">"cmt">// Fixed scale mode CHART_PROP_SCALEFIX_11, class=class="str">"cmt">// class="num">1:class="num">1 scale mode CHART_PROP_SCALE_PT_PER_BAR, class=class="str">"cmt">// The mode of specifying the scale in points per bar CHART_PROP_SHOW_TICKER, class=class="str">"cmt">// Display a symbol ticker in the upper left corner CHART_PROP_SHOW_OHLC, class=class="str">"cmt">// Display OHLC values in the upper left corner CHART_PROP_SHOW_BID_LINE class=class="str">"cmt">// Display Bid value as a horizontal line on the chart
图表窗口与配色属性的枚举落点
上面这批 CHART_PROP_* 枚举收尾在子窗口可见性与像素尺寸上,其中 CHART_PROP_WINDOW_IS_VISIBLE、CHART_PROP_WINDOW_YDISTANCE、CHART_PROP_HEIGHT_IN_PIXELS 三个是调多窗布局时最容易漏掉的。 CHART_PROP_WINDOW_YDISTANCE 量的是指标子窗上边框到主图窗上边框的 Y 轴像素距离,改它能在不重排指标的情况下压窄留白。 配色类从 CHART_PROP_COLOR_BACKGROUND 到 CHART_PROP_COLOR_CHART_LINE 共 9 个,覆盖背景、坐标轴、网格、成交量、涨跌柱和 Doji 线;直接写 ChartSetInteger/ChartGetInteger 改这些属性,比手动在 MT5 属性面板点更快,也方便用小布脚本批量换肤。 外汇与贵金属杠杆高、滑点随机,任何界面层改动都只是辅助观察,不替代仓位与止损纪律。
CHART_PROP_SHOW_ASK_LINE, class=class="str">"cmt">// Display Ask value as a horizontal line on a chart CHART_PROP_SHOW_LAST_LINE, class=class="str">"cmt">// Display Last value as a horizontal line on a chart CHART_PROP_SHOW_PERIOD_SEP, class=class="str">"cmt">// Display vertical separators between adjacent periods CHART_PROP_SHOW_GRID, class=class="str">"cmt">// Display a grid on the chart CHART_PROP_SHOW_VOLUMES, class=class="str">"cmt">// Display volumes on a chart CHART_PROP_SHOW_OBJECT_DESCR, class=class="str">"cmt">// Display text descriptions of objects CHART_PROP_VISIBLE_BARS, class=class="str">"cmt">// Number of bars on a chart that are available for display CHART_PROP_WINDOWS_TOTAL, class=class="str">"cmt">// The total number of chart windows including indicator subwindows CHART_PROP_WINDOW_IS_VISIBLE, class=class="str">"cmt">// Subwindow visibility CHART_PROP_WINDOW_HANDLE, class=class="str">"cmt">// Chart window handle CHART_PROP_WINDOW_YDISTANCE, class=class="str">"cmt">// Distance in Y axis pixels between the upper frame of the indicator subwindow and the upper frame of the chart main window CHART_PROP_FIRST_VISIBLE_BAR, class=class="str">"cmt">// Number of the first visible bar on the chart CHART_PROP_WIDTH_IN_BARS, class=class="str">"cmt">// Width of the chart in bars CHART_PROP_WIDTH_IN_PIXELS, class=class="str">"cmt">// Width of the chart in pixels CHART_PROP_HEIGHT_IN_PIXELS, class=class="str">"cmt">// Height of the chart in pixels CHART_PROP_COLOR_BACKGROUND, class=class="str">"cmt">// Color of background of the chart CHART_PROP_COLOR_FOREGROUND, class=class="str">"cmt">// Color of axes, scale and OHLC line CHART_PROP_COLOR_GRID, class=class="str">"cmt">// Grid class="type">class="kw">color CHART_PROP_COLOR_VOLUME, class=class="str">"cmt">// Color of volumes and position opening levels CHART_PROP_COLOR_CHART_UP, class=class="str">"cmt">// Color for the up bar, shadows and body borders of bull candlesticks CHART_PROP_COLOR_CHART_DOWN, class=class="str">"cmt">// Color of down bar, its shadow and border of body of the bullish candlestick CHART_PROP_COLOR_CHART_LINE, class=class="str">"cmt">// Color of the chart line and the Doji candlesticks