实证资产定价中有一些常用的调整方法,如White调整方差、Newey West调整方差,以及由此衍生出的White检验和Newey West调整方法,本文构建了这些常用的调整方法。
本文的Package已发布于Github:
Github: GitHub - whyecofiliter/EAP: empirical asset pricing
adjust
This module consists of several common adjustment method in factor analysis.
def ols(y, x, constant=True):
The function is for OLS regression, which is equal to the OLS module in package statsmodels.
input :
y : The dependent variable.
x : The explanatory variable.
constant : add constant or not in OLS model. The default is True.
output :
result : The result of the regression.
import numpy as np
from statsmodels.base.model import Model
from statsmodels.tools.tools import add_constant
from EAP.adjust import newey_west, newey_west_t, ols, white_t
from EAP.adjust import white
X = np.random.normal(loc=0.0, scale=1.0, size=(2000,10))
b = np.random.uniform(low=0.1, high=1.1, size=(10,1))
e = np.random.normal(loc=0.0, scale=1.0, size=(2000,1))
y = X.dot(b) + e + 1.0
re = ols(y, X, constant=True)
print('\nTrue b : ', b)
print('\nEstimated b : ', re.params)
print('\nresidue : ', re.resid.shape)
====================================================
True b : [[0.59169091]
[0.91342353]
[0.19599503]
[0.9112773 ]
[0.70647024]
[0.41873624]
[0.64871071]
[0.20685505]
[0.13172035]
[0.82358063]]
Estimated b : [1.00206596 0.57602159 0.91832825 0.2104454 0.935377 0.71526534
0.39181771 0.65432445 0.22666925 0.13173488 0.83208811]
residue : (2000,)
def white(y, X, **kwargs):
This function is for the White test. White estimate of variance:
X(r,c): r is sample number, c is variable number, S0 is covariance matrix of residue.
The variance estimate is
$$
V_{ols}=T(X^`X)^{-1}S_0(X^`X)^{-1}.
$$
The white estimation of S0 is
$$
S_0=\frac 1T X^`(XR).
$$
input :
y : The dependent variable.
X : The explanatory variable.
output :
V_ols : The white variance estimate
Example
# continue the previous code
import numpy as np
from statsmodels.api import add_constant
X = np.random.normal(loc=0.0, scale=1.0, size=(2000,10))
b = np.random.uniform(low=0.1, high=1.1, size=(10,1))
e = np.random.normal(loc=0.0, scale=1.0, size=(2000,1))
y = X.dot(b) + e + 1.0
re = white(y, X, constant=True)
np.set_printoptions(formatter={'float':'{:0.3f}'.format})
print(re*100)
X = add_constant(X)
r, c = np.shape(X)
print('\n', 1/r*X.T.dot(X).dot(re).dot(X.T.dot(X)))
============================================================================
[[0.052 0.004 0.002 0.002 0.000 -0.002 0.002 -0.004 -0.001 0.000 0.003]
[0.004 0.056 0.002 -0.002 -0.003 -0.004 -0.001 -0.001 -0.003 0.004 0.001]
[0.002 0.002 0.049 -0.003 -0.003 0.003 0.000 -0.002 -0.002 -0.003 0.002]
[0.002 -0.002 -0.003 0.051 -0.002 -0.002 0.004 -0.000 -0.000 -0.001 0.002]
[0.000 -0.003 -0.003 -0.002 0.054 0.004 0.000 -0.001 0.000 -0.001 0.003]
[-0.002 -0.004 0.003 -0.002 0.004 0.055 -0.001 0.000 0.000 -0.002 0.001]
[0.002 -0.001 0.000 0.004 0.000 -0.001 0.053 -0.003 -0.005 -0.002 0.004]
[-0.004 -0.001 -0.002 -0.000 -0.001 0.000 -0.003 0.057 -0.001 -0.001 -0.002]
[-0.001 -0.003 -0.002 -0.000 0.000 0.000 -0.005 -0.001 0.051 0.003 0.000]
[0.000 0.004 -0.003 -0.001 -0.001 -0.002 -0.002 -0.001 0.003 0.049 0.002]
[0.003 0.001 0.002 0.002 0.003 0.001 0.004 -0.002 0.000 0.002 0.052]]
[[1.036 0.029 -0.028 0.031 0.007 -0.067 -0.004 0.003 0.029 -0.022 -0.041]
[0.029 1.001 0.020 -0.056 -0.066 -0.023 0.000 -0.010 -0.070 0.069 0.023]
[-0.028 0.020 0.972 -0.057 -0.019 0.058 -0.048 -0.002 0.084 -0.005 0.045]
[0.031 -0.056 -0.057 1.004 -0.004 0.017 0.017 -0.072 -0.008 -0.042 0.041]
[0.007 -0.066 -0.019 -0.004 1.024 0.045 -0.035 0.017 0.003 0.006 0.029]
[-0.067 -0.023 0.058 0.017 0.045 1.125 0.010 -0.014 0.037 0.053 -0.017]
[-0.004 0.000 -0.048 0.017 -0.035 0.010 1.053 -0.022 -0.047 0.047 0.035]
[0.003 -0.010 -0.002 -0.072 0.017 -0.014 -0.022 0.955 -0.007 -0.002 -0.019]
[0.029 -0.070 0.084 -0.008 0.003 0.037 -0.047 -0.007 1.008 -0.025 0.025]
[-0.022 0.069 -0.005 -0.042 0.006 0.053 0.047 -0.002 -0.025 1.010 0.026]
[-0.041 0.023 0.045 0.041 0.029 -0.017 0.035 -0.019 0.025 0.026 1.058]]
def newey_west(y, X, J=None):
This function is for Newey-West adjustment. Newey-West estimate of variance:
X(r,c): r is sample number, c is variable number, and S0 is covariance matrix of residue.
The estimate variance is
$$
V_{ols}=T(X^`X)^{-1}S_0(X^`X)^{-1}.
$$
The Newey-West estimate variance of S0 is
$$
S_0= \frac1T X^`(XR)+\frac1T \sum_j\sum_tw_je_te_{t-j}(X_tX^`_{t-j}+X_{t-j}X^`_t).
$$
input :
y : The dependent variable.
X : The explanatory variable.
J : The lag.
output :
V_ols : The Newey-West variance estimate.
Example
# continue the previous code
import numpy as np
from statsmodels.stats.sandwich_covariance import cov_hac
X = np.random.normal(loc=0.0, scale=1.0, size=(10000,10))
b = np.random.uniform(low=0.1, high=1.1, size=(10,1))
e = np.random.normal(loc=0.0, scale=1.0, size=(10000,1))
y = X.dot(b) + e + 1.0
re = newey_west(y, X, constant=False)
np.set_printoptions(formatter={'float':'{:0.2f}'.format})
print(re)
# X = add_constant(X)
r, c = np.shape(X)
print('\n', 1/r*X.T.dot(X).dot(re).dot(X.T.dot(X)))
result = ols(y, X, constant=False)
print('\n', cov_hac(result))
print('\n', 1/r*X.T.dot(X).dot(cov_hac(result)).dot(X.T.dot(X)))
========================================================================
[[0.00 -0.00 -0.00 0.00 0.00 0.00 -0.00 0.00 -0.00 -0.00]
[-0.00 0.00 -0.00 -0.00 -0.00 0.00 -0.00 -0.00 0.00 -0.00]
[-0.00 -0.00 0.00 -0.00 -0.00 -0.00 -0.00 -0.00 -0.00 0.00]
[0.00 -0.00 -0.00 0.00 -0.00 -0.00 -0.00 0.00 -0.00 -0.00]
[0.00 -0.00 -0.00 -0.00 0.00 0.00 -0.00 -0.00 0.00 0.00]
[0.00 0.00 -0.00 -0.00 0.00 0.00 -0.00 -0.00 -0.00 0.00]
[-0.00 -0.00 -0.00 -0.00 -0.00 -0.00 0.00 0.00 0.00 0.00]
[0.00 -0.00 -0.00 0.00 -0.00 -0.00 0.00 0.00 -0.00 -0.00]
[-0.00 0.00 -0.00 -0.00 0.00 -0.00 0.00 -0.00 0.00 0.00]
[-0.00 -0.00 0.00 -0.00 0.00 0.00 0.00 -0.00 0.00 0.00]]
[[2.08 0.00 -0.09 -0.01 -0.03 -0.05 -0.02 0.00 -0.02 0.01]
[0.00 2.01 0.04 -0.00 0.00 -0.03 -0.00 -0.01 -0.00 0.02]
[-0.09 0.04 1.99 -0.02 0.01 0.00 -0.01 -0.08 0.03 0.02]
[-0.01 -0.00 -0.02 1.96 -0.00 -0.05 -0.01 -0.04 -0.01 -0.02]
[-0.03 0.00 0.01 -0.00 1.98 0.06 0.00 0.04 -0.01 -0.05]
[-0.05 -0.03 0.00 -0.05 0.06 1.94 -0.01 -0.00 -0.01 -0.02]
[-0.02 -0.00 -0.01 -0.01 0.00 -0.01 2.04 -0.00 0.01 -0.07]
[0.00 -0.01 -0.08 -0.04 0.04 -0.00 -0.00 1.89 -0.05 -0.02]
[-0.02 -0.00 0.03 -0.01 -0.01 -0.01 0.01 -0.05 1.97 -0.01]
[0.01 0.02 0.02 -0.02 -0.05 -0.02 -0.07 -0.02 -0.01 1.93]]
[[0.00 -0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00 -0.00]
[-0.00 0.00 0.00 -0.00 0.00 0.00 -0.00 0.00 -0.00 -0.00]
[0.00 0.00 0.00 -0.00 -0.00 0.00 -0.00 -0.00 -0.00 0.00]
[0.00 -0.00 -0.00 0.00 0.00 -0.00 -0.00 -0.00 -0.00 -0.00]
[0.00 0.00 -0.00 0.00 0.00 0.00 0.00 -0.00 0.00 0.00]
[0.00 0.00 0.00 -0.00 0.00 0.00 -0.00 -0.00 -0.00 -0.00]
[-0.00 -0.00 -0.00 -0.00 0.00 -0.00 0.00 0.00 -0.00 0.00]
[0.00 0.00 -0.00 -0.00 -0.00 -0.00 0.00 0.00 -0.00 0.00]
[0.00 -0.00 -0.00 -0.00 0.00 -0.00 -0.00 -0.00 0.00 0.00]
[-0.00 -0.00 0.00 -0.00 0.00 -0.00 0.00 0.00 0.00 0.00]]
[[2.07 -0.05 -0.04 0.02 0.06 -0.11 -0.08 0.03 0.05 0.02]
[-0.05 1.91 0.10 0.01 0.07 0.00 0.01 0.02 -0.09 0.03]
[-0.04 0.10 2.05 -0.06 0.01 0.07 -0.06 -0.11 -0.15 0.04]
[0.02 0.01 -0.06 1.87 0.04 -0.05 -0.02 -0.10 -0.01 -0.06]
[0.06 0.07 0.01 0.04 2.00 0.11 0.05 0.03 -0.00 -0.04]
[-0.11 0.00 0.07 -0.05 0.11 1.91 0.00 -0.05 -0.05 -0.05]
[-0.08 0.01 -0.06 -0.02 0.05 0.00 1.99 0.03 -0.02 -0.10]
[0.03 0.02 -0.11 -0.10 0.03 -0.05 0.03 2.01 -0.10 0.06]
[0.05 -0.09 -0.15 -0.01 -0.00 -0.05 -0.02 -0.10 2.16 0.01]
[0.02 0.03 0.04 -0.06 -0.04 -0.05 -0.10 0.06 0.01 1.97]]
def white_t(y, X, params=None, **kwargs):
This function constructs t-test based on White variance estimate.
input :
y : The dependent variable.
X : The explanatory variable.
params : Already have parameters or not. The default is None.
output :
t_value : The t-value of parameters.
p_value : The p-value of parameters.
Example
import numpy as np
X = np.random.normal(loc=0.0, scale=1.0, size=(10000,10))
b = np.random.uniform(low=-0.5, high=0.5, size=(10,1))
e = np.random.normal(loc=0.0, scale=1.0, size=(10000,1))
y = X.dot(b) + e + 1.0
re = white_t(y, X, constant=False)
np.set_printoptions(formatter={'float':'{:0.2f}'.format})
print('t_value : ', re[0], '\np_value : ', re[1])
print('b :', b.T)
=========================================================================
t_value : [2.50 34.58 13.23 6.56 -17.64 -34.69 -16.40 13.84 28.90 30.64]
p_value : [0.01 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00]
b : [[0.02 0.49 0.18 0.09 -0.25 -0.49 -0.22 0.19 0.44 0.43]]
def newey_west_t(y, X, params=None):
This function constructs t-test based on Newey-West variance estimate.
input :
y : The dependent variable.
X : The explanatory variable.
params : Already have parameters or not. The default is None.
output :
t_value : The t-value of parameters.
p_value : The p-value of parameters.
Example
import numpy as np
X = np.random.normal(loc=0.0, scale=1.0, size=(10000,10))
b = np.random.uniform(low=-0.5, high=0.5, size=(10,1))
e = np.random.normal(loc=0.0, scale=1.0, size=(10000,1))
y = X.dot(b) + e + 1.0
re = newey_west_t(y, X, constant=True)
np.set_printoptions(formatter={'float':'{:0.2f}'.format})
print('t_value : ', re[0], '\np_value : ', re[1])
print('b :', b.T)
=================================================================================
t_value : [135.08 -17.19 13.80 34.95 14.61 21.31 48.56 -44.62 2.75 -28.71 51.63]
p_value : [0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00]
b : [[-0.14 0.10 0.25 0.11 0.16 0.40 -0.36 0.03 -0.21 0.40]]










