第二章:金融时间序列特性

各位同学,今天我们来聊聊金融时间序列的那些“脾气”。

做量化交易,说白了就是跟数据打交道。但金融数据跟物理实验数据不一样——它有自己的性格,甚至有点“任性”。我刚开始做策略回测时,就吃过不少亏。明明策略在历史数据上跑得漂亮,一上实盘就崩。后来才发现,是我没摸透时间序列的特性。

这一章,我们就来把这些特性一个一个拆开看。

核心要点:金融时间序列的四大特性——平稳性、自相关性、随机性、波动聚集性。搞懂它们,你就能避开80%的坑。

2.1 平稳性与非平稳性

先问一个问题:股价是平稳的吗?

答案很明确——不是。股价会涨会跌,长期趋势明显,均值也在变。这就是典型的非平稳序列。

那什么是平稳序列?我个人的理解很简单:统计性质不随时间变化。比如白噪声,均值恒定,方差稳定,没有趋势。

为什么我们要关心这个?因为大多数统计模型(比如ARIMA、GARCH)都要求数据是平稳的。你用非平稳数据去建模,结果就是伪回归——看着相关,其实毫无意义。

我在项目中遇到过一位同事,用股价直接跑回归,R²高达0.9,兴奋得不行。结果我一测残差,有明显的单位根。嗯,那模型基本废了。

如何判断平稳性?

两种常用方法:

  • 肉眼观察法:看时序图。有趋势、有季节性波动,基本就是非平稳。
  • 统计检验法:ADF检验(Augmented Dickey-Fuller Test)。

ADF检验的原假设是“存在单位根”(即非平稳)。p值小于0.05,就拒绝原假设,认为序列平稳。

import pandas as pd
import numpy as np
from statsmodels.tsa.stattools import adfuller

# 模拟一个随机游走(非平稳)
np.random.seed(42)
n = 1000
random_walk = np.cumsum(np.random.randn(n))

# ADF检验
result = adfuller(random_walk)
print(f'ADF统计量: {result[0]:.4f}')
print(f'p值: {result[1]:.4f}')
# p值大概率 > 0.05,说明非平稳

# 一阶差分后
diff_series = np.diff(random_walk)
result_diff = adfuller(diff_series)
print(f'差分后p值: {result_diff[1]:.4f}')
# 差分后p值 < 0.05,变成平稳序列

个人经验:我习惯对收益率做分析,而不是价格。收益率通常接近平稳,而价格几乎永远非平稳。你想想看,如果两个不相关的股票价格都上涨,它们的相关系数可能很高——但这只是伪相关。

2.2 自相关与偏自相关

自相关,说白了就是“今天的价格跟昨天的价格有没有关系”。

金融数据里,短期自相关通常很弱。但如果你做高频交易,你会发现订单流有很强的自相关——大单后面往往跟着更多大单。

偏自相关呢?它是在剔除了中间滞后项的影响后,两个时间点之间的直接相关性。比如,今天和前天之间的偏自相关,就是去掉“今天和昨天”、“昨天和前天”这些间接关系后的纯相关。

这两个指标有什么用?

  • ACF(自相关函数):判断MA模型的阶数
  • PACF(偏自相关函数):判断AR模型的阶数

我曾经用ACF/PACF图来识别一个股指期货的日内模式。发现滞后1阶的ACF显著不为0,说明存在一阶自回归结构。后来用AR(1)模型做预测,效果还不错。

from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import matplotlib.pyplot as plt

# 生成一个AR(1)过程
np.random.seed(42)
ar1 = np.zeros(500)
for t in range(1, 500):
    ar1[t] = 0.7 * ar1[t-1] + np.random.randn()

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6))
plot_acf(ar1, lags=20, ax=ax1)
plot_pacf(ar1, lags=20, ax=ax2)
plt.show()

避坑指南:我曾经在分析日收益率时,看到ACF在滞后5阶处显著,以为发现了什么周期规律。后来才发现是数据里有一个异常值——某天市场暴跌5%。去掉这个点后,自相关就消失了。所以,做自相关分析前,一定要先处理异常值。

2.3 白噪声与随机游走

白噪声,是时间序列的“纯净版”。每个时间点的值独立同分布,均值为0,方差恒定。说白了,就是完全随机,没有任何可预测性。

随机游走呢?它是白噪声的累积和。今天的值 = 昨天的值 + 白噪声。股价走势就非常接近随机游走。

为什么说“接近”?因为实际股价有微小的时间相关性、波动聚集性,不是完美的随机游走。但有效市场假说认为,价格已经反映了所有信息,未来变化不可预测——这本质上就是随机游走。

我个人觉得,理解随机游走是量化交易的第一课。如果你相信市场是随机游走,那任何技术分析都是徒劳。但如果你能找到偏离随机游走的模式——比如短期动量、均值回复——那就是你的alpha来源。

# 模拟随机游走 vs 白噪声
np.random.seed(42)
white_noise = np.random.randn(500)
random_walk = np.cumsum(white_noise)

# 检验白噪声:Ljung-Box检验
from statsmodels.stats.diagnostic import acorr_ljungbox

lb_test = acorr_ljungbox(white_noise, lags=[10])
print(f'白噪声的Ljung-Box p值: {lb_test["lb_pvalue"].values[0]:.4f}')
# p值 > 0.05,不能拒绝白噪声假设

lb_test_rw = acorr_ljungbox(random_walk, lags=[10])
print(f'随机游走的Ljung-Box p值: {lb_test_rw["lb_pvalue"].values[0]:.4f}')
# p值 < 0.05,拒绝白噪声假设(因为随机游走有强自相关)

关键区别:白噪声是“无记忆”的,随机游走是“有记忆”的——它记得自己走过的所有路径。这就是为什么随机游走是非平稳的,而白噪声是平稳的。

2.4 ARCH效应检验

最后,也是最关键的一个特性——波动聚集性。

你有没有发现,股市大跌之后往往接着大跌?大涨之后也容易继续大涨?这不是价格在聚集,而是波动率在聚集。高波动时期和低波动时期会交替出现。

这就是ARCH效应(自回归条件异方差)。简单说:波动率本身是自相关的

为什么重要?因为很多模型假设方差恒定,但金融数据的方差明显在变。你用恒定方差的模型去预测,置信区间会严重失真。

检验ARCH效应的方法:

  1. 对收益率序列拟合一个均值模型(比如ARMA)
  2. 提取残差
  3. 对残差的平方做Ljung-Box检验或LM检验

如果残差平方存在自相关,就说明有ARCH效应。

from arch import arch_model

# 模拟一个ARCH(1)过程
np.random.seed(42)
n = 1000
omega = 0.1
alpha = 0.7
epsilon = np.random.randn(n)
sigma2 = np.zeros(n)
returns = np.zeros(n)

sigma2[0] = omega / (1 - alpha)
returns[0] = np.sqrt(sigma2[0]) * epsilon[0]

for t in range(1, n):
    sigma2[t] = omega + alpha * returns[t-1]**2
    returns[t] = np.sqrt(sigma2[t]) * epsilon[t]

# ARCH效应检验:使用arch包的LM检验
am = arch_model(returns, vol='ARCH', p=1)
res = am.fit(disp='off')
print(res.summary())

# 也可以手动检验残差平方的自相关
residuals = returns - np.mean(returns)
squared_resid = residuals**2
lb_test_arch = acorr_ljungbox(squared_resid, lags=[10])
print(f'残差平方的Ljung-Box p值: {lb_test_arch["lb_pvalue"].values[0]:.4f}')
# p值 < 0.05,说明存在ARCH效应

我的习惯:在做任何波动率模型之前,我都会先跑一遍ARCH效应检验。如果p值大于0.05,那GARCH模型基本不用考虑了——数据不支持。反过来,如果p值显著,那恭喜你,波动率建模有戏。

知识体系总览

下面这张图,是我自己整理的知识框架。你可以把它当作本章的“地图”。

金融时间序列特性知识体系 时间序列特性 平稳性 均值/方差恒定 自相关与偏自相关 ACF / PACF 白噪声与随机游走 可预测性检验 ARCH效应 波动聚集性 ADF检验 差分处理 AR/MA定阶 Ljung-Box检验 有效市场假说 不可预测性 LM检验 GARCH建模 目标:为波动率预测模型选择正确的数据预处理方法

这张图把四个核心特性串起来了。你会发现,它们之间是有逻辑关系的:先判断平稳性,再分析自相关结构,然后检验随机性,最后看波动率是否有聚集效应。每一步都为下一步做准备。

最后提醒一句:不要跳过这些检验直接建模。我曾经见过有人用非平稳数据跑GARCH,结果模型参数不稳定,预测结果时好时坏。花10分钟做检验,能省你10小时调试模型的时间。


公众号:蓝海资料掘金营,微信deep3321