From 7022675d003b4a603e9a04769e8a91e7232421ea Mon Sep 17 00:00:00 2001 From: Charles Young Date: Mon, 8 Mar 2021 19:07:28 +0800 Subject: [PATCH] Resolve https://github.com/microsoft/qlib/pull/280\#discussion_r589169489 --- qlib/portfolio/optimizer/enhanced_indexing.py | 40 +++++++++---------- qlib/portfolio/optimizer/optimizer.py | 25 ++++++------ 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/qlib/portfolio/optimizer/enhanced_indexing.py b/qlib/portfolio/optimizer/enhanced_indexing.py index 1f7de6cb4..5fdc1014d 100644 --- a/qlib/portfolio/optimizer/enhanced_indexing.py +++ b/qlib/portfolio/optimizer/enhanced_indexing.py @@ -21,15 +21,15 @@ class EnhancedIndexingOptimizer(BaseOptimizer): START_FROM_BENCH = "benchmark" def __init__( - self, - lamb: float = 10, - delta: float = 0.4, - bench_dev: float = 0.01, - inds_dev: float = None, - scale_alpha: bool = True, - verbose: bool = False, - warm_start: str = None, - max_iters: int = 10000, + self, + lamb: float = 10, + delta: float = 0.4, + bench_dev: float = 0.01, + inds_dev: float = None, + scale_alpha: bool = True, + verbose: bool = False, + warm_start: str = None, + max_iters: int = 10000, ): """ Args: @@ -56,11 +56,7 @@ class EnhancedIndexingOptimizer(BaseOptimizer): assert inds_dev is None or inds_dev >= 0, "industry deviation limit `inds_dev` should be positive or None." self.inds_dev = inds_dev - assert warm_start in [ - None, - self.START_FROM_W0, - self.START_FROM_BENCH, - ], "illegal warm start option" + assert warm_start in [None, self.START_FROM_W0, self.START_FROM_BENCH,], "illegal warm start option" self.start_from_w0 = warm_start == self.START_FROM_W0 self.start_from_bench = warm_start == self.START_FROM_BENCH @@ -69,14 +65,14 @@ class EnhancedIndexingOptimizer(BaseOptimizer): self.max_iters = max_iters def __call__( - self, - u: Union[np.ndarray, pd.Series], - F: np.ndarray, - covB: np.ndarray, - varU: np.ndarray, - w0: np.ndarray, - w_bench: np.ndarray, - inds_onehot: np.ndarray = None, + self, + u: Union[np.ndarray, pd.Series], + F: np.ndarray, + covB: np.ndarray, + varU: np.ndarray, + w0: np.ndarray, + w_bench: np.ndarray, + inds_onehot: np.ndarray = None, ) -> Union[np.ndarray, pd.Series]: """ Args: diff --git a/qlib/portfolio/optimizer/optimizer.py b/qlib/portfolio/optimizer/optimizer.py index 3daa98af3..54648a46a 100644 --- a/qlib/portfolio/optimizer/optimizer.py +++ b/qlib/portfolio/optimizer/optimizer.py @@ -30,13 +30,13 @@ class PortfolioOptimizer(BaseOptimizer): OPT_INV = "inv" def __init__( - self, - method: str = "inv", - lamb: float = 0, - delta: float = 0, - alpha: float = 0.0, - scale_alpha: bool = True, - tol: float = 1e-8, + self, + method: str = "inv", + lamb: float = 0, + delta: float = 0, + alpha: float = 0.0, + scale_alpha: bool = True, + tol: float = 1e-8, ): """ Args: @@ -63,10 +63,10 @@ class PortfolioOptimizer(BaseOptimizer): self.scale_alpha = scale_alpha def __call__( - self, - S: Union[np.ndarray, pd.DataFrame], - u: Optional[Union[np.ndarray, pd.Series]] = None, - w0: Optional[Union[np.ndarray, pd.Series]] = None, + self, + S: Union[np.ndarray, pd.DataFrame], + u: Optional[Union[np.ndarray, pd.Series]] = None, + w0: Optional[Union[np.ndarray, pd.Series]] = None, ) -> Union[np.ndarray, pd.Series]: """ Args: @@ -155,7 +155,7 @@ class PortfolioOptimizer(BaseOptimizer): return self._solve(len(S), self._get_objective_gmv(S), *self._get_constrains(w0)) def _optimize_mvo( - self, S: np.ndarray, u: Optional[np.ndarray] = None, w0: Optional[np.ndarray] = None + self, S: np.ndarray, u: Optional[np.ndarray] = None, w0: Optional[np.ndarray] = None ) -> np.ndarray: """optimize mean-variance portfolio @@ -251,6 +251,7 @@ class PortfolioOptimizer(BaseOptimizer): # add l2 regularization wrapped_obj = obj if self.alpha > 0: + def opt_obj(x): return obj(x) + self.alpha * np.sum(np.square(x))