--- title: 波动率类技术指标因子(cn_stock_factors_ta_volatility) source: bigfactorwarehouse / cn_stock / cn_stock_factors_ta_volatility format: markdown --- # 波动率类技术指标因子(cn_stock_factors_ta_volatility) > 度量价格波动幅度与分布形态:ATR 及其相对比率刻画真实波幅(含跳空),HV 为对数收益标准差的年化历史波动率,SKEW 刻画收益分布偏度,DRAWDOWN 度量区间回撤,CVLT/MASS/STD/VHF 分别从波幅变化率、波幅双均线比、价格离散度、趋势-盘整判别等角度补充。 > > - **因子数量**:21 个因子 / 21 个数据列 > - **主键**:`date` + `instrument`(按 `cn_stock_instruments` 对齐全市场标的) > - **数据起始**:2010-01-01,日频增量更新 > - **复权口径**:后复权(`cn_stock_bar1d` 全表统一) --- ## 1. 上游依赖(基础数据表) | 上游表 | 用途 | 本表用到的字段 | |---|---|---| | `cn_stock_bar1d` | 后复权日行情,全部因子的计算输入 | `date`, `instrument`, `high`, `low`, `close` | | `cn_stock_instruments` | 全市场标的清单,决定本表每日的 `date` / `instrument` 组合 | `date`, `instrument` | > `cn_stock_bar1d` 为分区表,SQL 的 date 过滤由 `dai.query(filters={"date": [...]})` 下推完成。 --- ## 2. 因子清单(21 列) | # | 因子中文名 | 字段名 | 参数 | 因子逻辑 | 所属因子族 | |---|---|---|---|---|---| | 1 | 平均真实波幅 | `atr7` | 7 | 短窗真实波幅均值 | ATR 平均真实波幅族 | | 2 | 平均真实波幅 | `atr14` | 14 | 标准 ATR | ATR 平均真实波幅族 | | 3 | 平均真实波幅 | `atr21` | 21 | 长窗 ATR | ATR 平均真实波幅族 | | 4 | ATR 相对比率 | `atr_ratio_7` | 7 | ATR7 / 收盘价(相对波动强度) | ATR 相对比率族 | | 5 | ATR 相对比率 | `atr_ratio_14` | 14 | ATR14 / 收盘价 | ATR 相对比率族 | | 6 | ATR 相对比率 | `atr_ratio_21` | 21 | ATR21 / 收盘价 | ATR 相对比率族 | | 7 | 年化历史波动率 | `hv10` | 10 | 10 日对数收益标准差年化 | 年化历史波动率族 | | 8 | 年化历史波动率 | `hv20` | 20 | 20 日对数收益标准差年化 | 年化历史波动率族 | | 9 | 年化历史波动率 | `hv60` | 60 | 60 日对数收益标准差年化 | 年化历史波动率族 | | 10 | 收益偏度 | `skew20` | 20 | 20 日收益率分布偏度 | 收益偏度族 | | 11 | 收益偏度 | `skew60` | 60 | 60 日收益率分布偏度 | 收益偏度族 | | 12 | 区间最大回撤 | `drawdown20` | 20 | 当前价相对 20 日最高收盘的回撤 | 区间最大回撤族 | | 13 | 区间最大回撤 | `drawdown60` | 60 | 当前价相对 60 日最高收盘的回撤 | 区间最大回撤族 | | 14 | 佳庆离散指标 | `cvlt` | 10 | 波幅均线的 10 日变化率 | CVLT / MASS / STD / VHF 组合 | | 15 | 梅斯线 | `mass` | 9/25 | 波幅双重均线比值的 25 日累加 | CVLT / MASS / STD / VHF 组合 | | 16 | 标准差 | `std25` | 25 | 收盘价的 25 日标准差 | CVLT / MASS / STD / VHF 组合 | | 17 | 纵横指标 | `vhf28` | 28 | 趋势/盘整行情判别(值高为趋势行情) | CVLT / MASS / STD / VHF 组合 | | 18 | 平均真实波动率 | `atr_6` | 6 | TR 的 n1 周期均值 | ATR 平均真实波动率族(多档) | | 19 | 平均真实波动率 | `atr_20` | 20 | TR 的 n1 周期均值 | ATR 平均真实波动率族(多档) | | 20 | 平均真实波动率 | `atr_30` | 30 | TR 的 n1 周期均值 | ATR 平均真实波动率族(多档) | | 21 | 平均真实波动率 | `atr_60` | 60 | TR 的 n1 周期均值 | ATR 平均真实波动率族(多档) | --- ## 3. 因子族公式与 DAI SQL ### 3.1 ATR 平均真实波幅族 **公式**:TR = MAX(H−L, |H−前C|, |L−前C|);ATR_N = SMA_N(TR) **输出列(3)**:`atr7`、`atr14`、`atr21` ```sql SELECT date, instrument, m_ta_atr(high, low, close, 7) AS atr7, m_ta_atr(high, low, close, 14) AS atr14, m_ta_atr(high, low, close, 21) AS atr21 FROM cn_stock_bar1d WHERE close IS NOT NULL ORDER BY date, instrument ``` ### 3.2 ATR 相对比率族 **公式**:ATR_Ratio_N = ATR_N / Close **输出列(3)**:`atr_ratio_7`、`atr_ratio_14`、`atr_ratio_21` ```sql SELECT date, instrument, m_ta_atr(high, low, close, 7) / NULLIF(close, 0) AS atr_ratio_7, m_ta_atr(high, low, close, 14) / NULLIF(close, 0) AS atr_ratio_14, m_ta_atr(high, low, close, 21) / NULLIF(close, 0) AS atr_ratio_21 FROM cn_stock_bar1d WHERE close IS NOT NULL ORDER BY date, instrument ``` ### 3.3 年化历史波动率族 **公式**:HV_N = STD_N(LN(Close/前Close)) × √252 **输出列(3)**:`hv10`、`hv20`、`hv60` ```sql SELECT date, instrument, m_stddev(ln(close / NULLIF(m_lag(close, 1), 0)), 10) * sqrt(252) AS hv10, m_stddev(ln(close / NULLIF(m_lag(close, 1), 0)), 20) * sqrt(252) AS hv20, m_stddev(ln(close / NULLIF(m_lag(close, 1), 0)), 60) * sqrt(252) AS hv60 FROM cn_stock_bar1d WHERE close IS NOT NULL ORDER BY date, instrument ``` ### 3.4 收益偏度族 **公式**:Skew_N = SKEWNESS_N(LN(Close/前Close)) **输出列(2)**:`skew20`、`skew60` ```sql SELECT date, instrument, m_skewness(ln(close / NULLIF(m_lag(close, 1), 0)), 20) AS skew20, m_skewness(ln(close / NULLIF(m_lag(close, 1), 0)), 60) AS skew60 FROM cn_stock_bar1d WHERE close IS NOT NULL ORDER BY date, instrument ``` ### 3.5 区间最大回撤族 **公式**:Drawdown_N = Close / MAX_N(Close) − 1(≤ 0) **输出列(2)**:`drawdown20`、`drawdown60` ```sql SELECT date, instrument, close / NULLIF(m_max(close, 20), 0) - 1 AS drawdown20, close / NULLIF(m_max(close, 60), 0) - 1 AS drawdown60 FROM cn_stock_bar1d WHERE close IS NOT NULL ORDER BY date, instrument ``` ### 3.6 CVLT / MASS / STD / VHF 组合 **公式**:CVLT = Δ10(MA10(H−L)) / LAG(MA10(H−L), 10);MASS = SUM(MA9(H−L) / MA25(MA9(H−L)), 25);STD25 = STD(Close, 25);VHF = (MAX28(C) − MIN28(C)) / SUM(|C − 前C|, 28) **输出列(4)**:`cvlt`、`mass`、`std25`、`vhf28` ```sql SELECT date, instrument, m_delta(m_avg(high - low, 10), 10) / NULLIF(m_lag(m_avg(high - low, 10), 10), 0) AS cvlt, m_sum(m_avg(high - low, 9) / NULLIF(m_avg(m_avg(high - low, 9), 25), 0), 25) AS mass, m_stddev(close, 25) AS std25, (m_max(close, 28) - m_min(close, 28)) / NULLIF(m_sum(abs(close - m_lag(close, 1)), 28), 0) AS vhf28 FROM cn_stock_bar1d WHERE close IS NOT NULL ORDER BY date, instrument ``` ### 3.7 ATR 平均真实波动率族(多档) **公式**:TR = max(H−L, |H−前C|, |L−前C|);ATR = SMA(TR, n) **输出列(4)**:`atr_6`、`atr_20`、`atr_30`、`atr_60` ```sql SELECT date, instrument, m_ta_atr(high, low, close, 6) AS atr_6, m_ta_atr(high, low, close, 20) AS atr_20, m_ta_atr(high, low, close, 30) AS atr_30, m_ta_atr(high, low, close, 60) AS atr_60 FROM cn_stock_bar1d WHERE close IS NOT NULL ORDER BY date, instrument ``` --- ## 4. 数据加工说明 ### 4.1 加工链路 ``` cn_stock_bar1d(后复权,WHERE close IS NOT NULL) → 7 组因子族 SQL 并行执行(joblib loky, n_jobs=8) → 按 cn_stock_instruments 左连接对齐全市场标的 → schema 归一化(列序 / 类型 / 缺失值) → dai_write 按 date 的年份分区落库 ``` - 历史构建:`create()`,自 **2010-01-01** 起按 **2 年**一段滚动执行,每段结束后 `gc.collect()` 释放内存。 - 增量构建:`build()`,默认覆盖最近 5 个自然日;落库前跑 `tester.py`,落库后更新前端文档。 ### 4.2 回溯冗余(避免窗口未预热导致的缺失值) 窗口算子只在查询下推后的行集上计算,所以每次计算都会**向前多取一段行情**: | 参数 | 取值 | 说明 | |---|---|---| | `lookback_days` | **500 个自然日**(≈ 334 个交易日) | 本表最长窗口 / 预热需求约 60 个交易日 | 多读一段历史不改变任何输出值(窗口算子只向前看),只是把区间首日的"本可避免的缺失"消掉。 EMA / RSI / ATR / MACD / TRIX 属于 IIR 递推算子,理论上预热期无限长,因此这些表的冗余按 **约 5 倍最长周期**取值,而非刚好等于窗口长度。 ### 4.3 停牌空值行的处理 `cn_stock_bar1d` 在停牌日会保留一行、但 `open/high/low/close/amount` 全为 NULL、`volume` 为 0。 `m_ta_*` 递推类算子只要吃到一个 NULL,之后就永久输出 NULL。因此所有 SQL 统一加 `WHERE close IS NOT NULL`,把停牌行从计算输入中剔除(此时 `m_lag(close, 1)` 指向上一个**交易日**, 符合技术指标的常规口径)。 实测(2024-01 全市场,回溯起点 2021-06): | 处理方式 | bbands_middle_20 | atr14 | kdj_j_9 | macd_diff_12_26_9 | |---|---|---|---|---| | 不加过滤 | 88.3% | 88.3% | 88.4% | 88.1% | | **加 `WHERE close IS NOT NULL`** | **99.7%** | **99.7%** | **99.7%** | **99.5%** | ### 4.4 累计型因子的锚点 本表不含累计型因子,全部因子都是固定长度的滚动窗口计算,因此只受 `lookback_days` 影响。 ### 4.5 标的对齐与覆盖度 落库前以 `cn_stock_instruments` 为基准左连接,因此**每个交易日都是全市场标的的完整行**, 停牌股与上市不足窗口长度的新股在对应因子列上为 NULL。入库校验要求单因子整体覆盖度 ≥ 85% (`tester.py` 关键测试点),单日覆盖度 ≥ 80%(非关键,仅告警)。 ### 4.6 本表实现要点 - `atr7/14/21` 与 `atr_6/20/30/60` 是同一算子的两组档位(因子文档中 14 日档已去重),命名差异沿用上游因子表与工程代码的历史约定。 - `atr_ratio_*` = ATR / Close,已除量纲,可直接跨股横截面比较;`atr*` 为绝对波幅,横截面使用前需先标准化。 - `hv*` 年化系数取 √252。`cvlt` 按因子文档 SQL 采用 `m_avg`(SMA)平滑波幅,与部分行情软件的 EMA 口径略有差异,此处保持与因子文档一致。 - ATR 为 Wilder 递推(IIR),`atr_60` 预热较长,回溯冗余取 500 个自然日(约 330 个交易日)。 --- ## 5. 覆盖度实测 实测区间 **2026-09-07 ~ 2026-09-17**(9 个交易日、50052 行,已按 `cn_stock_instruments` 对齐全市场标的): | 指标 | 数值 | |---|---| | 因子列数 | 21 | | 最低覆盖度 | **98.98%**(skew60) | | 中位覆盖度 | 99.48% | | 最高覆盖度 | 99.68% | | 覆盖度 < 85% 的列数 | 0 | | `tester.py` 关键测试点 | ✅ 通过 | 覆盖度最低的三列:`skew60`(99.0%)、`hv60`(99.0%)、`atr_60`(99.0%)。缺失主要来自**上市不足窗口长度的新股**与**当日停牌**,逐列明细见 `testdata/coverage_report.md`,数据示例见 `testdata/sample_data.csv`。 --- ## 6. 示例数据 {{sample_data}} --- ## 7. 使用建议 1. **横截面标准化**:本表含绝对量纲列(价位、波幅、成交量等),跨股票比较前建议用 `c_zscore(因子, group=date)` 或 `c_rank(因子, group=date)` 处理,或改用同族的比值型因子。 2. **去极值**:比值类因子分母虽已做 `NULLIF` 保护,但小分母仍会放大尾部,建议按日做分位数截断。 3. **冗余筛选**:同一指标的多参数档位之间相关性很高,建模前建议按 IC / 相关性 / 特征重要性做筛选, 而不是把全部列直接喂给模型。 4. **无未来函数**:全部因子只用当期与历史滚动数据;回测时注意前向收益口径(建议用次日开盘价), 收盘价口径会系统性高估短周期反转类因子的收益。
波动率技术因子 (cn_stock_factors_ta_volatility)
数据描述: 波动率类技术指标因子
文档
用例
表结构
| 字段 | 字段类型 | 字段描述 |
| instrument | string | 证券代码 |
| __PARTITION__ | int64 | - |
| date | timestamp[ns] | 日期 |
| atr7 | double | 平均真实波幅(参数 7)。短窗真实波幅均值。计算式:m_ta_atr(high, low, close, 7) |
| cvlt | double | 佳庆离散指标(参数 10)。波幅均线的 10 日变化率。计算式:m_delta(m_avg(high - low, 10), 10) / NULLIF(m_lag(m_avg(high - low, 10), 10), 0) |
| hv10 | double | 年化历史波动率(参数 10)。10 日对数收益标准差年化。计算式:m_stddev(ln(close / NULLIF(m_lag(close, 1), 0)), 10) * sqrt(252) |
| hv20 | double | 年化历史波动率(参数 20)。20 日对数收益标准差年化。计算式:m_stddev(ln(close / NULLIF(m_lag(close, 1), 0)), 20) * sqrt(252) |
| hv60 | double | 年化历史波动率(参数 60)。60 日对数收益标准差年化。计算式:m_stddev(ln(close / NULLIF(m_lag(close, 1), 0)), 60) * sqrt(252) |
| mass | double | 梅斯线(参数 9/25)。波幅双重均线比值的 25 日累加。计算式:m_sum(m_avg(high - low, 9) / NULLIF(m_avg(m_avg(high - low, 9), 25), 0), 25) |
| atr14 | double | 平均真实波幅(参数 14)。标准 ATR。计算式:m_ta_atr(high, low, close, 14) |
| atr21 | double | 平均真实波幅(参数 21)。长窗 ATR。计算式:m_ta_atr(high, low, close, 21) |
| atr_6 | double | 平均真实波动率(参数 6)。TR 的 n1 周期均值。计算式:m_ta_atr(high, low, close, 6) |
| std25 | double | 标准差(参数 25)。收盘价的 25 日标准差。计算式:m_stddev(close, 25) |
| vhf28 | double | 纵横指标(参数 28)。趋势/盘整行情判别(值高为趋势行情)。计算式:(m_max(close, 28) - m_min(close, 28)) / NULLIF(m_sum(abs(close - m_lag(close, 1)), 28), 0) |
| atr_20 | double | 平均真实波动率(参数 20)。TR 的 n1 周期均值。计算式:m_ta_atr(high, low, close, 20) |
| atr_30 | double | 平均真实波动率(参数 30)。TR 的 n1 周期均值。计算式:m_ta_atr(high, low, close, 30) |
| atr_60 | double | 平均真实波动率(参数 60)。TR 的 n1 周期均值。计算式:m_ta_atr(high, low, close, 60) |
| skew20 | double | 收益偏度(参数 20)。20 日收益率分布偏度。计算式:m_skewness(ln(close / NULLIF(m_lag(close, 1), 0)), 20) |
| skew60 | double | 收益偏度(参数 60)。60 日收益率分布偏度。计算式:m_skewness(ln(close / NULLIF(m_lag(close, 1), 0)), 60) |
| drawdown20 | double | 区间最大回撤(参数 20)。当前价相对 20 日最高收盘的回撤。计算式:close / NULLIF(m_max(close, 20), 0) - 1 |
| drawdown60 | double | 区间最大回撤(参数 60)。当前价相对 60 日最高收盘的回撤。计算式:close / NULLIF(m_max(close, 60), 0) - 1 |
| atr_ratio_7 | double | ATR 相对比率(参数 7)。ATR7 / 收盘价(相对波动强度)。计算式:m_ta_atr(high, low, close, 7) / NULLIF(close, 0) |
| atr_ratio_14 | double | ATR 相对比率(参数 14)。ATR14 / 收盘价。计算式:m_ta_atr(high, low, close, 14) / NULLIF(close, 0) |
| atr_ratio_21 | double | ATR 相对比率(参数 21)。ATR21 / 收盘价。计算式:m_ta_atr(high, low, close, 21) / NULLIF(close, 0) |
表名:cn_stock_factors_ta_volatility
起始时间:
最近更新时间: