基于日频 A 股数据,构建主动买卖资金流因子并完成因子有效性分析。
主动买卖力量指标 a
a = (buy_value - sell_value) / (buy_value + sell_value) ∈ [-1, 1]
因子计算逻辑
参数:WINDOW_DAYS = 20,λ = 0.2,SELECT_N = 4
回溯过去 20 个交易日,选出 pct_rate 最低的 4 天,对这 4 天的 a 取均值 → factor
有效性阈值:窗口内 pct_rate 非 NaN 天数 ≥ 16,且选出的 4 天中 a 的 NaN 数 < 2。
- 来源:
数据.csv - 规模:约 5,343 只股票 × 1,329 个交易日
- 核心字段:
order_book_id、date、buy_value、sell_value、pct_rate
使用 pandas 完成原始数据读取与结构检查:字段类型、date 转换、按 (order_book_id, date) 排序、股票数 / 交易日数 / 日期范围统计、面板完整性与重复主键检查。
使用 isnull().sum() / .mean() 对三个核心字段按字段、按股票、按日期三个维度统计缺失情况,识别核心字段严重缺失的异常交易日。
使用 .notna().any(axis=1) 标记 valid_obs(三字段至少一个非 NaN 即视为当天有效),区分"区间外缺失"与"区间内缺失"两类 NaN,避免后续时序操作引入隐性误差。
- 计算
a:calculate_a()向量化计算,分母为 0 时自动置 NaN。 - 计算
factor:_factor_single_stock()用numpy.lib.stride_tricks.as_strided构造滑动窗口矩阵,全程无 Python 级别循环;calculate_factor()按股票 for 循环调用,兼顾性能与可读性。
NaN 来源拆解:窗口期不足(每只股票前 19 天固定为 NaN,共 ~101,517 行)+ 数据质量不足(pct 有效天数 < 16 或选出的 4 天 a 中 NaN ≥ 2)。
用对数收益 log(1+r) + 按股票分组 cumsum 构造 T+1 / T+3 / T+5 / T+10 / T+20 五个期限的未来收益率。任意区间收益由两端点 cumlog 相减得到,时间复杂度 O(N) 与期限数无关(直接滚动连乘为 O(K·N))。pct_rate NaN 临时填 0 防止 cumsum 断链,对应窗口含缺失的结果在 IC 计算时 dropna 过滤。
calc_ic_series() 计算 T+1 / T+3 / T+5 / T+10 / T+20 的每日横截面 Spearman IC(= Pearson(rank(factor), rank(return)),全程向量化),输出 IC_mean、IC_std、ICIR、t-stat 汇总表。有效日阈值:当日有效股票数 ≥ 30。另外单独计算 T+1 到 T+20 逐天 IC 衰减序列,识别因子预测力有效期。
calc_group_return_table() 每日横截面按 factor 等分 5 组(G1 最低 ~ G5 最高),计算各组等权日均未来收益及 G5-G1 利差。
- 累计 IC 曲线:T+1/3/5/10/20 的 cumIC(t) 折线图,斜率用于识别因子失效时段。T+20 因窗口重叠(~95% 自相关)曲线更平滑,以 T+1 为基准解读。
- IC 衰减柱状图:T+1 到 T+20 逐天 IC_mean,标注首次衰减至 T+1 的 20% 以下的天数。
- 分组收益柱状图:G1~G5 各组 T+1/5/10/20 累计收益对比及 G5-G1 利差。
- G5-G1 利差 T+20 累计 -91 bps,折算日均仅 -0.5 bps,交易成本后几乎无超额。
- G1 非最高收益组(G2 更高),底部分位非单调,无法构造干净多空组合。
- G2~G5 单调性明确:因子主要识别"未来跑输"的高分位股票(G5)。
- 结论:该因子更适合作为排除信号(规避 G5),而非双边多空策略。
.
├── readme.md
├── 数据.csv
└── work.ipynb
Python 3.x
pandas
numpy
matplotlib
- 数据体检阶段不直接删除或填充 NaN,区分不同成因后再处理
- 资金流缺失不等于 0,不建议直接
fillna(0) - 因子计算前数据必须已按
(order_book_id, date)排序 - IC 与分组收益分析须严格使用
shift(-1)对齐未来收益,避免前视偏差