# v6.4 训练数据从零构建完整指南 本文档结合项目从 v3.0 至 v6.4 的全部历史版本,梳理训练数据的完整构建逻辑,并给出从原始行情数据出发,**不依赖任何已有训练文件**重建全套训练样本的标准流程。 --- ## 1. 历史版本数据演化脉络 ### 1.1 关键节点 | 版本 | 数据核心变化 | 对后续的影响 | | :------------- | :---------------------------------------------------------------- | :----------------- | | v3.0 之前 | 逐日价格命中入样(收盘价在 `[7,10]` 即采样) | 被废弃 | | v3.0 ~ v3.2 | **股票级长期过滤 + 全历史滑窗** | 奠定主训练框架,沿用至今 | | v3.3 ~ v3.6 | 特征消融与增强(34 基础特征定型) | 特征体系成形 | | v4.0 ~ v4.4 | 引入 `period_id` 用于 Top 标签构造 | 标签更公平 | | v5.0 | 主训练帧固化(`v5.0_training_frame.parquet`) | v5.1 ~ v6.4 全部依赖此帧 | | v6.3 share-fix | 重算 4 个 `total_share` 相关特征,产出 `share_fixed_training_frame.parquet` | v6.4 直接使用 | | v6.4 | 复用 v6.3 训练样本,仅新增 Meta Ranker | 当前生产基线 | ### 1.2 核心继承关系 ``` v3.0 样本构造逻辑 (长期过滤+滑窗) └── v5.0 首次生成主训练帧 └── v5.1/v5.2/v5.3 复用同一样本,追加特征 └── v6.3 share-fix 修复股本特征 └── v6.4 直接使用 (share_fixed_training_frame.parquet) ``` > **结论**:v6.4 的训练样本本质上是 v5.0 时代首次生成的,之后只在同一样本上追加或修正特征,**从未重建过样本集**。 --- ## 2. 构建概览 重建 v6.4 训练数据需要严格按照以下步骤: 1. 准备原始数据(K线、股本、市场情绪、指数) 2. 对全市场股票进行**股票级长期过滤**(`batch_filter`) 3. 对通过过滤的股票进行**全历史滑窗采样**(窗口 120 天,步长 20 天) 4. 计算多维特征(基础、负向、独立性、行业、情绪) 5. 计算标签(`y_rounds`:未来 60 天网格轮回数) 6. 合并输出为单个 Parquet 文件 下面逐一展开。 --- ## 3. 数据准备 ### 3.1 原始数据清单 | 数据 | 时间范围 | 股票范围 | 必要字段 | |:---|:---|:---|:---| | 个股日 K 线 | **≥ 2018‑01‑01** ~ 2026‑04‑30 | 沪市主板(600/601/603/605)
深市主板(000/001/002/003)
创业板(300/301) | `date`, `open`, `high`, `low`, `close`, `volume` | | 股本数据 | 最新快照 | 全市场 | `total_share` | | 全市场涨跌比 | 2018‑01‑01 ~ 2026‑04‑30 | — | `date`, `advance_ratio` | | 沪深 300 指数日线 | 2018‑01‑01 ~ 2026‑04‑30 | — | `date`, `open`, `high`, `low`, `close` | | 中证 500 指数日线 | 2018‑01‑01 ~ 2026‑04‑30 | — | `date`, `open`, `high`, `low`, `close` | | 中证 1000 指数日线 | 2018‑01‑01 ~ 2026‑04‑30 | — | `date`, `open`, `high`, `low`, `close` | ### 3.2 K 线清洗规则 - 删除 `open`、`high`、`low`、`close`、`volume` 中存在 NaN 的行。 - 删除 `open`、`high`、`low`、`close` ≤ 0 的行。 - 删除 `high < max(open, low, close)` 或 `low > min(open, high, close)` 的异常行。 - 按 `date` 升序排序,重复日期保留最后一条。 - 重置索引。 ### 3.3 股本数据处理 - 从股本快照中读取每只股票最新的 `total_share`(总股本,单位:亿股)。 - 提供映射字典 `{stock_code: total_share}`,用于计算市值相关特征。 ### 3.4 市场情绪与指数数据 - 全市场涨跌比用于计算 4 个宽松情绪因子(`relaxed_emotion`)。 - 沪深 300、中证 500、中证 1000 指数日线用于计算独立性特征(振幅独特性等)。 --- ## 4. 股票级长期过滤 (batch_filter) ### 4.1 过滤函数签名 ``` batch_filter(stock_data_dict, grid_lower=1, grid_upper=11, price_upper=14, lookback=180, ratio_threshold=0.5) ``` ### 4.2 四个必须同时满足的条件 1. **最新收盘价** ∈ `[1, 14]` 元 (低于 1 元有退市风险,高于 14 元远离网格上界 11 元,不纳入训练) 2. **过去 180 天至少有一天收盘价** ∈ `[1, 11]` 元 (保证该股票曾踏入网格区间) 3. **过去 180 天收盘价在 `[1, 11]` 内的天数占比 ≥ 50%** (排除偶尔路过网格的股票,保留长期在区间内活动的标的) 4. **非 ST、上市满 180 天** (剔除风险警示股和次新股) ### 4.3 过滤后预期 - 历史经验:在 2018‑2026 年全市场数据上,通过过滤的股票数约为 **1,500 ~ 1,800 只**。 --- ## 5. 全历史滑窗采样 ### 5.1 窗口参数 | 参数 | 值 | 说明 | |:---|:---|:---| | 观察窗口 | **120** 个交易日 | 用于计算特征 | | 标签窗口 | **60** 个交易日 | 紧随观察窗口之后,用于计算标签 | | 滑动步长 | **20** 个交易日 | 每个位置生成一个样本 | | `period_id` | `start // 60` | 用于同一时期内 Top 标签的相对排名 | ### 5.2 采样流程 对每只通过过滤的股票,从其 K 线数据第 `0` 天开始,以步长 20 天滑动: ```python max_start = len(df) - 120 - 60 for start in range(0, max_start + 1, 20): obs_window = df[start : start + 120] future_window = df[start + 120 : start + 120 + 60] period_id = start // 60 # 计算特征、标签... ``` --- ## 6. 特征计算 ### 6.1 基础特征(34 维) 调用 `calculate_features(obs_window, total_share=..., feature_version='v3.3')`,包括: - **价格波动类**:`price_cv`, `volatility_20d`, `avg_daily_amp`, `atr_pct`, `bb_width`, `amplitude_cv` 等 - **成交量与资金类**:`amount_mean_20d`, `amount_cv_20d`, `turnover_proxy_20d`, `volume_ratio`, `obv_slope`, `liquidity_drying_up_20d` - **趋势与位置类**:`trend_slope_60d`, `trend_slope_20d`, `trend_abs_slope_20d`, `drawdown_60d`, `range_position_60d`, `intraday_trend_strength` - **网格结构类**:`grid_room_balance`, `grid_touch_count_60d`, `dist_to_grid_upper`, `dist_to_grid_lower`, `cross_freq_x_bb` - **市值类**:`ln_float_mv`, `mv_vol_interact`, `small_cap_premium`, `amplitude_uniqueness_20d`(需要 `total_share`) ### 6.2 负向特征 调用 `calculate_negative_features(obs_window)`。 ### 6.3 市场独立性特征 调用 `calculate_independence_features(obs_window)`,基于沪深 300 指数计算。 ### 6.4 行业独立性特征 调用 `calculate_sector_independence_features(obs_window)`。 ### 6.5 宽松情绪特征(4 维) 调用 `calculate_relaxed_emotion_features(emotion_window, market_regime_data)`。 **⚠️ 关键约束**:情绪特征的历史窗口必须为 **180 天**,而非观察窗口的 120 天。 正确做法: ```python # 从观察窗口结束日向前回溯 180 天作为情绪窗口 hist_end = start + 120 hist_start = max(0, hist_end - 180) emotion_window = df[hist_start : hist_end] ``` --- ## 7. 标签计算 **v6.4 使用 `y_rounds`**(未来 60 天网格匹配轮回数)。 调用 `calc_grid_rounds(future_window, grids=[1,2,...,11])`,模拟网格交易(基准价 10 元,每格 200 股,LIFO),统计有效轮回次数。 > **注意**:v6.4 的标签是轮回数,不是利润。若需切换到收益导向标签(v7.0),请使用 `total_return_60d`(已实现利润 + 期末持仓市值)。 --- ## 8. 最终输出 每条样本包含以下字段: | 字段 | 说明 | |:---|:---| | `stock_code` | 股票代码 | | `obs_start` | 观察窗口开始日期 | | `obs_end` | 观察窗口结束日期 | | `future_start` | 标签窗口开始日期 | | `future_end` | 标签窗口结束日期 | | `period_id` | 时期 ID(`start // 60`) | | 34 基础特征 | 如 `price_cv` 等 | | 负向特征 | 如 `trend_consistency_20d` 等 | | 市场独立性特征 | 如 `amplitude_uniqueness_20d` 等 | | 行业独立性特征 | 如 `sector_amplitude_deviation_20d` 等 | | 4 情绪特征 | `relaxed_panic_amplification_ratio` 等 | | `y_rounds` | 标签(网格匹配轮回数) | 输出格式:**单个 Parquet 文件**,约 21 万条样本,覆盖 1,500 ~ 1,800 只股票。 --- ## 9. 关键约束与常见错误 | 约束 | 正确值 | 常见错误 | |:---|:---|:---| | K 线时间范围 | **≥ 2018‑01‑01** | 从 2020 年开始 → 过滤后股票数锐减 | | 股票范围 | 沪深主板 + 创业板 | 仅 600 开头 → 过滤后股票数不足 | | 观察窗口 | 120 天 | — | | 标签窗口 | 60 天 | — | | 滑窗步长 | 20 天 | — | | 情绪特征历史窗 | **180 天** | 错误使用 120 天 → 情绪因子值偏移 | | `batch_filter` 的 `ratio_threshold` | **0.5** | 0.3 会引入偶尔路过的股票 | | `batch_filter` 的 `price_upper` | **14** | 提高到 18 会增加高价股,但匹配度下降 | | 标签 | `y_rounds`(轮回数) | 改用利润标签会改变模型行为 | --- ## 10. 如果数据源暂未就绪 **务实方案**:直接复用 v6.3 的 `share_fixed_training_frame.parquet`(211,976 条,1,799 只股票),然后在其上追加计算 v7.0 所需的 `total_return_60d` 标签和新特征。 此方案的优势: - 保留 v6.3 已验证的样本规模和股票覆盖 - 避免从零重建的复杂性和潜在偏差 - 可快速启动收益导向实验 待全市场数据(2018‑2026)完全就绪后,再按本文档启动完整的从零重建。 --- ## 11. 与 v7.0 的关系 v7.0 的训练数据构建流程与 v6.4 **完全一致**,差异仅在: - 标签从 `y_rounds` 改为 `total_return_60d` - 新增 2 个规模中性化特征(`amount_to_mv_ratio`、`obv_slope_to_mv`) - 新增 3 个指数独立性特征(基于沪深 300、中证 500、中证 1000) 若数据源已就绪,可以直接按 v7.0 的标签和特征一步到位生成训练样本,无需先重建 v6.4 再修改。