Files
ProStock/docs/Classify2_load_model_doc.md
liaozhaorun a9e4746239 refactor: 代码审查修复 - 日期过滤、性能优化、数据泄露防护
- 修复 data_loader.py 财务数据日期过滤,支持按范围加载
- 优化 MADClipper 使用窗口函数替代 join,提升性能
- 修复训练日期边界问题,添加1天间隔避免数据泄露
- 新增 .gitignore 规则忽略训练输出目录
2026-02-25 21:11:19 +08:00

25 KiB
Raw Blame History

Classify2_load_model.ipynb 代码流程详解文档

概述

本文档详细描述了 Classify2_load_model.ipynb 文件中完整的代码流程该notebook实现了一个股票分类模型的特征工程与数据预处理流程。整个流程涵盖了从原始数据加载、多源数据合并、因子计算、数据清洗、特征标准化等多个环节最终输出可供机器学习模型使用的特征矩阵。


第一部分:环境配置与初始化

1.1 基础环境设置

notebook开头的第一个代码单元负责基础的开发环境配置。首先启用Jupyter的自动重载功能通过%load_ext autoreload%autoreload 2指令,使得在修改导入的模块后能够自动重新加载,这对于开发调试阶段非常实用。随后进行垃圾回收机制的相关设置,导入gc模块用于手动管理内存因为后续处理的数据量较大数GB级别及时释放不需要的对象可以避免内存溢出。

系统路径的配置通过sys.path.append完成将项目根目录添加到Python的模块搜索路径中这样可以直接导入项目内的自定义模块。打印工作目录用于确认当前运行环境。数据处理的核心库pandas被导入用于表格数据处理,同时导入项目内部的因子模块和工具函数,包括get_rolling_factorget_simple_factor用于计算技术因子,read_industry_data用于读取行业分类数据,calculate_score用于计算目标变量。最后通过warnings.filterwarnings("ignore")忽略所有警告信息,保持输出界面的整洁。

1.2 并行计算配置

第二个代码单元配置了Modin框架的并行计算参数。通过设置环境变量os.environ["MODIN_CPUS"] = "4"指定使用4个CPU核心进行并行计算。Modin是一个pandas的并行替代库能够在多核CPU上并行执行pandas操作显著加速大规模数据的处理速度。这一配置对于后续处理数千万条记录的数据框至关重要。


第二部分:核心数据加载与合并

2.1 日线数据加载

第三个代码单元是整个流程中最关键的数据加载步骤依次从HDF5文件中读取多个数据源并合并。HDF5是一种高效的分块压缩存储格式非常适合存储大规模数值型数据。

第一步:加载日线行情数据

使用read_and_merge_h5_data函数从daily_data.h5文件中读取日线行情数据。该函数是项目自定义的工具函数,其核心逻辑在main/utils/utils.py中实现。读取的字段包括股票代码ts_code、交易日期trade_date、开盘价open、收盘价close、最高价high、最低价low、成交量vol、成交额amount以及涨跌幅pct_chg。这些字段构成分析的基础价格信息。首次调用该函数时df参数为空,因此直接返回读取的数据作为初始数据框。

第二步:加载日线基础数据

继续调用read_and_merge_h5_data读取daily_basic.h5文件获取每日股票的基础财务指标。本次读取使用内连接inner join方式与已有数据进行合并这意味着只保留两个数据集中都存在的股票记录。读取的字段包括turnover_rate(换手率)、pe_ttm(滚动市盈率)、circ_mv(流通市值)、total_mv(总市值)以及volume_ratio(量比)。这些指标对于评估股票的流动性和估值水平非常重要。

第三步:加载涨跌停限制数据

stk_limit.h5文件中读取股票的涨跌停价格信息。读取的字段包括pre_close(前一日收盘价)、up_limit(涨停价)和down_limit(跌停价)。这些信息用于后续识别股票的涨停状态,是构建目标变量的重要依据。

第四步:加载资金流数据

money_flow.h5文件中读取资金流信息,这是计算资金流因子的基础数据。读取的字段包括各类成交量的分解:buy_sm_volsell_sm_vol代表小单买卖成交量、buy_lg_volsell_lg_vol代表大单买卖成交量、buy_elg_volsell_elg_vol代表超大单买卖成交量,以及net_mf_vol(净资金流成交量)。通过分析这些不同档位的资金流向,可以判断机构投资者和散户的交易行为。

第五步:加载筹码分布数据

最后从cyq_perf.h5文件中读取筹码分布相关指标。这些数据反映的是股票持仓成本分布情况,包括历史最低价his_low、历史最高价his_high、不同成本分位线的价格(cost_5pctcost_15pctcost_50pctcost_85pctcost_95pct)、加权平均成本weight_avg以及获利盘比例winner_rate。这些指标是计算筹码分布因子的核心数据。

经过上述五个步骤的依次合并最终生成的数据框包含9436343条记录、33个字段占用内存约2.3GB。

2.2 行业数据加载与合并

第四个代码单元处理行业分类数据的加载与合并。首先使用read_and_merge_h5_data函数从industry_data.h5文件中读取行业分类数据,提取股票代码、二级行业代码l2_code以及行业纳入日期in_date

随后定义了merge_with_industry_data函数用于将行业数据与主数据框进行时间匹配合并。该函数的核心逻辑分为以下几个步骤首先确保日期字段转换为datetime类型然后分别对行业数据和主数据按股票代码和日期排序接着使用pd.merge_asof函数进行向后合并direction='backward'),这意味着对于每一股票的每一个交易日,会匹配该日之前(包括当日)最近的行业变更记录;对于交易日期早于所有行业变更日期的记录,使用每个股票的最早行业代码进行填充。

这一合并策略的设计目的是确保在任意交易日期都能获取到该股票当前所属的行业分类,这对于后续进行行业中性化处理至关重要。


第三部分:指数数据处理

3.1 指数数据读取

第五个代码单元实现指数数据的读取与指标计算。定义了两个核心函数:calculate_indicators用于计算单个指数的技术指标,generate_index_indicators用于批量处理多个指数。

calculate_indicators函数中,首先对数据按交易日期排序,然后计算以下指标:

当日涨跌幅:通过(close - pre_close) / pre_close * 100计算,这是最基础的收益率指标。

RSI指标相对强弱指数计算过程包括首先计算价格变动delta然后分离上涨和下跌部分分别计算14日滚动平均最后通过公式100 - (100 / (1 + rs))得到RSI值。RSI是衡量股票近期涨跌动能的经典技术指标。

MACD指标移动平均收敛发散指标计算过程包括12日EMA减去26日EMA得到MACD线9日EMA得到信号线MACD与信号线的差值得到MACD柱。MACD是判断趋势方向和动量变化的重要工具。

情绪因子

  • 上涨比例up_ratio_20d过去20天上涨天数占比反映市场整体情绪
  • 成交量变化率volume_change_rate当日成交量与20日均量的比率反映成交量异常变化
  • 波动率volatility过去20天日收益率的标准差反映市场波动程度
  • 成交额变化率amount_change_rate当日成交额与20日均额的比率

generate_index_indicators函数则对所有指数分别计算上述指标,然后将结果透视为宽表格式,使每个指数的指标成为独立的列。最终输出包含多个指数技术指标的数据框,这些指标可以作为市场情绪的代理变量加入模型。

3.2 行业指数数据处理

第六个代码单元使用talib库和numpy库进行更专业的技术指标计算。talib是专业的技术分析库包含数百种经典技术指标的实现。

sw_daily.h5文件读取行业日线数据后,依次计算:

OBV能量潮指标:通过talib.OBV函数计算,将成交量与价格变动方向结合,衡量资金流入流出的强度。

短期收益率return_55日收益率计算公式为x / x.shift(5) - 1

中期收益率return_2020日收益率用于捕捉中短期动量。

动量因子act_factor:通过get_act_factor函数计算该函数对不同周期的EMA指数移动平均进行arctan变换得到平滑的动量因子。这是项目自定义的核心因子之一。

收益率分位数排名:将收益率在截面内转换为百分位排名,消除不同行业间的基数差异,便于跨行业比较。

最终对所有新增字段添加industry_前缀,并重命名ts_codecat_l2_code,形成行业级别的因子数据,可用于后续的行业对标分析。


第四部分:财务数据加载

4.1 财务指标数据

第九至十一个代码单元负责加载各类财务数据,为模型增加基本面因子。

财务指标数据fina_indicator:从fina_indicator.h5文件读取,包含undist_profit_ps(每股未分配利润)、ocfps(每股经营现金流)、bps(每股净资产)、roa(资产收益率)和roe(净资产收益率)。这些指标反映企业的盈利能力和财务健康状况。

现金流数据cashflow:从cashflow.h5文件读取,包含n_cashflow_act(经营活动净现金流),用于评估企业现金流的真实状况。

资产负债表数据balancesheet:从balancesheet.h5文件读取,包含money_cap(货币资金)和total_liab(总负债),用于计算企业的偿债能力。

这些财务数据通过ann_date(公告日期)与交易数据进行时间匹配,确保使用最新披露的财务信息。需要注意的是,财务数据存在滞后性,通常季报在季度结束后一段时间才披露,因此在匹配时使用向后合并策略。


第五部分:数据过滤与清洗

5.1 数据过滤规则

第十一个代码单元定义了filter_data函数,应用一系列过滤规则清理数据:

排除ST股票df[~df['is_st']]过滤掉所有ST特别处理股票这类股票存在较大风险。

排除北京股票df[~df['ts_code'].str.endswith('BJ')]排除北京交易所的股票。

排除创业板和科创板df[~df['ts_code'].str.startswith('30')]排除创业板股票,df[~df['ts_code'].str.startswith('68')]排除科创板股票。这一设计可能是因为这两个板块的股票特性与主板有较大差异。

排除ST类代码df[~df['ts_code'].str.startswith('8')]排除了以8开头的股票代码通常这类代码也属于风险警示类。

时间范围过滤df[df['trade_date'] >= '2019-01-01']]只保留2019年及以后的数据确保数据质量和一致性。

删除冗余列:如果存在in_date列则删除,避免与交易日期混淆。

过滤后的数据量从9436343条减少到5087384条约减少46%。


第六部分:因子计算

6.1 财务因子计算

第十二个代码单元是因子计算的核心部分,首先计算一系列财务相关因子:

现金流因子cashflow_to_ev_factor:将现金流数据与企业价值进行对比,计算企业现金流的相对估值水平。

市净率因子book_to_price_ratio:通过caculate_book_to_price_ratio函数计算,每股净资产与股价的比值,是价值投资的经典指标。

6.2 基础技术因子

继续计算各类技术因子:

换手率均值turnover_rate_mean_55日平均换手率反映股票的交易活跃程度。

收益率方差variance_2020日收益率方差衡量短期波动性。

BBI比率因子bbi_ratio_factorBBI是多空指数的简称通过不同周期均线的组合判断多空趋势。

日偏离度daily_deviation:当日涨跌幅与市场平均涨跌幅的差异,反映个股的相对强弱。

日行业偏离度daily_industry_deviation:相对于所在行业平均涨跌幅的偏离,反映行业内相对表现。

6.3 滚动因子与简单因子

调用get_rolling_factorget_simple_factor函数批量计算大量因子。这两个函数定义在main/factor/factor.py中,是项目最核心的因子计算模块。

get_rolling_factor函数主要计算的因子包括:

资金流因子组

  • lg_elg_net_buy_vol:超大单加大单的净买入量
  • flow_lg_elg_intensity:主力资金流强度,等于净买入量除以成交量
  • sm_net_buy_vol:散户净买入量
  • flow_divergence_diff:散户与主力背离度,主力净买入减去散户净买入
  • flow_divergence_ratio:背离比率形式
  • lg_elg_buy_prop:主力买入占比
  • flow_struct_buy_change资金流结构变动1日变化率
  • flow_lg_elg_accel:资金流加速度,二阶导数

筹码分布因子组

  • chip_concentration_range95%成本价 - 5%成本价)/ 当前价格,反映筹码集中程度
  • chip_skewness:(加权平均成本 - 50%成本价)/ 50%成本价,反映成本分布偏斜方向
  • floating_chip_proxy:浮筹比例,结合获利盘和价格位置
  • cost_support_15pct_change15%成本线变化率,反映支撑位变动
  • cat_winner_price_zone:获利盘价格区域分类

资金与筹码结合因子

  • flow_chip_consistency:资金流与筹码结构一致性
  • profit_taking_vs_absorb:获利了结压力与承接盘强度

收益率分布因子

  • upside_voldownside_vol:上涨和下跌方向的标准差
  • vol_ratio:上下波动率比值
  • return_skewreturn_kurtosis:收益率的偏度和峰度

成交量因子

  • volume_change_rate:成交量变化率
  • cat_volume_breakout:成交量突破信号
  • turnover_deviation:换手率偏离度
  • cat_turnover_spike:换手率激增信号
  • avg_volume_ratiocat_volume_ratio_breakout:量比相关因子

talib技术指标

  • atr_14atr_614日和6日平均真实波幅
  • obvmaobv_6能量潮及其6日均线
  • rsi_33日RSI

收益率因子

  • return_5return_205日和20日收益率
  • std_return_5std_return_90std_return_90_2:不同周期的收益率标准差

EMA与动量因子

  • 各周期EMA5、13、20、60日
  • act_factor1act_factor4基于EMA的动量因子

协方差因子

  • cov:高价与成交量的滚动协方差
  • delta_cov:协方差差分
  • alpha_22_improved改进的alpha因子

其他因子

  • alpha_003:收盘价与开盘价的相对位置
  • alpha_007收盘价与成交量的5日滚动相关性
  • alpha_0135日与20日累计收益差值
  • vol_break价格突破85%成本线且量比大于2的信号
  • weight_roc5加权成本5日变化率
  • price_cost_divergence:价格与成本相关性
  • smallcap_concentration:小盘股筹码集中度
  • cost_stability:筹码稳定性指数
  • liquidity_risk:筹码流动性风险

get_simple_factor函数在滚动因子的基础上进一步计算衍生因子:

  • momentum_factor动量因子等于成交量变化率加0.5倍换手率偏离度
  • resonance_factor:共振因子,量比乘以涨跌幅
  • log_close:收盘价对数
  • cat_vol_spike:成交量激增分类变量
  • updown:上下影线比例
  • obv_maobv_6OBV与6日均线差值
  • std_return_5_over_std_return_90:短期与长期波动率比值
  • act_factor5act_factor6:综合动量因子
  • active_buy_volume_*:各档位主动买入占比
  • ctrl_strength:控制强度,反映成本区间与历史区间的比值
  • low_cost_devasymmetrylock_factor:各类筹码特征因子
  • cat_golden_resonance:黄金共振信号

6.4 资金流因子

第十三个代码单元继续计算money_factor.py中定义的各类资金流相关因子。这些因子主要分析大单资金的流动特征和动量属性。

lg_flow_mom_corr大单资金流与20至60日滚动窗口的动量相关性衡量资金流趋势的持续性。

lg_flow_accel:大单资金流加速度,捕捉资金流入流出的加速变化。

profit_pressure:盈利压力因子,结合价格位置和资金流向。

underwater_resistance:水下阻力因子,分析亏损区域的支持强度。

cost_conc_std_2020日成本集中度标准差反映筹码分布的稳定程度。

profit_decay_2020日盈利衰减因子衡量获利盘随时间的减少程度。

vol_amp_loss_2020日波动幅度损失因子。

vol_drop_profit_cnt_55日内量价齐升计数。

lg_flow_vol_interact_2020日大单资金流与成交量交互因子。

cost_break_confirm_cnt_55日内成本突破确认计数。

atr_norm_channel_pos_1414日ATR标准化通道位置。

turnover_diff_skew_2020日换手率差值偏度。

lg_sm_flow_diverge_2020日大小单资金流背离。

pullback_strong_20_2020日回撤强度因子。

vol_wgt_hist_pos_2020日成交量加权历史位置。

vol_adj_roc_2020日成交量调整变动率。

6.5 截面排名因子

第十三个代码单元的后半部分定义了一系列cs_rank_*开头的截面排名因子,这些因子都是通过截面排名方式计算得出,可以消除不同股票间的基数差异。

cs_rank_net_lg_flow_val:大单净流入值截面排名

cs_rank_flow_divergence:资金流背离截面排名

cs_rank_industry_adj_lg_flow:行业调整后大单资金流截面排名

cs_rank_elg_buy_ratio:超大单买入占比截面排名

cs_rank_rel_profit_margin:相对盈利-margin截面排名

cs_rank_cost_breadth:成本宽度截面排名

cs_rank_dist_to_upper_cost:到上方成本距离截面排名

cs_rank_winner_rate:获利盘比例截面排名

cs_rank_intraday_range:日内振幅截面排名

cs_rank_close_pos_in_range:收盘价在成本区间位置截面排名

cs_rank_opening_gap:跳空缺口截面排名(需要前收盘价)

cs_rank_pos_in_hist_range:历史区间位置截面排名

cs_rank_vol_x_profit_margin成交量与盈利margin交互截面排名

cs_rank_lg_flow_price_concordance:大单资金流与价格一致性截面排名

cs_rank_turnover_per_winner:单位获利盘换手率截面排名

cs_rank_ind_cap_neutral_pe:行业市值中性市盈率截面排名

cs_rank_volume_ratio:量比截面排名

cs_rank_elg_buy_sell_sm_ratio:超大单买卖与小单比值截面排名

cs_rank_cost_dist_vol_ratio:成本分布成交量比值截面排名

cs_rank_size:市值规模截面排名

经过上述所有因子计算数据框最终包含181个字段内存占用约6.5GB。


第七部分:数据预处理函数定义

7.1 特征漂移检测

第十四个代码单元定义了remove_shifted_features函数,用于检测训练集和测试集之间是否存在特征分布漂移。漂移检测使用两种统计方法:

KS检验Kolmogorov-Smirnov检验比较两个分布是否来自同一分布通过p值判断p值小于阈值默认0.05)则认为存在显著差异。

Wasserstein距离衡量两个分布之间的Earth Mover距离距离大于阈值默认0.1)则认为漂移严重。

如果特征同时满足两个条件,则认为该特征存在漂移并将其移除。这一步骤对于确保模型在测试集上的泛化能力非常重要。

7.2 标准化处理函数

第十五个代码单元定义了三个核心的标准化处理函数:

cs_mad_filter截面MAD去极值函数

MADMedian Absolute Deviation中位绝对偏差是一种稳健的极值检测方法。具体步骤包括按日期分组计算每列的中位数然后计算每个值与中位数的绝对偏差再次取中位数得到MAD最后将超出[median - k * MAD, median + k * MAD]范围的值截断到边界。默认k=3scale_factor=1.4826使得MAD约等于正态分布的标准差。

cs_neutralize_market_cap_numpy市值中性化函数

对每个交易日的每只股票使用OLS回归将因子值对市值取对数进行回归提取残差作为中性化后的因子值。这一步骤消除因子中与市值相关的系统性偏差使因子更能反映股票的真实特性而非市值效应。

cs_zscore_standardize截面Z-Score标准化函数

对每个截面每日计算各因子的均值和标准差然后进行Z-Score变换Z = (value - mean) / (std + epsilon)。这使得不同量纲的因子具有可比性且均值为0、标准差为1。

fill_nan_with_daily_median截面中位数填充函数

对每个交易日分别计算各因子的中位数,用该中位数填充该日内的缺失值。这一方法比全局中位数填充更能反映数据的时间特性。

7.3 其他预处理函数

第十五个代码单元还定义了其他辅助预处理函数:

remove_outliers_label_percentile对标签进行百分位去极值默认保留1%到99%分位之间的数据。

calculate_risk_adjusted_target:计算风险调整后的目标变量,结合未来收益率和未来波动性。

calculate_score:计算综合评分目标,考虑未来收益减去风险惩罚(最大回撤)。

remove_highly_correlated_features:移除高度相关的特征,避免多重共线性问题。

cross_sectional_standardization截面标准化使用StandardScaler进行标准化。

neutralize_manual_revised:手动实现的行业市值中性化函数,对每个行业分别进行回归取残差。

mad_filter全局MAD去极值函数简化版

percentile_filter:百分位去极值函数。

iqr_filter:四分位距标准化函数。

quantile_filter:滚动分位数去极值函数。

select_top_features_by_rankic基于RankIC选择最优特征。

create_deviation_within_dates:创建截面偏差特征,计算行业内各因子与均值的偏差。


第八部分:目标变量构建

8.1 未来收益率计算

第十六个代码单元负责构建预测目标变量。

未来收益率:通过df.groupby('ts_code')['close'].shift(-days) / df['close'] - 1计算days默认为5即预测未来5日的收益率。shift(-days)表示向后移动获取未来价格。

涨停标签构建分类目标变量首先识别当日涨幅超过5%的股票(cat_up_limit然后计算过去5日内是否存在涨停通过rolling窗口的max函数再向后shift(5)避免未来信息泄露最后fillna(0)并转换为整数类型。

过滤异常收益率:使用between方法保留1%到99%分位之间的收益率,去除极端值。


第九部分:特征列筛选

9.1 特征列筛选逻辑

第十七个代码单元进行特征列的最终筛选。通过一系列排除规则,从所有可用列中筛选出建模所需的特征列:

排除非特征列:排除trade_datets_codelabel等标识列;排除包含futurelabelscoregenis_stpe_ttmcirc_mvcode等关键词的列;排除原始基础数据列origin_columns;排除下划线开头的临时列。

排除特定特征:手动排除存在问题的特征如intraday_lg_flow_corr_20cap_neutral_cost_metrichurst_net_mf_vol_60等;排除财务因子roaroe

最终筛选出191个特征列用于建模。


第十部分:缺失值处理与标准化流程

10.1 缺失值填充

第十八个代码单元将所有特征的缺失值填充为0。这一简化处理的假设是缺失值可能代表数据不可用或极小概率事件用0填充对模型影响相对中性。

10.2 完整的预处理流水线

第十九个代码单元展示了完整的预处理流程执行:

第一步:特征列确定——合并行业数据、指数数据后确定最终特征列表。

第二步MAD去极值——执行第一轮截面MAD去极值处理全量特征。

第三步:市值中性化——对第一轮去极值后的特征进行截面市值中性化。

第四步第二轮MAD去极值——对中性化后的特征再次进行去极值处理。

第五步Z-Score标准化——最后对所有特征进行截面Z-Score标准化。

整个流水线确保了最终进入模型的特征具有:稳定的分布(去极值)、去除市值偏差(中性化)、可比性(标准化)。


总结

Classify2_load_model.ipynb实现了一个完整、规范的量化因子工程流程。整个流程涵盖了数据加载、多源数据合并、因子计算、特征筛选、预处理标准化等关键步骤。

数据层面整合了日线行情、资金流、筹码分布、财务指标、行业分类、指数数据等多维度数据源形成了超过180个特征的基础特征池。

因子层面:因子体系覆盖了资金流因子、筹码分布因子、技术指标因子、动量因子、波动率因子、截面排名因子等多个类别,形成了多角度、全方位的特征体系。

预处理层面建立了完整的预处理流水线包括MAD去极值、市值中性化、Z-Score标准化等标准化步骤确保特征的质量和稳定性。

整个notebook的设计体现了量化投资特征工程的最佳实践为后续的机器学习模型训练提供了高质量的数据基础。