# Symbol Coverage Pitfall (2026-07-10 实战) ## 症状 Cron 推送"💤 静默: 无持仓, 无变化"或"💤 无持仓, 跳过做T",但实际账户**持有 1.45 张 SPCX**(或其他币种)。 **用户原话**: "一直在提示吗... 这个定时任务没改名称, 是币圈还是股票"。后续他从来没问过是否持仓,但 agent 看到 cron 消息也没去查实际持仓,以为没问题。 ## 根因 `okx_t_monitor.py` 的 `DEFAULT_SYMBOLS` 是静态列表: ```python DEFAULT_SYMBOLS = ['ETH', 'BTC', 'SOL', 'DOGE', 'XRP'] # 漏了 SPCX ``` `monitor()` 循环每个币种拉 OKX 持仓,**只在循环里的币种才被监控**。SPCX 不在列表里 → 永远查不到 → 被视为"无持仓"。 `SYMBOL_SPECS` 也必须包含该币种,否则 `KeyError` 直接崩。 **变种 1**: 用户开了小众币种(非主流)做T,监控不到 **变种 2**: 用户开了 OKX 交易但用 ccxt 报"unexpected type" 失败的币种 ## 修复:三步 **1. 把持仓币种加进 `DEFAULT_SYMBOLS`**: ```python DEFAULT_SYMBOLS = ['ETH', 'BTC', 'SOL', 'DOGE', 'XRP', 'SPCX'] # + 持仓币 ``` **2. 把持仓币种加进 `SYMBOL_SPECS`**(避免 KeyError): ```python SYMBOL_SPECS = { 'ETH': {'ct_val': 0.1, 'leverage': 25, 't_qty': 0.05, 'min_sz': 0.01}, ... 'SPCX': {'ct_val': 1.0, 'leverage': 5, 't_qty': 0.5, 'min_sz': 0.01}, # ⚠️ t_qty 是"每次做T张数", NOT "总持仓" } ``` **3. (推荐) 自动检测持仓币种**: ```python def get_monitored_symbols(): """从 OKX 实际持仓 + 预设列表合并""" syms = set(DEFAULT_SYMBOLS) try: positions = ex.fetch_positions() for p in positions: if abs(float(p.get('contracts', 0))) > 0.001: inst_id = p.get('instId', '') # e.g. "SPCX-USDT-SWAP" sym = inst_id.replace('-USDT-SWAP', '') syms.add(sym) except Exception as e: print(f"⚠️ 拉持仓失败: {e}") return sorted(syms) ``` `monitor()` 第一行调用 `DEFAULT_SYMBOLS = get_monitored_symbols()`。 ## 防御性编程 **新加币种时(尤其是用户/交易员信号里出现的)**:立刻同步 `DEFAULT_SYMBOLS` 和 `SYMBOL_SPECS`。否则: - 信号来了推不到做T → 错过机会 - 平仓信号到了不被检测 → 持仓过夜 - 浮盈大幅波动不报警 → 用户不知道风险 **最稳**:用 `get_monitored_symbols()` 自动合并 + 当新币种出现时让用户填 SYMBOL_SPECS(告警一次后自动用默认 0.01 张)。 ## 实测教训 **SPCX 1.45 张空 @ 149.15** 在 2026-07-10 上午被实测发现时,DEFAULT_SYMBOLS 没有,SYMBOL_SPECS 也没有,导致: 1. cron 跑 N 次,显示"💤 无持仓" 2. 实际有 SPCX 持仓但**变化检测 + 做T 触发都跳过** 3. 浮盈变化根本不被监控 4. 价格触及 buy1/buy2/sell1/sell2 也不会触发平仓 **修复后**: - DEFAULT_SYMBOLS += ['SPCX'] - SYMBOL_SPECS['SPCX'] = {'ct_val': 1.0, 'leverage': 5, 't_qty': **0.5**(不是 1.45!), 'min_sz': 0.01} - 下次 cron 跑 → 检测 SPCX 价格触及 149.15 ± ATR×0.7 → 自动推送"📍 价格触及"或成交 ## t_qty 重要澄清 `t_qty` 是**每次做T张数**,不是总持仓大小。 - SPCX 持仓 1.45 张,t_qty = 0.5 → 每次 low/high 0.5 张,做满要 3 次 - 1.45 张仓位 + 做 T 一次就 1 张 → 仓位瞬间变化 67%,太大 **规则**:`t_qty ≤ 总仓位 × 0.5`(单笔不超过一半仓位)。 ## 相关决策 - v2.1 C 方案"有变化时推"上线后,**静默覆盖了**"持仓不在列表"的 bug——之前会推"💤 无持仓"噪音,现在静默不推,bug 隐藏更深。 - **必须**每 24 小时或新币种出现时,核对 DEFAULT_SYMBOLS 是否包含全部持仓币种 - 实战:应该用 `get_monitored_symbols()` 而不是静态列表