如何基于HTML和CSV报表可视化多币种交易历史·综合运用
「清理残留的副图指标」
在 MT5 脚本里批量移除旧版副图指标,最直接的方式是遍历图表上的指标槽位,用前缀做匹配。下面这段代码针对名称为 "SubChartReporter" 开头的指标执行删除,避免手动一个个右击移除的低效操作。 [CODE] string name = ChartIndicatorName(0, i, 0); if(StringFind(name, "SubChartReporter") == 0) { Print("Deleting ", name); result &= ChartIndicatorDelete(0, i, name); } } return result; } [/CODE] 逐行拆解:第 1 行用 ChartIndicatorName 取当前图表(0 号)、第 i 个窗口、第 0 子项的指标名;第 2 行 StringFind 返回 0 表示名字以 "SubChartReporter" 起头;第 4 行 Print 仅打印日志便于排查;第 5 行 ChartIndicatorDelete 执行删除,并用 &= 累积成功标记;末尾 return 把整体结果交回调用方。 实盘前先在 EURUSD 的 M1 上挂两个同名测试指标跑一遍,确认无残留再用于正式模板。外汇与贵金属杠杆高,误删正在计算的信号指标可能让策略短暂失聪,操作前建议先存模板。
class="type">class="kw">string name = ChartIndicatorName(class="num">0, i, class="num">0); if(StringFind(name, "SubChartReporter") == class="num">0) { Print("Deleting ", name); result &= ChartIndicatorDelete(class="num">0, i, name); } } class="kw">return result; }
◍ 主图指标怎么甩掉缓冲区
MainChartReporter 直接画在主图窗口,不需要任何指标缓冲区,也不画趋势以外的对象。它会在 apply 里把当前图表切到真实分析品种,并留一行 Comment 显示标题,逻辑上就是 SubChartReporter 的精简版。 三个核心类 Processor、ReportProcessor、HistoryProcessor 被挪进共用头文件,靠 CHART_REPORTER_MAIN 与 CHART_REPORTER_SUB 两个宏做条件编译区分。主图版只加两行切换品种和注释,子图版才保留按 _Symbol 重绘的兼容代码。 原缓冲相关声明全部删掉:indicator_buffers 设 0、indicator_plots 设 0,子窗口参数组一并移除。OnCalculate 留空函数壳,数据拉取完全交给 OnInit 里启动的定时器。 代码里有一段 ChartNavigate 试图滚到首笔交易位置,作者实测从未生效——图表不会被移动。更稳的思路是用 CHART_CURRENT_POS 基于当前位置相对导航,但样本里没采用。外汇与贵金属品种切换涉及实时报价,实操请先在模拟盘验证高风险。
class="macro">#ifdef CHART_REPORTER_MAIN ChartSetSymbolPeriod(class="num">0, real, _Period); class="macro">#endif class="macro">#ifdef CHART_REPORTER_MAIN Comment(title); class="macro">#endif class="macro">#ifdef CHART_REPORTER_SUB ChartSetSymbolPeriod(class="num">0, _Symbol, _Period); class="macro">#endif class="macro">#class="kw">property indicator_chart_window class="macro">#class="kw">property indicator_buffers class="num">0 class="macro">#class="kw">property indicator_plots class="num">0 class="kw">input GroupSettings Chart_Settings; class=class="str">"cmt">// 子图表设置 class="kw">input class="type">class="kw">string SubSymbol = ""; class=class="str">"cmt">// · 交易品种 class="kw">input class="type">bool Exact = true; class=class="str">"cmt">// · Exact class="type">void OnTimer() { EventKillTimer(); if(processor.isEmpty()) class=class="str">"cmt">// 只载入一次文件 { if(processor.attach(ReportFile)) { processor.apply(); class="type">class="kw">datetime start = processor.getStart(); if(start != class="num">0) { ChartSetInteger(ChartID(), CHART_AUTOSCROLL, class="kw">false); class=class="str">"cmt">// FIXME: 这里没有正确工作 ChartNavigate(ChartID(), CHART_END, -class="num">1 * (iBarShift(_Symbol, _Period, start))); } } } }
别急着下结论
把多品种报价和成交记录画到一张图上看,核心输入不一定是 MT5 自带报表。用通用解析器吃 HTML,再补一层 CSV 支持,就能把信号历史也拉进来——俄文原版工程里那套 report2chart 就是这么干的,ZIP 包 34.55 KB,开源可改。 MQL 环境有个坑:编译器不保证向后兼容,老头文件在新版 MT5 可能直接编不过。上面讨论区里有人 2020 年 1 月换掉两个头文件才跑通,说明你下载源码后第一件事不是拖进图表,而是核对构建版本。 下面这三行是原文里顺手给出的水平线画法,能在图表上标出当前收盘价参考线,自己开 MT5 新建脚本粘进去就能验证: ObjectCreate 建一条名为 Close 的水平线,绑定到子窗口 1;ObjectSetInteger 把颜色设成浅石板灰;ObjectMove 按 close[0] 重定位。外汇和贵金属波动大,这类参考线只是视觉辅助,不代表方向判断。
ObjectCreate(NULL,"Close",OBJ_HLINE,class="num">1,class="num">1,close[class="num">0]); ObjectSetInteger(class="num">0,"Close",OBJPROP_COLOR,clrLightSlateGray); ObjectMove(class="num">1,"Close",class="num">1,class="num">1,close[class="num">0]);