Files
obsidian_vault/FleetingNotes/GridSeeker/数据构建过程.md
T

10 KiB
Raw Blame History

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 线 ≥ 20180101 ~ 20260430 沪市主板(600/601/603/605)
深市主板(000/001/002/003)
创业板(300/301)
date, open, high, low, close, volume
股本数据 最新快照 全市场 total_share
全市场涨跌比 20180101 ~ 20260430 date, advance_ratio
沪深 300 指数日线 20180101 ~ 20260430 date, open, high, low, close
中证 500 指数日线 20180101 ~ 20260430 date, open, high, low, close
中证 1000 指数日线 20180101 ~ 20260430 date, open, high, low, close

3.2 K 线清洗规则

  • 删除 openhighlowclosevolume 中存在 NaN 的行。
  • 删除 openhighlowclose ≤ 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 天滑动:

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 天。

正确做法:

# 从观察窗口结束日向前回溯 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 时期 IDstart // 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 线时间范围 ≥ 20180101 从 2020 年开始 → 过滤后股票数锐减
股票范围 沪深主板 + 创业板 仅 600 开头 → 过滤后股票数不足
观察窗口 120 天
标签窗口 60 天
滑窗步长 20 天
情绪特征历史窗 180 天 错误使用 120 天 → 情绪因子值偏移
batch_filterratio_threshold 0.5 0.3 会引入偶尔路过的股票
batch_filterprice_upper 14 提高到 18 会增加高价股,但匹配度下降
标签 y_rounds(轮回数) 改用利润标签会改变模型行为

10. 如果数据源暂未就绪

务实方案:直接复用 v6.3 的 share_fixed_training_frame.parquet211,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_ratioobv_slope_to_mv
  • 新增 3 个指数独立性特征(基于沪深 300、中证 500、中证 1000

若数据源已就绪,可以直接按 v7.0 的标签和特征一步到位生成训练样本,无需先重建 v6.4 再修改。