基于季节性因素的MetaTrader 5外汇价差交易质量评估·进阶篇
「用多年样本看跨品种价差季节性」
把两个品种报价相减就能得到价差:价差 = 第一品种报价 - 第二品种报价,再乘权重系数可修正 tick 价值差异。比如欧美系数取 1、镑美取 0.8,就是因为镑美每跳价值更高,直接 1:1 会扭曲真实价差结构。 白银兑美元加载指标后看 15 年 1 月数据,橄榄色历史均值、黄色本年曲线和橙色箭头全部指向价差收窄,说明该贵金属组合在中段月份有统计上可重复的收敛倾向。金银配比可设白银 1、黄金 2,也可在 tick 价值接近时直接 1:1。 欧美-镑美 12 月、镑美-纽元 4 月的历史均值曲线与本年曲线同向,后者两条线均自下而上呈扩大态势;但镑美-白银 6 月本年走势未验证历史均值方向,说明季节性不是每月都兑现。WTI-布伦特 7 月黄线配合橙色下行箭头,历史规律倾向 WTI 跌幅大于布伦特,可考虑做空该价差,指标须加载在 WTI 图表且配比 1:1。 评估季节性靠样本质量:观测期至少 10 年,15–20 年更稳;各年数值应平稳如 100、150、90、166、200、150、130、125,避免出现离群极值。若连续多年同月方向一致率≥70% 且区间相近,该模型可靠性才高,可用于当年交易。外汇与贵金属杠杆高、价差跳变频繁,任何季节性结论都只是概率倾向,需先在 MT5 加载 SpreadMultiYearComparison 用 CME 历史数据回看再动手。
价差跨年多周期对比的副图玩法
这个副图指标把品种间价差按年份拆开看,外部参数就六个:Symbol1 是主品种(比如 XAUUSD),Symbol2 留空就只算单一品种自身,MonthToShow 取 1–12,YearsToShow 支持回看 1–15 年,FillGaps 打开时用最近有效值补缺失。 核心逻辑落在日线周期,以点数为单位对 Symbol1 做统计。CalculateAllStatistics() 负责算月初到月末的价差变化并照顾小数位精度,DisplayFullStatistics() 抛逐年盈亏表并标趋势(强趋势或横盘),GetRecommendation() 看盈利月份占比给方向报告。 代码里 input 段直接暴露了默认值:MonthToShow=6、YearsToShow=15、FillGaps=true,意味着加载后默认就在看 6 月、回溯 15 年的价差结构。 季节性表格里有一条值得验证:6 月白银倾向下跌,6 月 GBPUSD 减 XAGUSD 价差也倾向下行;7 月 WTI–布伦特价差倾向走弱。外汇贵金属杠杆高,季节性只是概率倾向,不等于必然,止损和 COT 持仓报告得一并看。 下面这段取价函数是理解指标的基础,注意 iBarShift 拿日线偏移、iOpen 取开盘价再乘权重系数。
class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| SpreadMultiYearComparison.mq5 class=class="str">"cmt">//| Copyright class="num">2025, Roman Shiredchenko class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Copyright class="num">2025" class="macro">#class="kw">property version "class="num">7.1" class="macro">#class="kw">property strict class="macro">#class="kw">property indicator_separate_window class="macro">#class="kw">property indicator_buffers class="num">18 class="macro">#class="kw">property indicator_plots class="num">17 class=class="str">"cmt">//--- Input parameters class="kw">input class="type">class="kw">string Symbol1 = "EURUSD"; class=class="str">"cmt">// First symbol(required) class="kw">input class="type">class="kw">string Symbol2 = ""; class=class="str">"cmt">// Second symbol(empty for single symbol analysis) class="kw">input class="type">class="kw">double k_Symbol1 = class="num">1.0; class=class="str">"cmt">// Weight coefficient for Symbol1 class="kw">input class="type">class="kw">double k_Symbol2 = class="num">1.0; class=class="str">"cmt">// Weight coefficient for Symbol2 class="kw">input class="type">int MonthToShow = class="num">6; class=class="str">"cmt">// Month to analyze(class="num">1-class="num">12) class="kw">input class="type">int YearsToShow = class="num">15; class=class="str">"cmt">// Number of years to analyze(class="num">1-class="num">15) class="kw">input class="type">bool FillGaps = true; class=class="str">"cmt">// Fill gaps in data class=class="str">"cmt">//+------------------------------------------------------------------+ class=class="str">"cmt">//| Get spread/price value | class=class="str">"cmt">//+------------------------------------------------------------------+ class="type">class="kw">double GetSpreadValue(class="type">class="kw">datetime dt) { class=class="str">"cmt">//--- Get data for first symbol class="type">int shift1 = iBarShift(Symbol1, PERIOD_D1, dt, false); if(shift1 < class="num">0) { Print("No data for ", Symbol1, " at ", TimeToString(dt)); class="kw">return EMPTY_VALUE; } class="type">class="kw">double price1 = k_Symbol1 * iOpen(Symbol1, PERIOD_D1, shift1); class=class="str">"cmt">//--- Return first symbol price if second symbol not specified if(Symbol2 == "") { class="kw">return price1; } class=class="str">"cmt">//--- Get data for second symbol class="type">int shift2 = iBarShift(Symbol2, PERIOD_D1, dt, false); if(shift2 < class="num">0) {
◍ 跨品种日线开盘价差的计算收口
上面这段是跨品种价差函数的收尾逻辑,先判断副品种在指定时间是否有日线开盘数据,没有就直接打印提示并返回 EMPTY_VALUE,避免后续算出脏值。 具体看,Print 输出 "No data for " 加 Symbol2 和 TimeToString(dt),让 MT5 终端日志能定位是哪一对品种、哪一个时间点缺数据;return EMPTY_VALUE 则保证调用方拿到的是无效值而非 0,防止把“无数据”误当“价差为零”。 最后在有数据的情况下,price2 用 k_Symbol2 乘 iOpen(Symbol2, PERIOD_D1, shift2) 拿到副品种经系数调整后的日线开盘价,函数返回 price1 - price2 作为两品种开盘价差(spread)。 实盘里把这段塞进 EA 的 OnTick 前先跑一遍,若日志频繁出现 No data,多半是副品种不在市场报价窗口或周期未加载,外汇与贵金属跨品种套利本身高风险,缺数据时点应直接跳过交易而非硬算。
Print("No data for ", Symbol2, " at ", TimeToString(dt)); class="kw">return EMPTY_VALUE; } class="type">class="kw">double price2 = k_Symbol2 * iOpen(Symbol2, PERIOD_D1, shift2); class=class="str">"cmt">//--- Return price difference(spread) class="kw">return price1 - price2; }
「用跨年价差对比挖日线季节性窗口」
在 MT5 里做日线季节性,先别急着翻日历。打开一个品种图表,加载 SpreadMultiYearComparison 指标,填入你要对比的两个品种代码,再把历史年份拉到 10–15 年区间,指标才会给出跨年同期的价差堆叠视图。 选品种对讲究关联,不是随便两个标的凑一对。货币对、商品、指数甚至股票都行,但核心动作是同时一多一空开仓——价差交易赚的是两者相对位移,不是单边方向。某一方走反时,另一腿可能部分或完全抵掉亏损,这种结构常被称为对冲。 找规律看两条:一是翻出过去 10–15 年同月价差,抓那些每年同一月份持续扩张或收缩的窗口;二是看曲线够不够「平滑」,中间没大跳空、所需年份都有报价的,可靠性才高。统计越干净,重复概率越值得盯。 日线周期下单,可叠别的指标确认入出场,但止损必须按波动率摆,仓位别压太重。还要注意基本面突袭——经济数据、天气、主力投机、税务或监管变动都可能打断旧规律。 跑之前核对四件事:品种在所有年份都有报价(15 年优、10 年底线);图表切日线;两个代码都在市场报价窗;加载指标后右键刷新拉全数据。外汇贵金属杠杆高、季节窗也可能失效,历史重复只提示关注,不预示必然。
用多年价差季节性拆季节窗口
在 MT5 里把 SpreadMultiYearComparison 挂到 Symbol1 的图表上,比如 XAUUSD,就能同时看到橄榄色的历史同期价差均值曲线和黄色的本年曲线。把 Symbol2 设成 XAGUSD 可算金银价差,MonthToShow 填 12 即只看 12 月,YearsToShow 设 15 代表回看 15 年同期。 统计口径分三档:盈利年份占比 ≥75% 判为强势趋势;60%–75% 是中等趋势,得再叠加过滤;低于 60% 就是横盘,价差在区间里晃,原文建议配包络线指标做边界参考。外汇与贵金属价差受流动性和央行日程影响,高风险,以上仅为概率倾向。 实战上,强势档(>75%)可顺曲线方向进场,止损放历年平均亏损幅度,止盈取平均盈利两倍,触盈后按权益变化开移动止损。横盘档低于 60% 不赌方向,借包络线上轨空、下轨多,属于高抛低吸的季节性观察,不代表稳赚。
◍ 记住这一条就够了
SpreadMultiYearComparison 这套多年度价差比法,核心是把季节性统计当成‘统计罗盘’而非占卜。它靠双品种对冲把波动率压到单品种以下,D1 周期上只留正向概率超 70% 的季节性信号,确实能砍掉不少噪音。 但别以为机会少就没法玩——原文作者 7 月靠 NAS100 价差拿了约 900 点,8 月 AUDNZD 季节性也走顺了,缺的入场密度可用‘同月多组价差+多品种分散’补回来。 外汇与贵金属价差对冲仍属高风险,白银抵不掉黄金单边崩盘的情形历史上出现过;真要上手,先下那 39.97 KB 的 mq5 在 MT5 跑一遍再说。