From 7292ef5dd4fd1fa1a6625ae98daa301b8216f86a Mon Sep 17 00:00:00 2001 From: jackyu66git Date: Fri, 28 Aug 2026 22:03:59 +0800 Subject: [PATCH] =?UTF-8?q?research:=20=E4=BD=8E=E6=BB=9E=E5=90=8E+?= =?UTF-8?q?=E8=B4=A8=E9=87=8F=E8=BF=87=E6=BB=A4=E7=BB=84=E5=90=88=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=EF=BC=8C=E8=BF=87=E6=BB=A4=E5=99=A8=E7=AC=A6=E5=8F=B7?= =?UTF-8?q?=E7=BF=BB=E8=BD=AC=EF=BC=8C=E4=B8=80=E7=B1=BB=E7=BA=BF=E5=85=B3?= =?UTF-8?q?=E9=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 把 step62 的 ext_run 质量过滤接到 step56 的低滞后版上——两者各解决一半约束, 是唯一同时处理滞后和识别精度的路径。 失败,且失败方式本身是判据:过滤器符号反了。5m 上延伸度分档在滞后版是 Q1 0.12 / Q4 0.46(越延伸越好),在低滞后版是 Q1 0.58 / Q4 0.33(越短越好)。 叠加后 PF 从 0.37 掉到 0.30~0.33,比不过滤更差。div 同样翻转。 同一批信号、同一个特征,换个入场时点最优方向就反过来,说明这些过滤效果是 入场时点的交互产物而非信号的稳定属性,继续挑阈值就是拟合噪声。 一类线六次独立进攻全部止步 1.0 以下:引擎原生 0.24、反手 0.92(因果回放后)、 实时重写 0.41、结构止损 0.36、用未来函数选样 0.83、质量过滤 0.54、 低滞后+过滤 0.33。第五项尤其说明问题——即使选样做到完美也只到 0.83。 判定关闭。病根是入场价已在结构底上方 2.9 ATR、实盘再晚 15 根,来自「等笔确认」 机制本身而非参数。识别可以优化(精度能翻倍),但识别从来不是瓶颈。 fast_bsp1 顺带补 ext_atr 字段,用 ATR 归一才与 step62 的 ext_run 同口径。 Co-authored-by: Cursor --- research/HANDOFF.md | 64 ++++++++++++++++++++++++++++++++++++ research/lib/fast_bsp1.py | 7 ++++ research/step56_fast_bsp1.py | 30 +++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/research/HANDOFF.md b/research/HANDOFF.md index ea4782e..052e25d 100644 --- a/research/HANDOFF.md +++ b/research/HANDOFF.md @@ -1322,6 +1322,70 @@ B4 跑出 PF 1.83~2.06 / t +8.5~+10.7。所以 fast B1 的负数不是管线接 亏损(死于立即反向而非目标够不着)。它与 §3.397 的结论一致:一类的入场价已在 结构底上方 2.9 ATR,那个位置本身就是负期望的。 +### 3.399 ⛔ 一类线收尾:过滤器符号随入场时点翻转,判定为拟合(step62/56) + +用户指出:很多一二类实际在**趋势中途**被识别而非末期;若真在末期,即使有延迟 +也该走出行情。step60 的数据支持这个判断——命中线段顶点的 30% 是 PF 0.70~0.83, +**没命中的 70% 是 PF 0.08**,亏损几乎全部来自误识别在趋势中途的那批。 + +**step62:找到了区分变量,识别精度接近翻倍** + +`ext_run`(极值越过中枢边界几个 ATR)单调有效,5m: + +| ext_run 档 | 命中线段顶点 | PF | +|---|---|---| +| Q1 最短 | **12.0%** | 0.12 | +| Q4 最延伸 | **43.8%** | 0.46 | + +最佳组合 `ext_run≥P75 且 div≥中位`:命中率 47.9%、PF 0.54 +(基准 28.7% / 0.22)。**识别确实可以优化,且幅度不小。** + +三个附带结论: + +- **背驰越强反而越差**:div Q1(最强)命中 17.0% / PF 0.13,Q4(最弱) + 37.5% / 0.28。这是对 `check_bi_div` 这个 MACD 面积判据的直接证伪。 +- **趋势级数无区分力**:连续同向中枢数 ≤1/2/3/≥4 的命中率 + 28.5/30.6/28.6/25.5%,基本持平。 +- **「趋势 vs 盘整」前提引擎已隐含强制**(纠正我先前的猜测):B1 要求 + `enter_bi.dir == leave_bi.dir == DOWN`,中枢向下进、向下出本身就定义了它嵌在 + 下跌趋势里,实测该条件在 2504 笔上**恒为 True**,过滤器无从添加。 + `zs_count` 也不可用——它是全局中枢序号(310、585)而非趋势内序号。 + +**step56 复测:把过滤器接到低滞后版上,符号翻转** + +step56 的实时版把滞后压到 ≤1 根但无质量过滤(PF 0.40),step62 有过滤但滞后 +未解(PF 0.54)。两者各解决一半,合起来是唯一同时处理两个约束的路径。结果: + +| 5m · 延伸度分档 | 滞后版(step62) | 低滞后版(step56) | +|---|---|---| +| Q1 最短 | 0.12 | **0.58** | +| Q4 最延伸 | **0.46** | 0.33 | + +叠加后 PF 从 0.37 掉到 0.30~0.33,**比不过滤更差**。`div` 同样翻转:滞后版里 +背驰最弱的最好,低滞后版里背驰最强的最好。 + +**这个符号翻转是判定依据,不是需要再调的参数。** 同一批信号、同一个特征, +换个入场时点最优方向就反过来,说明这些「过滤效果」是入场时点的交互产物, +不是信号的稳定属性。继续在上面挑阈值就是拟合噪声。 + +**一类线全部尝试汇总(六次独立进攻,全部止步于 1.0 以下)** + +| 尝试 | 最好 PF | 出处 | +|---|---|---| +| 引擎原生 | 0.20~0.24 | step55 | +| 反手 | 2.35~3.03 → **0.92/1.30** 因果回放后 | step57 / **step59** | +| 实时重写(fast_bsp1) | 0.36~0.41 | step56 | +| 结构止损(目标等比放大) | 0.36 | step58 | +| 线段顶点选样(**用未来函数**) | 0.70~0.83 | step60 | +| 质量过滤(ext_run + div) | 0.54 | step62 | +| **低滞后 + 质量过滤** | **0.33** | step56 | + +注意第五行:**即使用未来函数把选样做到完美,也只到 0.83。** + +**判定:一类线关闭。** 病根是 §3.397 的几何——入场价已在结构底上方 2.9 ATR, +实盘回放还要再晚 15 根(§3.396),而这来自「等笔确认」这个机制本身, +不是可调参数。识别可以优化,但识别从来不是瓶颈。 + ### 3.4 alpha 的来源(step32 消融) 逐条拆掉 `fast_bsp3` 的条件后发现:**alpha 完全来自缠论中枢的上下文定位, diff --git a/research/lib/fast_bsp1.py b/research/lib/fast_bsp1.py index 1bd8ae4..68a79ee 100644 --- a/research/lib/fast_bsp1.py +++ b/research/lib/fast_bsp1.py @@ -118,6 +118,7 @@ def find_fast_bsp1( high = df["high"].to_numpy(float) low = df["low"].to_numpy(float) hist = df["macdhist"].to_numpy(float) + atr = df["atr"].to_numpy(float) n = len(df) rows = [] @@ -198,11 +199,17 @@ def find_fast_bsp1( note("√成交") edge = zd if d == -1 else zg + # 延伸度用 ATR 归一,才和 step62 的 ext_run 同口径 —— 那里实测它是 + # 唯一单调区分「趋势末端 vs 趋势中途」的特征(命中率 12%→44%)。 + # 用相对边界的百分比会混入价格水平,不同币之间不可比。 + a_ext = atr[ext_idx] rows.append({ "entry_idx": entry_idx, "direction": -d, "bo_idx": bo_idx, "ext_idx": ext_idx, "lag": entry_idx - ext_idx, "div": div_at, + "ext_atr": (abs(ext - edge) / a_ext + if np.isfinite(a_ext) and a_ext > 0 else np.nan), "depth": abs(ext - edge) / edge, "zg": zg, "zd": zd, "width_pct": (zg - zd) / close[bo_idx], diff --git a/research/step56_fast_bsp1.py b/research/step56_fast_bsp1.py index 965d204..c1b9572 100644 --- a/research/step56_fast_bsp1.py +++ b/research/step56_fast_bsp1.py @@ -134,6 +134,36 @@ def report(d: pd.DataFrame) -> None: print(" 15m B1 PF 0.21 t −18.9 | S1 PF 0.23 t −15.9") f1 = x[x.kind == "fastB1"] + if len(f1) >= 120 and "ext_atr" in f1.columns: + y = f1.dropna(subset=["ext_atr"]) + print("\n延伸度分档(ext_atr,step62 在滞后版上实测的唯一单调特征:" + "\n命中线段顶点的比例 12%→44%,PF 0.12→0.46):") + q = pd.qcut(y["ext_atr"], 4, + labels=["Q1最短", "Q2", "Q3", "Q4最延伸"], + duplicates="drop") + print(pd.DataFrame([{"档": k, **stats(v)} + for k, v in y.groupby(q, observed=True) + if len(v) >= 30]).to_string(index=False)) + + print("\n⭐ 组合:低滞后(本模块)+ 延伸过滤(step62)—— " + "唯一同时处理两个约束的路径") + p50, p75 = y["ext_atr"].quantile(.50), y["ext_atr"].quantile(.75) + dm = y["div"].median() + rows = [{"过滤器": "无", **stats(y)}] + for nm, g in [ + (f"ext≥P50({p50:.1f})", y[y["ext_atr"] >= p50]), + (f"ext≥P75({p75:.1f})", y[y["ext_atr"] >= p75]), + (f"ext≥P75 且 div≥中位", y[(y["ext_atr"] >= p75) + & (y["div"] >= dm)]), + (f"ext≥P50 且 div≥中位", y[(y["ext_atr"] >= p50) + & (y["div"] >= dm)]), + ]: + if len(g) >= 30: + rows.append({"过滤器": nm, **stats(g)}) + print(pd.DataFrame(rows).to_string(index=False)) + print("对照 · 同过滤器在滞后版(step62,5m):无 PF 0.22 → " + "ext≥P75且div≥中位 PF 0.54") + if len(f1) >= 60: print("\n背驰强度分档(div = 离开段面积/进入段面积,越小背驰越强):") q = pd.qcut(f1["div"], 4, labels=["Q1最强", "Q2", "Q3", "Q4最弱"],