diff --git a/sanguo_factor/alpha_datasets.py b/sanguo_factor/alpha_datasets.py index aac644b..1c2a1ee 100644 --- a/sanguo_factor/alpha_datasets.py +++ b/sanguo_factor/alpha_datasets.py @@ -48,7 +48,7 @@ def _mount(dataset_cls, category: str) -> int: def mount_alpha101() -> int: - """挂载 WorldQuant Alpha101(100 个),category=alpha101.""" + """挂载 WorldQuant Alpha101(82 个),category=alpha101.""" from vnpy.alpha.dataset.datasets.alpha_101 import Alpha101 return _mount(Alpha101, "alpha101") diff --git a/sanguo_factor/metrics.py b/sanguo_factor/metrics.py index 8ca78e4..f41ec19 100644 --- a/sanguo_factor/metrics.py +++ b/sanguo_factor/metrics.py @@ -51,12 +51,12 @@ def factor_turnover(F: pd.DataFrame) -> float: return float(1.0 - corr.mean()) if len(corr) else 0.0 -def _quantile_mask(F: pd.DataFrame, lo_frac: float, hi_frac: float) -> pd.DataFrame: - """按行把因子值分位选mask(基于升序秩/当日有效数).""" +def _quantile_mask(F: pd.DataFrame, top: bool) -> pd.DataFrame: + """按行把因子值分位选mask(基于升序秩/当日有效数). top=True选最大10%,False选最小10%.""" ranks = F.rank(axis=1, ascending=False) # 1=最大 n = ranks.notna().sum(axis=1) k = np.maximum((n * 0.1).round().astype(int), 1) - if lo_frac == 0.0: + if top: return ranks.le(k, axis=0) & ranks.notna() return ranks.ge(n - k + 1, axis=0) & ranks.notna() @@ -66,8 +66,8 @@ def long_short_annual_return(F: pd.DataFrame, R: pd.DataFrame) -> float | None: cols = F.columns.intersection(R.columns) idx = F.index.intersection(R.index) f, r = F.loc[idx, cols], R.loc[idx, cols] - top = _quantile_mask(f, 0.0, 0.1) - bot = _quantile_mask(f, 0.9, 1.0) + top = _quantile_mask(f, top=True) + bot = _quantile_mask(f, top=False) daily = (r.where(top).mean(axis=1) - r.where(bot).mean(axis=1)).dropna() if daily.empty: return None