# QuantLib 金融计算——案例之主成分久期（PCD）

## 主成分久期

1. 算出关键利率的 KRD；
2. 对关键利率做 PCA；

## 计算案例

### 利率变化的主成分分析

import pandas as pd
import statsmodels.api as sm
import seaborn as sns

'ratesChg.csv', parse_dates=True, index_col='date')
'returns.csv', parse_dates=True, index_col='date')

pca = sm.PCA(
ratesChg,
standardize=False,
demean=True,
normalize=True)

'''
comp_00   comp_01   comp_02  ...   comp_11   comp_12   comp_13
1D   0.471356  0.877932 -0.060239  ...  0.015957  0.024632  0.006903
6M   0.047785  0.023852  0.897648  ... -0.001783  0.012518 -0.018913
1Y   0.298379 -0.136045  0.227319  ... -0.132121 -0.011556 -0.044387
2Y   0.310444 -0.149192  0.123286  ...  0.645939 -0.030575  0.140874
3Y   0.342030 -0.157388  0.033696  ... -0.385047 -0.121084  0.023274
4Y   0.342225 -0.187096  0.013315  ...  0.023240  0.393166 -0.008804
5Y   0.303104 -0.174121  0.034038  ...  0.066626 -0.031194 -0.094945
6Y   0.266243 -0.131857 -0.053863  ... -0.499595 -0.316239 -0.183736
7Y   0.224635 -0.120262 -0.054711  ...  0.102571 -0.247733  0.106077
8Y   0.218911 -0.138575 -0.168238  ... -0.150574  0.655571 -0.091769
9Y   0.217848 -0.115892 -0.188426  ...  0.132909 -0.470151  0.134931
10Y  0.136793 -0.117408 -0.208336  ...  0.180370  0.058729  0.088273
15Y  0.135273 -0.106458 -0.087883  ...  0.259897 -0.024268 -0.592554
20Y  0.102095 -0.090580 -0.020611  ... -0.106187  0.108275  0.733208
'''


R2 = pd.DataFrame(
data=[sm.OLS(endog=returns, exog=pca.factors.iloc[:, i]).fit().rsquared for i in range(pca._ncomp)],

print(R2)

'''
comp_00  0.442932
comp_01  0.098024
comp_02  0.039253
comp_03  0.129587
comp_04  0.035543
comp_05  0.036428
comp_06  0.055197
comp_07  0.000370
comp_08  0.045802
comp_09  0.000013
comp_10  0.004617
comp_11  0.000724
comp_12  0.018448
comp_13  0.000376
'''


pcReg = sm.OLS(
endog=returns, exog=pca.factors).fit()

# print(pcReg.summary())

idx = [0, 1, 2, 3, 4, 5, 6, 8, 10, 12]

pcReg = sm.OLS(
endog=returns, exog=pca.factors.iloc[:, idx]).fit()

print(pcReg.summary())

'''
OLS Regression Results
=======================================================================================
Dep. Variable:                 return   R-squared (uncentered):                   0.906
Model:                            OLS   Adj. R-squared (uncentered):              0.902
Method:                 Least Squares   F-statistic:                              228.9
Date:                Wed, 18 Nov 2020   Prob (F-statistic):                   4.81e-116
Time:                        15:22:48   Log-Likelihood:                          1424.0
No. Observations:                 248   AIC:                                     -2828.
Df Residuals:                     238   BIC:                                     -2793.
Df Model:                          10
Covariance Type:            nonrobust
==============================================================================
coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
comp_00       -0.0265      0.001    -33.458      0.000      -0.028      -0.025
comp_01        0.0125      0.001     15.740      0.000       0.011       0.014
comp_02        0.0079      0.001      9.960      0.000       0.006       0.009
comp_03       -0.0143      0.001    -18.097      0.000      -0.016      -0.013
comp_04       -0.0075      0.001     -9.478      0.000      -0.009      -0.006
comp_05        0.0076      0.001      9.595      0.000       0.006       0.009
comp_06        0.0094      0.001     11.811      0.000       0.008       0.011
comp_08       -0.0085      0.001    -10.759      0.000      -0.010      -0.007
comp_10       -0.0027      0.001     -3.416      0.001      -0.004      -0.001
comp_12        0.0054      0.001      6.828      0.000       0.004       0.007
==============================================================================
Omnibus:                      130.528   Durbin-Watson:                   1.924
Prob(Omnibus):                  0.000   Jarque-Bera (JB):             7723.672
Skew:                          -1.214   Prob(JB):                         0.00
'''


### 计算 PCD

• 水平因子（h）对应的向量所有元素都必须为正；
• 斜率因子（s）对应的向量在短期限一端为负，在长期限一端为正；
• 曲率因子（c）对应的向量在中间期限为正，在两端为负。

krd = pd.DataFrame(
data=[
-0.00273973, 0.01761345, 0.02607589, 0.06751827, 0.09790298,
0.12608806, 0.15196510, 0.17540198, 0.19649419, 3.12947679,
3.35232738, 0.00000000, 0.00000000, 0.00000000],
columns=['KRD'])

hsc.columns = ['h','s','c']

# print(hsc)

hsc.loc[:,'s'] = -hsc.loc[:,'s']
hsc.loc[:,'c'] = -hsc.loc[:,'c']

print(hsc)

hsc.plot(marker='o')

'''
h         s         c
1D   0.471356 -0.877932 -0.027072
6M   0.047785 -0.023852 -0.426987
1Y   0.298379  0.136045  0.416754
2Y   0.310444  0.149192  0.261607
3Y   0.342030  0.157388  0.222109
4Y   0.342225  0.187096  0.086126
5Y   0.303104  0.174121  0.047247
6Y   0.266243  0.131857 -0.176602
7Y   0.224635  0.120262 -0.063345
8Y   0.218911  0.138575 -0.288706
9Y   0.217848  0.115892 -0.352268
10Y  0.136793  0.117408 -0.506713
15Y  0.135273  0.106458 -0.108318
20Y  0.102095  0.090580 -0.068624
'''


pcd = (hsc * krd.values).sum()

print(pcd)

pcdNormalize = pcd * np.sqrt(pca.eigenvals[0:3]).values

print(pcdNormalize)

'''
h    1.657201
s    0.950000
c   -2.066973

h    0.026187
s    0.012167
c   -0.013483
'''


pcd 是债券关于主成分因子的敏感性，pcdNormalize 是债券关于归一化后主成分的敏感性（和书中的约定一样），可以看出 pcdNormalize 的值和回归系数大体保持一致（注意到符号的转换）。

pcd['h'] * pca.loadings['comp_00'].sum()
# 5.662857296706285


## 扩展阅读

《QuantLib 金融计算》系列合集

posted @ 2020-11-18 20:57  xuruilong100  阅读(660)  评论(1编辑  收藏  举报