市场模拟(第六部分):将信息从 MetaTrader 5 传输到 Excel·进阶篇
📊

市场模拟(第六部分):将信息从 MetaTrader 5 传输到 Excel·进阶篇

(2/3)· 非程序员最头疼的 MT5 与 Excel 互通,本篇拆解不需深啃 COM 的落地路径

进阶 第 2/3 篇

很多交易者拿着 Excel 管风控,却被 MT5 没有原生导出功能卡住,要么硬学 COM 编程,要么放弃用表盘盯头寸。其实对持仓两三天、同时铺二十个多空仓的人来说,轻微延迟的自动接收就够用,没必要把计算搬出平台。

「为什么选服务而不是 EA 或指标」

拿到 MT5 想做轻量实时任务,路线很多:Python 拉实时报价、RTD/DDE 外挂都行,但纯 MQL5 里最快落地的其实是服务(Service)。它不挂图表、终端没开图也能常驻,这点区别于 EA、指标、脚本。 MT5 四类程序定位要先分清:EA 负责发单交易;指标只在图上画信息;脚本绑特定图表、跑完就退;服务不绑图表,启停快却可后台常活。四类各有用处,但只有服务脱离图表独立运行。 代码层面服务和脚本几乎同构,差别仅在一行属性声明。脚本里加了 #property service 就变服务,删掉就退回脚本(此时必绑图表)。本方案用服务,若你想改成脚本,去掉那行即可,逻辑不用动。 外汇/贵金属波动剧烈、杠杆高风险大,任何常驻程序上线前请在模拟盘验证稳定性。

MQL5 / C++
class="macro">#class="kw">property service

把报价文件接进 Excel 的实操路径

MQL5 出于安全限制,只允许读写 MQL5 目录下 FILES 文件夹里的文件,不能随便碰系统其他路径。所以第一步要在 MetaEditor 导航窗格里定位到这个 FILES 目录,把后续要用的 QUOTE.CSV 先丢进去。 在 FILES 里建好 QUOTE.CSV 后,打开 Excel 新建空白表,用「从文本/CSV」导入(老版本藏在「获取数据」下面)。文件浏览器指到 MQL5\FILES\QUOTE.CSV,加载时选「加载到…」并放在默认高亮区域即可,图 05 就是刚导进来的静态样子。 关键点:没用 RTD 或 DDE,Excel 不会自己刷。选中表格切到「查询」选项卡点「属性」,把刷新间隔设成 60 秒、允许后台刷新,确认后 Excel 才会按文件变动约每 60 秒拉一次新值。 验证方法很直白——用记事本打开 QUOTE.CSV 改几行数值存盘,别关编辑器,等一分钟看 Excel 表是不是自动变成新内容。下面这段就是 CSV 里应有的格式样例,分号隔开标的与价格,外汇贵金属实盘接这思路同样高风险,行情断流或写盘失败都可能让表停更。

MQL5 / C++
PETR4;
VALE3;
ITUB3;
PETR4;class="num">30.80
VALE3;class="num">190.31
ITUB3;class="num">25.89

◍ 把报价喂给 Excel 的服务怎么写

在 MT5 里做服务比想象中轻量:不需要把资产显示在市场观察窗口,直接跑后台服务也不会拖慢终端。代码用类封装,方便以后把同样的逻辑挪去给其他外部程序传数据,不局限于 Excel。 第 2 行 #property service 是核心开关,告诉编译器这是服务而非脚本;删掉它就能当脚本挂到图表上跑,逻辑不受影响。第 8 行 input string user01 = "Quote.csv" 让用户指定共享文件名,必须和前一节建好的文件一致,否则系统起不来。 类内部从第 12 行 private: 起封装变量与日志函数,第 18 行 Message 统一在终端打印「Sharing service with Excel: […]」方便跟踪状态。构造函数第 25 行接收文件名参数,第 33 行尝试读文件,读不到就第 35–36 行报错返回;能读就按第 41 行用分号 ; 切出交易品种,第 45 行规范化大小写,这里故意不校验品种是否存在——出错时 Excel 会显示异常,人眼能秒查。 真循环从第 65 行开始,迭代间靠第 75 行 Sleep 按秒暂停,不会吃满 CPU。第 68–69 行拼好要写的内容,第 70 行用 FILE_SHARE_WRITE 标志开文件,解决生产者-消费者场景里「Excel 正读时 MT5 写」的冲突,第 72 行一次性写入、第 73 行立刻关文件。外汇与贵金属报价共享涉及实时外部读写,存在文件锁与延迟误差,属高风险操作,实盘前请在模拟环境验证。 想自己改推送字段,直接动第 69 行构建字符串那一段就行;比如塞进去 bid/ask 或持仓量,Excel 侧不用重连就能看到新列。

MQL5 / C++
class="macro">#class="kw">property service
class="macro">#class="kw">property copyright "Daniel Jose"
class="macro">#class="kw">property description "Quote sharing service between"
class="macro">#class="kw">property description "MetaTrader class="num">5 and Excel"
class="macro">#class="kw">property version   "class="num">1.00"
class=class="str">"cmt">//+------------------------------------------------------------------+
input class="type">class="kw">string user01 = "Quote.csv"; class=class="str">"cmt">//FileName
class=class="str">"cmt">//+------------------------------------------------------------------+
class C_ShareAtExcel
{
   class="kw">private :
      class="type">class="kw">string   szSymbol[],
               szFileName;
      class="type">int      maxBuff;
      class="type">bool     bError;
class=class="str">"cmt">//+------------------------------------------------------------------+
class="kw">inline class="type">void Message(const class="type">class="kw">string szMsg)
            {
               PrintFormat("Sharing service with Excel: [%s].", szMsg);
            }
class=class="str">"cmt">//+------------------------------------------------------------------+
   class="kw">public  :
class=class="str">"cmt">//+------------------------------------------------------------------+
            C_ShareAtExcel(class="type">class="kw">string szArg)
            :bError(true),

「从 CSV 批量灌入交易标的」

这段逻辑负责把一个 ANSI 编码的 CSV 文件读进内存,逐行解析后把标的代码塞进 szSymbol 动态数组。文件打开失败会直接弹 Message("Failed") 并 return,不会让后续数组越界。 循环里用 FileIsEnding 判断收尾,每次 FileReadString 抓一整行;只有 StringSplit 按分号切出来的字段数大于 1 才认定是有效行,避免空行或脏数据进数组。 有效行取 szRet[0] 作为原始代码,ArrayResize 把 szSymbol 扩 1 格,写入后跑一次 StringToUpper 统一成大写,maxBuff 自增记录总量。外汇与贵金属标的最好先确认 CSV 里是 EURUSD 这类无斜杠写法,否则匹配 Symbol() 时可能漏掉。 开 MT5 把这段嵌进 EA 初始化,放一个两列以上的 test.csv 到 MQL5/Files,能直接看到 szSymbol 被填满,比手写十几个 Symbol 参数省事。

MQL5 / C++
maxBuff(class="num">0),
szFileName(szArg)
 {
  class="type">int    file;
  class="type">class="kw">string sz0, szRet[];

  if ((file = FileOpen(szFileName, FILE_CSV | FILE_READ | FILE_ANSI)) == INVALID_HANDLE)
  {
     Message("Failed");
     class="kw">return;
  }
  while (!FileIsEnding(file))
  {
     sz0 = FileReadString(file);
     if (StringSplit(sz0, &class="macro">#x27;;&class="macro">#x27;, szRet) > class="num">1)
     {
        ArrayResize(szSymbol, maxBuff + class="num">1);
        szSymbol[maxBuff] = szRet[class="num">0];
        StringToUpper(szSymbol[maxBuff]);
        maxBuff++;
     }
  }
让小布替你跑这套
这些诊断与传输模板小布盯盘的 AIGC 已内置,打开对应品种页即可看到样例配置,把重复劳动交给小布,你专注决策。

常见问题

两者都依赖 COM 接口编程,且为单向通信,只建桥梁不开放 Excel 端反向控制,灵活性偏低,适合实时报价而非复杂交互。
小布盯盘内置了常见的传输样例与诊断页,可大幅减少手动写接口的成本,但具体表结构仍要按你的风控逻辑微调。
多数情况下分钟级延迟足够支撑多空对与仓位再平衡决策,不必强求 tick 级实时,反而能降系统复杂度。
平台内计算更稳定且低延迟,把仓位计算外移再等回传会增加故障点,Excel 更适合做监控与人工风控而非执行控制。