全系统key配对升级 bug14
配对维度优化后系统缺陷与不足分析
本文档记录在全系统 Key 已改为 (symbol, base_symbol) 配对维度后,当前仍存在的缺陷与不足,涵盖数据库、脚本、统计与一致性四类问题。
一、当前已正确落地的部分(简要)
- 核心交易链路:
position_manager.py、strategy.py、orchestrator.py、trade_repository.py的仓位/信号/策略状态均按PairKey = (symbol, base_symbol)存储与查询。 - 库表与迁移:
trading_signals、pair_positions、analysis_results均有symbol+base_symbol;20260219_fix_pairkey_indexes.sql已把索引与压缩分段统一为 PairKey。 - 黑名单与配置:
symbol_blacklist表与BlacklistRepository按(symbol, base_symbol)读写;配置层is_symbol_allowed/is_close_disabled支持币种级与配对级。 - 实时服务:配对缓存
alt → [bases],分析循环对每个base_sym调用_analyze_and_alert(..., base_symbol=base_sym),写入分析结果时带base_symbol。 - 数据自愈:
data_healing/orchestrator.py使用(self.symbol, self.base_symbol)查询analysis_results。
二、缺陷与不足
1. 历史压缩 Chunk 与 PairKey 不一致
位置:database/migrations/20260219_fix_pairkey_indexes.sql 末尾说明。
问题:仅新写入的数据会按 (symbol, base_symbol) 分段压缩;已压缩的历史 chunk 仍使用旧分段方式(若此前为 symbol 单列分段,则与当前设计不一致)。
影响:历史数据压缩段内可能混多个 base,按配对查询/压缩效率与语义不完全一致;新 chunk 与旧 chunk 行为不一致。
建议:若需全库一致,对受影响的 hypertable 执行 decompress_chunk + 再 compress_chunk(或按 TimescaleDB 文档做 chunk 重压),并评估 I/O 与锁;或在文档中明确“仅新数据为 PairKey 压缩”的边界。
2. 分析/回测/脚本中 analysis_results 未按配对查询
问题:多处对 analysis_results 的查询仍只按 symbol 过滤,未带 base_symbol。同一 symbol 对应多个 base 时,会混用不同配对的数据,与“全系统 Key 为配对维度”不一致。
典型位置与修改方向:
| 文件 | 说明 |
|---|---|
src/scripts/backtest_base.py |
fetch_analysis_data() 仅 WHERE symbol = %s,回测若支持多配对需增加 base_symbol 参数并条件 |
src/scripts/backfill_analysis_results.py |
get_existing_kline_times() 仅 WHERE symbol = %s,补数若按配对跑需传入并过滤 base_symbol |
src/scripts/query_analyze_result/query_eth_zscore.py |
WHERE symbol = %s,应按配对查询或明确“单 symbol 聚合”的语义 |
src/scripts/query_analyze_result/query_purr_zscore.py |
同上 |
src/scripts/query_analyze_result/check_missing_purr_zscore.py |
同上 |
src/scripts/query_analyze_result/check_buffer_continuity.py |
WHERE symbol = %s AND zscore_4h IS NOT NULL,若按配对校验需加 base_symbol |
src/scripts/fix_buffer_loading.py |
WHERE symbol = %s AND zscore_4h IS NOT NULL,同上 |
src/scripts/optimize_adaptive_zscore.py / optimize_adaptive_zscore_v2.py |
查询 analysis 仅按 symbol,优化结果应按配对解读或按配对查询 |
src/scripts/validate_data_consistency.py |
多处 AND symbol = %s,若校验“按配对一致”需增加 base_symbol 条件 |
建议:
- 凡“按配对”的统计/回测/补数/校验,统一改为
WHERE symbol = %s AND base_symbol = %s(或等价),并对外接口增加base_symbol参数(或明确脚本仅单配对使用)。 - 若部分脚本故意做“单 symbol 多 base 聚合”,在注释或文档中写明,避免与配对维度混淆。
3. daily_trading_stats 无配对维度
位置:database/init_timescaledb.sql 表 daily_trading_stats,主键 (stat_date, network);trade_repository.py 的 update_daily_stats() 仅按日+网络累加。
问题:无 symbol/base_symbol 或等价配对字段,无法按配对做每日统计(如每配对信号数、开平次数、实现盈亏)。
影响:运营/风控无法按配对做日报或历史对比;与“全系统 Key 为配对维度”的统计视角不统一。
建议(二选一或组合):
- 若需按配对统计:增加“配对每日统计”表(例如
daily_pair_stats(stat_date, network, symbol, base_symbol, ...)),并在信号/成交写库时更新;或 - 保持现有表为“全局汇总”,在文档中明确“日报为全局维度,不做配对拆分”,并在需要时通过
trading_signals/pair_positions等按配对聚合做离线报表。
4. 孤儿收纳时 is_close_disabled 的语义
位置:position_manager.py 中 _collect_orphan_candidates() 调用 is_close_disabled(coin_to_symbol(coin)),仅传了 symbol(等价于 base_symbol="")。
现状:对“真孤儿”(单腿、无配对)而言,用“该 symbol 是否禁止平仓”是合理的(币种级)。
潜在不足:若后续把“配对孤儿”(交易所有两腿但 DB 无记录)也通过同一路径收纳,是否应传 (original_alt, original_base) 需再确认,以符合配对级 close_disabled 的语义。
建议:在注释中写明“当前仅用于单腿孤儿,等价于 base_symbol=''”;若以后支持配对孤儿收纳,在此处改为传入配对并调用 is_close_disabled(symbol, base_symbol)。
5. 索引命名与 analysis_results 无 timeframe 列
位置:database/init_timescaledb.sql 中索引 idx_analysis_results_symbol_timeframe 建在 (symbol, base_symbol, analysis_time DESC)。
问题:analysis_results 表并无 timeframe 列,实际是 PairKey + 时间;索引名易让人误以为按“周期”区分。
建议:将索引重命名为例如 idx_analysis_results_pair_time,并在迁移或 init 中统一(若存在多处创建需一并改),避免后续维护误解。
6. trade_orders 压缩维度与配对的关系
位置:database/init_timescaledb.sql 中 trade_orders 压缩分段为 coin。
说明:订单表无 symbol/base_symbol,通过 position_id 关联 pair_positions;按 coin 压缩是合理的设计选择,并非错误。
建议:若希望“按配对查某段时间订单”,需通过 position_id → pair_positions(symbol, base_symbol) 做 JOIN;在架构/文档中注明“订单表不存配对键,配对维度通过仓位表关联”即可。
7. 小结与优先级建议
flowchart LR
subgraph high [高优先级]
A[脚本 analysis_results 按配对查询]
B[历史压缩 chunk 一致性策略]
end
subgraph mid [中优先级]
C[daily_trading_stats 是否按配对]
D[索引命名与文档]
end
subgraph low [低优先级]
E[孤儿收纳 close_disabled 注释]
end
A --> C
B --> D
- 高:统一所有“按配对”的 analysis 查询与回测/补数/校验脚本(避免多 base 混用);明确历史压缩 chunk 的处理策略(重压或文档约定)。
- 中:决定是否需要按配对的每日统计并落地表或聚合方式;修正
idx_analysis_results_*命名并补充说明。 - 低:在孤儿收纳处补充
is_close_disabled的语义注释,便于后续扩展配对孤儿逻辑。
以上为当前系统在“全系统 Key 改为配对维度”之后仍存在的缺陷与不足,以及可执行的改进方向。