1
0
mirror of https://github.com/microsoft/qlib.git synced 2026-07-14 16:26:55 +08:00
Charles Young
2021-03-08 19:08:55 +08:00
parent 7022675d00
commit 6a305c73ae
4 changed files with 17 additions and 18 deletions

View File

@@ -38,8 +38,11 @@ class RiskModel(BaseModel):
self.scale_return = scale_return self.scale_return = scale_return
def predict( def predict(
self, X: Union[pd.Series, pd.DataFrame, np.ndarray], return_corr: bool = False, is_price: bool = True, self,
return_decomposed_components=False, X: Union[pd.Series, pd.DataFrame, np.ndarray],
return_corr: bool = False,
is_price: bool = True,
return_decomposed_components=False,
) -> Union[pd.DataFrame, np.ndarray, tuple]: ) -> Union[pd.DataFrame, np.ndarray, tuple]:
""" """
Args: Args:
@@ -53,7 +56,7 @@ class RiskModel(BaseModel):
pd.DataFrame or np.ndarray: estimated covariance (or correlation). pd.DataFrame or np.ndarray: estimated covariance (or correlation).
""" """
assert ( assert (
not return_corr or not return_decomposed_components not return_corr or not return_decomposed_components
), "Can only return either correlation matrix or decomposed components." ), "Can only return either correlation matrix or decomposed components."
# transform input into 2D array # transform input into 2D array
@@ -84,8 +87,9 @@ class RiskModel(BaseModel):
# return decomposed components if needed # return decomposed components if needed
if return_decomposed_components: if return_decomposed_components:
assert 'return_decomposed_components' in inspect.getfullargspec(self._predict).args, \ assert (
'This risk model does not support return decomposed components of the covariance matrix ' "return_decomposed_components" in inspect.getfullargspec(self._predict).args
), "This risk model does not support return decomposed components of the covariance matrix "
F, cov_b, var_u = self._predict(X, return_decomposed_components=True) F, cov_b, var_u = self._predict(X, return_decomposed_components=True)
return F, cov_b, var_u return F, cov_b, var_u

View File

@@ -50,7 +50,7 @@ class POETCovEstimator(RiskModel):
if self.num_factors > 0: if self.num_factors > 0:
Dd, V = np.linalg.eig(Y.T.dot(Y)) Dd, V = np.linalg.eig(Y.T.dot(Y))
V = V[:, np.argsort(Dd)] V = V[:, np.argsort(Dd)]
F = V[:, -self.num_factors:][:, ::-1] * np.sqrt(n) F = V[:, -self.num_factors :][:, ::-1] * np.sqrt(n)
LamPCA = Y.dot(F) / n LamPCA = Y.dot(F) / n
uhat = np.asarray(Y - LamPCA.dot(F.T)) uhat = np.asarray(Y - LamPCA.dot(F.T))
Lowrank = np.asarray(LamPCA.dot(LamPCA.T)) Lowrank = np.asarray(LamPCA.dot(LamPCA.T))

View File

@@ -248,8 +248,7 @@ class ShrinkCovEstimator(RiskModel):
roff1 = np.sum(v1 * cov_mkt[:, None].T) / var_mkt - np.sum(np.diag(v1) * cov_mkt) / var_mkt roff1 = np.sum(v1 * cov_mkt[:, None].T) / var_mkt - np.sum(np.diag(v1) * cov_mkt) / var_mkt
v3 = z.T.dot(z) / t - var_mkt * S v3 = z.T.dot(z) / t - var_mkt * S
roff3 = ( roff3 = (
np.sum(v3 * np.outer(cov_mkt, cov_mkt)) / var_mkt ** 2 - np.sum( np.sum(v3 * np.outer(cov_mkt, cov_mkt)) / var_mkt ** 2 - np.sum(np.diag(v3) * cov_mkt ** 2) / var_mkt ** 2
np.diag(v3) * cov_mkt ** 2) / var_mkt ** 2
) )
roff = 2 * roff1 - roff3 roff = 2 * roff1 - roff3
rho = rdiag + roff rho = rdiag + roff

View File

@@ -32,23 +32,19 @@ class StructuredCovEstimator(RiskModel):
FACTOR_MODEL_FA = "fa" FACTOR_MODEL_FA = "fa"
DEFAULT_NAN_OPTION = "fill" DEFAULT_NAN_OPTION = "fill"
def __init__( def __init__(self, factor_model: str = "pca", num_factors: int = 10, **kwargs):
self,
factor_model: str = "pca",
num_factors: int = 10,
**kwargs
):
""" """
Args: Args:
factor_model (str): the latent factor models used to estimate the structured covariance (`pca`/`fa`). factor_model (str): the latent factor models used to estimate the structured covariance (`pca`/`fa`).
num_factors (int): number of components to keep. num_factors (int): number of components to keep.
kwargs: see `RiskModel` for more information kwargs: see `RiskModel` for more information
""" """
if 'nan_option' in kwargs.keys(): if "nan_option" in kwargs.keys():
assert kwargs['nan_option'] in [self.DEFAULT_NAN_OPTION], \ assert kwargs["nan_option"] in [self.DEFAULT_NAN_OPTION], "nan_option={} is not supported".format(
"nan_option={} is not supported".format(kwargs['nan_option']) kwargs["nan_option"]
)
else: else:
kwargs['nan_option'] = self.DEFAULT_NAN_OPTION kwargs["nan_option"] = self.DEFAULT_NAN_OPTION
super().__init__(**kwargs) super().__init__(**kwargs)