为了帮您彻底理清“残差的计算”“如何对残差进行测试”,我们用 R 语言来亲手模拟一组可口可乐(Coke)和百事可乐(Pepsi)的数据。

在量化金融中,这种模拟最迷人的地方在于:我们可以像上帝一样,主动在数据中埋入一条“橡皮筋”(协整关系),然后再通过两步法把它验证出来。

整体思路:采用==Engle-Granger==两步法:

  1. 先建立水平项的长期关系回归模型,
  2. 再检验其残差是否平稳。若残差平稳,则存在协整关系。

1 第一步:准备工作(安装并加载包)

我们需要 urca 包或 tseries 包来进行 ADF 检验。这里我们使用最专业的 urca 包。

# 如果没有安装,请先运行下面这行:
# install.packages("urca")

library(urca)
set.seed(2026) # 设置随机种子,确保您运行的结果和下面完全一致

2 第二步:上帝视角——模拟生成具有“协整关系”的数据

我们要制造两个非平稳的价格序列,但它们之间有一个固定的长期关系:\(Coke = 10 + 1.5 \times Pepsi + 误差\)

n <- 250  # 模拟 250 个交易日(大约一年的数据)

# 1. 模拟百事可乐 (Pepsi) 的价格:让它像无头苍蝇一样随机游走 (Non-stationary, I(1))
pepsi_returns <- rnorm(n, mean = 0, sd = 1) # 每日涨跌幅
pepsi <- 50 + cumsum(pepsi_returns)         # 从50元开始累加,形成股票价格

# 2. 模拟一个【平稳的长期误差】(Stationary Error, I(0))
# 这就是连接两者的“橡皮筋”,它会围绕 0 上下波动,但绝不跑远
true_error <- arima.sim(model = list(ar = 0.5), n = n) * 2 # 一个自回归平稳序列

# 3. 根据长期关系,生成可口可乐 (Coke) 的价格
coke <- 10 + 1.5 * pepsi + true_error

# 把它们画出来看看
# Use english only in subtitles
plot(coke, type="l", col="red", ylim=c(min(pepsi), max(coke)), 
     main="Coke and Pepsi's price Simulation", xlab="Date", ylab="Price")
lines(pepsi, col="blue")
legend("topleft", legend=c("Coke", "Pepsi"), col=c("red", "blue"), lty=1)

运行到这里,你会看到两根线虽然都在波动,但步调极其一致。这就是协整。


3 第三步:回到现实——执行 Engle-Granger 两步法

现在我们假装不知道上帝公式,只拿到了 cokepepsi 的价格数据。

3.1 Step 1: 估计长期关系回归(计算残差)

我们用普通的最小二乘法(OLS)让系统自己去寻找那条“最拟合的线”。

# 运行 OLS 回归
model <- lm(coke ~ pepsi)

# 查看回归结果
summary(model)
## 
## Call:
## lm(formula = coke ~ pepsi)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -6.1755 -1.4689 -0.0553  1.8594  6.9669 
## 
## Coefficients:
##             Estimate Std. Error t value             Pr(>|t|)    
## (Intercept)  7.22003    1.36817   5.277          0.000000286 ***
## pepsi        1.56373    0.02909  53.761 < 0.0000000000000002 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.404 on 248 degrees of freedom
## Multiple R-squared:  0.921,  Adjusted R-squared:  0.9207 
## F-statistic:  2890 on 1 and 248 DF,  p-value: < 0.00000000000000022

在回归输出中,你会发现系统的估计非常接近我们的上帝设置(截距项接近 10,pepsi 的系数接近 1.5)。

【核心:残差是怎么计算出来的?】 残差(Residuals)就是“实际观察到的可口可乐价格”减去“模型预测的可口可乐价格”。 在 R 中,我们可以直接用 residuals() 函数提取它:

# 手动/自动计算残差
my_residuals <- residuals(model)
# 让我们画出这个残差图
plot(my_residuals, type="l", col="purple", main="两步法提取出的残差序列", 
     xlab="时间", ylab="残差值")
abline(h=0, col="black", lty=2) # 画一条 0 刻度线

解释残差图: 你会发现这个残差极其规律,它虽然在上下跳动,但永远不会离 0 轴太远,只要涨高了就会跌回来,跌深了就会涨上去(均值回归)。这就说明这根“橡皮筋”是存在的。

3.2 Step 2: 检验残差是否平稳(测试残差)

虽然肉眼看它是平稳的,但考试和学术需要严格的统计检验。我们对刚才提取出来的 my_residuals 运行 ADF 检验。

# 对残差进行单位根检验 (ADF test)
# selectlags="AIC" 会自动选择最佳的滞后期
adf_result <- ur.df(my_residuals, type = "none", selectlags = "AIC")

# 查看检验报告
summary(adf_result)
## 
## ############################################### 
## # Augmented Dickey-Fuller Test Unit Root Test # 
## ############################################### 
## 
## Test regression none 
## 
## 
## Call:
## lm(formula = z.diff ~ z.lag.1 - 1 + z.diff.lag)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -5.0355 -1.5682  0.1876  1.5156  6.1824 
## 
## Coefficients:
##            Estimate Std. Error t value            Pr(>|t|)    
## z.lag.1    -0.56013    0.06551  -8.550 0.00000000000000132 ***
## z.diff.lag  0.05744    0.06372   0.902               0.368    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 2.126 on 246 degrees of freedom
## Multiple R-squared:  0.2673, Adjusted R-squared:  0.2614 
## F-statistic: 44.88 on 2 and 246 DF,  p-value: < 0.00000000000000022
## 
## 
## Value of test-statistic is: -8.5501 
## 
## Critical values for test statistics: 
##       1pct  5pct 10pct
## tau1 -2.58 -1.95 -1.62

4 四、 如何看懂测试报告(重点)

运行完上面最后一行代码后,控制台会输出一个报告。我们要找的是以下两个核心数据:

  1. Value of test-statistic (测试统计量的值):
  • 假设你看到的值大约是 -5.24(或者其他比较大的负数)。
  1. Critical values (临界值表):
  • 报告下方会给出一行临界值,比如:1pct: -2.58, 5pct: -1.95, 10pct: -1.62

⚠️ 注意(考试/实践避坑):

刚才提到过,因为这里的残差是“估计出来的”,ur.df 输出的普通 DF 临界值(如 -2.58)会过于宽松。严格意义上,我们必须人工去对比 Engle-Granger 专用麦金农(MacKinnon)临界值表。 对于 250 个样本、2 个变量的情况:

  • 1% 显著性水平的真实临界值约为:-3.93
  • 5% 显著性水平的真实临界值约为:-3.37

4.1 最终如何做决策?

我们将测试统计量(-5.24)与专用临界值(-3.37)进行对比:

  • 规则统计量比临界值更负(更小),说明越显著。
  • 对比\(-5.24 < -3.37\)(确实更负了)。
  • 结论:我们成功拒绝了“残差不平稳”的原假设。证明残差是平稳的(\(I(0)\))。
  • 终极结论:可口可乐与百事可乐的价格之间存在协整关系

5 总结

  • 残差的计算:就是 \(Y\) 的真实值与 \(Y\) 的回归预测值之间的差。
  • 残差的测试:对这门差值运行 ADF 检验,如果差值不会随着时间“炸开(发散)”,即统计量足够负,就说明两个变量有长期长短不一但终将回头的纽带(协整)。