Skip to content

Commit d5ddff4

Browse files
author
Tonny@Home
committed
feature: Implement rolling training logic with state management
1 parent 9f5ad02 commit d5ddff4

File tree

10 files changed

+2389
-2
lines changed

10 files changed

+2389
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ The system strictly decouples the **Engine (Code)** from the **Workspace (Config
2929

3030
```text
3131
QuantPits/
32-
├── docs/ # Detailed system manuals (00-08)
32+
├── docs/ # Detailed system manuals (00-08, 30+, 70)
3333
├── ui/ # Streamlit interactive dashboards
3434
│ ├── dashboard.py # Macro performance app
3535
│ └── rolling_dashboard.py# Temporal strategy health app
@@ -143,6 +143,7 @@ For a deep dive into each module, refer to the documentation in `docs/`:
143143
- `01_TRAINING_GUIDE.md`
144144
- `02_BRUTE_FORCE_GUIDE.md`
145145
- `03_ENSEMBLE_FUSION_GUIDE.md`
146+
- `30_ROLLING_TRAINING_GUIDE.md` (Rolling Training: Sliding Window Training)
146147
- ...and more.
147148

148149
All documentation is available in both Chinese and English (`docs/en/`).

README_zh.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
```text
3131
QuantPits/
32-
├── docs/ # 详细的系统开发及应用操作手册(00-08)
32+
├── docs/ # 详细的系统开发及应用操作手册(00-08, 30+, 70
3333
├── ui/ # 交互式数据图表面板
3434
│ ├── dashboard.py # 宏观资管业绩评估 Streamlit 面板
3535
│ └── rolling_dashboard.py# 时序策略执行健康监测 Streamlit 面板
@@ -143,6 +143,7 @@ python -m quantpits.scripts.init_workspace \
143143
- `01_TRAINING_GUIDE.md` (全量训练及模型配置向导)
144144
- `02_BRUTE_FORCE_GUIDE.md` (穷举回测及GPU加速矩阵操作向导)
145145
- `03_ENSEMBLE_FUSION_GUIDE.md` ...以此类推。
146+
- `30_ROLLING_TRAINING_GUIDE.md` (滚动训练:滑动窗口训练、冷启动、断点恢复)
146147

147148
所有文档均已提供中文与纯正的英文(`en/`)双语版本支持。
148149

docs/00_SYSTEM_OVERVIEW.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ flowchart TB
5050
IT["incremental_train.py<br/>增量训练"]
5151
end
5252
53+
subgraph ROLLING["⑨ 滚动训练(按需)"]
54+
RT["rolling_train.py<br/>冷启动/日常/预测"]
55+
end
56+
5357
subgraph PREDICT["② 预测(每次)"]
5458
PO["prod_predict_only.py<br/>仅预测"]
5559
end
@@ -81,15 +85,20 @@ flowchart TB
8185
8286
REG["model_registry.yaml<br/>模型注册表"]
8387
LTR["latest_train_records.json<br/>训练记录"]
88+
LRR["latest_rolling_records.json<br/>滚动训练记录"]
8489
PRED_CSV["output/predictions/<br/>预测 CSV"]
8590
WC["prod_config.json<br/>持仓/现金"]
8691
8792
REG --> TRAIN
8893
REG --> PREDICT
94+
REG --> ROLLING
8995
TRAIN --> LTR
9096
PREDICT --> LTR
97+
ROLLING --> LRR
9198
LTR --> BRUTEFORCE
9299
LTR --> FUSION
100+
LRR -.->|--record-file| BRUTEFORCE
101+
LRR -.->|--record-file| FUSION
93102
FUSION --> PRED_CSV
94103
PREDICT --> PRED_CSV
95104
PRED_CSV --> ORDERGEN
@@ -198,6 +207,24 @@ python quantpits/scripts/ensemble_fusion.py \
198207
# ⑤⑥ 同上
199208
```
200209

210+
### 场景 E:滚动训练(适应市场风格漂移)
211+
212+
当静态模型预测质量因市场风格变化而衰减时,使用滚动训练让模型持续适应。
213+
214+
```bash
215+
# ⑨ 冷启动:首次滚动训练
216+
python quantpits/scripts/rolling_train.py --cold-start --all-enabled
217+
218+
# ③④ 穷举 + 融合(使用滚动预测)
219+
python quantpits/scripts/brute_force_fast.py --record-file latest_rolling_records.json
220+
python quantpits/scripts/ensemble_fusion.py \
221+
--from-config --record-file latest_rolling_records.json
222+
223+
# ⑤⑥ Post-Trade + 订单生成(同其他场景)
224+
```
225+
226+
> 日常运行只需:`python quantpits/scripts/rolling_train.py --all-enabled`(自动判断训练/预测)
227+
201228
---
202229

203230
## 模块速查
@@ -217,6 +244,19 @@ python quantpits/scripts/ensemble_fusion.py \
217244
- 训练记录修改前自动备份到 `data/history/`
218245
- 增量训练支持 `--resume`(断点续训)和 `--dry-run`(预览)
219246

247+
### ⑨ 滚动训练模块
248+
249+
> 详见 [30_ROLLING_TRAINING_GUIDE.md](30_ROLLING_TRAINING_GUIDE.md)
250+
251+
| 脚本 | 用途 | 保存语义 |
252+
|------|------|----------|
253+
| `rolling_train.py` | 滑动窗口训练 + 预测拼接 | **独立** `latest_rolling_records.json` |
254+
255+
- 与静态训练完全独立,共存于同一 Workspace
256+
- 支持冷启动、日常模式(自动判断训练/预测)、仅预测、断点恢复
257+
- 下游通过 `--record-file latest_rolling_records.json` 无缝切换数据源
258+
- 配置文件:`config/rolling_config.yaml`(起点、训练年数、验证年数、步长)
259+
220260
### ② 预测模块
221261

222262
> 详见 [05_PREDICT_ONLY_GUIDE.md](05_PREDICT_ONLY_GUIDE.md)
@@ -350,13 +390,15 @@ python quantpits/scripts/ensemble_fusion.py \
350390
| `prod_config.json` | 实盘与状态层:持仓、现金、处理时间 | Post-Trade、订单生成 |
351391
| `cashflow.json` | 出入金记录:按日期的出入金 | Post-Trade |
352392
| `ensemble_config.json` | 多组合融合配置:combo 定义、权重、default | 融合预测、订单生成、信号排名 |
393+
| `rolling_config.yaml` | 滚动训练参数:起点、训练/验证年数、步长 | 滚动训练 |
353394
| `workflow_config_*.yaml` | Qlib 工作流:各模型的训练配置 | 训练 |
354395

355396
### 输出文件 (`output/`)
356397

357398
| 目录/文件 | 用途 |
358399
|-----------|------|
359400
| `predictions/*.csv` | 各模型和 ensemble 的预测结果(多 combo 带组合名) |
401+
| `predictions/rolling/` | 滚动训练预测(per-window CSV + 拼接 CSV) |
360402
| `brute_force/` | 暴力穷举精确回测结果和分析报告 |
361403
| `brute_force_fast/` | 快速穷举结果 |
362404
| `ensemble/` | 融合配置、排行榜、图表、跨组合对比 |
@@ -373,6 +415,8 @@ python quantpits/scripts/ensemble_fusion.py \
373415
| `history/` | 自动备份的历史文件 |
374416
| `order_history/` | 历史订单建议、交易明细、交易软件导出表(由归档脚本管理) |
375417
| `run_state.json` | 增量训练运行状态(支持断点续跑) |
418+
| `rolling_state.json` | 滚动训练状态(断点恢复用) |
419+
| `latest_rolling_records.json` | 滚动训练记录(下游 `--record-file` 使用) |
376420
| `trade_log_full.csv` | 累计交易日志(含买入和卖出) |
377421
| `holding_log_full.csv` | 累计持仓日志 |
378422
| `daily_amount_log_full.csv` | 每日资金汇总 |
@@ -398,6 +442,7 @@ python quantpits/scripts/ensemble_fusion.py \
398442
| 06 | [ORDER_GEN_GUIDE](06_ORDER_GEN_GUIDE.md) | 订单生成、买卖建议输出 |
399443
| 07 | [SIGNAL_RANKING_GUIDE](07_SIGNAL_RANKING_GUIDE.md) | 信号排名 Top N 推荐 |
400444
| 08 | [ANALYSIS_GUIDE](08_ANALYSIS_GUIDE.md) | 单模型质量、融合相关性、执行滑点成本及多维组合风险综合评测 |
445+
| **30** | **[ROLLING_TRAINING_GUIDE](30_ROLLING_TRAINING_GUIDE.md)** | **滚动训练:时间窗口滑动训练、冷启动、断点恢复** |
401446
| 70 | [WALKTHROUGH](70_WALKTHROUGH.md) | **端到端实战操作手册(从这里开始!)** |
402447

403448
---

docs/30_ROLLING_TRAINING_GUIDE.md

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
# 滚动训练指南 (Rolling Training)
2+
3+
> 30 系列文档专注于**非静态训练**逻辑——即训练窗口随时间推进而滚动的训练范式。
4+
5+
---
6+
7+
## 概述
8+
9+
传统静态训练(`prod_train_predict.py``incremental_train.py`)使用**固定的日期区间**训练模型。当市场风格发生漂移时,静态模型的预测质量会逐渐衰减。
10+
11+
**滚动训练 (Rolling Training)** 通过将时间轴切分为多个滑动窗口,在每个窗口上独立训练模型,从而使模型始终适应最新的市场状态。
12+
13+
### 静态 vs. 滚动
14+
15+
| 特性 | 静态训练 | 滚动训练 |
16+
|------|---------|---------|
17+
| 训练区间 | 固定(如 2015–2022) | 滑动窗口(每窗口独立训练) |
18+
| 模型数量 | 每模型 1 个 | 每模型 × N 个窗口 |
19+
| 适应性 | 低(依赖长期统计特征) | 高(随市场风格滑动更新) |
20+
| 预测输出 | 单段连续预测 | 多段拼接(自动拼接为连续文件) |
21+
| 下游兼容性 | `latest_train_records.json` | `latest_rolling_records.json`(通过 `--record-file` 切换) |
22+
23+
### 共存架构
24+
25+
滚动训练与静态训练**完全独立**,共存于同一 Workspace:
26+
27+
```text
28+
output/
29+
├── predictions/ # 静态训练预测
30+
│ └── rolling/ # 滚动训练预测(per-window CSV + 拼接 CSV)
31+
data/
32+
├── latest_train_records.json # 静态训练记录
33+
├── latest_rolling_records.json# 滚动训练记录
34+
└── rolling_state.json # 滚动训练运行状态(中间态,断点恢复用)
35+
```
36+
37+
---
38+
39+
## 核心脚本
40+
41+
| 脚本 | 用途 |
42+
|------|------|
43+
| `rolling_train.py` | 滚动训练主脚本:冷启动、日常模式、仅预测、断点恢复 |
44+
45+
---
46+
47+
## 时间窗口划分
48+
49+
### 配置参数
50+
51+
`config/rolling_config.yaml` 中配置:
52+
53+
```yaml
54+
rolling_start: "2020-01-01" # T: 起始日期
55+
train_years: 3 # X: 训练区间(整数年)
56+
valid_years: 1 # Y: 验证区间(整数年)
57+
test_step: "3M" # Z: 测试步长(nM 或 nY)
58+
```
59+
60+
### 划分公式
61+
62+
对于第 `n` 个窗口(从 0 开始):
63+
64+
```
65+
Train: [T + nZ, T + X + nZ − 1d]
66+
Valid: [T + X + nZ, T + X + Y + nZ − 1d]
67+
Test: [T + X + Y + nZ, T + X + Y + (n+1)Z − 1d]
68+
```
69+
70+
> [!IMPORTANT]
71+
> **绝对不重叠**:训练、验证、测试三段之间没有任何日期重叠,包括端点。`train_end + 1d = valid_start`,`valid_end + 1d = test_start`。
72+
73+
### 示例
74+
75+
`T=2020-01-01, X=3年, Y=1年, Z=3M`:
76+
77+
| 窗口 | 训练区间 | 验证区间 | 测试区间 |
78+
|:---:|---------|---------|---------|
79+
| W0 | 2020-01-01 ~ 2022-12-31 | 2023-01-01 ~ 2023-12-31 | 2024-01-01 ~ 2024-03-31 |
80+
| W1 | 2020-04-01 ~ 2023-03-31 | 2023-04-01 ~ 2024-03-31 | 2024-04-01 ~ 2024-06-30 |
81+
| W2 | 2020-07-01 ~ 2023-06-30 | 2023-07-01 ~ 2024-06-30 | 2024-07-01 ~ 2024-09-30 |
82+
| W3 | 2020-10-01 ~ 2023-09-30 | 2023-10-01 ~ 2024-09-30 | 2024-10-01 ~ 2024-12-31 |
83+
84+
最后一个窗口的 `test_end` 自动截断至 `anchor_date`(Qlib 最新交易日)。
85+
86+
---
87+
88+
## 运行模式
89+
90+
### 模式一:冷启动
91+
92+
**首次运行必须执行冷启动。** 生成所有 windows 并逐个训练。
93+
94+
```bash
95+
# 全量冷启动
96+
python quantpits/scripts/rolling_train.py --cold-start --all-enabled
97+
98+
# 指定模型
99+
python quantpits/scripts/rolling_train.py --cold-start --models linear_Alpha158
100+
101+
# Dry-run: 仅查看窗口划分
102+
python quantpits/scripts/rolling_train.py --cold-start --dry-run --all-enabled
103+
```
104+
105+
冷启动流程:
106+
1.`rolling_config.yaml` 读取参数
107+
2. 生成所有 rolling windows(到 anchor_date 为止)
108+
3. 对每个 window × 每个模型执行训练 + 预测
109+
4. 拼接所有 windows 的预测为连续时间序列
110+
5. 保存 `latest_rolling_records.json`
111+
112+
### 模式二:日常模式
113+
114+
自动检测是否有新 window 需要训练:
115+
- **有新 window** → 训练新 window + 重新拼接
116+
- **无新 window** → 使用最近模型执行预测
117+
118+
```bash
119+
python quantpits/scripts/rolling_train.py --all-enabled
120+
```
121+
122+
### 模式三:仅预测
123+
124+
使用最近一个 window 训练的模型对最新数据预测:
125+
126+
```bash
127+
python quantpits/scripts/rolling_train.py --predict-only --all-enabled
128+
```
129+
130+
### 断点恢复
131+
132+
训练中断时,自动跳过已完成的 window × model:
133+
134+
```bash
135+
python quantpits/scripts/rolling_train.py --resume
136+
```
137+
138+
### 状态查看
139+
140+
```bash
141+
# 查看当前状态
142+
python quantpits/scripts/rolling_train.py --show-state
143+
144+
# 清除状态(重新开始)
145+
python quantpits/scripts/rolling_train.py --clear-state
146+
```
147+
148+
---
149+
150+
## 模型选择
151+
152+
与静态训练一致,支持所有模型筛选方式:
153+
154+
| 参数 | 说明 |
155+
|------|------|
156+
| `--models m1,m2` | 按名称指定 |
157+
| `--algorithm alg` | 按算法筛选 |
158+
| `--dataset ds` | 按数据集筛选 |
159+
| `--tag tag` | 按标签筛选 |
160+
| `--all-enabled` | 所有 enabled 模型 |
161+
| `--skip m1,m2` | 排除指定模型 |
162+
163+
---
164+
165+
## 下游衔接
166+
167+
滚动训练的预测结果通过 `--record-file` 参数无缝衔接下游脚本:
168+
169+
```bash
170+
# 穷举
171+
python quantpits/scripts/brute_force_fast.py \
172+
--record-file latest_rolling_records.json
173+
174+
# 融合
175+
python quantpits/scripts/ensemble_fusion.py \
176+
--from-config --record-file latest_rolling_records.json
177+
```
178+
179+
> [!TIP]
180+
> 静态和滚动训练的下游流程完全相同,仅通过 `--record-file` 切换数据来源。默认值为 `latest_train_records.json`(静态),指定 `latest_rolling_records.json` 即切换到滚动。
181+
182+
---
183+
184+
## 状态管理与断点恢复
185+
186+
`rolling_state.json` 记录训练进度,结构如下:
187+
188+
```json
189+
{
190+
"started_at": "2025-03-14 10:00:00",
191+
"rolling_config": {"test_step": "3M", ...},
192+
"anchor_date": "2025-03-14",
193+
"total_windows": 4,
194+
"completed_windows": {
195+
"0": {"linear_Alpha158": "rec_001", "gru_Alpha158": "rec_002"},
196+
"1": {"linear_Alpha158": "rec_003"}
197+
}
198+
}
199+
```
200+
201+
- 每完成一个 window × model,立即保存状态
202+
- 中断后使用 `--resume` 恢复,自动跳过已完成项
203+
- `--clear-state` 清除状态重新开始(旧状态自动备份到 `data/history/`
204+
205+
---
206+
207+
## MLflow 实验命名
208+
209+
| 实验名 | 内容 |
210+
|--------|------|
211+
| `Rolling_Windows_{FREQ}` | 各 window 的单独训练记录 |
212+
| `Rolling_Combined_{FREQ}` | 拼接后的完整预测记录 |
213+
214+
其中 `{FREQ}` 为交易频率(如 `WEEK``DAY`)。
215+
216+
---
217+
218+
## 配置文件参考
219+
220+
`config/rolling_config.yaml` 完整示例:
221+
222+
```yaml
223+
# Rolling Training Configuration
224+
# 滚动训练配置
225+
226+
rolling_start: "2020-01-01" # T: 起始日期
227+
train_years: 3 # X: 训练区间长度(整数年)
228+
valid_years: 1 # Y: 验证区间长度(整数年)
229+
test_step: "3M" # Z: 测试步长
230+
# - nM: n 个月 (如 3M, 6M)
231+
# - nY: n 年 (如 1Y)
232+
```
233+
234+
> [!CAUTION]
235+
> `train_years``valid_years` 必须为**整数年**`test_step` 必须为 `nM`(整数月)或 `nY`(整数年),不支持小数。

0 commit comments

Comments
 (0)