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_poolsingle_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:
  • weightsget_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_datapre_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_seriescalc_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均值: float

  • IC_std: float

  • ICIR: float

  • 胜率(IC>0): float

  • t统计量: float

  • p值: 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_poolsingle_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()