Tutorial/外汇预测
Tutorial

你能在外汇预测上跑赢随机游走吗?用 30 行代码验证

经典结论是:一个"不做任何预测"的策略——明天汇率等于今天——在样本外击败几乎所有模型。这里是让你亲自验证这一结论的代码,用的是真实的每日汇率数据。

MMexchangerate.dev·Jul 6, 2026·7 分钟阅读

任何汇率预测都必须先跨过一道门槛:随机游走——这个什么都不做的预测认为,明天的汇率就等于今天的。自 Meese 和 Rogoff(1983)以来,短期内几乎没有模型能跑赢它,2025 年美联储的一篇工作论文用现代机器学习再次验证了这一点。本文是《四十年的高墙》的实操姊妹篇:大约 30 行 Python 代码,拉取数据、搭建基准、诚实地为一个模型打分。

Key points
任何外汇预测都必须跑赢的基准是随机游走:明天的汇率等于今天的。在每日主要货币对上,这个基准出奇地难以被击败。
你可以在免费套餐上跑完整个测试:拉取序列、搭建"无变化"基准,用样本外 R² 加 Clark-West 检验打分。
要丢弃前向填充的周末和假日行(is_forward_filled 标志),否则你的模型会悄悄从"周日汇率不变"这种假象中学到错误的规律。
增加模型复杂性只会让样本外准确率变差,而不是变好。你可以实时观察到过拟合的发生。
姊妹篇在五个货币对上跑了同样的测试,展示了仅凭两个看似合理的分析选择,就足以"制造"出一个统计显著的优势假象。

基准:"明天等于今天"

1983 年,Meese 和 Rogoff 证明了:没有任何宏观模型能跑赢"明天的汇率就是今天的汇率"这个预测。利率差、货币供给、购买力平价——统统没用。这个"模型"就是随机游走,四十年来越来越精巧的经济学研究大多在它面前碰壁。我们在《你能预测汇率吗?》中讨论了背后的原因。本文是实操的另一半:亲自验证这一结论的代码。

2025 年 9 月,一位美联储经济学家用同样的测试检验了现代机器学习。这篇论文——*Virtue or Mirage? Complexity in Exchange Rate Prediction*(Rehim Kılıç,FEDS 2025-089)——让基于随机傅里叶特征(Random Fourier Features)的岭回归(Ridge regression)对阵随机游走,用样本外 R² 以及 Clark-West 和 Diebold-Mariano 检验评判。结论很审慎:复杂性只带来了"微弱、局部的收益",且"脆弱、很少具有统计显著性",从未转化为对随机游走的系统性优势。

我们能复现什么,不能复现什么
这篇论文使用了汇率 API 不提供的月度宏观基本面数据,因此我们无法完全复现它。但我们可以检验那个真正重要的问题——大多数开发者实际会遇到的问题:只用价格历史,一个训练出的模型能否跑赢"明天等于今天"?

拉取数据

通过 /v1/range 端点获取五年的每日 EUR/USD 数据。免费套餐无需密钥即可开始。

python — fetch a daily seriescopy
import requests, numpy as np, pandas as pd

def fetch_range(base, symbol, start, end, key=None):
    rows, cursor = [], None
    headers = {"Authorization": f"Bearer {key}"} if key else {}
    while True:
        p = {"base": base, "symbols": symbol, "start_date": start, "end_date": end}
        if cursor: p["cursor"] = cursor
        d = requests.get("https://api.exchangerate.dev/v1/range",
                         params=p, headers=headers, timeout=30).json()
        rows += [{"date": r["date"], "rate": r["rates"][symbol]} for r in d["data"]]
        if not d.get("has_more"): break
        cursor = d["next_cursor"]
    df = pd.DataFrame(rows).drop_duplicates("date")
    df["date"] = pd.to_datetime(df["date"])
    return df.sort_values("date").set_index("date")

fx = fetch_range("EUR", "USD", "2021-01-01", "2026-01-01")

有件事值得做对:每一行都携带 is_forward_filled 标志和 source 字段。周末和假日的数据是前向填充的,因此严谨的研究会丢弃这些行。你不希望模型从一个"平坦的周日"中"学到"东西——这是《无前视偏差的数据回填》中提到的前视陷阱的一个缩影。

搭建基准和一个挑战者模型

随机游走每天都预测零收益率(Meese 和 Rogoff 使用的无漂移鞅)。给挑战者模型提供仅从价格序列中就能获得的所有廉价特征——动量、均值回归、已实现波动率,再让岭回归(论文本身采用的估计器)预测明天的收益率。

python — features and a Ridge modelcopy
from sklearn.linear_model import Ridge

fx["ret"] = np.log(fx["rate"]).diff()
f = pd.DataFrame(index=fx.index)
for lag in (1, 2, 3, 5, 10): f[f"lag{lag}"] = fx["ret"].shift(lag)
f["mom5"], f["mom20"] = fx["ret"].rolling(5).sum().shift(1), fx["ret"].rolling(20).sum().shift(1)
f["vol10"], f["y"] = fx["ret"].rolling(10).std().shift(1), fx["ret"]
f = f.dropna()

split = int(len(f) * 0.7)
X = [c for c in f.columns if c != "y"]
m = Ridge(alpha=1.0).fit(f.iloc[:split][X], f.iloc[:split]["y"])
pred, y = m.predict(f.iloc[split:][X]), f.iloc[split:]["y"].values

诚实地打分

计算相对随机游走的样本外 R²(正值意味着你赢了),再加上 Clark-West 检验——当随机游走嵌套在你的模型内部时,这是正确的检验方法。

python — out-of-sample R² and Clark-Westcopy
from scipy import stats
r2 = 1 - np.sum((y - pred)**2) / np.sum(y**2)
f_hat = y**2 - ((y - pred)**2 - pred**2)
t = f_hat.mean() / (f_hat.std(ddof=1) / np.sqrt(len(f_hat)))
print(f"OOS R2 {r2:+.4%} | Clark-West t {t:+.2f} p {1-stats.norm.cdf(t):.3f}")

在 EUR/USD、GBP/USD、USD/JPY 以及几个不同窗口上跑一遍,规律相当顽固。样本外 R² 基本处于零或以下,从大致持平到负几个百分点不等,也就是说训练出的模型通常比"假设完全不变"表现更差。Clark-West 统计量很少达到显著水平,那些接近显著的格子只要你稍微调整划分点或标准误就会变来变去。把特征数量拉高来增加"复杂性",样本外表现只会更差。你正在实时观察过拟合的发生。我们在五个货币对上跑了完整测试,并公布了每一个数字。

如果你在做产品,为什么这很重要

如果你上线一个"预测汇率"功能,你必须跑赢的基准就是"返回今天的汇率",而在每日主要货币对数据上,这个基准出奇地难以击败。一个悄悄表现更差的预测接口,就是一个自信满满却错误的数字,安放在别人的结算流程或财资仪表盘里。

真正站得住脚的价值在别处。准确、快速地提供当前汇率水平,因为对下一个汇率最好的点预测确实就是当前值。与其做点预测,不如量化不确定性:波动率和置信区间是真正有用的,而且不需要跑赢随机游走。同时对预测的时间跨度要诚实——可预测性在日度层面基本为零,只有拉长到数月才会略有提升,而这正是文献中发现些许优势存在的地方。

那条平坦的随机游走线本身就是信息。它在说:今天的价格已经包含了关于明天几乎所有可知的东西。对一个数据提供方而言,真正的制胜之道是比任何人都更准确、更快地发布这个价格,并且对预测的局限性保持坦诚。

MM
exchangerate.dev
面向开发者的外汇数据指南,聚焦指示性汇率的实际应用。

Keep reading

Blog我们试图在五个货币对上跑赢随机游走Read Guide你能预测汇率吗?四十年的高墙Read Guide无前视偏差地回填外汇汇率Read