Adaptive Z-Score 标准差正则化设计方案(规避标准差过小带来的计算值爆炸)
Adaptive Z-Score 标准差正则化设计方案
版本: v1.0 | 日期: 2026-03-07 | 分支: std_adaptive
1. 问题背景
1.1 核心公式
Adaptive Bollinger Z-Score 策略的核心计算:
adaptive_z = (z4h - ema) / std
其中:
z4h: 协整分析产出的 4 小时 Z-Score(衡量配对价差偏离程度)ema: z4h 的指数移动平均(跟踪"当前正常水位")std: z4h 的滚动标准差(衡量近期波动率,Welford 增量算法)
1.2 问题现象
当市场进入低波动期(盘整/窄幅震荡),z4h 变化极小,导致 std → 0。此时:
adaptive_z = (z4h - ema) / 0.001 → 数千甚至数万
后果:
- az 值爆炸,轻松突破任何阈值(如 threshold=2.9)
- 产生大量虚假入场信号
- 实际价差偏离极小,无套利空间,交易成本无法覆盖
- 以 PURR|HYPE 配对为例:std=0.01 时,z4h 仅偏离 ema 0.03 就产生 az=3.0 的"强信号",但对应的实际价格偏离不到 0.1%,扣除手续费后必然亏损
1.3 问题本质
这是统计学中经典的除零/小分母放大效应。在信噪比极低时,标准化操作将噪声放大为虚假信号。需要一种机制确保分母有合理下界,同时保持高波动期的信号灵敏度。
2. 方案选型
2.1 候选方案对比
| 方案 | 公式 | 优点 | 缺点 |
|---|---|---|---|
| 硬下限 | effective_std = max(std, floor) |
简单直观 | std 在 floor 附近产生不连续跳变,信号突变 |
| 线性混合 | effective_std = w·std + (1-w)·prior |
可控 | 需额外调权重 w,两个超参数 |
| 方差加法正则化 | effective_std = √(var + floor²) |
平滑过渡、单参数、等价 L2/贝叶斯先验 | 需回测确定 floor 值 |
| 自适应阈值 | threshold = base + k/std |
从阈值端解决 | 阈值随 std 变化难以直观理解 |
2.2 最终选择:方差加法正则化
effective_std = √(sample_variance + floor²)
选择理由:
- 数学等价性:等价于对方差施加 L2 正则化(Ridge Regression),在统计学和机器学习中是处理小方差/奇异矩阵的标准做法
- 贝叶斯解释:等价于对方差设置 Inverse-Gamma 先验,floor² 为先验方差的下界。即"在没有足够证据(数据)时,我相信波动率不会低于 floor"
- 平滑过渡:当 std 从 0 增大时,effective_std 从 floor 平滑过渡到 std(无跳变、无拐点)
- 单参数:只需调一个
std_floor,无额外权重或窗口参数 - 行业标准:广泛应用于金融风控(VaR 计算)、信号处理(Wiener 滤波)、贝叶斯推断
3. 数学原理
3.1 正则化公式推导
设 z4h 序列的滚动样本方差为 $\sigma^2_{sample}$,正则化后的有效方差为:
$$\sigma^2_{eff} = \sigma^2_{sample} + \sigma^2_{floor}$$
有效标准差:
$$\sigma_{eff} = \sqrt{\sigma^2_{sample} + \sigma^2_{floor}}$$
正则化后的 adaptive_z:
$$az_{reg} = \frac{z_{4h} - \text{ema}}{\sigma_{eff}} = \frac{z_{4h} - \text{ema}}{\sqrt{\sigma^2_{sample} + \sigma^2_{floor}}}$$
3.2 极端情况分析
| 场景 | 条件 | effective_std | adaptive_z 行为 |
|---|---|---|---|
| 极低波动 | std ≈ 0 | ≈ floor | az 被压制到合理范围 |
| 正常波动 | std ≈ floor | ≈ 1.41 × floor | az 略有衰减 |
| 高波动 | std >> floor | ≈ std | 几乎无影响,保留原始灵敏度 |
3.3 与 L2 正则化的等价性
在 Ridge 回归中,损失函数为:
$$L = |y - X\beta|^2 + \lambda|\beta|^2$$
对方差估计做加法正则化 $\sigma^2_{eff} = \sigma^2 + \lambda$ 与 Ridge 的正则项结构相同。floor² 即正则化强度 λ,控制"对小方差的不信任程度"。
4. 参数标定:回测验证
4.1 回测配置
- 标的: PURR/USDC:USDC vs HYPE/USDC:USDC
- 数据: 最近 30 天,8255 个 5 分钟数据点
- 固定参数:
- STD_WINDOW = 72(滚动窗口)
- MIN_ZSCORE_ABS = 0.25(z4h 绝对值过滤)
- STOP_LOSS = 30%
- MAX_HOLD_HOURS = 24h
- REVERSION_FACTOR = 0.0(纯止损/超时退出)
- COOLDOWN = 15 min
- 平仓逻辑: 使用 adaptive_z 判断(与实盘一致),非 z4h 原始值
4.2 EMA=72 回测结果(主参数)
Threshold = 2.9(生产参数)
| floor | 交易数 | 胜率 | 累计收益 | 盈亏比 | 最大回撤 |
|---|---|---|---|---|---|
| 0.00 | 27 | 37.0% | -96.09% | 0.42 | 108.83% |
| 0.10 | 27 | 37.0% | -95.28% | 0.43 | 108.02% |
| 0.20 | 24 | 41.7% | -48.11% | 0.51 | 70.96% |
| 0.24 | 21 | 47.6% | +3.73% | 1.17 | 39.17% |
| 0.25 | 21 | 52.4% | +9.57% | 1.04 | 31.78% |
| 0.28 | 19 | 57.9% | +34.66% | 1.60 | 15.31% |
| 0.30 | 18 | 61.1% | +59.56% | 2.85 | 10.66% |
| 0.32 | 17 | 70.6% | +76.10% | 2.71 | 9.05% |
| 0.35 | 15 | 66.7% | +48.37% | 2.27 | 13.50% |
Threshold = 2.5
| floor | 交易数 | 胜率 | 累计收益 | 盈亏比 | 最大回撤 |
|---|---|---|---|---|---|
| 0.00 | 27 | 40.7% | -72.77% | 0.49 | 85.51% |
| 0.20 | 26 | 38.5% | -62.53% | 0.50 | 82.68% |
| 0.28 | 21 | 47.6% | +3.93% | 1.14 | 39.37% |
| 0.30 | 20 | 55.0% | +21.48% | 1.21 | 22.36% |
| 0.35 | 17 | 64.7% | +54.53% | 2.25 | 12.67% |
Threshold = 2.0
| floor | 交易数 | 胜率 | 累计收益 | 盈亏比 | 最大回撤 |
|---|---|---|---|---|---|
| 0.00 | 28 | 35.7% | -96.49% | 0.45 | 109.23% |
| 0.28 | 24 | 37.5% | -30.00% | 0.82 | 56.30% |
| 0.30 | 23 | 34.8% | -25.56% | 0.89 | 49.29% |
| 0.35 | 21 | 42.9% | -3.73% | 1.03 | 30.26% |
4.3 EMA=36 回测结果(对照组)
Threshold = 2.9
| floor | 交易数 | 胜率 | 累计收益 | 盈亏比 | 最大回撤 |
|---|---|---|---|---|---|
| 0.00 | 27 | 48.1% | -5.93% | 0.96 | 20.26% |
| 0.10 | 27 | 55.6% | +13.06% | 1.01 | 21.94% |
| 0.30 | 20 | 60.0% | +4.28% | 0.76 | 27.27% |
| 0.32 | 18 | 72.2% | +16.55% | 0.69 | 15.44% |
| 0.35 | 17 | 76.5% | +18.70% | 0.55 | 23.65% |
Threshold = 2.0
| floor | 交易数 | 胜率 | 累计收益 | 盈亏比 | 最大回撤 |
|---|---|---|---|---|---|
| 0.00 | 28 | 50.0% | +5.03% | 1.10 | 23.30% |
| 0.10 | 28 | 57.1% | +17.76% | 1.05 | 18.70% |
| 0.15 | 28 | 60.7% | +23.74% | 0.95 | 33.36% |
| 0.35 | 22 | 63.6% | +37.80% | 1.79 | 9.70% |
4.4 回测结论
- EMA=72 有明确的稳健区间:floor=0.28~0.32 在 threshold=2.5 和 2.9 下均盈利,是跨参数稳健区间
- EMA=36 无稳定规律:各 threshold 下最优 floor 差异大(0.00/0.10/0.35 交替最优),不具备参数稳健性
- floor=0.0(无正则化)在 EMA=72 下全面亏损:threshold=2.0/2.5/2.9 均为负收益,验证了正则化的必要性
- floor=0.30 的综合表现:
- EMA=72 + threshold=2.9: +59.56%,胜率 61.1%,盈亏比 2.85,最大回撤 10.66%
- EMA=72 + threshold=2.5: +21.48%,胜率 55.0%
- 跨参数稳健,非过拟合于单一参数组合
最终选定值: std_floor = 0.3
5. 正则化效果量化
std_floor=0.3 时,原始 std 与正则化后 std 的映射关系(100 个等距数据点,0.01~0.30):
| 原始 std 区间 | 正则化后 std | 放大倍数 | 效果描述 |
|---|---|---|---|
| 0.01 ~ 0.05 | 0.300 ~ 0.304 | 30x ~ 6x | 强力压制: az 几乎不可能突破阈值,过滤全部低波动噪声 |
| 0.05 ~ 0.10 | 0.304 ~ 0.316 | 6x ~ 3.1x | 显著衰减: 过滤无套利空间的假信号 |
| 0.10 ~ 0.20 | 0.316 ~ 0.361 | 3.1x ~ 1.8x | 适度抑制: 仍允许真正强信号通过 |
| 0.20 ~ 0.30 | 0.361 ~ 0.424 | 1.8x ~ 1.4x | 轻微影响: 基本保留原始信号特征 |
| > 0.30 | > 0.424 | < 1.4x | 几乎无影响: 高波动期信号完全保留 |
核心特性:
- std < floor 时,effective_std 被"兜底"到 ≈ floor,az 抑制效果显著
- std > floor 时,正则化影响衰减,高波动信号灵敏度不受损
- 过渡区间平滑,无硬截断的不连续跳变(对比
max(std, floor)方案)
6. 代码实现
6.1 核心计算(strategy.py)
def _update_adaptive_z(self, bl: SymbolBaseline,
realtime_z4h: float | None = None,
std_floor: float = 0.0) -> float | None:
"""计算 adaptive_z 并更新 bl.last_std
std 正则化:effective_std = √(sample_var + floor²)
当 std_floor > 0 时,对方差做加法正则化(L2 regularization),
平滑抑制低波动期 az 爆炸,无不连续跳变。
"""
if bl.ema is None:
return None
n = len(bl.std_window)
if n < max(10, bl.std_window.maxlen // 2):
return None
variance = bl.welford_m2 / (n - 1) if n > 1 else 0.0
regularized_var = variance + std_floor * std_floor # L2 正则化
std = max(regularized_var ** 0.5, self._min_std)
bl.last_std = std
current_z4h = realtime_z4h if realtime_z4h is not None else bl.std_window[-1]
return (current_z4h - bl.ema) / std
调用点:
# strategy.py: _process_tick_unlocked()
adaptive_z = self._update_adaptive_z(bl, realtime_z4h=z4h, std_floor=params.std_floor)
6.2 配置层(config.py)
@dataclass(frozen=True)
class StrategyParams:
# ... 其他参数 ...
# 标准差正则化下限(方差加法正则化: effective_std = √(local_var + floor²), 0=禁用)
std_floor: float = 0.3
支持三级覆盖:全局默认 → 币种级 → 配对级
# 全局
TRADING_STRATEGY_STD_FLOOR=0.3
# 币种级覆盖(如 PURR 使用不同 floor)
TRADING_STRATEGY_PURR_STD_FLOOR=0.25
# 配对级覆盖(如 PURR|HYPE 配对专属)
TRADING_STRATEGY_PURR__HYPE_STD_FLOOR=0.35
6.3 Welford 增量算法
滚动标准差采用 Welford 增量算法,避免对整个窗口重复计算:
# 窗口已满时:移除旧值 + 添加新值
if n == bl.std_window.maxlen:
old = bl.std_window[0]
old_mean = bl.welford_mean
bl.welford_mean = old_mean + (z4h - old) / n
bl.welford_m2 += (z4h - old) * ((z4h - bl.welford_mean) + (old - old_mean))
if bl.welford_m2 < 0:
bl.welford_m2 = 0.0 # 浮点保护
# 每 500 次更新重新精确计算,消除浮点漂移
if bl.welford_updates >= 500:
self._recalculate_welford(bl)
bl.welford_updates = 0
正则化在 Welford 输出端施加,不修改 Welford 内部状态——保持统计量的纯粹性。
7. 改动文件清单
| 文件 | 改动 |
|---|---|
src/trading/strategy.py |
_update_adaptive_z() 新增 std_floor 参数,方差加法正则化 |
src/trading/config.py |
StrategyParams.std_floor、TradingConfig.strategy_std_floor,三级覆盖支持 |
.env |
TRADING_STRATEGY_STD_FLOOR=0.3 |
.env.example |
TRADING_STRATEGY_STD_FLOOR=0.3(含注释说明) |
.env.prod |
TRADING_STRATEGY_STD_FLOOR=0.3 |
8. 使用指南
8.1 启用/禁用
# 启用正则化(默认)
TRADING_STRATEGY_STD_FLOOR=0.3
# 禁用正则化(恢复原始行为)
TRADING_STRATEGY_STD_FLOOR=0
8.2 参数调优建议
| 场景 | 建议 floor | 说明 |
|---|---|---|
| 标准配对(如 PURR|HYPE) | 0.3 | 回测验证的稳健值 |
| 高波动配对 | 0.15 ~ 0.25 | 高波动 std 本身较大,floor 影响小 |
| 低波动/稳定币配对 | 0.35 ~ 0.50 | 更强过滤,避免微波动噪声 |
| 新配对(无历史数据) | 0.3 | 默认值,积累数据后再调优 |
| 回测/研究场景 | 0 | 禁用正则化,观察原始信号 |
8.3 监控要点
实盘运行时关注日志中的 std= 字段:
📍 tick(candle) | PURR|HYPE | z4h=+0.1234 az=+1.85 (64%thresh) | ema=0.0856 std=0.3012 | buf=72/72
std ≈ 0.30:正则化在起作用(原始 std 很小)std > 0.40:原始波动率已足够,正则化影响很小std >> 0.50:高波动期,正则化几乎无影响