research: 低滞后信号口径定稿与实盘前偏差审计
fast_bsp3 改用 tol=-1 + require_touch=False,信号滞后从 5.8 根降到 2.2 根。 滞后与收益严格单调(年化 370% -> 906%,同一份数据同一套成本), 这是本轮提升的主因,也意味着实盘延迟会直接侵蚀收益。 新增 step31~39 验证策略能否落地: - 跨品种样本外——8 个未参与调参的币,PF 2.73 / t 28.5,无一为负 - 时点重建——只喂到信号那一根重算,同根命中 100%,确认无未来函数; 1m 在 2000 根窗口即饱和,计算耗时 0.20s - 偏差审计——多空对称、中枢生效时刻零回退、滑点稳健至 30bp、持仓几乎不重叠 - 消融——alpha 来自缠论中枢的上下文定位,而非「收盘转强」这个触发动作 补 research/HANDOFF.md:记录确切口径与参数、已排除的偏差、 已验证无效因而不必重做的方向,以及下一步用影子交易器实测执行滑点的方案。 清理 step1~20 的输出:早期方法论已被推翻(存在未来函数偏差), 其结论不再被引用;脚本保留,需要时可重跑。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,499 @@
|
||||
# 缠论信号研究 → 实盘落地:交接文档
|
||||
|
||||
> 最后更新:2026-08-27。写给接手这项工作的下一个 agent。
|
||||
> 读完这份文档应该不需要再翻聊天记录。若确有需要,历史转录在
|
||||
> `/Users/jack/.cursor/projects/Users-jack-Project-chan/agent-transcripts/`。
|
||||
|
||||
---
|
||||
|
||||
## 0. 一句话现状
|
||||
|
||||
策略在回测和多重偏差审计下都站得住(跨 11 个币、7 年、多空对称、无未来函数),
|
||||
**研究阶段基本结束**;当前唯一的拦路问题是「实盘执行成本能否压进预算」,
|
||||
下一步是写影子交易器实测滑点,而不是继续调参。
|
||||
|
||||
**用户明确要求:不要再跑新的参数优化。** 他的原话是「很多时候回测数据特别好,
|
||||
一到 dry run 和实盘就歇菜了」。他要的是执行层的验证。
|
||||
|
||||
---
|
||||
|
||||
## 1. 策略的确切定义
|
||||
|
||||
这是全文最重要的一节。所有回测数字都基于以下这套口径,改任何一条数字就不可比。
|
||||
|
||||
### 1.1 信号生成(三层)
|
||||
|
||||
```
|
||||
第一层 小级别(LTF) 自身的中枢 build_htf_zones(cdf, ltf, chan=chan_l)
|
||||
第二层 中枢突破后回抽不回,收盘转强 → 入场 find_fast_bsp3(cdf, zones)
|
||||
第三层 大级别(HTF) 分型方向必须同向 attach_htf_context(...) 后取 h1_agree == 1
|
||||
可选 中枢阶梯方向过滤(顺向推进) z_above / z_below,见 1.4
|
||||
```
|
||||
|
||||
用户对「区间套」的定义(务必按这个理解,早期我理解错过):
|
||||
**大级别(1h/4h)分型定位转折点 + 小级别(15m/5m/1m)中枢突破形成第三类买卖点。**
|
||||
不是大级别中枢突破。
|
||||
|
||||
### 1.2 `find_fast_bsp3` 的当前默认参数
|
||||
|
||||
`research/lib/fast_bsp3.py`:
|
||||
|
||||
| 参数 | 默认值 | 含义与注意 |
|
||||
|---|---|---|
|
||||
| `scan` | 200 | 中枢成立后向后扫多少根找突破 |
|
||||
| `pullback_win` | 30 | 回抽窗口 |
|
||||
| `tol` | **-1.0** | 负值=禁用「回抽未触及边界就跳过」。**这是最关键的参数**,见 3.2 |
|
||||
| `max_per_zone` | 1 | 同一中枢只做首次入场,见 4.2 |
|
||||
| `require_touch` | **False** | 不要求回抽触及中枢边界,见 3.2 |
|
||||
|
||||
`tol=-1` + `require_touch=False` 是当前口径,**滞后 2.2 根**。
|
||||
早期默认(`tol=0.003`, `require_touch=True`)滞后 5.8 根,年化从 906% 掉到 370%。
|
||||
新旧差异已完整量化在 step34(tol 扫描)与 step33(`require_touch`)里,
|
||||
旧口径的原始输出已清理——**不需要它,也不要回到旧口径**。
|
||||
|
||||
### 1.3 交易执行口径
|
||||
|
||||
```python
|
||||
SL, TP, MAX_BARS = 1.5, 3.0, 48 # ATR 倍数止损/止盈 + 超时根数
|
||||
run_trades(cdf, entries, SL, TP, MAX_BARS, fee=..., entry_delay=1)
|
||||
```
|
||||
|
||||
- **入场:信号次根开盘价**(`entry_delay=1`),不是信号根收盘价
|
||||
- 研究口径成本:**4bp 手续费 + 1bp 滑点 = 5bp**(所有带「已扣 5bp」的数字都是这个)
|
||||
- ATR 取信号根的值(`atr[sig_idx]`),不是入场根
|
||||
|
||||
### 1.4 阶梯过滤(顺向推进)
|
||||
|
||||
对应缠论「趋势 vs 盘整」:当前中枢相对前一个中枢是否同向推进。
|
||||
|
||||
```python
|
||||
pg, pdn = z["zg"].shift(), z["zd"].shift()
|
||||
z["z_above"], z["z_below"] = z["zd"] > pg, z["zg"] < pdn
|
||||
push = z_above if direction == 1 else z_below
|
||||
```
|
||||
|
||||
加上它 PF 从 2.72 → 3.41(30m/2h)。**用户特别在意这一点**,因为它印证了
|
||||
缠论对趋势的定义(一个分型后第一个中枢就反转的概率低于出现第二个中枢后反转)。
|
||||
|
||||
### 1.5 各级别的确切配对
|
||||
|
||||
| 小级别 | 大级别(h1,做同向过滤) | 备注 |
|
||||
|---|---|---|
|
||||
| 1m | **5m** | step23 的配置是 `1m:5m:15m`,15m 只记录不过滤 |
|
||||
| 5m | **30m** | 统计量最强 |
|
||||
| 15m | **1h** | |
|
||||
| 30m | **2h** | 单笔质量最高 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 最优配置与核心数字
|
||||
|
||||
### 2.1 级别矩阵(step28,同向+阶梯,3 币)
|
||||
|
||||
| 组合 | 笔数 | 胜率 | 中位 | PF | t值 |
|
||||
|---|---|---|---|---|---|
|
||||
| **5m/30m** | 1321 | 53.1% | +0.31% | 1.98 | **10.16** |
|
||||
| **30m/2h** | 258 | 65.1% | +1.65% | **3.41** | 8.51 |
|
||||
| 5m/15m | 1292 | 51.7% | +0.24% | 1.82 | 8.84 |
|
||||
| 15m/1h | 467 | 56.5% | +0.74% | 2.46 | 7.96 |
|
||||
|
||||
选择逻辑:**30m/2h 单笔质量最好,5m/30m 统计显著性最强**。1h 及以上小级别笔数不足。
|
||||
|
||||
### 2.2 跨品种样本外(step37)— 最有说服力的一项
|
||||
|
||||
参数一个没动,拿 8 个完全没参与调参的币验证:
|
||||
|
||||
| 分组 | 笔数 | 年笔数 | 胜率 | 中位 | PF | t值 | 剔10%PF |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 样本内(BTC/ETH/SOL) | 2309 | 334 | 61.4% | +0.531% | 2.86 | +19.11 | 1.77 |
|
||||
| **样本外(8 个新币)** | 5859 | 884 | 62.9% | +0.592% | **2.73** | **+28.50** | 1.66 |
|
||||
|
||||
逐币最弱的 XRP 仍是 PF 2.21 / t 7.64。**没有一个币是负的。**
|
||||
|
||||
### 2.3 收益量级——务必用正确口径(step35 第 5 节)
|
||||
|
||||
这一条最容易被误读,历史上我自己也一度报错过口径:
|
||||
|
||||
| 口径 | 年化 | 回撤 | Sharpe |
|
||||
|---|---|---|---|
|
||||
| A 1%风险+20倍上限+复利 | +1323.8% | 8.1% | 10.38 |
|
||||
| B 1%风险+20倍上限+不复利 | +270.0% | 8.4% | 10.38 |
|
||||
| **C 固定名义1倍+不复利** | **+194.7%** | 8.4% | 7.95 |
|
||||
| D 固定名义3倍+不复利 | +584.1% | 25.2% | 7.95 |
|
||||
|
||||
**只有 C/D 是可以直接对照的量级。** 那些 906%/1323% 的数字来自复利+杠杆假设。
|
||||
平均单笔杠杆 2.1x(中位 1.8x)。
|
||||
**未含资金费率,未含同时持仓的保证金约束。**
|
||||
|
||||
---
|
||||
|
||||
## 3. 已验证成立的结论
|
||||
|
||||
### 3.1 没有未来函数(step38,最要紧的一项)
|
||||
|
||||
担心的是 `incremental.py` 里那句注释:「最后一笔 is_sure 允许收回」——
|
||||
中枢生效时刻 `available_ts` 取自笔的 `sure_time`,而那是全量重算得出的。
|
||||
|
||||
做法:对每个信号只喂到该根为止的数据(窗口 4000 根),重跑
|
||||
`TF_DF → 中枢 → fast_bsp3`,看信号是否真的在那一刻存在。
|
||||
|
||||
结果:**同根命中 100.0%(抽检 1217 个信号),完全消失 0.0%,假阳性 0.7%。**
|
||||
偏移中位 +0.0 根。回测口径可信。
|
||||
|
||||
### 3.2 滞后是收益的第一驱动(step34)
|
||||
|
||||
| 口径 | 笔数 | 滞后(根) | 胜率 | PF | 年化 | Sharpe |
|
||||
|---|---|---|---|---|---|---|
|
||||
| **禁用跳过(现用)** | 2309 | **2.2** | 61.4% | 2.86 | +906.1% | 9.02 |
|
||||
| tol 0 | 2214 | 2.7 | 60.4% | 2.74 | +731.3% | 8.43 |
|
||||
| tol 0.1% | 2134 | 3.6 | 58.7% | 2.64 | +569.8% | 7.65 |
|
||||
| tol 0.3%(旧默认) | 2045 | 5.8 | 55.4% | 2.37 | +370.4% | 6.30 |
|
||||
| tol 1% | 1561 | 9.9 | 48.3% | 1.88 | +112.0% | 3.53 |
|
||||
|
||||
滞后与收益严格单调。**这也意味着实盘延迟会直接侵蚀收益**,是下一阶段的核心风险。
|
||||
|
||||
### 3.3 其余已排除的偏差
|
||||
|
||||
- **中枢生效时刻**(step36 §1):0% 走 `end_time` 回退分支,全部用 `sure_time`
|
||||
- **多空对称**(step36 §3):做多 PF 3.12 / t 14.77,做空 PF 2.62 / t 12.27
|
||||
→ 不是单纯吃加密货币的上涨 beta
|
||||
- **时间样本外**(step36 §4):2019~2022 挑参数,2023~2026 验证 →
|
||||
PF 从 3.31 降到 2.44,t 仍 12.29。有衰减但成立
|
||||
- **滑点脆弱性**(step35 §1):加到 +30bp 仍 PF 1.73 / t 10.15
|
||||
- **入场后移**(step35 §2):后移 1→4 根平滑衰减(PF 3.18→2.53),
|
||||
未来函数会呈断崖,这里没有
|
||||
- **持仓重叠**(step35 §3-4):单腿平均并发 0.01,组合 9 腿平均并发 0.1,
|
||||
有仓位时间仅 8.6% → t 值没被虚高,各笔基本独立
|
||||
|
||||
### 3.4 alpha 的来源(step32 消融)
|
||||
|
||||
逐条拆掉 `fast_bsp3` 的条件后发现:**alpha 完全来自缠论中枢的上下文定位,
|
||||
不是「回抽结束、收盘转强」那个触发动作本身。** 触发条件只负责压低滞后。
|
||||
|
||||
这个结论回答了用户当时的问题(「如果有这个,那就可以去判断任何笔的端点了」):
|
||||
**不能**。脱离中枢上下文,那个触发条件没有预测力。
|
||||
|
||||
---
|
||||
|
||||
## 4. 已验证无效 / 不要重做的方向
|
||||
|
||||
| 方向 | 结论 | 出处 |
|
||||
|---|---|---|
|
||||
| 动态止盈(小级别三买后等大级别三买再调止盈) | 无效。持仓期太短(8~13 根),大级别确认来得太罕见 | step27 |
|
||||
| 同一中枢重复入场(二次、三次) | 质量骤降,**只做首次** | step25 |
|
||||
| 缠论引擎原生 `find_all_bsp` 的 B3/S3 | 因 `is_sure` 确认滞后,统计上呈逆势、显著亏损。几何位置没错,但实时不可用 | step30/31 |
|
||||
| 刷交易额换 VIP 费率 | 成本收益不划算,见 5.3 | step23 |
|
||||
| 线段(`Chan_XD`)做大级别 | 滞后太大,且中枢极少 | 早期,用户也这么说 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 实盘落地的现状与关键约束
|
||||
|
||||
### 5.1 交易所:这是当前最大的未决项 ⚠️
|
||||
|
||||
用户实际用 **Bitget**(`手续费.xlsx` 在项目根目录):
|
||||
|
||||
| VIP | maker | taker | 升级门槛(月交易额) |
|
||||
|---|---|---|---|
|
||||
| 1 | 0.020% | 0.060% | 0 |
|
||||
| 2 | 0.016% | 0.040% | $3M |
|
||||
| 3 | 0.014% | 0.0375% | $20M |
|
||||
|
||||
返还比例:**手动 60%、API 50%**。
|
||||
|
||||
**框架支持情况(已查证,2026-08):**
|
||||
|
||||
| 框架 | Bitget 永续 | 说明 |
|
||||
|---|---|---|
|
||||
| freqtrade(本地已装 2025.4-dev) | ❌ | 源码里搜不到一处 `bitget`;`SUPPORTED_EXCHANGES` = binance/bingx/bitmart/bybit/gate/htx/hyperliquid/kraken/okx |
|
||||
| NautilusTrader | ❌ | `nautilus-bitget` 是 0.0.0 空壳无 API;官方适配器列表(2026-06-30)无 Bitget。Bitget 只出现在第三方 Tardis 历史数据里 |
|
||||
| **Hummingbot** | ✅ | `bitget_perpetual` v2.0 连接器,2026 年 Bitget 官方合作。支持单向/对冲、限价/市价,有 Perp Candles Feed |
|
||||
|
||||
**用户最后问的就是「还有没有其他框架支持 Bitget」,答案是 Hummingbot——
|
||||
这个问题还没得到他的回应,需要先确认交易所再定框架。**
|
||||
|
||||
其他信息:Hummingbot V2 的 `PositionExecutor` 结构恰好匹配我们的
|
||||
「入场 + 止损 + 止盈 + 超时」,架构上契合。用户的费率表里还有一列空着的 `HL`
|
||||
(Hyperliquid),而 Hyperliquid 在 freqtrade 和 Nautilus 都是原生支持的。
|
||||
|
||||
### 5.2 网络:Bitget 必须走代理 ⚠️
|
||||
|
||||
```
|
||||
直连 失败 NetworkError: bitget GET https://api.bitget.com/api/v2/spot/public/coins
|
||||
代理 OK 2.39s (http://127.0.0.1:7897)
|
||||
```
|
||||
|
||||
盘口实测(BTC/USDT:USDT 永续):bid 79492.7 / ask 79492.8,
|
||||
**价差仅 0.01bp,100 档深度**。即时价差成本可忽略。
|
||||
|
||||
**但代理会把延迟从几百毫秒放大到秒级,而 1m 那条腿的滑点预算只有 3.9bp。
|
||||
实盘这条腿最终必须落到境外 VPS,否则测出来的滑点是代理的账,不是策略的账。**
|
||||
|
||||
### 5.3 1m 那条腿的经济性(用户的核心问题)
|
||||
|
||||
用户原话:「1m 测的是返佣后是否能够不亏钱」,配合「一边刷交易额,一边走大点周期」。
|
||||
|
||||
1m 同向信号实测:**3578 笔 / 2.28 年 / 3 币 = 524 笔/年/币,
|
||||
毛均收益 +0.0991%,胜率 54.2%,平均持仓仅 8.3 分钟。**
|
||||
|
||||
按 Bitget 真实费率算滑点预算:
|
||||
|
||||
| 档位 | 双边费率 | PF=1 滑点上限 | t>2 实用上限 |
|
||||
|---|---|---|---|
|
||||
| VIP1 taker + API 返50% | 0.060% | **3.9bp** | ~2.5bp |
|
||||
| VIP1 taker + 手动返60% | 0.048% | 5.1bp | ~3.8bp |
|
||||
| VIP2 taker + API 返50% | 0.040% | 5.9bp | ~4.5bp |
|
||||
| VIP1 maker + API 返50% | 0.020% | 7.9bp | ~6.5bp |
|
||||
|
||||
**四条腿的滑点余量对比**(VIP1 taker + API 返50%,即双边费率 0.060%):
|
||||
|
||||
| 级别 | 笔数 | 毛均收益 | 平均持仓 | 滑点余量 |
|
||||
|---|---|---|---|---|
|
||||
| **1m** | 3578 | +0.0991% | 8.3 根 | **3.91bp** |
|
||||
| 5m | 1984 | +0.3253% | 9.7 根 | 26.53bp |
|
||||
| 15m | 689 | +0.4436% | 12.1 根 | 38.36bp |
|
||||
| 30m | 340 | +0.9504% | 11.7 根 | **89.04bp** |
|
||||
|
||||
**1m 和 30m 的余量差 23 倍。**
|
||||
|
||||
> **重要判断:1m 若失败,唯一的结论是「执行成本超了 3.9bp」,
|
||||
> 绝不能拿它去否定 5m/30m。** 三条腿的成本敏感度不在一个量级上。
|
||||
|
||||
风险点:入场条件恰好是「收盘突破转强」,那一刻价格正朝我们的方向跑,
|
||||
所以延迟造成的是**系统性的追高/追低,不会正负抵消**。这正是
|
||||
「回测漂亮、实盘歇菜」最常见的具体机制。
|
||||
|
||||
### 5.4 实时计算窗口(step39,已跑完)
|
||||
|
||||
`research/step39_pit_1m.py`(新写,**已跑完**:3 币 × 每币 60 信号 = 180 笔抽检):
|
||||
|
||||
| 窗口(根) | 覆盖天数 | 同根命中 | ±3根内 | 完全消失 | 同向过滤也成立 | 假阳性 | 耗时中位 | 耗时P95 |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| **2000** | 1.4 | **100.0%** | 100.0% | 0.0% | 100.0% | **0.0%** | **0.20s** | 0.22s |
|
||||
| 4000 | 2.8 | 100.0% | 100.0% | 0.0% | 100.0% | 0.0% | 0.40s | 0.42s |
|
||||
| 8000 | 5.6 | 100.0% | 100.0% | 0.0% | 100.0% | 0.0% | 0.81s | 0.84s |
|
||||
| 16000 | 11.1 | 100.0% | 100.0% | 0.0% | 100.0% | 0.0% | 1.68s | 1.81s |
|
||||
|
||||
分币种(最大窗口):BTC/ETH/SOL 各 60 笔全部 100% 命中,零偏移。
|
||||
|
||||
**结论:1m 在 2000 根窗口(1.4 天)就已完全饱和,单次计算 0.20s,假阳性 0%。**
|
||||
比 15m/30m 的 step38 结果还干净(那里有 0.7% 假阳性)。耗时对窗口严格线性
|
||||
(约 0.105ms/根),所以没有任何理由带更长的历史。
|
||||
|
||||
**这一步顺带解决了一个更重要的问题**:1m 的回测口径本身是可信的,
|
||||
`is_sure` 回撤对 1m 同样没有影响。**1m 现在唯一的风险就剩执行成本。**
|
||||
|
||||
⚠️ **延迟预算的分解**(这直接决定 1m 生死):
|
||||
|
||||
| 环节 | 实测 | 说明 |
|
||||
|---|---|---|
|
||||
| 信号计算 | **0.20s** | 2000 根窗口,可控 |
|
||||
| 走代理访问 Bitget | **约 2.4s** | 单次 REST 往返(含建连),**这才是瓶颈** |
|
||||
|
||||
计算只占延迟的一小部分,**网络是主要来源**。所以影子交易器必须:
|
||||
用 **WebSocket 订阅**而非轮询 REST 拉 K 线,并尽快把实盘迁到境外 VPS。
|
||||
否则测到的滑点全是代理的账。
|
||||
|
||||
> 为什么这一步必要:step38 只验证了 15m/30m,从没验证 1m。而窗口 4000 根
|
||||
> 对 15m 是 41 天、对 1m 只有 2.8 天,中枢的左边界效应完全不是一个量级。
|
||||
> 窗口同时牵动两头:太短则中枢被截断信号不符,太长则算得慢延迟大滑点高。
|
||||
|
||||
---
|
||||
|
||||
## 6. 接下来要做的事(按优先级)
|
||||
|
||||
### ~~第 1 步:跑完 step39,确定实时窗口~~ ✅ 已完成
|
||||
|
||||
**结果见 5.4 节。结论:影子交易器用 2000 根 1m 窗口,单次计算 0.20s。**
|
||||
完整输出在 `research/out/step39.log` 与 `step39_pit_1m.csv`,无需重跑。
|
||||
|
||||
(若日后要重跑:`python research/step39_pit_1m.py --symbols BTC,ETH,SOL
|
||||
--probe 60 --workers 3`,约 4 分钟。瓶颈不在窗口重建,而在 `run_one` 开头
|
||||
那次 120 万根 1m 的全量 `TF_DF`。)
|
||||
|
||||
### 第 2 步:向用户确认交易所(当前的阻塞项)
|
||||
|
||||
这个问题必须他回答,因为它决定框架:
|
||||
|
||||
- 留 Bitget → 只有 Hummingbot 支持,或用 ccxt 自己写执行层
|
||||
- 换 Hyperliquid / Binance / Bybit / OKX → freqtrade 和 Nautilus 都能用
|
||||
|
||||
他已选定**先只上 1m**(在我问「先从哪条腿落地」时选的 `1m_first`)。
|
||||
|
||||
### 第 3 步:写影子交易器测滑点(核心工作)
|
||||
|
||||
**关键判断:测滑点不需要任何交易框架。** 完整框架解决的是「如何可靠下单」,
|
||||
而当前的未知量是「成交价会差多少」。所以先写一个不下单的影子跑法:
|
||||
|
||||
```
|
||||
每根 1m 收盘 → 拉最新 K 线 → 算信号(窗口取第 1 步的结论)
|
||||
→ 信号触发时抓真实盘口(bid/ask + 深度)
|
||||
→ 按仓位吃单深度算出真实成交价
|
||||
→ 等下一根 K 线出来,取其开盘价(回测假设的成交价)
|
||||
→ 两者相减 = 真实滑点
|
||||
```
|
||||
|
||||
**必须把时间戳拆开记录**,否则不知道该优化哪里:
|
||||
|
||||
| 时间戳 | 含义 |
|
||||
|---|---|
|
||||
| `t_close` | K 线收盘时刻 |
|
||||
| `t_data` | 数据到手时刻 → 拉取延迟 |
|
||||
| `t_signal` | 信号算完时刻 → 计算延迟 |
|
||||
| `t_book` | 盘口快照时刻 → 下单时点 |
|
||||
|
||||
滑点应分解成三块:**延迟漂移**(`t_book` 中间价 − 次根开盘价)、
|
||||
**盘口价差**(ask − 中间价)、**深度冲击**(加权成交价 − ask)。
|
||||
预期延迟漂移是主项,价差可忽略(0.01bp)。
|
||||
|
||||
建议路径 `research/live/shadow.py`,复用 `research/lib/` 下同一套信号代码,
|
||||
这样两边数字直接可比。代码量约两三百行。
|
||||
|
||||
实现要点:
|
||||
- 数据格式必须与 `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 根超时,出场同样记录真实盘口
|
||||
- 状态要落盘,重启不能丢
|
||||
|
||||
### 第 4 步:根据滑点结果决策
|
||||
|
||||
- 滑点 ≤ 2.5bp → 1m 可行,`t>2`,可以进入真实 dry run
|
||||
- 2.5~3.9bp → 1m 勉强不亏但无统计显著性,考虑争取 60% 手动返佣或 VIP2
|
||||
- > 3.9bp → 1m 放弃,**但 5m/30m 不受影响**(余量 26bp / 89bp)
|
||||
|
||||
### 第 5 步(后续):1m 与 5m 分实例
|
||||
|
||||
用户问过「1m 和 5m 分成两个实例跑呢?」——**对,而且是硬要求**:
|
||||
freqtrade 一实例只能一个 timeframe;另有资金池隔离、统计独立、
|
||||
API 限流风险隔离三个好处。
|
||||
|
||||
⚠️ **有个坑要提前处理**:两个实例可能在同一个币上同时持反向仓位
|
||||
(1m 出三卖做空、5m 出三买做多),单向持仓模式下会互相平掉或直接报错。
|
||||
要么开对冲模式,要么两个实例分配不同币种(币种够多,分开还能看出品种间差异)。
|
||||
|
||||
---
|
||||
|
||||
## 7. 环境与数据
|
||||
|
||||
### 7.1 数据
|
||||
|
||||
- 位置:`data/binance/futures/{SYM}_USDT_USDT-{tf}-futures.feather`
|
||||
- BTC/ETH/SOL:全周期 1m~1w,2172~2543 天
|
||||
- 另有 8 个样本外币种(BNB/XRP/DOGE/ADA/AVAX/LINK/LTC/TRX):
|
||||
**48 个文件已全部校验,2020~2026-08-26,零缺口零重复**
|
||||
- 读取统一走 `research/lib/data.py` 的 `fetch_ohlcv(symbol, tf, limit)`,
|
||||
本地优先,回落到 `https://provider.jackyu66.com`(该服务只有 BTC/ETH/SOL,
|
||||
且小周期仅 90 天,别指望它)
|
||||
|
||||
### 7.2 代理
|
||||
|
||||
本地代理 `127.0.0.1:7897`。Binance 和 Bitget 的 API 都需要它。
|
||||
|
||||
### 7.3 已修过的两个 bug(别再踩)
|
||||
|
||||
1. **时间戳精度**(`lib/data.py`):不能用 `date.astype("int64")//10**6`,
|
||||
该值单位取决于列精度(`[ns]` 给纳秒、`[ms]` 给毫秒),对毫秒精度的文件
|
||||
会把时间戳砸平,再被 `drop_duplicates` 删掉九成数据。
|
||||
正确写法:`(date - pd.Timestamp("1970-01-01", tz="UTC")) // pd.Timedelta("1ms")`
|
||||
2. **相邻中枢撞同一 entry_idx**:会让下游 `set_index("entry_idx")` 抛
|
||||
`InvalidIndexError`。已在 `find_fast_bsp3` 末尾按
|
||||
`["entry_idx","occ","zone_i"]` 排序后 `drop_duplicates("entry_idx")` 去重。
|
||||
|
||||
### 7.4 跑长任务的注意事项
|
||||
|
||||
- 用 shell 工具的原生后台执行(`block_until_ms=0`),
|
||||
**不要用 `nohup`**——早期用 `nohup` 的后台任务多次莫名消失
|
||||
- 1m 全量数据(120 万根)的 `TF_DF` 约需 2 分钟,任何涉及 1m 全量的脚本
|
||||
都要预留时间
|
||||
- 多进程用 `ProcessPoolExecutor`,记得在子进程里重新
|
||||
`sys.path.insert` 并 `warnings.filterwarnings("ignore")`
|
||||
- 内存很大(用户说「随便用」),但 1m 全量 × 多进程仍可能吃掉几十 GB
|
||||
|
||||
---
|
||||
|
||||
## 8. 代码地图
|
||||
|
||||
### 8.1 研究库 `research/lib/`
|
||||
|
||||
| 文件 | 作用 |
|
||||
|---|---|
|
||||
| `data.py` | 数据层,本地 feather 优先 |
|
||||
| `fast_bsp3.py` | **核心**:自研低滞后第三类买卖点。滞后 2.2 根 |
|
||||
| `nested_level.py` | `build_htf_zones`:构建中枢,可传入已建好的 `chan` 复用 |
|
||||
| `nested_bsp.py` | `htf_fx_timeline` / `attach_htf_context`:区间套上下文。
|
||||
`confirm_ts` 已 `+period` 修正 K 线收盘时刻 |
|
||||
| `fx_signal.py` | 分型信号提取与背驰 |
|
||||
| `breakout.py` | 事件驱动回测。`run_trades` 支持 `entry_delay`/`slippage`/
|
||||
`boost_dir`(动态止盈,已验证无效) |
|
||||
|
||||
### 8.2 缠论引擎 `chanlun/`
|
||||
|
||||
- `TF_DF(df, 1, tf)` 是入口,`.dataframe` 拿到含缠论标注的 DataFrame
|
||||
- `pipeline/builders/incremental.py`:增量更新(`init_stream` / `append_bar` /
|
||||
`replace_last_bar` / `rebuild_bi_zs`)。**注释写明「最后一笔 is_sure 允许收回」**,
|
||||
这是 step38 要验证的那个隐患(已证实无影响)。
|
||||
实盘若要用增量而非全量重算,需重新验证
|
||||
- `pipeline/orchestrator.py`:`TF_DF` 方法的门面
|
||||
- `web/`:图表与分析服务,**无下单/订单管理功能**,实盘用不上
|
||||
|
||||
### 8.3 实验索引
|
||||
|
||||
| step | 一句话 |
|
||||
|---|---|
|
||||
| 1~14 | 早期探索:信号有效性、滞后测量、直接预测收益(后发现有未来函数偏差,已弃) |
|
||||
| 15~18 | 区间套雏形;`fast_bsp3` 诞生(降滞后) |
|
||||
| 19~20 | 级别配对批量扫描 + 并行化 |
|
||||
| 21 | 最优配置的尽调(尾部依赖、成本敏感) |
|
||||
| 22 | 执行压力:收盘价 vs 次根开盘、滑点 |
|
||||
| 23 | **费率分档 + 刷量测算**(1m 经济性的数据来源) |
|
||||
| 24 | 信号聚簇:同一大级别分型下的多信号是否独立(是) |
|
||||
| 25 | 同中枢重复入场(只做首次) |
|
||||
| 26 | **中枢阶梯序列**(趋势 vs 盘整,印证缠论定义) |
|
||||
| 27 | 动态止盈(无效) |
|
||||
| 28 | **全级别矩阵**(最优配置来源) |
|
||||
| 29 | 信号漏斗诊断 + 参数敏感性 |
|
||||
| 30/31 | 引擎原生 B3/S3 对比 + 方向反转诊断(引擎信号因滞后而亏损) |
|
||||
| 32 | **消融研究**(alpha 来自中枢上下文,非触发动作) |
|
||||
| 33 | `require_touch=False` 的影响(显著提升) |
|
||||
| 34 | **tol 扫描**(滞后与收益严格单调) |
|
||||
| 35 | **高收益审计**(口径、滑点、并发) |
|
||||
| 36 | 偏差审计(生效时刻、多空、时间样本外) |
|
||||
| 37 | **跨品种样本外**(8 个新币) |
|
||||
| 38 | **时点重建**(无未来函数) |
|
||||
| 39 | **1m 时点重建 + 窗口扫描**(新写,待跑完) |
|
||||
|
||||
输出都在 `research/out/`。**2026-08-27 清理过一轮**:step1~20 的输出(早期方法论
|
||||
已被推翻,含未来函数偏差)与旧口径备份一并删除,只留支撑当前结论的证据。
|
||||
脚本都还在,需要时可重跑。step31 及之后的 `.py` 都在 `research/` 下。
|
||||
|
||||
---
|
||||
|
||||
## 9. 与用户协作的注意事项
|
||||
|
||||
- **用中文回复**(用户规则)
|
||||
- 用户技术判断力强,会主动纠正方向(他纠正过我对区间套的理解、
|
||||
指出内存回收、指出结论印证缠论定义)。**他的领域直觉值得认真对待**
|
||||
- 他反复强调**不要再调参**,要落地验证
|
||||
- 他讨厌长时间等待,早期多次问「还在跑吗」「好了吗」。
|
||||
长任务要后台跑并主动汇报进度,不要让他干等
|
||||
- 报数字时**必须交代口径**(复利/杠杆/费率),否则会误导
|
||||
|
||||
---
|
||||
|
||||
## 10. 待办清单
|
||||
|
||||
- [x] **step39**:1m 时点重建 + 窗口扫描 → **2000 根窗口饱和,计算 0.20s,
|
||||
假阳性 0%,1m 回测口径可信**
|
||||
- [ ] **向用户确认交易所**(阻塞后续框架选择,这是当前第一件事)
|
||||
- [ ] 写 `research/live/shadow.py` 影子交易器,测 1m 真实滑点。
|
||||
**务必用 WebSocket 而非 REST 轮询**——代理下单次 REST 往返约 2.4s,
|
||||
而信号计算只要 0.20s,网络是延迟主项
|
||||
- [ ] 收集 1~2 周影子数据,与回测口径逐笔对比
|
||||
- [ ] 按 6.4 的判据决策 1m 是否可行
|
||||
- [ ] 若可行:选框架(Bitget→Hummingbot)做真实 dry run
|
||||
- [ ] 补一项研究阶段的缺口:**资金费率**从未计入任何回测。
|
||||
30m 腿平均持仓 6.5 小时会跨结算点,需要评估影响
|
||||
- [ ] 补:同时持仓的保证金约束也未建模(组合有仓位时间仅 8.6%,
|
||||
预计影响小,但没算过)
|
||||
Reference in New Issue
Block a user