外汇套利交易:一款轻松上手的简单合成做市商机器人·综合运用
(3/3)·从实时信息面板到交易帝国扩展,收尾篇拆解简单套利EA的工程化拼图
很多交易者把套利EA当成黑箱,跑起来就丢一边,直到滑点吃掉利润才翻日志。另一些人盲目加品种,却从没看过机器人自己记录的关联失衡数据。第三篇文章直接拆开这套合成做市商的信息层与扩展层,让你知道它平时到底在算什么、能长多大。
「把EA从黑箱里拽出来」
不少自动化策略最让人难受的地方,是跑起来像封死的黑箱:下单、平仓、加减仓全在后台,交易者连当前盯的是哪几个货币对、仓位怎么算的都看不见。做 TrisWeb_Optimized 时,我直接把信息输出当一等需求,用 DisplayInfo() 把内部状态摊在图表上。 你可以切基本模式,只留总订单数和总浮盈,适合嫌屏幕乱的人;也能开标准模式,把三个货币对各自的利润、成交笔数、自动手数全列出来。这跟老车只有速度油表、新车满屏数显一个道理——看多少取决于你习惯怎么盯盘。 下面这段是早期版本的信息函数骨架,已经能看出设计取向:自动手数开启时,当场调用 CalculateOptimalLotSize 算完三个符号的 lot,再拼成字符串用 Comment 打到图上。
<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, <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, <span class="keyword">class="type">int</span> count1, <span class="keyword">class="type">int</span> count2, <span class="keyword">class="type">int</span> count3) { <span class="keyword">class="type">class="kw">string</span> info = <span class="class="type">class="kw">string">""</span>; <span class="keyword">if</span>(AutoLotOptimization) { <span class="keyword">class="type">class="kw">double</span> lot1 = CalculateOptimalLotSize(Symbol1, Lot_Symbol1); <span class="keyword">class="type">class="kw">double</span> lot2 = CalculateOptimalLotSize(Symbol2, Lot_Symbol2); <span class="keyword">class="type">class="kw">double</span> lot3 = CalculateOptimalLotSize(Symbol3, Lot_Symbol3); 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>) + <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>) + <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>; } <span class="comment">class=class="str">"cmt">// ... the rest of the information generation code</span> <span class="functions">Comment</span>(info); } <span class="keyword">input</span> <span class="keyword">class="type">bool</span> DisplayDetailedInfo = <span class="macro">false</span>; <span class="comment">class=class="str">"cmt">// Show detailed information</span>
<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, <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, <span class="keyword">class="type">int</span> count1, <span class="keyword">class="type">int</span> count2, <span class="keyword">class="type">int</span> count3) { <span class="keyword">class="type">class="kw">string</span> info = <span class="class="type">class="kw">string">""</span>; <span class="keyword">if</span>(AutoLotOptimization) { <span class="keyword">class="type">class="kw">double</span> lot1 = CalculateOptimalLotSize(Symbol1, Lot_Symbol1); <span class="keyword">class="type">class="kw">double</span> lot2 = CalculateOptimalLotSize(Symbol2, Lot_Symbol2); <span class="keyword">class="type">class="kw">double</span> lot3 = CalculateOptimalLotSize(Symbol3, Lot_Symbol3); 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>) + <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>) + <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>; } <span class="comment">class=class="str">"cmt">// ... the rest of the information generation code</span> <span class="functions">Comment</span>(info); } <span class="keyword">input</span> <span class="keyword">class="type">bool</span> DisplayDetailedInfo = <span class="macro">false</span>; <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 到底从哪来。把这类底层取值先跑通,再谈参数秘籍,不然下一篇实战设置看了也白看。
class="type">class="kw">double commission = PositionGetDouble(POSITION_COMMISSION);