From ff2a201aff3963a218de1e5800e4721b54710727 Mon Sep 17 00:00:00 2001 From: zlt Date: Wed, 2 Sep 2026 17:03:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=8D=E7=9B=98=E6=B1=87=E6=80=BB=E5=8A=A0?= =?UTF-8?q?=E6=A0=B7=E6=9C=AC=E5=8A=A0=E6=9D=83=E4=B8=89=E5=88=97=EF=BC=88?= =?UTF-8?q?ret=5Fw/excess=5Fw/beat=5Fw=EF=BC=89=EF=BC=8C=E4=B8=8E=E6=96=B9?= =?UTF-8?q?=E6=A1=88=E7=AC=AC=E4=B8=80=E8=8A=82=E6=89=8B=E5=B7=A5=E8=AF=BB?= =?UTF-8?q?=E6=95=B0=E5=90=8C=E5=8F=A3=E5=BE=84=E5=AF=B9=E8=B4=A6=EF=BC=9B?= =?UTF-8?q?=E4=B8=BB=E5=8F=A3=E5=BE=84=E4=BB=8D=E6=8C=89=E8=AE=A1=E5=88=92?= =?UTF-8?q?=E6=97=A5=E7=AD=89=E6=9D=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- plan_review.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/plan_review.py b/plan_review.py index db95415..db7373d 100644 --- a/plan_review.py +++ b/plan_review.py @@ -262,10 +262,17 @@ def run(since: str, until: str | None, horizons: tuple, start: str, out_dir: str # 汇总:按名单 × 期限(全部);按分组 × 期限;按事后环境 × 名单(只作解释) def agg(g: pd.DataFrame) -> pd.Series: - return pd.Series({"days": g["date"].nunique(), "n": int(g["n"].sum()), + # 主口径按日等权:每个计划日先算名单均值,再跨日平均——一份名单一天一票; + # 带 _w 的三列按样本加权(大名单的日子权重大),与方案 1.8b/1.8c 手工读数同口径,只作对账。 + n = g["n"].astype(float) + w = n / n.sum() if n.sum() else n + return pd.Series({"days": g["date"].nunique(), "n": int(n.sum()), "ret": round(g["ret"].mean(), 2), "excess_all": round(g["excess_all"].mean(), 2), - "beat": round(g["beat"].mean(), 1)}) + "beat": round(g["beat"].mean(), 1), + "ret_w": round(float((g["ret"] * w).sum()), 2), + "excess_w": round(float((g["excess_all"] * w).sum()), 2), + "beat_w": round(float((g["beat"] * w).sum()), 1)}) lists_tbl = df[df["group"] == "全部"].groupby(["list", "h"]).apply(agg).reset_index() groups_tbl = df[df["group"] != "全部"].groupby(["list", "group", "h"]).apply(agg).reset_index() regime_tbl = df[df["group"] == "全部"].groupby(["regime_post", "list", "h"]).apply(agg).reset_index() @@ -275,7 +282,8 @@ def run(since: str, until: str | None, horizons: tuple, start: str, out_dir: str md = [f"# 候选单复盘 · {days_plan[0]} 至 {stamp}(起点价 {start})", "", f"计划日 {len(days_plan)} 期;样本纪律:分组样本少于一百只或覆盖计划日少于二十个只看方向;" f"口径切换的总样本少于六十个计划日只写方向。", "", - "## 一、六份名单 × 期限(超额=相对全池等权,命中=跑赢全池比例)", "", + "## 一、六份名单 × 期限(超额=相对全池等权,命中=跑赢全池比例;" + "不带后缀的列按计划日等权,带 _w 的列按样本加权,后者只用于与方案第一节手工读数对账)", "", _md(lists_tbl), "", "## 二、分组读数", "", _md(groups_tbl), "", "## 三、按事后环境分组(未来 h 日全池涨跌,只作解释,不作交易前置)", "",