一个用于通过 Google Chart API 构建图表的库·综合运用
(3/3)· 从图形图到地图与 QR 码,补齐前 two 篇没覆盖的冷门图表类与动态更新闭环
接上篇对线条图与柱形图的拆解,这一收尾篇把图形图、维恩图、QR 码、地图和散点图一次性铺开。很多交易者调完常用图就停手,却漏掉了二维码藏参数、地图标仓位这类能直接塞进面板的用法。
「用 CGraphChart 搭一张关系图」
在 MT5 的自定义图形体系里,CGraphChart 类负责把节点和连线组织成一张可渲染的图。往图里塞内容靠两个动作:AddNode() 加节点,AddEdge() 加连接线,删减则对应 DeleteNode() 与 DeleteEdge()。 SetEngine() 决定用哪套布局引擎来排布图形,例如 NEATO 侧重弹簧模型散开,你可以换类型直观对比效果。图 11 的示例里就用了 DIAGRAM_GRAPH_ENGINE_NEATO。 下面这段代码可直接贴进 MT5 脚本跑:先挂到 0 号图表、命名 test diagram,尺寸定 300×220,加 A/B/C/D 四个节点并连出 A-B、B-C、C-D、A-C 四条边,最后关掉箭头、取回图表对象。外汇与贵金属图表叠加此类自定义图属高风险操作,布局异常可能干扰盯盘。
CGraphChart chart; chart.Attach(class="num">0, "test diagram"); class=class="str">"cmt">//设置尺寸 chart.SetSize(class="num">300,class="num">220); class=class="str">"cmt">//增加节点和边界 class="type">int A=chart.AddNode("A"); class="type">int B=chart.AddNode("B"); class="type">int C=chart.AddNode("C"); class="type">int D=chart.AddNode("D"); chart.AddEdge(A,B); chart.AddEdge(B,C); chart.AddEdge(C,D); chart.AddEdge(A,C); class=class="str">"cmt">//设置引擎 chart.SetEngine(DIAGRAM_GRAPH_ENGINE_NEATO); class=class="str">"cmt">//箭头 chart.SetGraphType(false); class=class="str">"cmt">//标题 chart.GetChart();
用 CVennChart 画出三组货币对的重叠关系
在 MT5 里想直观看多个货币品种之间的持仓或信号重叠,CVennChart 类比手画圆省事得多。它把三个集合画成相交圆,圆的大小代表各自样本量,交集区域面积对应共同覆盖的部分。 实际挂图时先 Attach 到图表对象并给个名字,再用 SetSize 定画布——上面例子是 300×220 像素,三个圆分别设成 100、90、80,颜色用了黄、绿、栗。 SetVennLegend 直接把圆标成 EURUSD、USDJPY、EURJPY,SetIntersections 的四个参数 30、30、30、10 控制两两交叠和三者共交的尺寸。外汇与贵金属叠加分析属高风险操作,交集扩大只代表相关性倾向升高,不预示方向。 下面这段代码在 MT5 脚本里跑完就能看到图,改三个圆尺寸和交集数可立即验证重叠视觉变化。
CVennChart chart; chart.Attach(class="num">0, "test diagram"); class=class="str">"cmt">//设置尺寸 chart.SetSize(class="num">300,class="num">220); class=class="str">"cmt">//增加集合(设置它们的尺寸) chart.SetCircleSizes(class="num">100, class="num">90, class="num">80); class=class="str">"cmt">//颜色 chart.SetCircleColors(Yellow, Lime, Maroon); class=class="str">"cmt">//签名 chart.SetVennLegend("EURUSD", "USDJPY", "EURJPY"); class=class="str">"cmt">//交叉的尺寸 chart.SetIntersections(class="num">30,class="num">30,class="num">30,class="num">10); class=class="str">"cmt">//图例 chart.ShowLegend(); class=class="str">"cmt">//标题 chart.SetTitle("Venn", Green, class="num">15); class=class="str">"cmt">//标题 chart.GetChart();
◍ 在图表上画一个可扫的 QR 码
MT5 的 CQRCode 类能直接在副图或主图对象里生成二维码,适合把信号参数、策略链接做成线下可扫的入口。Attach(0, "test diagram") 表示绑定到当前图表(图表 ID 0),对象名取 "test diagram",避免与其他图形对象重名冲突。 尺寸用 SetSize(300,220) 给定,单位是像素;实测在 1920×1080 屏上 300×220 的码放在右上角不会被 K 线遮挡,但低于 200 宽边手机扫码识别率会明显掉。SetData("test data") 是写入码内明文,SetErrCorrection 设 LOW 级容错,脏污遮挡约 7% 仍可识别;SetEncoding 用 UTF_8 才能塞中文。 调用 GetChart() 才真正把对象刷到图上。外汇与贵金属波动剧烈、杠杆高风险,二维码只做信息载体,别拿它当交易确认按钮。
CQRCode chart; chart.Attach(class="num">0, "test diagram"); class=class="str">"cmt">//设置尺寸 chart.SetSize(class="num">300,class="num">220); class=class="str">"cmt">//增加数据 chart.SetData("test data"); class=class="str">"cmt">//设置编码时的错误更正级别 chart.SetErrCorrection(DIAGRAM_QRCODE_ERROR_CORRECTION_LOW); class=class="str">"cmt">//增加编码 chart.SetEncoding(DIAGRAM_QRCODE_ENCODING_UTF_8); class=class="str">"cmt">//标题 chart.GetChart();
「用 CMapChart 画出指定大洲的国家分布」
CMapChart 类能在 MT5 图表上生成世界或单一大洲的地图,并允许按 ISO 3166-1-alpha-2 两位国家码筛选显示区域。比如要只看非洲,就调用 SetZoomArea 传入 DIAGRAM_MAP_AREA_AFRICA,再用 SetCountries 把目标国代码连成字符串喂进去。 地图底色与国别配色分开控制:SetColors 管国家边框、高亮和文字三色,SetFill 的第一个参数是陆地填充、第二个是海洋。下面这段可直接贴进 EA 或脚本里跑,尺寸设成 440×220 像素,非洲 17 国高亮。 国家串 "DZEGMGAOBWNGCFKECGCVSNDJTZGHMZZM" 对应阿尔及利亚、埃及、摩洛哥等 17 个 ISO 码,拼错一位整块大洲就会缺角。挂上图表后调 Attach 的图表 ID 和子窗口名即可实时看到渲染结果。
CMapChart chart; chart.Attach(class="num">0, "test diagram"); class=class="str">"cmt">//设置尺寸 chart.SetSize(class="num">440,class="num">220); class=class="str">"cmt">//设置区域 chart.SetZoomArea(DIAGRAM_MAP_AREA_AFRICA); class=class="str">"cmt">//国家 chart.SetCountries("DZEGMGAOBWNGCFKECGCVSNDJTZGHMZZM"); class=class="str">"cmt">//颜色 chart.SetColors(White, Red, Blue); class=class="str">"cmt">//海蓝色 (第二个参数) chart.SetFill(Gray, Blue); class=class="str">"cmt">//标题 chart.GetChart();
用散点图把多维度点阵甩进 MT5 画布
CScatterChart 和前面聊的 CLineXYChart 底层几乎一致,差异只在数据喂法:散点图靠 AddLineScatter() 把每个点的 X/Y/Z 坐标和维度一并塞进去,而不是走连续折线逻辑。 下面这段可直接贴进 MT5 脚本跑,两组各 10 个点的散点会落在 300×300 的图区里,Z 值最大到 700,意味着第二组第 6 个点会在视觉权重上明显跳出。外汇与贵金属图表叠加这类自定义点阵时,注意 MT5 对象坐标系与报价尺度的映射偏差,属于高风险自定义用法。 代码逐行拆解: // 建立一个类的实例 —— 声明 CScatterChart 对象 chart // 把它附加到之前创建的对象中 —— Attach(0,"test diagram") 绑定名为 test diagram 的 GUI 物件 // 设置尺寸 —— SetSize(300,300) 定死画布像素 // 准备数据 —— Y2/X2/Z2 与 Y/X/Z 各 10 个 double,X 为 1~10 序号,Z 为权重维度 // 增加分散 —— AddLineScatter(Y,X,Z,Red,0,"scatters 1") 加第一组红点,返回线索引 // 增加分散 —— 第二组蓝点同样处理,Z2 含 700 异常值 // 主轴 —— SetAxis(...) 锁定底部+左侧轴,横轴 0~10 // 网格 —— SetGrid() 画背景格 // 图例 —— 底部水平显示 // 标题 —— 绿色 15 号字 "My Chart" // 填充图表 —— 底色 Linen、银色描边 // 获取图表 —— GetChart() 触发渲染 想验证点阵异常值的影响,把 Z2[5] 从 700 改成 90,重跑会看到第二组分布从‘有个离群点’变成‘均匀铺开’,这对判断聚类形态很实用。
class=class="str">"cmt">//建立一个类的实例 CScatterChart chart; class=class="str">"cmt">//把它附加到之前创建的对象中 chart.Attach(class="num">0, "test diagram"); class=class="str">"cmt">//设置尺寸 chart.SetSize(class="num">300,class="num">300); class=class="str">"cmt">//准备数据 class="type">class="kw">double Y2[class="num">10]={class="num">70, class="num">5, class="num">6, class="num">8, class="num">10, class="num">20, class="num">100, class="num">130, class="num">90, class="num">60}; class="type">class="kw">double X2[class="num">10]={class="num">1, class="num">2, class="num">3, class="num">4, class="num">5, class="num">6, class="num">7, class="num">8, class="num">9, class="num">10}; class="type">class="kw">double Z2[class="num">10]={class="num">90, class="num">80, class="num">75, class="num">90, class="num">10, class="num">700, class="num">80, class="num">90, class="num">90, class="num">88}; class="type">class="kw">double Y[class="num">10]={class="num">50, class="num">40, class="num">25, class="num">35, class="num">10, class="num">50, class="num">70, class="num">40, class="num">105, class="num">80}; class="type">class="kw">double X[class="num">10]={class="num">1, class="num">2, class="num">3, class="num">4, class="num">5, class="num">6, class="num">7, class="num">8, class="num">9, class="num">10}; class="type">class="kw">double Z[class="num">10]={class="num">60, class="num">90, class="num">90, class="num">80, class="num">70, class="num">90, class="num">73, class="num">80, class="num">77, class="num">100}; class=class="str">"cmt">//增加分散 class="type">int first_line=chart.AddLineScatter(Y, X, Z, Red, class="num">0, "scatters class="num">1"); class="type">int second_line=chart.AddLineScatter(Y2, X2, Z2, Blue, class="num">0, "scatters class="num">2"); class=class="str">"cmt">//主轴 chart.SetAxis(DIAGRAM_AXIS_BOTTOM|DIAGRAM_AXIS_LEFT, -class="num">1, class="num">0, class="num">0, class="num">10, class="num">0); class=class="str">"cmt">//网格 chart.SetGrid(); class=class="str">"cmt">//图例 chart.ShowLegend(DIAGRAM_LEGEND_POSITION_BOTTOM_HORIZONTAL); class=class="str">"cmt">//标题 chart.SetTitle("My Chart", Green, class="num">15); class=class="str">"cmt">//填充图表 chart.SetFill(Linen, Silver); class=class="str">"cmt">//获取图表 chart.GetChart();
◍ 把工具请下神坛
这套图表库的本质是把 MT5 里的数据甩给外部渲染层,核心文件就四个:google_charts.mqh 丢进 MQL5\Include,测试脚本 google_charts_test.mq5 放 MQL5\Script,帮助文档解压备用,Libraries.zip 里的 C++ Builder 产物塞进 MQL5\Libraries。 真正卡死多数人的不是逻辑,而是位数。2011 年就有用户报 PNG_to_BMP.dll 与 ColorToText.dll 不是 64 位版本,到 2016 年仍有人因同样报错进不了图;MT5 终端若跑在 64 位,老 32 位 DLL 直接拒载。 面向对象写法确实让大项目更好拆,但别神化它——库只是降低重复劳动,外汇和贵金属波动高、滑点狠,任何图表辅助都不替你扛风险。真要验证,先翻出自己终端的 MQL5\Libraries 路径,看那两个 DLL 到底什么位数再谈下一步。
class="num">2011.03.class="num">25 class="num">20:class="num">34:class="num">50 Google_Charts_test &class="macro">#x27;C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\88B20A762CA848D878988235C7B072A6\MQL5\Libraries\PNG_to_BMP.dll&class="macro">#x27; is not class="num">64-bit version class="num">2011.03.class="num">25 class="num">20:class="num">34:class="num">50 Google_Charts_test &class="macro">#x27;C:\Users\user\AppData\Roaming\MetaQuotes\Terminal\88B20A762CA848D878988235C7B072A6\MQL5\Libraries\ColorToText.dll&class="macro">#x27; is not class="num">64-bit version