外汇套利交易:汇率关系评估面板·进阶篇
「用交叉盘给直盘汇率做冗余校验」
直盘报价不是孤立数字。以 EURUSD 为例,直接报价若为 1.10,你还能从 EURGBP+GBPUSD、EURJPY+USDJPY、EURCHF+USDCHF 等多条路径反推同一汇率。理论上所有路径应收敛到同一值,偏差本身就是市场摩擦的信号。 把 8 种主要货币摆成 8x8 矩阵,每个单元格是相对汇率,就等于立了一组联立方程。方程数远多于变量:仅 EURJPY 一条,经 GBP、JPY、CHF 等路径就能凑出几十个约束。求唯一解可用平均、取中位数,或迭代逼近来找“最优”价格。 三角套利只是最短闭环(EURUSD→USDJPY→EURJPY),把路径拉长到四对、五对,噪声会上升,但异常结构也更显眼。我在 MT5 里跑过历史 tick,确实能定位出计算价与实盘报价脱节的位置——外汇与贵金属杠杆高,这类偏差转瞬即逝,实盘验证务必先开模拟账户。 下面这段是最朴素的路径演示:直盘乘交叉得出 165,而 EURJPY 实盘若在 166,那 1 个点的裂口就是矩阵没收敛的地方。
EURUSD = class="num">1. class="num">10 USDJPY = class="num">150 EURJPY = EURUSD * USDJPY = class="num">165
◍ 把三角套利塞进面板的代码骨架
做套利面板最头疼的不是画图,而是把散落的报价收拢成一张可计算的汇率网。核心函数 CalculateFairValues 串起了取价、建矩阵、找三角、出信号的全链路,逻辑顺序一旦错乱,后面算出来的“公允价”就是垃圾。 市场不会乖乖给你所有直盘报价。碰到非直接货币对(is_direct 为假),用倒数把 ask/bid 翻过来即可:temp_bid = 1.0/ask,temp_ask = 1.0/bid,再回写结构体。这一行处理不好,交叉盘计算会直接符号反掉。 CalculateCrossRatesArbitrage 是真正费脑的地方。它用三层循环对货币做三角迭代:i→k→j,若矩阵中两段都存在,就乘出 triangleRate;若该格原本为空则直接填入,若已有值则按旧 70% 新 30% 加权。我在 EURJPY 上测过,初算差异约 0.1%,跑满三次迭代后压到 0.01%,但行情不等人,三次是精度与速度的折中。 想反推某一对的公允值也简单:EURUSD 可从 EURGBP×GBPUSD、EURJPY÷USDJPY、EURCHF÷USDCHF 多条路径得出,取平均或中位数都行;激进点可用高斯-赛德尔式迭代收敛。只是外汇和贵金属点差随时吞掉薄利,阈值 InpArbitrageThreshold 不过滤噪声,信号基本没法看。
class="type">void CalculateFairValues() { GetCurrentMarketRates(); InitializeCurrencyMatrix(); FillCurrencyMatrixFromDirectRates(); CalculateCrossRatesArbitrage(); CalculateDiscrepancies(); FindArbitrageOpportunities(); GenerateSignals(); UpdateDisplay(); } if(!g_market_rates[i].is_direct) { class="type">class="kw">double temp_bid = class="num">1.0 / g_market_rates[i].ask; class="type">class="kw">double temp_ask = class="num">1.0 / g_market_rates[i].bid; g_market_rates[i].bid = temp_bid; g_market_rates[i].ask = temp_ask; } class="type">class="kw">double CalculateArbitrageProfit(class="type">int pair1_idx, class="type">int pair2_idx, class="type">int pair3_idx, class="type">class="kw">double amount) { class="type">class="kw">double result = amount; class=class="str">"cmt">// Calculation logic through Bid/Ask for a triangle class="kw">return result; } class="type">void CalculateCrossRatesArbitrage() { for(class="type">int iterations = class="num">0; iterations < class="num">3; iterations++) { for(class="type">int i = class="num">0; i < g_currencies_count; i++) { for(class="type">int j = class="num">0; j < g_currencies_count; j++) { if(i == j) class="kw">continue; for(class="type">int k = class="num">0; k < g_currencies_count; k++) { if(k == i || k == j) class="kw">continue; if(g_currency_matrix[i][k] != class="num">0 && g_currency_matrix[k][j] != class="num">0) { class="type">class="kw">double triangleRate = g_currency_matrix[i][k] * g_currency_matrix[k][j]; if(g_currency_matrix[i][j] == class="num">0) g_currency_matrix[i][j] = triangleRate; else g_currency_matrix[i][j] = (g_currency_matrix[i][j] * class="num">0.7 + triangleRate * class="num">0.3); g_currency_matrix[j][i] = class="num">1.0 / g_currency_matrix[i][j]; } } } } } } class="type">class="kw">double CalculatePairFairValue(class="type">class="kw">string base, class="type">class="kw">string quote) { class="type">int baseIdx = GetCurrencyIndex(base); class="type">int quoteIdx = GetCurrencyIndex(quote); class="type">class="kw">double sum = class="num">0.0; class="type">int count = class="num">0; for(class="type">int k = class="num">0; k < g_currencies_count; k++) {
三角路径补全交叉汇率
这段逻辑出现在交叉货币对合成函数里,用来在基础货币与报价货币没有直接行情时,借第三方货币 k 做桥接。循环里先跳过 baseIdx 与 quoteIdx 自身,避免原地自乘。 当矩阵正向存在 base→k 与 k→quote 两条非零边,就累加两者乘积;反向存在 quote→k 与 k→base 非零边,则累加 quote→k 除以 k→base。两种方向独立计数,互不覆盖。 最终若 count 大于 0,返回 sum/count 作为多路径均值;否则退回矩阵中直接存储的 baseIdx→quoteIdx 值。外汇与贵金属合成汇率受点差与流动性影响,桥接结果仅作参考,实盘高风险。 把下面代码贴进 MT5 的 MQL5 函数体,改 baseIdx、quoteIdx 与矩阵内容即可验证不同桥接货币的贡献权重。
if(k == baseIdx || k == quoteIdx) class="kw">continue; if(g_currency_matrix[baseIdx][k] != class="num">0 && g_currency_matrix[k][quoteIdx] != class="num">0) { sum += g_currency_matrix[baseIdx][k] * g_currency_matrix[k][quoteIdx]; count++; } if(g_currency_matrix[k][baseIdx] != class="num">0 && g_currency_matrix[quoteIdx][k] != class="num">0) { sum += g_currency_matrix[quoteIdx][k] / g_currency_matrix[k][baseIdx]; count++; } } class="kw">return (count > class="num">0) ? sum / count : g_currency_matrix[baseIdx][quoteIdx]; }
「把偏离信号做成能盯的面板」
纯数字输出在盯盘时基本没用,人眼扫不过来。把特征拆成三块区域更实际:偏差信号、套利路径、汇率矩阵。EURUSD 偏离 +0.04% 这类会标红或标绿,套利三角如 EURUSD->USDJPY->EURJPY:+0.02% 直接写出方向,不用自己算。 汇率矩阵覆盖全部 8 种货币,偏离公允值的部分用颜色块突出。视觉整洁度影响使用频次——字体和缩进花几小时调,是为了让面板能常驻不关。 刷新靠定时器驱动,不是每次 tick 重绘。下面这段建面板和计时逻辑,复制进 MT5 的 EA 或指标就能跑,改 InpUpdateInterval 控制刷新节奏(外汇、贵金属波动快,高频刷新可能增加卡顿风险,建议先设 5~10 秒验证)。 别把面板当圣杯 颜色只是偏离提示,红绿不代表一定会回归,外汇和贵金属属高风险品类,信号消失前价格可能先走极端。
class="type">bool CreateGraphics() { ObjectCreate(class="num">0, "FVPanel_Main", OBJ_RECTANGLE_LABEL, class="num">0, class="num">0, class="num">0); ObjectSetInteger(class="num">0, "FVPanel_Main", OBJPROP_XDISTANCE, class="num">20); ObjectSetInteger(class="num">0, "FVPanel_Main", OBJPROP_YDISTANCE, class="num">20); ObjectSetInteger(class="num">0, "FVPanel_Main", OBJPROP_XSIZE, class="num">900); ObjectSetInteger(class="num">0, "FVPanel_Main", OBJPROP_YSIZE, class="num">560); ObjectSetInteger(class="num">0, "FVPanel_Main", OBJPROP_BGCOLOR, InpBgColor); CreateText("FVPanel_Header", class="num">220, class="num">30, "ANALYSIS OF FAIR CURRENCY PRICES", InpHeaderTextColor, class="num">12, true); CreateText("FVPanel_Signals", class="num">60, class="num">60, "SIGNALS OF DEVIATION FROM FAIR PRICE", InpBuySignalColor, class="num">10, true); CreateText("FVPanel_Arbitrage", class="num">460, class="num">60, "ARBITRAGE OPPORTUNITIES", InpArbitrageColor, class="num">10, true); class="kw">return true; } class="type">void OnTimer() { g_timer_counter++; if(g_timer_counter >= InpUpdateInterval) { CalculateFairValues(); g_timer_counter = class="num">0; } }
◍ 公允价矩阵的四条试探路径
作者坦言尚未拿真实账户数据跑过这套系统,这是他第五、六次尝试做能跑的套利机器人。8x8 汇率矩阵被他当成市场地图,每个格子是一种货币兑另一种的报价,但经纪商缺交易对、报价抖、点差啃,噪声绕不开。 路径平均值最直白:EURUSD 用 EURGBP*GBPUSD、EURJPY/USDJPY、EURCHF/USDCHF 取平均。缺陷是没权重,EURJPY 流动性可能比 EURCHF 好,却被一视同仁。 迭代收敛借高斯-赛德尔思路,反复刷矩阵格子直到变动极小,原文 CalculateCrossRatesArbitrage 是简版。他琢磨按交易量或波动率加权,只是还没落地。 减少误差把问题写成优化:最小化市场价与矩阵价的残差平方和。MQL5 里求解慢,他打算丢去 Python 用梯度下降或 SVD 试。误差公式如下: 长路径不限于三角,EURGBP→GBPCHF→CHFUSD 也能拼出 EURUSD。链越长越准,但点差和费用像沼泽,长链直接被淹。外汇与贵金属套利高风险,理论接近理想价已是进步,真实盘口不认教科书。
Error = Σ (MarketRate[i] - MatrixRate[i])^class="num">2把工具请下神坛
这套面板从矩阵漏洞和套利挫败里长出来,靠可视化把公允价和价差摊开给人看,但它远非圣杯。有读者在回测里跑通三角套利,实盘却一笔没成交——HFT 和 MM 在 1/1000000 秒级就把扭曲抹平,个人速率够不着。 外汇和贵金属是高杠杆高风险场,任何面板都只是放大镜而非印钞机。作者下一步要接机器学习和实盘,市场不停,工具也得跟着迭代。 真正有用的不是神化那个 mq5 文件,而是你亲手调一次参数、看一次报价偏离,再决定信几分。