外汇套利交易:一款轻松上手的简单合成做市商机器人·综合运用
🤖

外汇套利交易:一款轻松上手的简单合成做市商机器人·综合运用

(3/3)·从实时信息面板到交易帝国扩展,收尾篇拆解简单套利EA的工程化拼图

含代码示例 第 3/3 篇

很多交易者把套利EA当成黑箱,跑起来就丢一边,直到滑点吃掉利润才翻日志。另一些人盲目加品种,却从没看过机器人自己记录的关联失衡数据。第三篇文章直接拆开这套合成做市商的信息层与扩展层,让你知道它平时到底在算什么、能长多大。

「把EA从黑箱里拽出来」

不少自动化策略最让人难受的地方,是跑起来像封死的黑箱:下单、平仓、加减仓全在后台,交易者连当前盯的是哪几个货币对、仓位怎么算的都看不见。做 TrisWeb_Optimized 时,我直接把信息输出当一等需求,用 DisplayInfo() 把内部状态摊在图表上。 你可以切基本模式,只留总订单数和总浮盈,适合嫌屏幕乱的人;也能开标准模式,把三个货币对各自的利润、成交笔数、自动手数全列出来。这跟老车只有速度油表、新车满屏数显一个道理——看多少取决于你习惯怎么盯盘。 下面这段是早期版本的信息函数骨架,已经能看出设计取向:自动手数开启时,当场调用 CalculateOptimalLotSize 算完三个符号的 lot,再拼成字符串用 Comment 打到图上。

MQL5 / C++
<span class="keyword">class="type">void</span> DisplayInfo(<span class="keyword">class="type">int</span> totalOrders, <span class="keyword">class="type">class="kw">double</span> totalProfit, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">class="kw">double</span> profit1, <span class="keyword">class="type">class="kw">double</span> profit2, <span class="keyword">class="type">class="kw">double</span> profit3,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">int</span> count1, <span class="keyword">class="type">int</span> count2, <span class="keyword">class="type">int</span> count3)
{
&nbsp;&nbsp; <span class="keyword">class="type">class="kw">string</span> info = <span class="class="type">class="kw">string">""</span>;
&nbsp;&nbsp; 
&nbsp;&nbsp; <span class="keyword">if</span>(AutoLotOptimization)
&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">class="kw">double</span> lot1 = CalculateOptimalLotSize(Symbol1, Lot_Symbol1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">class="kw">double</span> lot2 = CalculateOptimalLotSize(Symbol2, Lot_Symbol2);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">class="kw">double</span> lot3 = CalculateOptimalLotSize(Symbol3, Lot_Symbol3);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info += <span class="class="type">class="kw">string">"Auto Lot: "</span> + Symbol1 + <span class="class="type">class="kw">string">"="</span> + <span class="functions">DoubleToString</span>(lot1, <span class="number">class="num">2</span>) + 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="class="type">class="kw">string">", "</span> + Symbol2 + <span class="class="type">class="kw">string">"="</span> + <span class="functions">DoubleToString</span>(lot2, <span class="number">class="num">2</span>) + 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="class="type">class="kw">string">", "</span> + Symbol3 + <span class="class="type">class="kw">string">"="</span> + <span class="functions">DoubleToString</span>(lot3, <span class="number">class="num">2</span>) + <span class="class="type">class="kw">string">"\n"</span>;
&nbsp;&nbsp; }
&nbsp;&nbsp; 
&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">// ... the rest of the information generation code</span>
&nbsp;&nbsp; 
&nbsp;&nbsp; <span class="functions">Comment</span>(info);
}
<span class="keyword">input</span> <span class="keyword">class="type">bool</span> DisplayDetailedInfo = <span class="macro">false</span>;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Show detailed information</span>
逐行拆一下:函数头把总订单、总利润、三个对的利润与笔数都传进来,说明面板要覆盖组合层与单品种层。AutoLotOptimization 为真时,才进分支算 lot1~lot3,用 DoubleToString(...,2) 统一保留两位小数,拼成 "Auto Lot: XXX=0.12, YYY=0.08, ZZZ=0.05" 这类可读串。末尾 Comment(info) 把内容绘到图表左上——MT5 里跑起来,开 DisplayDetailedInfo 输入项就能对比两种密度。外汇与贵金属波动剧烈,这类实时面板只帮你看清逻辑,不削减爆仓风险。

MQL5 / C++
<span class="keyword">class="type">void</span> DisplayInfo(<span class="keyword">class="type">int</span> totalOrders, <span class="keyword">class="type">class="kw">double</span> totalProfit, 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">class="kw">double</span> profit1, <span class="keyword">class="type">class="kw">double</span> profit2, <span class="keyword">class="type">class="kw">double</span> profit3,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">int</span> count1, <span class="keyword">class="type">int</span> count2, <span class="keyword">class="type">int</span> count3)
{
&nbsp;&nbsp; <span class="keyword">class="type">class="kw">string</span> info = <span class="class="type">class="kw">string">""</span>;
&nbsp;&nbsp; 
&nbsp;&nbsp; <span class="keyword">if</span>(AutoLotOptimization)
&nbsp;&nbsp; {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">class="kw">double</span> lot1 = CalculateOptimalLotSize(Symbol1, Lot_Symbol1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">class="kw">double</span> lot2 = CalculateOptimalLotSize(Symbol2, Lot_Symbol2);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class="type">class="kw">double</span> lot3 = CalculateOptimalLotSize(Symbol3, Lot_Symbol3);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info += <span class="class="type">class="kw">string">"Auto Lot: "</span> + Symbol1 + <span class="class="type">class="kw">string">"="</span> + <span class="functions">DoubleToString</span>(lot1, <span class="number">class="num">2</span>) + 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="class="type">class="kw">string">", "</span> + Symbol2 + <span class="class="type">class="kw">string">"="</span> + <span class="functions">DoubleToString</span>(lot2, <span class="number">class="num">2</span>) + 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="class="type">class="kw">string">", "</span> + Symbol3 + <span class="class="type">class="kw">string">"="</span> + <span class="functions">DoubleToString</span>(lot3, <span class="number">class="num">2</span>) + <span class="class="type">class="kw">string">"\n"</span>;
&nbsp;&nbsp; }
&nbsp;&nbsp; 
&nbsp;&nbsp; <span class="comment">class=class="str">"cmt">// ... the rest of the information generation code</span>
&nbsp;&nbsp; 
&nbsp;&nbsp; <span class="functions">Comment</span>(info);
}
<span class="keyword">input</span> <span class="keyword">class="type">bool</span> DisplayDetailedInfo = <span class="macro">false</span>;&nbsp;&nbsp;<span class="comment">class=class="str">"cmt">// Show detailed information</span>

◍ 把 TrisWeb 改造成套利网络的三条路

TrisWeb_Optimized 本身不是封闭 EA,而是一个可扩展的三角套利底架。作者五年里持续迭代,加功能但没动核心执行逻辑,这意味着你也能在不动地基的前提下接外部模块。 接 Python 是最值得做的扩展。通过 TCP/IP 或文件管道把 MT5 报价甩给 Python,就能跑三个货币对的历史互动模式,用相关性分析或简单机器学习预判哪组会出现统计失衡。原系统只盯当前报价,加上历史层后,触发逻辑会从「看到才做」变成「预期要做」。 Telegram 推送不用多说,EA 跑在 VPS 上时,用 WebRequest 调 Bot API 把开仓、平仓、价差阈值突破事件推到手机。改动量极小,却能把你从终端前解放出来。 真正拉开差距的是扩到数十个关联货币对。三角逻辑不变,只是把「EURUSD/GBPUSD/EURGBP」换成动态网络,同时监控数百个潜在套利窗口。外汇与贵金属价差套利受滑点、点差和经纪商限制影响,实际成交概率随品种数上升而稀释,扩展前先用 MT5 策略测试器跑一轮多对回测。

把这条线请下神坛

TrisWeb_Optimized 从 2019 年前后一个脚本雏形,滚到今天成了带仓位与风控模块的完整 EA,作者公开称它跨过极端波动和静默市都没停过正向预期,但评论区里 Zhang Yi 直接点出某段取值恒为 0、质疑逻辑造假,Maxim 也提醒盈利是人和系统共同结果——神坛上的曲线别当圣经抄。 外汇与贵金属杠杆高、滑点跳空随时吞掉回测漂亮值,真要验就得自己挂 MT5 用真实点差跑,而不是信一句「从未停止盈利」。下面这段取当前持仓佣金的函数,是少数能直接贴进 EA 验证逻辑闭环的硬骨头: double commission = PositionGetDouble(POSITION_COMMISSION); 它只返回当前持仓佣金字段,若你的券商不回报该字段就恒为 0——这正好解释了评论里说的那个 0 到底从哪来。把这类底层取值先跑通,再谈参数秘籍,不然下一篇实战设置看了也白看。

MQL5 / C++
class="type">class="kw">double commission = PositionGetDouble(POSITION_COMMISSION);
把重复劳动交给小布
这些诊断小布盯盘的 AIGC 已内置,打开对应品种页即可看到三种关联货币对的失衡热力与订单布置状态,你只需在异常扩大时介入判断。

常见问题

重点看三组货币对价差偏离阈值、挂单成交比与未平仓净敞口,这三项能直接反映失衡是否进入可执行区间,其余多为运行噪音。
会,关联组合越多,尾部共振概率可能上升;扩展时建议分池隔离并按波动率约束总敞口,而非简单复制同一逻辑。
它不预测方向,只捕捉数学上的短暂失衡,只要流动性未枯竭,回归倾向就存在,但极端跳空仍可能使概率优势失效。
小布目前提供品种页的失衡与订单诊断视图,可替代人工刷面板,但下单与参数调整仍建议在客户端完成,它不代操账户。
不复杂,用CEvent或全局变量配合OBJ_LABEL即可,含代码示例的章节给了最小可用模板,改几个字段就能接你自己的逻辑。