research: 1m 出场口径重定、费率修正,与影子测量的判据常数
起因是用户看图指出「止盈没做好」,查下来 TP=3.0 确实把右尾截早了, 而且 1m 不该沿用 5m/15m/30m 的参数——成本固定在 bp、目标随 ATR 缩放, 1m 的 3 ATR 只有 0.39% 而 30m 是 1.87%,成本占比差 5 倍。 step41(5m/15m/30m)与 step42(1m)跑同一张全网格: SL × TP × MAX_BARS × 分批(3 ATR 减半 → 剩余目标 × 剩余半仓止损位)。 - 1m 最优 SL2 / 3ATR 减半 / 剩余止损保持 2.0 / 目标 8ATR / 48 根, 样本外 8/8 币、7/7 年全面提升,均R/R夏普/回撤/剔10%PF 四项全赢 - 分批要做,但**减仓后不要动止损**。止损位 0/0.5/1/1.5/2 ATR 严格单调, 越紧越差,三组初始 SL 全一致。保本损是全表最差的一档 - SL=1.0 在 1m 上是废的:剔10%PF 0.78~0.99、中位收益 −0.122% 费率此前写的 taker 3bp / maker 1bp 隐含「原始 taker 6bp」的错误前提, 实际是原始 taker 0.040% / maker 0.016%、返 50% 后 2.0 / 0.8bp。方向是保守的, 所以首轮跑出来的数字全部偏低。exit_model 已改,费率只在分析阶段套用, 不必重跑模拟。改完 1m 的均R +8%,5m/15m/30m 只动 2%——费率只对 1m 有杠杆。 顺带查证了用户的一个假设:余量逐年递减是不是跟波动率有关。成立,而且 r = +0.989。毛/ATR 七年在 2.26~2.67 之间没有趋势,衰减的是 ATR 本身 (2021 的 22.1bp 压到 2026 的 8.8bp)。**是波动率压缩,不是 alpha 衰减。** 由此引出 ATR 门控:低 ATR 桶的毛 R 其实最高(1.16 vs 高 ATR 桶的 0.94), 断崖只在扣费之后出现。所以阈值是**费率的函数**(约 5 + 1.1×taker费), 不是市场常数。当前费率下 ≥8bp,在 5m/15m/30m 上几乎不触发,可作全局规则。 lib/shadow_budget.py 放影子测量要对照的常数:逐币预算、门控阈值、 腿→maker/taker 映射、lag 阈值、判据。记录与报表归 research/live/, 分工的理由是这些数会变——今天预算就动了四次。 out/*.feather 转为 ignore:70MB+ 且重跑可得,摘要都在 HANDOFF。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+557
-29
@@ -62,6 +62,45 @@ run_trades(cdf, entries, SL, TP, MAX_BARS, fee=..., entry_delay=1)
|
||||
- 研究口径成本:**4bp 手续费 + 1bp 滑点 = 5bp**(所有带「已扣 5bp」的数字都是这个)
|
||||
- ATR 取信号根的值(`atr[sig_idx]`),不是入场根
|
||||
|
||||
> ⚠️ **TP=3.0 已被证明偏小(step41/42,见 3.5 与 5.3)**,且出场参数要按级别分开定。
|
||||
> 本文档所有历史数字仍是 TP=3.0 口径,**改口径前不要混用**。
|
||||
|
||||
#### 成本模型:不是一刀切的 5bp(用户 2026-08-27 指出)
|
||||
|
||||
用户指出「只有开仓才是 taker」。对了一半——**止盈挂限价确实是 maker,
|
||||
但止损是 stop-market,成交时仍是 taker**(做成 stop-limit 会有急跌不成交的
|
||||
风险,那种损失远大于省下的费)。所以按出场原因分别计费。
|
||||
|
||||
**实际费率档位(用户 2026-08-27 给的,单边):返佣前 taker 0.040% /
|
||||
maker 0.016%,API 返 50% → taker 2.0bp / maker 0.8bp。**
|
||||
|
||||
| 环节 | 性质 | 单边费率 |
|
||||
|---|---|---|
|
||||
| 入场(次根开盘市价) | taker + 滑点 | **2.0bp** |
|
||||
| 止盈(限价被动成交) | **maker,无滑点** | **0.8bp** |
|
||||
| 止损(stop-market) | taker + 滑点 | 2.0bp |
|
||||
| 超时(到点市价平) | taker + 滑点 | 2.0bp |
|
||||
|
||||
> ⚠️ **step41/42 首轮跑的时候这里写的是 taker 3.0 / maker 1.0bp**,
|
||||
> 隐含「原始 taker 6bp、返 50% 得 3bp」的错误前提。真实原始是 4bp。
|
||||
> **方向是保守的**——taker 高估了 50%,所以那两步跑出来的净收益、
|
||||
> 滑点余量、均R 全部偏低,不是偏高。`exit_model.py` 已改成实际值,
|
||||
> 但**本文档里凡是标注「旧费率 3/1bp」的数字尚未逐条重算**。
|
||||
|
||||
`SL1.5/TP3/48根` 1m 样本外实测(止盈成交占 60%):
|
||||
|
||||
| 口径 | 平均成本 | 说明 |
|
||||
|---|---|---|
|
||||
| 全 taker 双边 | 8.00bp | 最早的口径,双重高估 |
|
||||
| 混合费率 @ 3/1bp | 6.20bp | step41/42 首轮 |
|
||||
| **混合费率 @ 实际 2/0.8bp** | **2.00bp** | 当前 |
|
||||
| 研究口径 固定 5bp | 5.00bp | §2 那批老数字 |
|
||||
|
||||
**注意方向变了:研究口径的 5bp 现在是偏保守的。** 实际混合费率只有 2bp。
|
||||
实现在 `research/lib/exit_model.py`,step41/42 共用。
|
||||
**分批离场不额外增加费用**(手续费按名义额收,出场 0.5+0.5 总额不变),
|
||||
而且第一批必然是止盈成交,所以分批在成本上还占便宜。
|
||||
|
||||
### 1.4 阶梯过滤(顺向推进)
|
||||
|
||||
对应缠论「趋势 vs 盘整」:当前中枢相对前一个中枢是否同向推进。
|
||||
@@ -165,6 +204,38 @@ push = z_above if direction == 1 else z_below
|
||||
- **持仓重叠**(step35 §3-4):单腿平均并发 0.01,组合 9 腿平均并发 0.1,
|
||||
有仓位时间仅 8.6% → t 值没被虚高,各笔基本独立
|
||||
|
||||
### 3.35 跨 venue:信号身份不迁移,但总体期望迁移(live 前置测量)
|
||||
|
||||
**回测全部跑在 Binance 数据上,实盘要在 Bitget 成交。** 服务器侧的
|
||||
`research/live/venue_parity.py` 把这件事量了:
|
||||
|
||||
| 品种 | Bitget信号 | Binance信号 | 同根重合 |
|
||||
|---|---|---|---|
|
||||
| BTC | 47 | 38 | 42.6% |
|
||||
| ETH | 39 | 35 | 28.2% |
|
||||
| SOL | 48 | 29 | **14.6%** |
|
||||
|
||||
(5m 同向过滤后口径。SOL 差得最多是因为 tick 粗细不同:Bitget 0.001、
|
||||
Binance 0.01,粗 10 倍会让 `close > high[j-1]` 大量平局不触发,
|
||||
Bitget 上信号多出 74%。**这是系统性差异,不是随机扰动。**)
|
||||
|
||||
`signal_sensitivity.py` 进一步显示 **0.25bp 的数据扰动就能换掉一半信号**。
|
||||
|
||||
但 `aggregate_robustness.py` 的结论是:**总体期望不塌**。
|
||||
加 0.5 / 1 / 2bp 噪声重跑,毛均收益与 PF 都在原区间内摆动,没有单调恶化。
|
||||
|
||||
> **脆的是信号身份,不是 alpha。** 这决定了两件事:
|
||||
> 一、滑点**不能逐笔对照 Binance 回测**,只能对照同一 venue 上的总体毛均收益;
|
||||
> 二、影子测量必须跑在生产路径上(Bitget 原生数据 + Hummingbot),
|
||||
> 换个运行时测出来的数就不作数。
|
||||
|
||||
同窗口 Bitget vs Binance 毛均收益(210 天、TP=3.0 口径):
|
||||
BTC 5.87 vs 6.09、ETH 10.02 vs 12.06、SOL 8.92 vs 9.87bp。
|
||||
**Bitget 一致略低 0.2~2bp,但没有量级差异,总体口径可迁移。**
|
||||
|
||||
⚠️ 上面那批数字用的是 `毛均收益 − 6.0bp`、只有同向过滤、`TP=3.0`,
|
||||
**不能直接当预算用**,正确的逐币预算见 `lib/shadow_budget.py` 与 5.3。
|
||||
|
||||
### 3.4 alpha 的来源(step32 消融)
|
||||
|
||||
逐条拆掉 `fast_bsp3` 的条件后发现:**alpha 完全来自缠论中枢的上下文定位,
|
||||
@@ -173,6 +244,122 @@ push = z_above if direction == 1 else z_below
|
||||
这个结论回答了用户当时的问题(「如果有这个,那就可以去判断任何笔的端点了」):
|
||||
**不能**。脱离中枢上下文,那个触发条件没有预测力。
|
||||
|
||||
### 3.5 出场:TP=3.0 把右尾截早了(step41)
|
||||
|
||||
起因是用户看图指出「止盈没做好」。查下来确实如此。
|
||||
|
||||
先量 MFE(每笔在被止损打掉之前最远走到几个 ATR):
|
||||
|
||||
| 分组 | 级别 | 笔数 | 中位 MFE | ≥3ATR | ≥5ATR | ≥8ATR |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 样本内 | 15m/30m/5m | 2309 | 3.66 / 4.30 / 4.27 | 55~62% | 41~45% | 23~28% |
|
||||
| 样本外 | 15m/30m/5m | 5859 | 4.08 / 3.80 / 4.30 | 57~61% | 42~45% | 25~28% |
|
||||
|
||||
**中位数就已经高于 TP=3**,样本内外一致。抬高 TP 的样本外结果:
|
||||
|
||||
| 出场 | 胜率 | 均收益 | 中位 | PF | t值 | 剔10%PF | 均持仓 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| tp3(现用) | 62.6% | +0.559% | +0.588% | 2.71 | +28.31 | 1.64 | 11.2 |
|
||||
| tp4 | 58.7% | +0.692% | +0.579% | 2.95 | +29.24 | 1.71 | 15.3 |
|
||||
| **tp5** | 56.5% | **+0.783%** | +0.485% | **3.12** | **+29.36** | **1.75** | 18.8 |
|
||||
| tp6 | 55.3% | +0.860% | +0.369% | 3.28 | +29.17 | 1.77 | 21.7 |
|
||||
| tp8 | 54.1% | +0.983% | +0.284% | 3.56 | +28.27 | 1.78 | 25.7 |
|
||||
|
||||
- **8 个样本外币逐个看,均收益与 PF 全部提升**;2020~2026 七年 PF 也全部提升
|
||||
- 剔掉最好 10% 后 PF 仍从 1.64 升到 1.75 → 不是几笔暴利撑起来的
|
||||
- t 值在 tp5 见顶(+29.36)后走平,tp6/tp8 靠的是越来越薄的右尾
|
||||
- 基线复现校验:step41 的 tp3 = 5859 笔 / PF 2.71 / t +28.31 / 剔10% 1.64,
|
||||
对上 §2.2 的 2.73 / +28.50 / 1.66,差在千分位(同根内止损与新高并存时保守
|
||||
假定止损先到),说明对比是在正确基线上做的
|
||||
|
||||
**代价不是零**:胜率 62.6%→56.5%,中位 +0.588%→+0.485%(过半单子变差,
|
||||
输在「摸到 3ATR 没走到 5ATR 又反手止损」那批),**平均持仓 11.2→18.8 根**,
|
||||
§3.3 的并发数据需重算。心理上也更难拿。
|
||||
|
||||
#### 分批离场更优(用户提的方案,改一处后成立)
|
||||
|
||||
用户方案:到 3 ATR 平一半 + 止损移到开仓价,剩下跑到大目标。
|
||||
**前两步对,「止损移到开仓价」是错的。** 用户随后要求把剩余半仓的止损位
|
||||
也扫一遍(0 / 0.5 / 1 / 1.5 / 2 ATR),结果**严格单调,三组初始 SL 全一致**:
|
||||
|
||||
样本外 5859 笔,初始 SL1.5、分批→8 ATR、48 根:
|
||||
|
||||
| 剩余半仓止损位 | 净均收益 | 中位 | PF | t值 | 剔10%PF |
|
||||
|---|---|---|---|---|---|
|
||||
| 保本损(0) | +0.611% | +0.420% | 2.81 | +25.66 | 1.50 |
|
||||
| 留损 0.5 ATR | +0.688% | +0.455% | 3.03 | +27.65 | 1.65 |
|
||||
| 留损 1.0 ATR | +0.732% | +0.475% | 3.17 | +28.64 | 1.74 |
|
||||
| **留损 1.5 ATR(不动)** | +0.754% | +0.498% | 3.23 | +29.25 | 1.79 |
|
||||
| 留损 2.0 ATR(放宽) | +0.762% | +0.510% | 3.25 | +29.48 | 1.81 |
|
||||
|
||||
**没有中间最优点,越松越好,但增量在「不动」处饱和**:
|
||||
保本→0.5 加 0.077%,0.5→1 加 0.044%,1→1.5 加 0.022%,1.5→2 只加 0.008%。
|
||||
所以**止损保持原位即可,放得比原止损更宽是拿实打实的风险换千分之一的收益**。
|
||||
|
||||
机理与移动止损失败同源(§4):回抽到成本价是突破后的正常结构,不是信号失效。
|
||||
信号已用「摸到 3 ATR」自证,此时收紧止损等于用最坏价格淘汰掉最好的单子。
|
||||
|
||||
**胜率与整仓 TP3 完全相同是结构决定的**:摸到 3 ATR 的单子在分批下必然是赢家
|
||||
(半仓 +3 ATR,剩余半仓最坏 −1.5 ATR,净 +0.75 ATR)。这正是分批相对整仓
|
||||
高 TP 的价值——同一批单子在整仓 TP5 下会变成 −1.5 ATR 的亏损。
|
||||
|
||||
#### 初始 SL 扫描:必须用 R 倍数口径,否则会把仓位差异算成策略优势
|
||||
|
||||
用户要求扫 1 / 1.5 / 2 ATR 初始止损。**百分比收益会误导**:SL 越宽每笔风险越大,
|
||||
固定风险仓位下仓位越小,raw % 里 SL2 看着比 SL1.5 好 68%,其中大半是仓位效应。
|
||||
|
||||
样本外,分批→8 ATR、留损=初始 SL、48 根,§2.3 的 1%风险 + 20倍上限 + 复利:
|
||||
|
||||
| 配置 | 均R | R夏普 | 最差1%R | 平均杠杆 | 最大回撤(样本外/内) | Sharpe(外/内) |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 现用 SL1.5 整仓TP3 | +0.722 | 0.494 | −1.55 | 1.97x | 12.1% / 11.9% | 14.79 / 8.33 |
|
||||
| SL1.0 分批→8 | +1.023 | 0.381 | −1.93 | 2.70x | 16.0% / 14.7% | 11.36 / 6.72 |
|
||||
| **SL1.5 分批→8** | **+1.023** | 0.530 | −1.55 | 1.97x | 13.5% / 9.4% | 15.79 / 9.30 |
|
||||
| **SL2.0 分批→8** | +0.943 | **0.638** | **−1.37** | 1.53x | 13.1% / **6.4%** | **19.00 / 11.35** |
|
||||
|
||||
- **SL=1.0 明确最差**:均R 与 SL1.5 打平,但 R夏普 只有 0.381、回撤最大、
|
||||
最差单笔 −1.93R。止损太紧被噪声打掉,和 §3.2「滞后是第一驱动」是一类问题
|
||||
- **SL=1.5 期望值最高**(均R 1.023),**SL=2.0 风险调整最好**
|
||||
(R夏普 0.638、回撤 6.4%、Sharpe 11.35,样本内外一致)
|
||||
- SL2 只让出 8% 的单位风险期望,换来 20% 更高的 R夏普和更好的最差单笔。
|
||||
**纠正一次误判:修正仓位效应后 SL=2.0 仍然占优,不是纯粹的仓位错觉**
|
||||
- 按剔10%PF 排全网格,前 14 名全是 SL=2 的分批配置,
|
||||
第一名 `SL2 分批→8ATR 留损2 48根`:剔10%PF 2.26(现用 1.59)、
|
||||
净 +0.920%、PF 3.84、滑点余量 61.79bp(现用 40.05bp)
|
||||
- 该配置样本外 **8/8 币、7/7 年**对现用全面提升,无例外
|
||||
|
||||
> 上表的年化数字是 §2.3 的口径 A(复利+杠杆),且把 8 个币当一个账户串起来算,
|
||||
> 严重虚高,**故意不记录**。只有回撤、Sharpe、R 这些比值可以横向比。
|
||||
|
||||
#### 换成实际费率(2/0.8bp)后:几乎没变
|
||||
|
||||
step41 首轮跑的是错误的 3/1bp(见 §1.3),已用实际费率重算分析段
|
||||
(feather 存的是毛收益+出场原因,不必重跑模拟):
|
||||
|
||||
| 组 | 口径 | 平均费 | 净均收益 | 余量bp | 剔10%PF | 均R |
|
||||
|---|---|---|---|---|---|---|
|
||||
| 样本外 | 现用 SL1.5/TP3/48 | 3.00→**2.00bp** | 0.579→**0.589%** | 41.34→**42.05** | 2.01→2.05 | 0.790→0.811 |
|
||||
| 样本外 | 最优 SL2 分批→8 留损2/48 | 4.45→**3.01bp** | 0.941→**0.955%** | 62.17→**63.13** | 2.69→2.75 | 0.975→0.998 |
|
||||
| 样本内 | 最优 SL2 分批→8 留损2/48 | 4.43→**2.99bp** | 0.866→**0.881%** | 57.15→**58.10** | 2.91→2.98 | 0.960→0.984 |
|
||||
|
||||
**结论一个都没变,量级也没变**(余量动了 2%)。原因还是那条:
|
||||
成本固定在 bp、目标随 ATR 缩放,所以**费率只对 1m 有杠杆**——
|
||||
同一次改动在 1m 上把均R 抬了 8%,在这里只有 2%。
|
||||
|
||||
#### ATR 门控在这三条腿上是惰性的
|
||||
|
||||
1m 上有效的 `ATR ≥ 8bp` 门控(见 5.3),搬到这里几乎不触发:
|
||||
|
||||
| 级别 | ATR中位 | <8bp 占比 | 门控后保留 | 均R 变化 |
|
||||
|---|---|---|---|---|
|
||||
| 5m | 33.6bp | 2.60% | 97.4% | 1.007 → 1.006 |
|
||||
| 15m | 60.2bp | 0.16% | 99.8% | 0.995 → 0.992 |
|
||||
| 30m | 82.5bp | 0.00% | 100% | 0.947 → 0.947 |
|
||||
|
||||
**无害也无用**,所以可以当全局规则统一写进执行层,不必按级别分叉:
|
||||
`ATR ≥ 5 + 1.1 × taker费(bp)`,当前费率下即 ≥ 8bp。
|
||||
它只在 1m 上真正起作用(那里 21.5% 的信号在阈值以下)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 已验证无效 / 不要重做的方向
|
||||
@@ -180,9 +367,12 @@ push = z_above if direction == 1 else z_below
|
||||
| 方向 | 结论 | 出处 |
|
||||
|---|---|---|
|
||||
| 动态止盈(小级别三买后等大级别三买再调止盈) | 无效。持仓期太短(8~13 根),大级别确认来得太罕见 | step27 |
|
||||
| 移动止损(1.5 ATR 跟踪距离) | 明显劣于固定 TP:样本外 PF 2.32、剔10%PF 0.94(TP=3 是 2.71/1.64)。突破后的正常回抽就能把它洗出去,和 §3.2「滞后是第一驱动」同源 | step41 |
|
||||
| **分批后收紧剩余半仓的止损(保本损及一切更紧的位置)** | 直觉上该做,数据上是负的。止损位 0/0.5/1/1.5/2 ATR 严格单调,越紧越差,三组初始 SL 全一致:保本损比不动少赚 0.14%/笔,剔10%PF 从 1.79 塌到 1.50。与移动止损同源——回抽到成本价是正常结构,不是信号失效。**分批要做,止损保持原位** | step41 §3.5 |
|
||||
| 初始止损收到 1.0 ATR | 5m/15m/30m 上均R 与 1.5 打平但 R夏普 只有 0.381(1.5 是 0.530)、回撤 16.0%、最差单笔 −1.93R。**1m 上更极端**:剔10%PF 0.78~0.99、中位收益 −0.122%、回撤 25.5%。1 ATR 就是噪声宽度 | step41/42 |
|
||||
| 同一中枢重复入场(二次、三次) | 质量骤降,**只做首次** | step25 |
|
||||
| 缠论引擎原生 `find_all_bsp` 的 B3/S3 | 因 `is_sure` 确认滞后,统计上呈逆势、显著亏损。几何位置没错,但实时不可用 | step30/31 |
|
||||
| 刷交易额换 VIP 费率 | 成本收益不划算,见 5.3 | step23 |
|
||||
| 缠论引擎原生 `find_all_bsp` 的 B3/S3 | 统计上呈逆势、显著亏损:胜率 27.4%(低于 SL1.5/TP3.0 的随机基准 33%)、PF 0.66、t −18.76。**不是滞后造成的**——同一组过滤器把 B4 从 1.59 提到 2.26,对它无效(0.66→0.71),且入场后移 1~4 根只是平滑衰减。它几乎不筛(627 个中枢发 625 个信号),把「价格早已离开、再没回来」的历史区间也当信号发出来。B4/S4 因此单独立类,不是它的提前版 | step30/31 |
|
||||
| 刷交易额换 VIP 费率 | 成本收益不划算,见 5.3。**但前提已变**:该结论算于「原始 taker 6bp、全 taker、TP=3.0、无门控」,四个前提现在全不成立(实际 2/0.8bp、混合费率、分批出场、有 ATR 门控)。已在返 50% 的档位上,继续压缩的空间本就有限,但**若要重估需重跑,不要直接引用旧结论** | step23 |
|
||||
| 线段(`Chan_XD`)做大级别 | 滞后太大,且中枢极少 | 早期,用户也这么说 |
|
||||
|
||||
---
|
||||
@@ -238,6 +428,11 @@ push = z_above if direction == 1 else z_below
|
||||
|
||||
按 Bitget 真实费率算滑点预算:
|
||||
|
||||
> ⚠️ **下表的费率档位是错的**:它假设原始 taker 0.12%、返 50% 得 0.060% 双边。
|
||||
> 实际是原始 taker 0.040% / maker 0.016%,返 50% 后 taker 2.0bp / maker 0.8bp
|
||||
> (见 §1.3)。整张表连同下面那张「四条腿对比」都**只保留跨级别的相对关系**,
|
||||
> 绝对数字全部作废。
|
||||
|
||||
| 档位 | 双边费率 | PF=1 滑点上限 | t>2 实用上限 |
|
||||
|---|---|---|---|
|
||||
| VIP1 taker + API 返50% | 0.060% | **3.9bp** | ~2.5bp |
|
||||
@@ -256,8 +451,162 @@ push = z_above if direction == 1 else z_below
|
||||
|
||||
**1m 和 30m 的余量差 23 倍。**
|
||||
|
||||
> **重要判断:1m 若失败,唯一的结论是「执行成本超了 3.9bp」,
|
||||
> 绝不能拿它去否定 5m/30m。** 三条腿的成本敏感度不在一个量级上。
|
||||
> **重要判断:1m 若失败,绝不能拿它去否定 5m/30m。**
|
||||
> 三条腿的成本敏感度不在一个量级上。
|
||||
|
||||
#### ⚠️ 上面的 3.91bp 已被 step42 推翻:那是 30m 的参数套在 1m 上量出来的
|
||||
|
||||
用户指出:`SL1.5/TP3.0/MAXB48` 是在 5m/15m/30m 上定的,1m 不该混用。
|
||||
**成本固定 5bp,而目标随 ATR 缩放**,1m 的 3 ATR 只有 0.39%、30m 是 1.87%,
|
||||
成本占比差 5 倍,最优 TP 不可能相同。查证后确实如此,而且原因比成本更根本:
|
||||
|
||||
| 级别 | MFE 中位 | ≥6 ATR | ≥10 ATR |
|
||||
|---|---|---|---|
|
||||
| **1m** | **5.16 ATR** | **46.1%** | **28.6%** |
|
||||
| 5m | 4.29 | 37.8% | 18.6% |
|
||||
| 15m | 3.98 | 34.7% | 17.0% |
|
||||
| 30m | 3.94 | 36.6% | 18.7% |
|
||||
|
||||
**1m 以 ATR 计的右尾是其他级别的两倍。** 机理:1m 的 ATR 量的是分钟级噪声,
|
||||
但信号一旦成立抓到的是几小时级别的趋势,所以「行程 / ATR」比值天然更大;
|
||||
30m 的 ATR 本身已经吃进了一部分趋势。所以 TP=3 ATR 在 1m 上是个远比在 30m 上
|
||||
更紧的目标——**这不是调参问题,是量纲问题**。
|
||||
|
||||
(MFE 本身也随初始止损变化,止损越松活得越久、右尾越长:
|
||||
1m 上 SL1.0 中位 2.37 ATR、SL1.5 是 5.16、SL2.0 是 6.73。
|
||||
所以 TP 和 SL 必须一起定,不能固定一个扫另一个。)
|
||||
|
||||
#### 1m 全网格重测(step42,11 币 × 7 年,25476 笔)
|
||||
|
||||
> ⚠️ 本小节的表用的是**旧费率 3/1bp**(跑的时候费率档位写错了,见 §1.3)。
|
||||
> 实际是 2/0.8bp,所以下面所有净收益、余量、均R **都偏保守**。
|
||||
> 用实际费率重算的版本在再下一小节,**决策请用那一版**。
|
||||
|
||||
扫描空间:`SL ∈ {1.0, 1.5, 2.0}` × `TP ∈ {2,3,4,5,6,8,10,12}` ×
|
||||
`MAXB ∈ {48, 96}` × 分批(3 ATR 减半 → 剩余目标 {5,6,8,不设} × 留损 {0,0.5,1,1.5,2})。
|
||||
|
||||
**结论与 5m/15m/30m 同向,但幅度更大,且 1m 上没有取舍——最优解在每个指标上都赢。**
|
||||
|
||||
样本外(8 个未调参币,17734 笔):
|
||||
|
||||
| 口径 | 胜率 | 毛bp | 净均收益 | 中位 | PF | 剔10%PF | **滑点余量** | 均R | R夏普 | 最大回撤 | 均持仓 |
|
||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||
| 现用 SL1.5 / 整仓TP3 / 48根 | 60.8% | 20.27 | +0.141% | +0.169% | 2.09 | 1.24 | **11.06bp** | +0.434 | 0.274 | 14.7% | 9.7 |
|
||||
| SL1 分批→8ATR 留损1 / 48根 | 45.9% | 20.29 | +0.133% | −0.122% | 2.01 | 0.96 | 9.07bp | +0.649 | 0.225 | 25.5% | 17.5 |
|
||||
| SL1.5 分批→8ATR 留损1.5 / 48根 | 58.9% | 28.60 | +0.219% | +0.132% | 2.70 | 1.49 | 15.12bp | +0.781 | 0.376 | 14.1% | 23.7 |
|
||||
| **SL2 分批→8ATR 留损2 / 48根** | 67.6% | 34.90 | **+0.284%** | +0.233% | **3.41** | **2.01** | **20.12bp** | **+0.792** | **0.500** | **12.6%** | 28.4 |
|
||||
|
||||
(滑点余量口径已改:分子是毛收益减实际手续费,分母是 taker 名义额,
|
||||
即**每条 taker 腿能承受多少滑点**。旧表按双边固定 6bp 扣、不除 taker 腿,
|
||||
所以数字偏大——上一版写的 14.27bp 就是旧口径,与 11.06bp 是同一件事的两种算法。)
|
||||
|
||||
- **滑点余量 11.06 → 20.12bp,接近翻倍**;均 R +0.434 → +0.792(+82%)
|
||||
- **8/8 样本外币、7/7 年份全部提升**,无例外。最弱的 2026 年:
|
||||
现用余量 4.69bp / 剔10%PF 0.92(已跌破 1),最优 9.84bp / 1.45
|
||||
- 样本内同向:净 +0.100% → +0.221%,剔10%PF 1.07 → 1.72,回撤 19.7% → 10.2%
|
||||
- **`MAX_BARS=48` 不用改**:1m 上 96 根在同配置下一致略差(剔10%PF 2.01 → 1.95),
|
||||
这点与 5m/15m/30m 不同,是 1m 唯一沿用原参数的地方
|
||||
- 纯整仓高 TP(TP8/TP10)毛收益更高(44~47bp)但胜率跌到 59~60%、
|
||||
中位收益反而更低;分批版 PF 与剔10%PF 更好,是更稳的那一侧
|
||||
|
||||
**1m 上 SL=1.0 是废的**(比其他级别更明确):剔10%PF 只有 0.78~0.99,
|
||||
中位收益 −0.122%(一半以上的交易是亏的),最差 1% 到 −3.69R,回撤 25.5%。
|
||||
1 ATR 在 1m 上就是噪声宽度,止损放在噪声里必然被反复扫。
|
||||
|
||||
**减仓后剩余半仓的止损位——三组初始 SL 下都是同一条单调曲线:**
|
||||
|
||||
| 初始SL | 保本损(0) | 留损0.5 | 留损1 | 留损1.5 | 留损2 |
|
||||
|---|---|---|---|---|---|
|
||||
| SL1.0 剔10%PF | 0.78 | 0.91 | 0.96 | 0.98 | **0.99** |
|
||||
| SL1.5 剔10%PF | 1.23 | 1.38 | 1.45 | 1.49 | **1.50** |
|
||||
| SL2.0 剔10%PF | 1.68 | 1.86 | 1.95 | 2.00 | **2.01** |
|
||||
|
||||
**越松越好,到「不动」(= 初始 SL)为止基本饱和**,再放宽只有 +0.01 的边际。
|
||||
保本损在 SL2 上直接砍掉 0.33 的剔10%PF,是全表最差的一档。
|
||||
结论与 5m/15m/30m 完全一致:**减仓后不要动止损**。
|
||||
|
||||
#### 逐年余量在衰减——那是波动率压缩,不是 alpha 衰减
|
||||
|
||||
用户看到余量逐年递减后提的假设:「是不是跟波动率有关,2026 是熊市、2025 是牛市」。
|
||||
**查证成立,而且相关性高到接近恒等式。**
|
||||
|
||||
`余量bp` 与 `当年 ATR 中位数` 的跨年相关系数 **r = +0.989**(n=7)。
|
||||
|
||||
| 年 | ATR中位 | 毛bp | **毛/ATR** | 余量bp(旧费率) | 均R |
|
||||
|---|---|---|---|---|---|
|
||||
| 2020 | 16.3 | 39.8 | 2.44 | 23.98 | 0.939 |
|
||||
| 2021 牛 | **22.1** | 58.7 | 2.65 | **36.49** | 1.031 |
|
||||
| 2022 | 15.4 | 36.5 | 2.37 | 21.30 | 0.876 |
|
||||
| 2023 | 9.8 | 24.9 | 2.53 | 13.88 | 0.846 |
|
||||
| 2024 | 11.7 | 31.3 | 2.67 | 18.07 | 0.877 |
|
||||
| 2025 | 11.6 | 27.8 | 2.40 | 15.76 | 0.883 |
|
||||
| 2026 熊 | **8.8** | 19.8 | 2.26 | **10.28** | 0.713 |
|
||||
|
||||
**关键是「毛/ATR」列:2.26~2.67,七年无趋势。** 信号质量以 ATR 计几乎没衰减。
|
||||
衰减的是 ATR 本身——2021 的 22.1bp 压到 2026 的 8.8bp,掉了 60%。
|
||||
余量是 bp 口径,自然跟着掉。这就是 §5.3 的论证从跨级别搬到跨时间:
|
||||
**成本固定在 bp,目标随 ATR 缩放**。低波动年份等于「1m 变得更像 1m」。
|
||||
|
||||
保留意见:2026 的毛/ATR 2.26 与余量/ATR 1.17 都是七年最低,
|
||||
**可能还有一点真衰减**,但 8 个月 1682 笔分不出是噪声还是趋势。
|
||||
|
||||
#### ATR 门控:低 ATR 的信号毛质量不差,是被固定成本吃掉的
|
||||
|
||||
按信号根 ATR 分桶看**毛** R(零成本口径),结论与直觉相反:
|
||||
|
||||
| ATR桶 | 毛R | 净R @2/0.8bp | 净R @6/2bp |
|
||||
|---|---|---|---|
|
||||
| <6bp | **1.156** | — | 0.025 |
|
||||
| 6-8 | **1.160** | — | 0.527 |
|
||||
| 8-10 | 1.227 | — | 0.736 |
|
||||
| 12-15 | 1.203 | — | 0.870 |
|
||||
| >30 | **0.940** | — | 0.829 |
|
||||
|
||||
**低 ATR 桶的毛 R 不但不差,还是最高的一批**(1.16 vs 高 ATR 桶的 0.94)。
|
||||
断崖只在扣费之后出现。所以「低波动时段信号变差」是错的说法,
|
||||
正确说法是**固定成本在低波动时占比过大**。
|
||||
|
||||
**推论:门控阈值是费率的函数,不是市场常数。** 换 VIP 档 / 换返佣 /
|
||||
换交易所都要重算,不能抄:
|
||||
|
||||
| 单边 taker | 最优 ATR 阈值 |
|
||||
|---|---|
|
||||
| 0(假想) | 5bp |
|
||||
| 1.5bp | 8bp |
|
||||
| 3bp | 9bp |
|
||||
| 6bp | 12bp |
|
||||
|
||||
大致 `阈值 ≈ 5 + 1.1 × taker费(bp)`,亚线性。
|
||||
|
||||
#### 实际费率(2/0.8bp)下的最终口径——**决策用这一版**
|
||||
|
||||
| 口径 | 笔数 | 平均费 | 净bp | 余量bp | PF | 剔10%PF | 均R | R夏普 |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| 现用 SL1.5/TP3/48 | 17734 | 2.00bp | 18.3 | 13.06 | 2.73 | 1.96 | 0.702 | 0.482 |
|
||||
| 最优 SL2 分批→8 留损2/48 | 17734 | 2.99bp | 31.9 | 21.45 | 4.18 | 2.85 | 0.958 | 0.639 |
|
||||
| **最优 + ATR≥8bp 门控** | 13929 | 3.00bp | 36.5 | **25.39** | **4.23** | **2.98** | **0.987** | **0.662** |
|
||||
|
||||
逐年(最优 + 8bp 门控,样本外):
|
||||
|
||||
| 年 | ATR中位 | 无门控余量 | 门控余量 | 保留% | 笔/周 | 剔10%PF | 均R |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 2021 牛 | 22.1 | 37.47 | 37.80 | 98.6% | 55.5 | 3.41 | 1.064 |
|
||||
| 2023 | 9.8 | 14.84 | **19.45** | 63.5% | 28.4 | 2.84 | 0.982 |
|
||||
| 2025 | 11.6 | 16.73 | 20.79 | 71.2% | 45.5 | 3.11 | 1.007 |
|
||||
| 2026 熊 | 8.8 | 11.21 | **15.19** | 55.4% | 27.5 | 2.51 | 0.824 |
|
||||
|
||||
- **门控是自适应的**:高波动年份几乎不触发(2021 保留 98.6%),
|
||||
低波动年份才发力(2026 保留 55.4%、余量 +36%)。不是拟合出来的常数
|
||||
- **费率降低后门控的边际价值也降低**:旧费率下门控带来 +5.6% 均R,
|
||||
实际费率下只有 +3.0%。阈值曲线在 5~12bp 之间很平(均R 0.972~0.987),
|
||||
**8bp 是峰值但不敏感**,不必纠结精确值
|
||||
- **影子交易判据:14~15bp**(2026 最差年份口径)。近两年合计是 19.17bp,
|
||||
全样本外 25.39bp。**用 2026 那个数做及格线,别用平均值**
|
||||
|
||||
**与旧 3.91bp 的差距来源未完全对齐**:旧数字来自 step23(2.28 年数据、
|
||||
3578 笔、毛均收益 0.0991%),本步是 7 年、25476 笔、毛均收益 0.2027%,
|
||||
且滤网口径可能不同(§5.3 原文写的是「1m 同向信号」,未提阶梯),
|
||||
费率口径也已改成混合 maker/taker。**在重新对齐之前,两个数字不要混用。**
|
||||
|
||||
风险点:入场条件恰好是「收盘突破转强」,那一刻价格正朝我们的方向跑,
|
||||
所以延迟造成的是**系统性的追高/追低,不会正负抵消**。这正是
|
||||
@@ -311,15 +660,77 @@ push = z_above if direction == 1 else z_below
|
||||
--probe 60 --workers 3`,约 4 分钟。瓶颈不在窗口重建,而在 `run_one` 开头
|
||||
那次 120 万根 1m 的全量 `TF_DF`。)
|
||||
|
||||
### 第 2 步:向用户确认交易所(当前的阻塞项)
|
||||
|
||||
这个问题必须他回答,因为它决定框架:
|
||||
|
||||
- 留 Bitget → 只有 Hummingbot 支持,或用 ccxt 自己写执行层
|
||||
- 换 Hyperliquid / Binance / Bybit / OKX → freqtrade 和 Nautilus 都能用
|
||||
### ~~第 2 步:向用户确认交易所~~ ✅ 已定:Bitget + Hummingbot
|
||||
|
||||
他已选定**先只上 1m**(在我问「先从哪条腿落地」时选的 `1m_first`)。
|
||||
|
||||
#### 延迟已实测完成(2026-08-27,服务器侧)
|
||||
|
||||
四路对照(宿主机 ccxt.pro / 宿主机原始 WS / 容器原始 WS / 容器 Hummingbot,
|
||||
同一批 K 线对齐),把最初测到的「Hummingbot 慢 1030ms」拆开了:
|
||||
|
||||
- 容器网络 2~18ms
|
||||
- **Hummingbot 自身处理开销 −10~−30ms(不慢反快)**
|
||||
- 剩下 1350~1480ms 全在上游连接器的一个 bug 上
|
||||
|
||||
**Bug**:Bitget 换根时推的是带两根 K 线的消息 `[上一根, 新一根]`,
|
||||
而上游解析写的是 `data["data"][0]`,拿到的是上一根;新一根要等下一条
|
||||
单元素消息、约 1.1 秒后才进 deque。ccxt 遍历全部元素,所以没这问题。
|
||||
|
||||
**修法**:不能简单改成 `[-1]`——那样上一根的收盘价会永远停在换根前
|
||||
约 1 秒的那次推送上,而我们的信号对 0.25bp 的扰动都会换掉一半结果,
|
||||
收盘价偏一个 tick 不可接受。正确做法是处理消息里的**全部元素**:
|
||||
前面的就地写回,最后一根交基类 append。
|
||||
|
||||
20 分钟 / 60 根配对验证:
|
||||
|
||||
| 币 | 上游 lag | 补丁后 lag | 上游漂移 | 补丁后漂移 |
|
||||
|---|---|---|---|---|
|
||||
| BTC | 1454ms | **547ms** | 0.81bp | **0.50bp** |
|
||||
| ETH | 1683ms | **506ms** | 1.20bp | **0.66bp** |
|
||||
| SOL | 1408ms | **642ms** | 1.29bp | **0.87bp** |
|
||||
|
||||
补丁后与原始 WS 只差 5~14ms,贴着理论下限;19 根已收盘 K 线 OHLCV 逐根相同。
|
||||
|
||||
**漂移 0.50~0.87bp 对 15.19bp 的预算只用掉 6%,延迟这一关过了。**
|
||||
|
||||
⚠️ 但这是**无条件漂移**(60 根里绝大多数是普通换根),而我们只在
|
||||
「收盘突破转强」那一刻入场,那一刻价格正朝我们方向跑。§3.2 已量化
|
||||
滞后与收益严格单调且是系统性追高。**信号根上的条件漂移预计显著更高,
|
||||
影子测量必须按信号根条件化统计**,见第 3 步。
|
||||
另外测的是 BTC/ETH/SOL——既是流动性最好的,又恰好是样本内那三个;
|
||||
真正要跑的 8 个样本外币盘口更薄,至少补测 TRX 和 ADA。
|
||||
|
||||
#### 容器内可行性(同批确认)
|
||||
|
||||
Python 3.13.14 + pandas 3.0.5 + numpy 2.4.6,与本机 `.venv` 的 pandas 同版本。
|
||||
同一份切片喂进去,三个币的**信号下标、中枢数、中枢 checksum 全部逐一相同**,
|
||||
容器内 0.26s/币 比本机 0.29s 还快。**chanlun 直接挂载进容器即可,
|
||||
不需要另起信号服务。**(装进现有 `.venv` 走不通:Hummingbot 要
|
||||
`numba>=0.61.2` 和 `aiohttp<3.14`,与本机 Python 3.14 冲突。)
|
||||
|
||||
2000 根 1m 够取:单次上限 1000、分两页,1m 限 30 天。
|
||||
|
||||
#### 补丁落地方式:子类覆盖(已定)
|
||||
|
||||
不改镜像,用子类覆盖连接器的解析方法,升级 Hummingbot 不冲突。
|
||||
|
||||
⚠️ **这个方案有一个缺口必须堵**:如果上游把被覆盖的方法改名,
|
||||
子类覆盖会变成**死代码,静默退回 1.4s,不报任何错**。
|
||||
所以启动时要断言基类上确实存在该方法名(有条件的话连签名一起校验),
|
||||
把静默失效转成启动即失败。
|
||||
|
||||
⚠️ **无论用哪种补丁方式,都要有运行时 lag 探针**——补丁机制只防得住
|
||||
「上游代码变了」,防不住 Bitget 再改一次消息格式:
|
||||
|
||||
- 每根 K 线收盘记 `本地接收时间 − K线收盘时间`
|
||||
- 最近 30 根取滚动中位数
|
||||
- **中位数 > 800ms 告警并停止开新仓**(补丁后实测 506~642ms,
|
||||
理论下限约 500ms;800ms 留足抖动余量又能对 1.4s 的退化一刀切死)
|
||||
|
||||
要停开仓而不只是打日志,因为损失是**经济性且静默的**——
|
||||
不会崩、不会报错,只会让收益慢慢变差,几周后才从统计里看出来。
|
||||
|
||||
### 第 3 步:写影子交易器测滑点(核心工作)
|
||||
|
||||
**关键判断:测滑点不需要任何交易框架。** 完整框架解决的是「如何可靠下单」,
|
||||
@@ -344,24 +755,86 @@ push = z_above if direction == 1 else z_below
|
||||
|
||||
滑点应分解成三块:**延迟漂移**(`t_book` 中间价 − 次根开盘价)、
|
||||
**盘口价差**(ask − 中间价)、**深度冲击**(加权成交价 − ask)。
|
||||
预期延迟漂移是主项,价差可忽略(0.01bp)。
|
||||
延迟漂移已单独测过(第 2 步,0.50~0.87bp 无条件),
|
||||
但**信号根上的条件漂移才是要测的量**。
|
||||
|
||||
建议路径 `research/live/shadow.py`,复用 `research/lib/` 下同一套信号代码,
|
||||
这样两边数字直接可比。代码量约两三百行。
|
||||
#### 形态已定:Hummingbot V2 controller(不再写独立 shadow.py)
|
||||
|
||||
实现要点:
|
||||
- 信号承载在 V2 controller 里,chanlun 挂载进容器直接用
|
||||
- **chanlun 计算走 `ProcessPoolExecutor`**:0.26s 是纯 CPU 且受 GIL 限制,
|
||||
直接放进 async 会卡住事件循环
|
||||
- 滑点测量**读连接器真实盘口**,不用 paper trade 的模拟成交
|
||||
|
||||
#### 必须记录的字段(否则数据回来无法对判据)
|
||||
|
||||
时间戳四件套,拆开才知道该优化哪里:
|
||||
|
||||
| 字段 | 含义 |
|
||||
|---|---|
|
||||
| `t_close` | K 线收盘时刻 |
|
||||
| `t_data` | 数据到手时刻 → 拉取延迟 |
|
||||
| `t_signal` | 信号算完时刻 → 计算延迟 |
|
||||
| `t_book` | 盘口快照时刻 → 下单时点 |
|
||||
|
||||
**每笔还必须记 `atr_pct`**——判据是 bp 口径而 ATR 逐年变化(见 5.3),
|
||||
不记 ATR 就无法把实测滑点换算成 R、也无法验证门控是否正确执行。
|
||||
|
||||
**统计口径三条硬要求:**
|
||||
|
||||
1. **只统计通过全部滤网的信号根**(同向 + 阶梯 + `ATR ≥ 8bp` 门控)。
|
||||
在未过滤的根上测滑点会把判据算宽——那些单子我们根本不做
|
||||
2. **条件漂移与无条件漂移分开报**。无条件值(0.5~0.87bp)已知,
|
||||
要的是信号根上的值。两者的差就是「系统性追高」的大小
|
||||
3. **出场腿单独统计**:止盈是 maker 不吃滑点,止损/超时是 taker 要吃。
|
||||
§1.3 的费率模型按出场原因分别计费,滑点也必须这样分,
|
||||
否则会把 60% 不吃滑点的止盈腿混进平均值里,低估真实成本
|
||||
|
||||
对判据时用**每条 taker 腿的滑点**(入场 + 止损/超时出场),
|
||||
不是每笔的总滑点——余量 15.19bp 就是这个口径。
|
||||
|
||||
**记录与报表已在服务器侧实现**:`research/live/shadow_hb.py`(采集)与
|
||||
`shadow_report.py`(报表)。它的设计比研究侧曾经写过的那版好,不要重复造:
|
||||
**每个信号在 0.5s / 1s / 2s / 5s / actual 五个延迟上各测一次**——同信号内的
|
||||
受控对比,能直接读出「延迟压到 X 秒滑点是多少」,决策不被当前实现拖累;
|
||||
另外还扫了仓位,滑点也已拆成漂移 / 价差 / 冲击。
|
||||
|
||||
**判据常数留在研究侧**:`research/lib/shadow_budget.py`
|
||||
(逐币 `BUDGET_BP`、`ATR_GATE_BP`、`LEG_IS_TAKER`、`lag_healthy()`、
|
||||
`verdict()`)。分工的理由是这些数会变——2026-08-27 一天之内预算就动了四次,
|
||||
费率也改了一次,写死在 live 侧的任何一份都会静默过期。
|
||||
|
||||
其他实现要点:
|
||||
- 数据格式必须与 `lib/data.py` 一致:`timestamp`(int64 ms), `date`(tz
|
||||
Asia/Shanghai), `open/high/low/close/volume`
|
||||
- ccxt 拉 Bitget 需 `proxies = {'http': 'http://127.0.0.1:7897', 'https': ...}`
|
||||
和 `options={'defaultType':'swap'}`
|
||||
- 持仓也要影子管理:SL/TP/48 根超时,出场同样记录真实盘口
|
||||
- 持仓也要影子管理:出场按 1m 自己的参数(3 ATR 减半 / 留损 2 / 目标 8 ATR
|
||||
/ 48 根超时),出场同样记录真实盘口
|
||||
- 状态要落盘,重启不能丢
|
||||
|
||||
### 第 4 步:根据滑点结果决策
|
||||
|
||||
- 滑点 ≤ 2.5bp → 1m 可行,`t>2`,可以进入真实 dry run
|
||||
- 2.5~3.9bp → 1m 勉强不亏但无统计显著性,考虑争取 60% 手动返佣或 VIP2
|
||||
- > 3.9bp → 1m 放弃,**但 5m/30m 不受影响**(余量 26bp / 89bp)
|
||||
~~旧阈值(2.5 / 3.9bp)已作废~~:那是 TP=3.0、全 taker、原始费率记错
|
||||
三重错误叠加出来的,见 5.3。**新判据如下。**
|
||||
|
||||
前提:1m 用自己的出场参数(`SL2 / 3ATR减半 / 留损2 / 目标8ATR / 48根`)
|
||||
+ `ATR ≥ 8bp` 门控 + 实际费率 2/0.8bp。
|
||||
|
||||
**判据用 2026 那个最差年份的 15.19bp,不要用全样本的 25.39bp。**
|
||||
低波动环境是当前状态,不是尾部情形。
|
||||
|
||||
| 实测滑点(每条 taker 腿) | 判断 |
|
||||
|---|---|
|
||||
| ≤ 5bp | 1m 可行,各年份都有厚余量,进真实 dry run |
|
||||
| 5~10bp | 可行但只在中高波动期,门控阈值要上调(见 5.3 的费率-阈值关系) |
|
||||
| 10~15bp | 仅 2021 型牛市能做,常态环境不要开 |
|
||||
| > 15bp | 1m 放弃 |
|
||||
|
||||
**5m/30m 不受影响这一句仍成立**(余量 26bp / 89bp,且那是旧费率下的保守值)。
|
||||
|
||||
另外两点:
|
||||
- 滑点必须用 **WebSocket** 测。代理下 REST 单次往返约 2.4s,而信号计算只要
|
||||
0.20s(§5.4),REST 测出来的全是代理的账
|
||||
- 入场条件是「收盘突破转强」,那一刻价格正朝我们方向跑,
|
||||
**延迟造成系统性追高、不会正负抵消**(§3.2 已量化滞后与收益严格单调)
|
||||
|
||||
### 第 5 步(后续):1m 与 5m 分实例
|
||||
|
||||
@@ -420,8 +893,8 @@ API 限流风险隔离三个好处。
|
||||
| 文件 | 作用 |
|
||||
|---|---|
|
||||
| `data.py` | 数据层,本地 feather 优先 |
|
||||
| `fast_bsp3.py` | **核心**:自研低滞后第三类买卖点。滞后 2.2 根 |
|
||||
| `nested_level.py` | `build_htf_zones`:构建中枢,可传入已建好的 `chan` 复用 |
|
||||
| `fast_bsp3.py` | **实现已移入引擎**(`chanlun/analysis/fast_bsp.py`),这里只剩转发导入。所有 step 脚本的 `from lib.fast_bsp3 import find_fast_bsp3` 不用改 |
|
||||
| `nested_level.py` | `build_htf_zones` 同样移入引擎并转发;`annotate_position` 仍在本地 |
|
||||
| `nested_bsp.py` | `htf_fx_timeline` / `attach_htf_context`:区间套上下文。
|
||||
`confirm_ts` 已 `+period` 修正 K 线收盘时刻 |
|
||||
| `fx_signal.py` | 分型信号提取与背驰 |
|
||||
@@ -431,6 +904,23 @@ API 限流风险隔离三个好处。
|
||||
### 8.2 缠论引擎 `chanlun/`
|
||||
|
||||
- `TF_DF(df, 1, tf)` 是入口,`.dataframe` 拿到含缠论标注的 DataFrame
|
||||
- `analysis/fast_bsp.py`:**核心**,自研第四类买卖点 B4/S4(滞后 2.2 根),
|
||||
2026-08-27 从 `research/lib/` 搬来,回测与 web 图表现在共用同一份代码。
|
||||
搬运时逐条比对过 BTC/ETH/SOL × 15m/30m 六组,中枢与信号完全一致。
|
||||
**它不是「B3/S3 提前几根」**:判据(收盘价实时 vs 笔端点事后)、方向来源
|
||||
(突破侧 vs 离开笔)、选样口径(627 个中枢里认 212 个 vs 引擎发 625 个)都不同。
|
||||
step30 同条件对拍见 §4——同一组过滤器把 B4 从 PF 1.59 提到 2.26,对引擎
|
||||
B3/S3 无效(0.66→0.71);引擎那批胜率 27.4% 低于 SL1.5/TP3.0 的随机基准 33%,
|
||||
是系统性反向样本,不是滞后造成的衰减
|
||||
除 `find_fast_bsp3` / `build_htf_zones` 外,还有过滤用的 `add_zone_ladder`
|
||||
(中枢阶梯,§1.4)与 `htf_fx_timeline` / `attach_htf_agree`(区间套同向,§1.1 第三层)
|
||||
- `pipeline/builders/fast_bsp.py`:`TF_DF.cal_fast_bsp()`,把上面那套包成
|
||||
`ChanFastBSP`(类型 `Chan_BSP_TYPE.B4/S4`)。大级别由同一份 df 重采样得到,
|
||||
配对表 `FAST_BSP_HTF_PAIR` 就是 §1.5 那张表。
|
||||
**不在 `init_TF_DF` 里默认计算**,要显式调用
|
||||
- web 端:`/api/analyze` 返回 `fast_bsp_list` / `element_fast_bsp_list` /
|
||||
`sub_sub_fast_bsp_list`,每条带 `htf_agree` 与 `ladder_ok` 两个过滤标志。
|
||||
图上深色 B4/S4 = 两个标志都满足,浅色 = 未通过过滤
|
||||
- `pipeline/builders/incremental.py`:增量更新(`init_stream` / `append_bar` /
|
||||
`replace_last_bar` / `rebuild_bi_zs`)。**注释写明「最后一笔 is_sure 允许收回」**,
|
||||
这是 step38 要验证的那个隐患(已证实无影响)。
|
||||
@@ -462,7 +952,10 @@ API 限流风险隔离三个好处。
|
||||
| 36 | 偏差审计(生效时刻、多空、时间样本外) |
|
||||
| 37 | **跨品种样本外**(8 个新币) |
|
||||
| 38 | **时点重建**(无未来函数) |
|
||||
| 39 | **1m 时点重建 + 窗口扫描**(新写,待跑完) |
|
||||
| 39 | **1m 时点重建 + 窗口扫描**(2000 根窗口饱和) |
|
||||
| 40 | 第四类买卖点的过滤消融(web 端原始 vs 过滤) |
|
||||
| 41 | **出场口径全扫**(SL × TP × MAX_BARS × 分批 × 剩余半仓止损位 + 真实费率模型)。TP=3 截早了;分批要做但止损保持原位;SL=1.0 最差 |
|
||||
| 42 | **1m 单独定出场**(同一张全网格,11 币 7 年 25476 笔)。1m 右尾是其他级别 2 倍,TP 不能混用;`SL2 分批→8ATR 留损2 48根` 在均R/R夏普/回撤/剔10%PF 四项全赢,滑点余量 11.06→20.12bp;`MAX_BARS=48` 反而不用改 |
|
||||
|
||||
输出都在 `research/out/`。**2026-08-27 清理过一轮**:step1~20 的输出(早期方法论
|
||||
已被推翻,含未来函数偏差)与旧口径备份一并删除,只留支撑当前结论的证据。
|
||||
@@ -486,14 +979,49 @@ API 限流风险隔离三个好处。
|
||||
|
||||
- [x] **step39**:1m 时点重建 + 窗口扫描 → **2000 根窗口饱和,计算 0.20s,
|
||||
假阳性 0%,1m 回测口径可信**
|
||||
- [ ] **向用户确认交易所**(阻塞后续框架选择,这是当前第一件事)
|
||||
- [ ] 写 `research/live/shadow.py` 影子交易器,测 1m 真实滑点。
|
||||
**务必用 WebSocket 而非 REST 轮询**——代理下单次 REST 往返约 2.4s,
|
||||
而信号计算只要 0.20s,网络是延迟主项
|
||||
- [ ] **对齐 step23 与 step42 的 1m 数字**(3.91bp vs 11.06bp)。差距可能来自
|
||||
数据年限(2.28 年 vs 7 年)或滤网(§5.3 原文只提「同向」,未提阶梯)。
|
||||
§6 第 4 步的三条决策阈值全部依赖这个数字,对齐前不要据它做去留判断
|
||||
- [ ] **决定是否改出场口径**(step41/42 样本外均已过,见 3.5 与 5.3)。
|
||||
**出场参数要按级别分开定,不能一套走天下。** 5m/15m/30m 的首选是
|
||||
「初始 SL 2.0 ATR、到 3 ATR 平一半、剩余半仓止损保持原位、跑到 8 ATR、
|
||||
48 根超时」;若更看重单位风险期望而非回撤,初始 SL 用 1.5。
|
||||
**1m 用同一套形状,但 SL=2.0 是无争议的最优**(均 R、R夏普、回撤、
|
||||
剔10%PF 四项全赢,见 5.3),`MAX_BARS=48` 不变。
|
||||
改的话 `run_trades` 要支持分批(现在只支持整仓单目标),
|
||||
并重跑 step28/35/37 刷新本文档的年化/回撤/并发数字——**不要新旧口径混用**。
|
||||
注意分批后平均持仓从 11 根拉到 30 根,§3.3 的并发数据必须重算
|
||||
- [x] **用实际费率(2/0.8bp)重算 step41/42 的分析段** → 1m 见 5.3 末尾
|
||||
(均R +8%,判据 15.19bp);5m/15m/30m 见 3.5 末尾(余量只动 2%,结论不变)
|
||||
- [x] **ATR 门控搬到 5m/15m/30m 验证** → 惰性(30m 触发 0%、15m 0.16%、5m 2.6%),
|
||||
可作全局规则 `ATR ≥ 5 + 1.1×taker费(bp)`,当前即 ≥ 8bp
|
||||
- [x] **确认交易所与框架** → Bitget + Hummingbot,先只上 1m
|
||||
- [x] **测执行延迟** → 上游连接器 bug 已定位并修好,补丁后 lag 506~642ms、
|
||||
无条件漂移 0.50~0.87bp,占预算 6%。见 §6 第 2 步
|
||||
- [ ] **写 V2 controller + 盘口缓冲,跑影子测量**(当前第一件事)。
|
||||
字段与统计口径见 §6 第 3 步,**三条硬要求别漏**:只统计过滤后的信号根、
|
||||
条件漂移与无条件漂移分开报、出场腿按 maker/taker 分开统计
|
||||
- [ ] **改掉 `shadow_report.py` 的 `BUDGET_BP`**(当前 BTC −0.13 / ETH 4.02 /
|
||||
SOL 2.92)。那三个数由六处差异叠加而来:只有同向没有阶梯过滤、
|
||||
费率按 6bp 双边 taker、`TP=3.0`、余量没除 taker 名义额、无 ATR 门控、
|
||||
且 BTC/ETH/SOL 恰是 ATR 最低的三个币。正确值 8.58 / 20.64 / 16.83,
|
||||
直接从 `lib/shadow_budget.py` import。
|
||||
**这条优先级最高**:报表里 `drift > b` 与 `drift > b*0.6` 是自动停机开关,
|
||||
用错的预算会让它比真实情况早约五倍触发,误杀一个可行的策略
|
||||
- [ ] **live 信号路径补上中枢阶梯过滤与 ATR 门控**。现在是
|
||||
`fin = full[full["h1_agree"] == 1]`,只有同向。缺这两项测的就不是
|
||||
我们要交易的那批信号,改常数解决不了
|
||||
- [ ] **子类覆盖加启动断言** + **运行时 lag 探针(>800ms 停开仓)**,见 §6 第 2 步
|
||||
- [ ] 补测 ADA / DOGE / AVAX 的漂移——真正要交易的是这批(预算 15~22bp)。
|
||||
BTC/ETH/SOL 流动性最好,测滑点偏乐观是安全方向,但判可行性不能只看它们。
|
||||
**BTC 大概率不该做 1m**:ATR 中位 2026 仅 6.5bp(11 币最低),
|
||||
门控刷掉 58.5%,修正后预算 8.58bp 仍是最低。TRX 2026 门控后只剩 4.2%
|
||||
- [ ] 收集 1~2 周影子数据,与回测口径逐笔对比
|
||||
- [ ] 按 6.4 的判据决策 1m 是否可行
|
||||
- [ ] 若可行:选框架(Bitget→Hummingbot)做真实 dry run
|
||||
- [ ] 按 §6 第 4 步的四档判据决策 1m 是否可行
|
||||
- [ ] 若可行:真实 dry run
|
||||
- [ ] 补一项研究阶段的缺口:**资金费率**从未计入任何回测。
|
||||
注:1m 新参数下平均持仓 28.4 根 = 28 分钟,很少跨 8 小时结算点,
|
||||
这一项对 1m 影响小;30m 腿才是真问题。
|
||||
30m 腿平均持仓 6.5 小时会跨结算点,需要评估影响
|
||||
- [ ] 补:同时持仓的保证金约束也未建模(组合有仓位时间仅 8.6%,
|
||||
预计影响小,但没算过)
|
||||
|
||||
Reference in New Issue
Block a user