市场模拟(第六部分):将信息从 MetaTrader 5 传输到 Excel·综合运用
(3/3)· 不用 VBA 底子也能把报价和持仓喂进 Excel,长线多空仓管理不再靠手抄
「用循环把多品种日线收盘价吐给外部文件」
这段逻辑处在共享类的析构与轮询方法里,负责把一批品种的 D1 收盘价持续写出到文本文件,供 Excel 侧实时读取。
析构函数 ~C_ShareAtExcel() 先 ArrayResize(szSymbol, 0) 清空品种数组,再打印 Finished 收尾;构造函数里则在第 49 行 FileClose(file) 关句柄、第 50 行把 bError 置 false、第 51 行 Message("Started") 表示启动。
Looping(int seconds) 是核心:第 65 行 while ((!_StopFlag) && (!bError)) 在 EA 未被停止且未出错时死循环;第 68–69 行遍历 maxBuff 个品种,用 StringFormat("%s;%0.2f\r\n", szSymbol[c0], iClose(szSymbol[c0], PERIOD_D1, 0)) 拼出「品种名;日线最新收盘价(留两位小数)」并换行。
| 第 70 行以 `FILE_TXT | FILE_WRITE | FILE_ANSI | FILE_SHARE_WRITE` 打开文件,拿到非 `INVALID_HANDLE` 的句柄才继续写盘。外汇与贵金属价格跳动频繁,这种共享写盘方式在 MT5 实盘里可能带来文件锁竞争,建议开 MT5 用少量品种先验证 `maxBuff` 与刷新节奏。 |
|---|
class="num">49. FileClose(file); class="num">50. bError = false; class="num">51. Message("Started"); class="num">52. } class="num">53. class=class="str">"cmt">//+------------------------------------------------------------------+ class="num">54. ~C_ShareAtExcel() class="num">55. { class="num">56. ArrayResize(szSymbol, class="num">0); class="num">57. Message("Finished"); class="num">58. } class="num">59. class=class="str">"cmt">//+------------------------------------------------------------------+ class="num">60. class="type">void Looping(class="type">int seconds) class="num">61. { class="num">62. class="type">class="kw">string szInfo; class="num">63. class="type">int file; class="num">64. class="num">65. while ((!_StopFlag) && (!bError)) class="num">66. { class="num">67. szInfo = ""; class="num">68. for (class="type">int c0 = class="num">0; c0 < maxBuff; c0++) class="num">69. szInfo += StringFormat("%s;%class="num">0.2f\r\n", szSymbol[c0], iClose(szSymbol[c0], PERIOD_D1, class="num">0)); class="num">70. if ((file = FileOpen(szFileName, FILE_TXT | FILE_WRITE | FILE_ANSI | FILE_SHARE_WRITE)) != INVALID_HANDLE) class="num">71. {
把行情推给 Excel 的落地写法
上面这段是 EA 主逻辑里真正干活的尾巴:把拼好的字符串写进文件、关句柄,再按秒级间隔轮询。 FileWriteString(file, szInfo) 负责把一行共享信息落盘,FileClose(file) 紧跟其后释放文件句柄,避免 MT5 占用导致 Excel 侧读不到更新。 循环体里 Sleep(seconds * 1000) 用毫秒作单位,传参 2 就是每 2 秒跑一次 Looping,适合分钟级以下的高频盯盘共享,但别设太小——MT5 对 Sleep 低于 1 毫秒的调用会直接忽略。 OnStart 里先 new 一个 C_ShareAtExcel(user01) 实例,Looping(2) 启动后 delete 回收,外汇与贵金属波动剧烈、杠杆风险高,这类常驻共享进程建议只在模拟盘先验证句柄泄漏情况。
class="num">72. FileWriteString(file, szInfo); class="num">73. FileClose(file); class="num">74. }; class="num">75. Sleep(seconds * class="num">1000); class="num">76. } class="num">77. } class="num">78. class=class="str">"cmt">//+------------------------------------------------------------------+ class="num">79. }; class="num">80. class=class="str">"cmt">//+------------------------------------------------------------------+ class="num">81. C_ShareAtExcel *share; class="num">82. class=class="str">"cmt">//+------------------------------------------------------------------+ class="num">83. class="type">void OnStart() class="num">84. { class="num">85. share = new C_ShareAtExcel(user01); class="num">86. class="num">87. share.Looping(class="num">2); class="num">88. class="num">89. class="kw">delete share; class="num">90. } class="num">91. class=class="str">"cmt">//+------------------------------------------------------------------+
◍ 最后一句大实话
把 MT5 的持仓与历史数据导进 Excel,核心就是靠 ShareAtExcel.mq5 这个 4.03 KB 的脚本落地 CSV,再在表格里做组合监控;它不跑实时推送,适合那些隔几分钟看一眼仓位的人。 有读者在讨论里提到 quote.csv 必须存成 ANSI 编码,否则会报错,这点在自己改输出路径时先确认好,能省掉一半排错时间。 外汇和贵金属本身高波动高杠杆,这类离线监控只解决“看得见”,不解决“该不该动”,真要下单还是得回到价格行为本身。