Files
cbpred/docs/model.md
2026-08-23 14:30:20 +08:00

126 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 模型与评估
本文描述当前默认产物 [`artifacts/v1/model.joblib`](../artifacts/v1/model.joblib),不是所有历史实验的合集。
## 当前模型
| 项目 | 当前值 |
| --- | --- |
| 模型版本 | `v1` 目录,序列化版本 `4` |
| 特征版本 | `compact6` |
| 时间周期 | 8H |
| 输入窗口 | 最近 18 根已收盘 8H K 线 |
| 预测窗口 | 后续 6 根 8H K 线 |
| 点模型 | `ExtraTreesRegressor`,平方误差 |
| 分位数模型 | 两个 `HistGradientBoostingRegressor`,q20/q80 |
| 特征数 | 146 |
| 当前 ATR 过滤阈值 | `0.0`,不主动过滤样本 |
正式模型文件、训练报告和机器可读指标分别是:
```text
artifacts/v1/model.joblib
artifacts/v1/report.md
artifacts/v1/report.json
```
## 目标定义
对时间点 `t`,先取未来 6 根 K 线的最低价,再取这些最低价的 20% 分位数作为稳健低点参考:
```text
future_low_reference = quantile(low[t+1:t+6], 0.20)
raw_return = future_low_reference / close[t] - 1
target = raw_return / asset_atr_price_top20_median
```
这不是单根最低影线的 `lowestLow`。使用 20% 分位数可以降低一根异常影线对标签的支配,同时保留上涨阶段未来低点高于当前收盘的正收益。负 `raw_return` 表示未来稳健低点低于当前收盘,正值表示它高于当前收盘。
`asset_atr_price_top20_median` 是该品种训练期 `ATR / close` 按降序取前 20% 后的中位数。模型在训练时预测归一化目标,输出时再乘回该品种尺度,使不同价格和波动水平的品种可以由同一个模型处理。
## 特征
当前 `compact6` 由 `18 × (6 + 2) + 2 = 146` 个特征组成:
### 最近 18 根 K 线形态
每根 K 线保留 6 个无量纲或相对特征:
- `body_range`:有符号实体相对 K 线振幅;
- `upper_wick`、`lower_wick`:上下影线相对振幅;
- `close_location`:收盘价在本根高低区间中的位置;
- `range_pct`:振幅相对收盘价;
- `log_return`:对数收益率。
没有把绝对价格直接输入模型,也没有在 `compact6` 中重复保存实体绝对大小或独立的阳阴线标记。
### 最近 18 根成交量
- `quote_volume_rank`:本根 USDT 成交额在最近 18 根中的百分位排名;
- `quote_volume_log_rel_median`:本根 USDT 成交额对最近 18 根中位数的对数相对值。
这里使用 `quote` 成交额,而不是不同币种单位不可比的原始成交量。
### 品种画像
每个品种只保留两个训练期画像值,并在训练品种之间标准化:
- 高波动 20% 样本的 `ATR / close` 中位数;
- 高成交额 20% 样本的 `log1p(quote)` 中位数。
RSI、SMA、布林带、EMA、趋势汇总、全局市场摘要和横截面排名都做过候选实验,但当前正式模型没有使用它们。全局和横截面特征还会改变预测所需的上下文,不能直接用于当前的单 CSV 预测接口。
## 训练协议
默认使用最近 36 个月数据,最后 10 个月作为留出期。训练快照以前的样本只能使用完整的历史窗口和未来 6 根 K 线;跨越测试边界或数据缺口的样本会被丢弃。
品种先按固定随机种子 `42` 拆分,约 60% 作为训练品种、20% 作为验证品种、20% 作为测试品种。最近 10 个月再按时间拆成:
- 验证品种的前 30%:模型和特征选择;
- 验证品种的接续 20%:分位数校准;
- 测试品种的最后 50%:最终测试,只报告一次。
每个阶段会比较随机森林和 ExtraTrees 点模型,并使用 q20/q80 分位数模型。特征阶段和候选模型只根据验证选择分数确定,最终测试集不参与选择。
## 测试结果
当前报告的最终测试集包含 13,950 个样本。误差是在乘回品种 ATR 尺度后的原始收益空间中计算:
| 指标 | `compact6` |
| --- | ---: |
| 点预测 MAE | `0.024918` |
| 点预测 RMSE | `0.033563` |
| q80 覆盖率 | `77.50%` |
| q20 下界命中率 | `91.60%` |
| q20 覆盖率(`y <= q20`) | `8.40%` |
相同复核配置下,182 特征基线的点预测 MAE/RMSE 是 `0.025140 / 0.033789`,`compact6` 分别改善约 `0.88% / 0.67%`。q80 的实测覆盖率是测试集统计结果,不是未来每次预测的保证概率;`80%` 也不能被理解为盈利概率或交易成功率。
q20 的两个指标不要混淆:`q20_coverage` 统计真实目标低于 q20 预测的比例,`q20_hit_rate` 统计真实目标高于 q20 预测的比例,所以二者在没有相等值时大致互补。
## 预测字段语义
模型内部预测的是 signed future-low return,批量 CSV 将其转成更直观的字段:
```text
drawdown = -future_low_return × 100
price_level = close × (1 + future_low_return)
```
因此:
- `drawdown_point_pct` 是点预测;
- `drawdown_cap_80pct_pct` 使用 q80 收益,对应较浅的回撤上界参考;
- `price_level_reached_80pct` 使用 q20 收益,对应较保守的较低价格参考;
- `price_level_cap_80pct` 使用 q80 收益,对应较高的价格参考。
当未来稳健低点预测为正收益时,回撤列可以为负,这表示模型没有把上涨阶段强行截断为零。
## 使用限制
- 这是离线历史数据上的统一回归模型,不是交易信号,也不保证未来表现。
- 测试结果依赖当前数据快照、品种筛选和时间切分;更新数据后重新训练,指标可能变化。
- 模型只对保存了训练画像且有足够历史的品种预测。当前 ATR 排名至少需要 200 根 8H K 线。
- `atr_rank_200_pct` 是状态描述,不代表模型只预测高波动时刻;正式阈值为 `0.0`。
- 预测结果中的空值表示当前时刻不满足模型资格条件,不应替换成零。