时序分析 16
协整序列下
… 接上
乘法收益和加法收益都是稳定的。
但是在实践中我们发现这种情况并不一定总是出现这种情况。而且,我们也不能因为一个时序过去是平稳的,就认为未来也是平稳的。时序的平稳检测需要经常进行检测,包括交叉验证和样本外评估等多种方法。
实践中,我们经常在分析收益而不是在分析价格,原因就是价格是 I ( 1 ) I(1) I(1) 而收益是价格差分的结果,属于 I ( 0 ) I(0) I(0)
协整序列和实践
终于,我们开始探讨本文的最主要的话题:协整序列。
定义:
我们假设有一系列时序数据(
X
1
X_1
X1,
X
2
X_2
X2,
…
\dots
…,
X
k
X_k
Xk),如果这些时序都是
I
(
1
)
I(1)
I(1),但是它们的线性组合
Y
=
b
1
X
1
+
b
2
X
2
+
⋯
+
b
k
X
k
Y = b_1X_1 + b_2X_2 + \dots + b_kX_k
Y=b1X1+b2X2+⋯+bkXk 是
I
(
0
)
I(0)
I(0) ,我们就说这个时序集合是协整的。
让我们来试验一下,
X1为平稳正态过程,X2就是X1加上一个正态随机噪声。X2和X1都是 I ( 1 ) I(1) I(1)
# Length of series
N = 100
# Generate a stationary random X1
X1 = np.random.normal(0, 1, N)
# Integrate it to make it I(1)
X1 = np.cumsum(X1)
X1 = pd.Series(X1)
X1.name = 'X1'
# Make an X2 that is X1 plus some noise
X2 = X1 + np.random.normal(0, 1, N)
X2.name = 'X2'
plt.plot(X1)
plt.plot(X2)
plt.xlabel('Time')
plt.ylabel('Series Value')
plt.legend([X1.name, X2.name]);
Z = X2.diff()[1:]
Z.name = 'Z'
check_for_stationarity(Z);
p-value = 3.493980198694881e-17 The series Z is likely stationary.
Z = X2 - X1
Z.name = 'Z'
plt.plot(Z)
plt.xlabel('Time')
plt.ylabel('Series Value')
plt.legend(['Z']);
check_for_stationarity(Z);
p-value = 2.435247740681034e-16 The series Z is likely stationary.
情况符合预期。
协整的检验
协整序列的检验有很多方法。原始的思路是尝试求解系数
b
1
,
…
b
k
b_1, \dots b_k
b1,…bk 使得集合的线性组合为
I
(
0
)
I(0)
I(0).
在实践中,经常遇到的问题是两个序列的协整测试问题,通用的方法是采用线性回归
X
2
=
α
+
β
X
1
+
ϵ
X_2 = \alpha + \beta X_1 + \epsilon
X2=α+βX1+ϵ ,如果有具有显著性的
β
\beta
β 使得该线性关系成立,也就意味着
X
2
−
β
X
1
=
α
+
ϵ
X_2 - \beta X_1 = \alpha + \epsilon
X2−βX1=α+ϵ 是
I
(
0
)
I(0)
I(0).
实际数据
我们使用实际数据来尝试一下,
symbol_list = ['ABGB', 'FSLR']
prices = get_pricing(symbol_list, fields=['price']
, start_date='2014-01-01', end_date='2015-01-01')['price']
prices.columns = map(lambda x: x.symbol, prices.columns)
X1 = prices[symbol_list[0]]
X2 = prices[symbol_list[1]]
plt.plot(X1.index, X1.values)
plt.plot(X1.index, X2.values)
plt.xlabel('Time')
plt.ylabel('Series Value')
plt.legend([X1.name, X2.name]);
使用线性回归来计算
β
\beta
β
X1 = sm.add_constant(X1)
results = sm.OLS(X2, X1).fit()
# Get rid of the constant column
X1 = X1[symbol_list[0]]
results.params
const 26.609769
ABGB 1.536686
dtype: float64``
b = results.params[symbol_list[0]]
Z = X2 - b * X1
Z.name = 'Z'
plt.plot(Z.index, Z.values)
plt.xlabel('Time')
plt.ylabel('Series Value')
plt.legend([Z.name]);
check_for_stationarity(Z);
p-value = 0.000972948552814 The series Z is likely stationary.
我们可以看到结果
Z
Z
Z 是平稳的,这使我们接受假设:这两个时序是协整的。
但请注意,两个时序在过去出现协整的关系并不代表将来这种关系依然存在。
最后,给出程序包里已经提供的协整检测方法:
from statsmodels.tsa.stattools import coint
coint(X1, X2)
(-4.0503429043747827,
0.0060792512281641932,
array([-3.4565689 , -2.87307862, -2.572919 ]))