diff --git a/sanguo_factor/monthly_review.py b/sanguo_factor/monthly_review.py index f39f8ca5..b1da255e 100644 --- a/sanguo_factor/monthly_review.py +++ b/sanguo_factor/monthly_review.py @@ -115,7 +115,9 @@ def build_report(registry: dict, current_points: dict[str, dict], # 一期、首跑全空——t/ic_mean/count 同源于当月评估批) point = {"month": month_key, "t": cur.get("t"), "ic_mean": cur.get("ic_mean")} - if cur.get("t") is not None: + # 追加条件=t 或 ic_mean 任一非空(codex 复审 LOW:degenerate 月 + # sd==0 时 t=None 但 IC 有效,只看 t 会漏出 factor_stats 一期) + if cur.get("t") is not None or cur.get("ic_mean") is not None: hist = [p for p in hist if p["month"] != month_key] + [point] monthly_points[name] = sorted(hist, key=lambda p: p["month"]) if entry["status"] in ("promoted", "decaying"): diff --git a/tests/factor/test_monthly_review.py b/tests/factor/test_monthly_review.py index 23d1cc74..d967b4f8 100644 --- a/tests/factor/test_monthly_review.py +++ b/tests/factor/test_monthly_review.py @@ -321,3 +321,16 @@ def test_build_report_current_point_carries_ic_mean(): assert s["icAll"] == 0.05 # 首跑单点即有弹药 assert s["positiveRatio"] == 1.0 assert s["tAll"] is None # n=1 无合成 t,如实 + + +# —— codex 复审 LOW:degenerate 当月(t=None 但 IC 有效)不漏出 factor_stats —— +def test_build_report_degenerate_current_point_kept(): + """当月 sd==0 时 t=None 但 ic_mean 有效→当月点须进 monthly_points + 与 factor_stats(追加条件=t 或 ic_mean 任一非空).""" + reg = {"factors": {"fa_x": {"name": "fa_x", "hypothesis": "h", + "status": "assessable"}}} + rep = build_report(reg, {"fa_x": {"t": None, "ic_mean": 0.03, "count": 100}}, + history_points={}, as_of="2026-09-30", host="t") + assert rep["monthly_points"]["fa_x"] == [ + {"month": "2026-09", "t": None, "ic_mean": 0.03}] + assert rep["factor_stats"]["fa_x"]["icAll"] == 0.03