Factor API
factor.factor
核心因子处理模块,提供可交易池获取、因子预查询、分组打标签、权重生成等功能。
数据准备函数
- get_tradable_pool(date_list)
获取可交易股票池。对每个调仓日查询交易状态为1的证券。
- Parameters:
date_list – 日期列表
- Returns:
(date_ranges, code_ranges) 元组
- pre_query_characteristic_data(date_list, metric, time_tolerance=17520, table_name='fundamental_data', date_ranges=None, code_ranges=None)
批量预查询因子数据,生成符合因子排序函数要求的DataFrame。
- Parameters:
date_list – 调仓日期列表
metric – 因子指标名称
time_tolerance – 时间容差(小时),默认2年
table_name – 数据库表名
date_ranges – 可选,复用的日期范围
code_ranges – 可选,复用的代码范围
- Returns:
DataFrame,包含 input_ts, code, metric, datetime, diff_hours 等列
单因子函数
- single_characteristic(pre_queried_data, metric, quantiles)
单因子分组打标签。
- Parameters:
pre_queried_data – 预查询的因子数据DataFrame
metric – 因子指标名称
quantiles – 分位数字典,如 {“ROE”: 10}
- Returns:
带标签的DataFrame,索引为(input_ts, code)
- get_single_factor_weight(labeled_pool, params)
根据单因子标签生成多空权重。
- Parameters:
labeled_pool – 带标签的因子池
params – 参数字典,包含 factor_key, mode, long, short 等
- Returns:
权重DataFrame
- describe_labeled_pool(labeled_pool)
描述打标签后的因子池统计信息。
- Returns:
透视表,包含每个标签组的样本数和均值
双因子函数
- double_characteristic(pre_queried_data1, pre_queried_data2, metric1, metric2, quantiles1, quantiles2, sort_method='dependent')
双因子分组打标签(Double Sort)。
- Parameters:
pre_queried_data1 – 主因子数据
pre_queried_data2 – 次因子数据
metric1 – 主因子名称
metric2 – 次因子名称
quantiles1 – 主因子分组数
quantiles2 – 次因子分组数
sort_method – ‘independent’ 或 ‘dependent’
- Returns:
带双标签的DataFrame
- get_double_factor_weight(labeled_pool, params)
根据双因子标签生成多空权重。
- Parameters:
labeled_pool – 带双标签的因子池
params – 参数字典,包含 factor_key1, factor_key2, mode, long_combinations, short_combinations 等
- Returns:
权重DataFrame
- describe_double_labeled_pool(labeled_pool)
描述双因子打标签后的统计信息。
- Returns:
(count_pivot, mean_pivot1, mean_pivot2) 元组
多因子函数
- multi_characteristic(pre_queried_data_list, factors)
多因子分组打标签(Multi-Factor Sort)。
- Parameters:
pre_queried_data_list – DataFrame列表
factors – 因子配置列表,每个元素包含 name, quantiles, method
- Returns:
带多标签的DataFrame
- get_multi_factor_weight(labeled_pool, params)
根据多因子标签生成多空权重。
- Parameters:
labeled_pool – 带多标签的因子池
params – 参数字典,包含 mode, long_combinations, short_combinations 等
- Returns:
权重DataFrame
- describe_multi_labeled_pool(labeled_pool, max_display_dims=2)
描述多因子打标签后的统计信息。
- Parameters:
max_display_dims – 最大显示维度
- Returns:
统计信息字典
factor.preprocessing
因子预处理模块,在 pre_query_characteristic_data() 之后、single_characteristic() 之前调用。
提供截面级别的去极值、标准化、中性化,以及一键预处理流水线。
截面处理函数
- winsorize_factor(factor_series, method='mad', n=3.0)
截面去极值(单截面,index=code)。
- Parameters:
factor_series – 单截面因子值(pd.Series,index=code)
method –
'mad'中位数绝对偏差(推荐)|'percentile'百分位截尾 |'std'均值±n倍标准差n – 阈值倍数(percentile 方法时为单侧截尾百分比,如 n=1 截 [1%, 99%])
- Returns:
去极值后的 Series
>>> s = pd.Series({'A': 100, 'B': 2, 'C': 3, 'D': 1}) >>> winsorize_factor(s, method='mad', n=3)
- standardize_factor(factor_series, method='zscore')
截面标准化(单截面,index=code)。
- Parameters:
factor_series – 单截面因子值
method –
'zscore'(x-mean)/std |'rank'rank/N 映射到(0,1) |'minmax'缩放到[0,1]
- Returns:
标准化后的 Series
- neutralize_factor(factor_series, industry_labels=None, log_market_cap=None, return_stats=False)
OLS 残差中性化(单截面)。对行业哑变量 + log(市值) 做截面 OLS,返回残差。 行业标签既可直接传入,也可由
preprocess_factor(industry_scheme=...)自动从 industry 表注入。- Parameters:
factor_series – 因子值 Series,index=code(已标准化)
industry_labels – 行业标签 Series,index=code(None 则跳过)
log_market_cap – log 市值 Series,index=code(None 则跳过)
return_stats – True 时额外返回回归诊断 dict(
n_obs/n_industry_dummies/r2/skipped)
- Returns:
残差 Series;
return_stats=True时返回(残差 Series, stats dict)
>>> neutralize_factor(s, industry_labels=ind, log_market_cap=lmc) >>> resid, stats = neutralize_factor(s, industry_labels=ind, return_stats=True)
因子对因子中性化
- neutralize_factor_by_factor(factor_b_data, factor_a_data, metric_b, metric_a)
用因子 A 对因子 B 做截面 OLS 中性化,返回残差作为”剔除 A 影响后的 B”。
- Parameters:
factor_b_data – 被解释因子的
pre_query_characteristic_data()输出(列含 input_ts, code, {metric_b})factor_a_data – 解释因子的输出(列含 input_ts, code, {metric_a})
metric_b – 被解释因子列名
metric_a – 解释因子列名
- Returns:
同 factor_b_data 格式的 DataFrame,{metric_b} 列替换为残差值
>>> roe_pure = neutralize_factor_by_factor(roe_data, size_data, 'ROE', 'SIZE') >>> labeled = single_characteristic(roe_pure, 'ROE', quantiles={'ROE': 10})
行业中性化工具
- query_industry_panel(pre_queried_data, scheme='申万一级行业', industry_table='industry', verbose=True)
面板行业查询:为
pre_queried_data的每个 (input_ts, code) 取 point-in-time 行业名。 逐期调用 :func:`betalens.datafeed.query_industry`(datetime<=查询日 的最近一条,天然防前视),复用现有 API。- Parameters:
pre_queried_data – 含 input_ts, code 列(
pre_query_characteristic_data()的输出)scheme – 分类体系(metric),不带版本后缀时自动落到查询日生效的版本
industry_table – 行业表名,默认
'industry'verbose – True 时打印行业分布 / 缺失 / 面板平衡诊断
- Returns:
Series,MultiIndex=(input_ts, code),值为 ind_name
>>> ind_panel = query_industry_panel(pre_queried_data, '申万一级行业') >>> ind_panel.xs(ts) # 取某期 code->行业
- filter_pool_by_industry(labeled_pool, industry_map, include_industries)
将打标签的选股池限制在指定行业范围内。
- Parameters:
labeled_pool –
single_characteristic()的输出,MultiIndex(input_ts, code)industry_map – 行业映射表(列含 input_ts, code, industry)
include_industries – 保留的行业列表,如
['银行', '非银金融']
- Returns:
过滤后的 labeled_pool
- apply_industry_weight_constraint(weights, industry_map, method='equal', target_weights=None)
对已生成的权重矩阵施加行业权重约束。
- Parameters:
weights –
get_single_factor_weight()的输出industry_map – 行业映射表(列含 input_ts, code, industry)
method –
'equal'全行业等权 |'market'按目标比例 |'original'不调整target_weights – method=’market’ 时使用,dict
{industry: float}
- Returns:
调整后的权重 DataFrame
一键预处理流水线
- preprocess_factor(pre_queried_data, metric, winsorize_method='mad', winsorize_n=3.0, standardize_method='zscore', industry_col=None, log_mktcap_col=None, industry_scheme=None, industry_table='industry', verbose=True)
逐截面(按 input_ts)依次执行:去空值 → 去极值 → 标准化 → 中性化。
行业标签来源:
industry_scheme给定(推荐)则自动从 industry 表 point-in-time 查询, 并打印行业分布 / 缺失 / 面板平衡及中性化执行摘要;industry_col给定则用调用方预先 merge 的行业列(旧行为)。市值中性化仍由log_mktcap_col手动提供。- Parameters:
pre_queried_data –
pre_query_characteristic_data()的输出metric – 因子列名
winsorize_method –
'mad'|'percentile'|'std'winsorize_n – 去极值阈值
standardize_method –
'zscore'|'rank'|'minmax'industry_col – pre_queried_data 中的行业列名(None 跳过)
log_mktcap_col – pre_queried_data 中的 log 市值列名(None 跳过市值中性化)
industry_scheme – 自动查 industry 表的分类体系名,如
'申万一级行业';给定即自动注入行业标签并打印诊断(优先于 industry_col)industry_table – 行业表名,默认
'industry'verbose – True 时打印行业诊断与中性化执行摘要
- Returns:
同 pre_queried_data 格式的 DataFrame,{metric} 列已替换为处理后的值
>>> # 自动查表 + 诊断打印(推荐) >>> cleaned = preprocess_factor(raw_data, 'ROE', industry_scheme='申万一级行业') >>> # 旧用法:调用方自带行业列 >>> cleaned = preprocess_factor(raw_data, 'ROE', industry_col='industry') >>> labeled = single_characteristic(cleaned, 'ROE', quantiles={'ROE': 10})
factor.stats
因子统计检验模块,提供 IC/ICIR 分析、Fama-MacBeth 截面回归、分组收益统计。
IC / ICIR
- calc_ic(factor_data, return_data, method='spearman')
逐截面计算 IC(Information Coefficient)。
- Parameters:
factor_data – 宽表(pd.DataFrame),index=input_ts,columns=code,值为因子值
return_data – 宽表,index=input_ts,columns=code,值为持仓期收益率
method –
'spearman'Rank IC(推荐)|'pearson'普通 IC
- Returns:
pd.Series,index=input_ts,name=’IC’
>>> ic = calc_ic(factor_wide, return_wide) >>> print(ic.mean(), ic.std())
- calc_icir(ic_series, window=None)
计算 ICIR = mean(IC) / std(IC)。
- Parameters:
ic_series –
calc_ic()的输出window – None 返回全样本 float;整数返回滚动 Series
- Returns:
float(全样本)或 pd.Series(滚动)
>>> icir = calc_icir(ic) # 全样本 >>> rolling_icir = calc_icir(ic, window=12) # 滚动12期
- summarize_ic(ic_series)
IC 统计摘要。
- Parameters:
ic_series – IC 序列
- Returns:
dict,包含:
IC均值: floatIC_std: floatICIR: float胜率(IC>0): floatt统计量: floatp值: float
>>> summary = summarize_ic(ic) >>> pd.Series(summary)
Fama-MacBeth 截面回归
- fama_macbeth(factor_data_dict, return_data, industry_dummies=None)
Fama-MacBeth 两步法截面回归。
第一步:每截面期 t 做 OLS
R_i = α_t + Σ(λ_k,t * F_k,i) + ε_i第二步:对 λ_k 时间序列做 t 检验。
- Parameters:
factor_data_dict – dict,格式为 {因子名: 宽表 DataFrame}(index=date, columns=code)
return_data – 宽表(index=date, columns=code),持仓期超额收益
industry_dummies – 可选,行业哑变量宽表(控制变量,不纳入 λ 报告)
- Returns:
pd.DataFrame,index=factor_name,columns=[‘lambda_mean’, ‘lambda_std’, ‘t_stat’, ‘p_value’, ‘n_periods’]
>>> fm = fama_macbeth({'ROE': roe_wide, 'PE': pe_wide}, return_wide) >>> print(fm[['lambda_mean', 't_stat']])
分组收益统计
- group_return_summary(labeled_pool, return_data, metric)
计算各分组在持仓期内的等权平均收益。
- Parameters:
labeled_pool –
single_characteristic()输出,MultiIndex(input_ts, code),含 {metric}_label 列return_data – 宽表(index=input_ts, columns=code),持仓期收益率
metric – 因子名(用于找标签列
{metric}_label)
- Returns:
pd.DataFrame,index=input_ts,columns=[‘G1’…’GN’, ‘long_short’]
long_short= G_max - G_min(自动判断因子方向)>>> gr = group_return_summary(labeled_pool, return_wide, 'ROE') >>> gr.cumsum().plot()