今天确定了策略数据表的结构设计方案:把所有核心数据整合成一张”宽表”,一行一天,打开就能看到完整的市场状态。
所有核心数据整合为一张宽表,命名为 strategy_data.csv,以 trade_date(交易日期)为主键。
这张表的目标是:回测引擎和决策看板都直接读这一个文件,不需要再去拼接多个数据源。
数据源说明:OHLCV + 均线 + 热度来自中证500指数(000905.SH),无需复权。仅换手率取自 510500 ETF。
| 字段 | 类型 | 来源 / 计算方式 | 策略用途 |
|---|---|---|---|
| trade_date | 日期 | Tushare 交易日历 | 主键 |
| open | 浮点数 | 000905.SH 指数 (index_daily) |
T+1 执行价格 |
| high | 浮点数 | 000905.SH 指数 (index_daily) |
entry_high 止损 |
| low | 浮点数 | 000905.SH 指数 (index_daily) |
K 线绘图 |
| close | 浮点数 | 000905.SH 指数 (index_daily) |
均线、收益、趋势判断 |
| volume | 浮点数 | 000905.SH 指数 (index_daily vol 重命名) |
辅助参考 |
| amount | 浮点数 | 000905.SH 指数 (index_daily) |
计算 heat_z |
| ma_5 | 浮点数 | close.rolling(5).mean() |
支撑线(MA_Support) |
| ma_10 | 浮点数 | close.rolling(10).mean() |
趋势线(MA_Trend) |
| ma_20 | 浮点数 | close.rolling(20).mean() |
中期趋势参考 |
| ma_30 | 浮点数 | close.rolling(30).mean() |
防守线(MA_Filter) |
| breadth | 浮点数 (0~100) | 成分股 close > MA20 的占比 | 冰点抄底 / 过热逃顶 |
| heat_z | 浮点数 | (amount - 20日均值) / 20日标准差 |
资金热度 |
| etf_turnover | 浮点数 | 510500 ETF vol / fd_share_T-1 |
首阴入场门槛 (>1.0%) |
最初设计用 510500 ETF 数据,但 ETF 有分红导致的价格跳空问题,需要:
改用中证500指数(000905.SH)后,这些问题全部消失——指数数据天然是全收益口径,不存在复权问题,数据管道大幅简化。
换手率分母用 T-1:基金份额变动盘后公布,所以当天换手率的分母应该用前一个交易日的份额。实现方式:fd_share.ffill().shift(1)。
breadth 计算:基于成分股后复权收盘价的 MA20,个股复权在 stocks_data 准备阶段已完成。
热身数据:ma_30 需要往回看 30 天,heat_z 需要往回看 20 天。为了让 2019-01-01 的数据不缺失,脚本从 2018-11-01 开始拉取(WARMUP_START),这段热身数据只用于计算指标,不出现在最终输出中。
| 优点 | 说明 |
|---|---|
| 易于回测 | 直接丢给回测引擎逐行遍历,不用管数据对齐 |
| 高性能 | 均线和热度预先算好存着,运行时直接读取 |
| 清晰可读 | 打开 CSV 就能看到每天的完整状态 |
| 管道简洁 | 指数数据无需复权,减少出错环节 |
对应 build_strategy_data.py v5 的 4 个步骤:
| 步骤 | 内容 | 数据源 |
|---|---|---|
| STEP 1 | 拉取指数日线 OHLCV + amount | pro.index_daily('000905.SH') |
| STEP 2 | 计算 MA5/10/20/30 和 heat_z | 基于 STEP 1 的 close 和 amount |
| STEP 3 | 计算 breadth(广度) | stocks_data/ + csi500_components_schedule.csv |
| STEP 4 | 计算 etf_turnover | pro.fund_daily('510500.SH') + pro.fund_share() |
| 汇总 | 截取 2019-01-01 起,输出 14 列 CSV | — |