「用 SQL 在 MT5 里翻历史成交记录」
「用 SQL 在 MT5 里翻历史成交记录」
MT5 的测试器环境内置了 SQLite 引擎,策略回测时每一笔成交、订单和持仓都会落进内存数据库,不必导出到外部文件就能用 SQL 直接查。对价格行为交易者来说,这意味着可以在回测脚本里实时统计某段行情的连胜次数、最大回撤或特定形态后的胜率,而不是等回测跑完再拿 CSV 慢慢算。 下面这段代码演示如何在 EA 的 OnTester 里打开测试数据库并读取最后 10 条成交的时间与盈利。注意 SQLite 在 MT5 中是只读测试库,写操作会被忽略。 高风险提示:外汇与贵金属杠杆交易可能令本金快速亏损,以下代码仅用于回测验证,不构成任何实盘建议。
class="type">void OnTester() { class=class="str">"cmt">// 获取测试者数据库句柄 class="type">int db=DatabaseOpen("::tester", DATABASE_OPEN_READONLY); if(db==INVALID_HANDLE) class="kw">return; class=class="str">"cmt">// 执行 SQL 查询最近 class="num">10 笔成交 class="type">class="kw">string sql="SELECT Time, Profit FROM deals ORDER BY Time DESC LIMIT class="num">10"; DatabaseExecute(db, sql); class=class="str">"cmt">// 遍历结果集 class="kw">while(DatabaseRead(db)) { class="type">class="kw">datetime t=DatabaseReadDatetime(db, class="num">0); class="type">class="kw">double p=DatabaseReadDouble(db, class="num">1); Print(TimeToString(t), " profit=", p); } DatabaseClose(db); }
◍ 为什么单靠 MetaEditor 学不全 SQL 键概念
在 MT5 里用 MQL5 操作 SQLite 时,MetaEditor 确实是编译和调用代码的阵地,但它本质上是个代码编辑器,不是数据库教学环境。想真正吃透主键、外键这类数据库骨架概念,只靠它就不够了——它既不支持直接编辑、保存 SQL 脚本,也不会把执行结果以可视结构呈现给你。 更顺手的选择是 DB Browser(开源、C++ 编写、GitHub 免费获取)。它面向 SQLite 设计,能写脚本、能存查询、还带多语言界面,对非英语用户友好。实测中,用它在图形界面里建表、加 PRIMARY KEY 约束,比在 MQL5 里盲写 SQL 字符串更容易发现语法和逻辑错误。 需要明确:MetaEditor 并非无用,已熟悉 SQL 的人只做查询时两者差异不大;但初学阶段,用 DB Browser 跑通一套带外键关联的表,再回到 MQL5 用代码复现,是更短的学习路径。外汇与贵金属相关的数据回测涉及高杠杆风险,练手请用模拟数据,别直接挂实盘库。
文件型数据库逼出的策略转向
在 MQL5 里接数据库,很多人第一反应是绑死某种 SQL 实现,比如只会 SQL Server 就觉得 MySQL 没法用。其实这类执念多半来自对底层通信缺乏理解——只要掌握了套接字,Excel 和 MetaTrader 5 之间就能做双向数据交换,而不必困在 RTD 或 DDE 那种只能单向推给 Excel 的旧路子。 我们之前演示过用套接字打通 MT5 与外部程序,同样的机制稍作改写,就能让 MQL5 程序通过 SQL 命令访问数据库:核心只是会发 SQL 文本、会通过 socket 收发报文。剩下的事反而简单,因为服务器端数据库在并发和扩展性上比本地文件实用得多。 SQLite 默认把库塞进一个文件,这带来明显不便——它通常没有常驻服务进程,多端同时写容易锁表,且跨网络共享得靠文件共享协议。对单策略自用还算能忍,一旦要多个 EA 或分析脚本同时读写,就得转向 SQL 服务器。 不过从教学角度,本文不主张一上来就造轮子。文件型方案的限制真实存在,但未必是死结;相比文件存储,SQL 服务器在扩展性、并发和远程访问上始终占优。先放下 MySQL 的具体配置,把必要通信基础打牢,后面再谈怎么用套接字直接编程操作库。
「主键外键为什么是关系库的骨架」
很多人以为「数据库」天然就是键-值结构,其实非关系型库只是把数组落盘:内存里一个索引对应一条记录,存成文件再读回,本质是自己写了套增删改查子程序。这种私库在小工具里能用,但跨程序交换信息就很笨重,于是 SQL 这类公共方案才有意义。 真正分叉点在「键-值」怎么放。Python 的字典可以不依赖数字下标,用任意字符串做键去映射值;SQL 里也能建一列当键、另一列存对应记录。若无约束,即使跑在 SQL 上也会退化成非关系型——重复键一多,完整性就破了。 关系型的核心约束是:某列被声明后,值不允许重复,这通常就是主键。但作者强调,单列唯一还不算关系库;只有当一个表里的键与另一表里的键通过外键建立关联,像图结构那样互相引用,数据库才真正是关系型的。 举个可验证的落点:你在 MT5 外接 SQL 建「个人联系人库」,给每人设主键,把「共同属性」(如所属群组)抽成独立表并用外键回链。交叉查询时不必复制冗余字段,JOIN 速度明显快于全表扫。外汇或贵金属 EA 若用这套结构做信号回溯,注意实盘高杠杆高风险,历史关联快不等于未来概率高。
◍ 先搞懂键,再碰数据库
前面铺垫的那些抽象定义不是绕弯子。主键和外键之所以长这样,是因为关系型数据库在几十年里被反复打磨,不是谁拍脑袋定的;你要绕开 SQL 自己写一套文件读写,短期能跑,久了系统多半会塌。 我吃过这个亏:早年一直自己造轮子处理数据存储,方案能跑,但几个月后还是得回头用 SQL 那套标准做法。如果当初直接吃透现有实现,那些调试和重写的时间本可以省下来。 这里附带的工程清单能让你在 MT5 里直接验证这套思路:Experts\Expert Advisor.mq5 负责 Chart Trade 与 EA 交互(依赖 Mouse Study);Indicators\Chart Trade.mq5 做下单配置窗口;Services\Market Replay.mq5 是复制行情的主服务;Scripts\SQLite.mq5 演示 MQL5 里跑 SQL 脚本;Files\Script 01.sql 建带外键的表,Script 02.sql 往里插数据。 外汇和贵金属相关的自动化系统高风险,数据库结构理解错了,回测和实盘信号都可能失真。下一篇我们会直接拿这些键在库里实操,现在先把附带的 mq5 和 sql 文件拖进终端跑一遍,比空想有用。
顺手能抓的几条延伸线索
这一节原本是文章末尾的站外链接与作者信息区,但剥掉页面外壳后,有几条对做实盘验证有用的线索值得记一下。Daniel Jose 这位巴西作者连写了多期「市场模拟」套接字与 SQL 入门系列,最新到第十九、二十部分,说明用 MT5 本地做行情回放和轻量数据库管理已经有一套成熟路径,想自己搭仿真环境可以从第 18 部分直接抄起。 同期社区里 Sergey Chalyshev 在 2026 年 3 月 11 日的留言提到「第一步拖太久,该进第二步了」,侧面反映多数人在套接字通信的握手阶段耗了过多时间,真正卡点往往不在策略而在管道。外汇与贵金属这类高杠杆品种做本地仿真时,更要先跑通数据通道再谈模型,否则容易把延迟误判成信号。 另外挂出的几篇新文里,Prophet 模型做波动率预测、MACD+OBV 用卷积核微调信号类,都给了可直接套 MQL5 向导的自定义类思路。你今天就能开 MT5 把那两个指标组合拖进向导生成 EA 骨架,比从头写省掉至少一半脚手架。至于 BSA 优化算法,参数极少、记忆过往路径,适合拿去替你跑参数空间搜索,但任何优化结果都只是概率偏好,不代表实盘必然占优。