BTC滞后因子设计原理

BTC 滞后因果因子(BTC Lagged Causal Factor)

1. 设计动机

加密货币市场存在一个被广泛观察到的现象:BTC 的剧烈波动会以 10-20 分钟的延迟传导到山寨币

这种传导效应的成因包括:

  1. 流动性级联:BTC 剧烈波动触发大量清算 → 做市商全市场撤单/对冲 → 山寨币流动性骤降 → 随后山寨币出现同向剧烈波动
  2. 套利传导:量化套利策略在 BTC 波动后调整跨品种仓位,价格冲击逐步从 BTC 扩散到山寨币
  3. 情绪传染:BTC 作为市场风向标,其异常波动触发恐慌/贪婪情绪蔓延

这意味着:如果在 BTC 刚发生暴涨暴跌后,对山寨币开仓(特别是配对交易的单腿),极有可能在山寨币随后的跟随波动中被止损。

核心思路:利用 BTC 波动对山寨币的 领先因果关系,在 BTC 异常波动后主动收紧山寨币的开仓过滤阈值,等传导效应消退后再恢复正常敏感度。


2. 在系统中的位置

4 层过滤架构:

Layer 0 (硬过滤) ─ BOCPD 趋势检测     ← 判断是否处于趋势 regime
Layer 1 (软过滤) ─ ER 持续动量确认      ← 确认趋势是否持续
Layer 2 (硬过滤) ─ CUSUM 暴涨暴跌检测   ← ★ BTC 因子在此层生效
Layer 3 (仲裁)  ─ 价差均值回归仲裁      ← 最终仲裁

BTC 因子作用于 Layer 2(暴涨暴跌检测),通过动态调整 CUSUM 阈值来实现:

  • BTC 平静时 → CUSUM 阈值保持默认 → 正常开仓灵敏度
  • BTC 异常波动后 → CUSUM 阈值被收紧(降低) → 更容易触发过滤 → 暂时阻止山寨币开仓

3. 算法详解

3.1 数据采集:Stress 指标的积累

每当任意币种(包括 BTC 自身)有新 K 线到来时,系统会:

  1. 计算该币种的 Huber-CUSUM 累积值(正向 S+ 和负向 S-)
  2. max(S+, S-) 作为该币种当前的 stress 值
  3. 将 stress 值追加到该币种的历史队列中
# 每根新 K 线更新后(update 方法内)
sp, sn = self._cusum_state.get(symbol, (0.0, 0.0))
self._btc_stress_history[symbol].append(max(sp, sn))

其中 CUSUM 值的计算采用 Huber 鲁棒化处理:

# Rogers-Satchell 波动率估计
rs_vol = sqrt(RS_EMA)

# 标准化收益 z 值(Huber clip 在 ±5.0)
z_raw = (close - prev_close) / prev_close / rs_vol
z = copysign(min(|z_raw|, 5.0), z_raw)

# CUSUM 递推(自适应 drift)
S+ = max(0, S+_prev + z - drift)
S- = max(0, S-_prev - z - drift)

关键点:CUSUM 是一个有记忆的累积统计量。单根 K 线的小幅波动会被 drift 项吸收归零,但连续多根同向大幅波动会使 CUSUM 值持续攀升。这使得 stress 指标能区分"正常波动"和"持续剧烈波动"。

3.2 滞后回看:提取 BTC 近期最大 stress

当需要判断某个山寨币是否可以开仓时(_check_spike 方法),系统会:

  1. 跳过 BTC 自身(BTC 不需要参考自己)
  2. 从 BTC 的 stress 历史队列中取 最近 3 根 K 线(= 15 分钟,5 分钟 K 线 × 3)
  3. 取这 3 根中的 最大值 作为 btc_stress
if symbol != self._market_ref:
    btc_hist = self._btc_stress_history.get(self._market_ref)
    btc_stress = max(list(btc_hist)[-3:])  # lag = 3 根 K 线

为什么是 lag=3(15 分钟)

实证研究表明 BTC 到主流山寨币的波动传导延迟在 10-20 分钟之间。取 3 根 5 分钟 K 线(15 分钟窗口)能覆盖大部分传导延迟,同时避免窗口过长导致误判。

为什么取 max 而非 mean

传导效应由 BTC 的峰值冲击驱动,不是平均水平。一根极端 K 线就足以触发后续传导,所以用 max 更准确。

3.3 阈值收紧:指数衰减缩放因子

btc_stress 超过阈值时,计算一个 缩放因子 sf 来收紧 CUSUM 阈值:

btc_stress_thresh = 2.0   # stress 触发阈值
decay_rate = 0.3           # 衰减速率
factor_min = 0.7           # 最大收紧幅度(阈值最低缩到 70%)

if btc_stress > btc_stress_thresh:
    excess = btc_stress - btc_stress_thresh
    sf = max(factor_min, exp(-decay_rate * excess))
    eff_cusum_up   *= sf   # 收紧暴涨阈值
    eff_cusum_down *= sf   # 收紧暴跌阈值

缩放因子的数学形式:

sf = max(0.7, e^(-0.3 × (btc_stress - 2.0)))

行为特性:

BTC stress 值 excess sf = e^(-0.3×excess) 实际 sf(clamp) 阈值缩放效果
≤ 2.0 0 1.0(不触发) 无影响
2.5 0.5 0.861 0.861 阈值降至 86%
3.0 1.0 0.741 0.741 阈值降至 74%
3.5 1.5 0.638 0.700 阈值降至 70%(触底)
4.0+ 2.0+ < 0.549 0.700 阈值降至 70%(触底)

设计要点

  • 指数衰减(而非线性):BTC stress 轻微超标时温和收紧,严重超标时快速收紧,符合市场冲击的非线性传导特性
  • 下限 0.7:阈值最多降到原来的 70%,防止过度收紧导致完全无法开仓
  • 阈值 2.0:CUSUM 累积值达到 2.0 意味着 BTC 已经出现了显著超过正常波动的异常运动

3.4 实际过滤判定

收紧后的阈值直接参与 Layer 2 的过滤判定:

# strength=0.5 时的默认阈值
eff_up   = 3.5   # 暴涨阈值
eff_down = 2.5   # 暴跌阈值

# BTC 因子收紧后(假设 sf=0.75)
eff_up   = 3.5 × 0.75 = 2.625
eff_down = 2.5 × 0.75 = 1.875

# 过滤判定
if direction == 'short' and CUSUM+ >= eff_up:   → 阻止做空(暴涨中)
if direction == 'long'  and CUSUM- >= eff_down:  → 阻止做多(暴跌中)

原本山寨币的 CUSUM 值需要达到 3.5 才会被过滤,BTC 异常后只需达到 2.625 就会触发过滤。这意味着更早地阻止了在传导波动中的错误开仓


4. 与跨层修正的叠加

BTC 因子和 Layer 0 的 BOCPD 趋势概率可以叠加生效:

# 第一步:BTC 因子收紧
eff_up *= sf_btc                    # 例如 ×0.75

# 第二步:BOCPD 跨层修正(如果 Layer 0 检测到趋势)
if bocpd_trend_prob > 0.5:
    adj = 1.0 - 0.2 × (bocpd_trend_prob - 0.5)
    eff_up *= adj                   # 例如再 ×0.9

# 最终阈值 = 原始 × sf_btc × adj

这意味着:BTC 暴跌 + 山寨币自身也处于下行趋势 时,过滤阈值会被双重收紧,对开仓的保护最为严格。这正是最危险的市场环境。


5. 完整数据流

时间线(5min K 线)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

t=0   BTC 新 K 线到来
      │
      ├─ 计算 BTC 的 RS 波动率 & Huber-CUSUM
      ├─ stress = max(S+, S-) = 3.2
      └─ 追加到 btc_stress_history[BTC]

t=5   山寨币 X 新 K 线到来,策略尝试开空仓
      │
      ├─ 计算 X 的 CUSUM: S+ = 2.8
      ├─ 查询 BTC 最近 3 根 stress: [3.2, 1.5, 1.0]
      ├─ btc_stress = max = 3.2 > 2.0 → 触发
      ├─ excess = 1.2, sf = max(0.7, e^(-0.36)) = 0.698 → 0.700
      ├─ eff_up = 3.5 × 0.70 = 2.45
      ├─ S+(2.8) >= eff_up(2.45) → 阻止做空
      └─ 日志: "Layer2-暴涨不做空: CUSUM+=2.80>=2.45 BTC(lag=3)->x0.70"

t=20  BTC 恢复平静,stress 历史中最近 3 根均 < 2.0
      │
      ├─ btc_stress = max(0.8, 0.5, 1.2) = 1.2 < 2.0
      ├─ BTC 因子不触发,eff_up 保持 3.5
      └─ 正常判定:S+(1.5) < 3.5 → 允许开仓

6. 参数一览

参数 含义 类型
market_ref_symbol "BTC" 参考基准币种 可配置
btc_stress_lag 3 回看 K 线数量(= 15 分钟) 硬编码常量
btc_stress_thresh 2.0 stress 触发阈值 硬编码常量
btc_decay_rate 0.3 指数衰减速率 硬编码常量
btc_stress_factor_min 0.7 缩放因子下限(最大收紧 30%) 硬编码常量

其中只有 market_ref_symbol 是外部可配置参数(通过 strength 元参数无法控制,因为参考币种本身不是松紧度问题)。其余 4 个参数作为算法常量硬编码在 MomentumFilter.__init__ 中。


7. 设计权衡

为什么不直接用 BTC 价格变化率?

CUSUM stress 比单根 K 线的价格变化率更稳健:

  • 抗噪声:drift 项过滤掉正常波动,只有持续异常才会累积
  • 有记忆:连续 3 根中等幅度下跌比单根大跌更危险,CUSUM 能捕捉这种"持续冲击"
  • Huber 鲁棒化:z 值 clip 在 ±5.0,防止极端异常值(如交易所闪崩)污染指标

为什么不用相关系数/Granger 因果检验?

  • 相关系数是静态的,无法反映"此刻 BTC 是否正在剧烈波动"
  • Granger 因果检验需要大量历史样本且结论不实时
  • CUSUM stress 是实时计算的,能立即反映 BTC 的当前市场状态

为什么下限是 0.7 而非更低?

阈值缩到 70% 以下会导致正常市场波动也频繁触发过滤,错过大量合理的开仓机会。0.7 是在"保护力度"和"策略可用性"之间的平衡点。


8. 源码位置

模块 位置 说明
参数定义 momentum_filter.py:451-454 4 个 BTC 因子常量
状态存储 momentum_filter.py:481 _btc_stress_history 字典
Stress 积累 momentum_filter.py:797-801 update() 中追加 stress 值
因子生效 momentum_filter.py:704-713 _check_spike() 中阈值收紧
配置入口 config.pymomentum_market_ref_symbol 外部可配置的参考币种

Read more

跑步的技巧(滚动落地)

“滚动落地(rolling contact / rolling foot strike)”不是一种教条式的“脚法”,而是一种 让冲击沿着整只脚、整条后链逐级传递的落地机制。 它的核心不是“你先用哪儿着地”,而是: 你的脚落地之后,冲击是不是像轮子一样滚过去,而不是像锤子一样砸下去。 这就是滚动落地的本质。 一、什么叫“滚动落地”? 你可以把它理解成两种完全不同的落地方式: 1. 砸地(撞击式) 脚像锤子一样拍到地上: * 要么后跟先砸 * 要么前掌先戳 * 冲击集中在一个点 * 一个结构瞬间吃掉大部分载荷 结果就是: * 后跟砸 → 膝盖难受 * 前掌戳 → 前脚掌磨烂 * 都不是长跑友好模式 这叫 撞击式着地(impact strike)。 2. 滚地(滚动式) 脚像轮胎一样“滚”过地面: * 不是某一点硬砸 * 而是外侧中足先轻触 * 再向前滚到前掌 * 最后从大脚趾蹬离

By SHI XIAOLONG

AMI的优越性

世界模型(World Models)的具体例子 如下,我按类型分类,便于理解。每类都附带实际实现、演示效果和应用场景。 1. Yann LeCun / Meta 的 JEPA 系列(最直接对应“世界模型”概念) 这些是 LeCun 主张的非生成式抽象预测世界模型代表。 * I-JEPA(Image JEPA,2023) 输入一张图像,模型把不同区域(context 和 target)编码成抽象表示,然后预测 target 的表示(不在像素级别重建)。 例子:给定一张遮挡了部分物体的图片,模型能预测“被遮挡物体的大致位置和属性”,构建对物体持久性和空间关系的理解。 这是一个“原始世界模型”,能学习物理常识(如物体不会凭空消失)。 * V-JEPA / V-JEPA 2(Video JEPA,

By SHI XIAOLONG

什么是:“世界模型(World Models)”

世界模型(World Models) 是人工智能领域的一个核心概念,尤其在 Yann LeCun 等研究者推动的下一代 AI 架构中占据中心位置。它指的是 AI 系统在内部构建的对现实世界的抽象模拟或内部表示,让机器能够像人类或动物一样“理解”物理世界、预测未来、规划行动。 简单比喻 想象你闭上眼睛也能“看到”房间里的物体会如何移动、碰撞或掉落——这就是你大脑里的世界模型。AI 的世界模型就是类似的“数字孪生”(digital twin)或“内部模拟器”:它不是简单记住数据,而是学习世界的动态、因果关系和物理直觉(如重力、物体持久性、遮挡、因果等)。 为什么需要世界模型? 当前主流的大型语言模型(LLM) 擅长处理文本(统计模式预测),但存在根本局限: * 缺乏对物理世界的真正理解 → 容易“幻觉”、无法可靠规划。 * 样本效率低 → 人类/

By SHI XIAOLONG

K线周期可配置化设计方案

K线周期可配置化设计方案 1. 背景与目标 当前 Beta 套利策略的 K 线周期硬编码为 "1h",分散在多个文件中。需要: 1. 将 K 线周期从 1h 改为 2h 2. 提取为环境变量 BETA_ARB_KLINE_INTERVAL,使其可在 .env 中配置 2. 影响范围分析 2.1 需要修改的文件(共 6 个) 文件 硬编码位置 修改内容 src/trading/config.py BetaArbConfig dataclass 新增 kline_interval 字段,

By SHI XIAOLONG