问题描述
入股输入的factor是因子定义,函数会自动帮我中性化和去极值吗?
如果不会,那是不是定义完之后,自己计算出因子值,自己进行数据处理之后再做因子分析比较好?
载入函数库
from jqfactor import analyze_factor
对因子进行分析
far = analyze_factor(factor, start_date, end_date, industry, universe, quantiles, periods, weight_method, use_real_price, skip_paused, max_loss, factor_dep_definitions)
参数:
factor:因子值,可输入三种类型的值
pandas.DataFrame:因子值,columns为股票代码(如'000001.XSHE'),index为日期的DatetimeIndex或str
pandas.Series:因子值,index为日期和股票代码的MultiIndex
Fator的子类:因子定义(具体见下方示例)
解决方案
JoinQuant 单因子分析 analyze_factor 数据处理详解
针对您提出的关于 JoinQuant 聚宽平台中 analyze_factor 函数的问题,解答如下:
1. analyze_factor 会自动进行中性化和去极值吗?
不会。
当您将因子定义(Factor 的子类)直接传入 analyze_factor 时,系统会根据您的定义计算出原始的因子值,然后直接使用这些原始因子值进行后续的收益、IC、换手率等分析。analyze_factor 函数内部并没有内置自动去极值(Winsorize)、标准化(Standardize)或中性化(Neutralize)的预处理步骤。
2. 正确的因子处理与分析流程
正如您所推测的,为了得到更准确、更符合实际投资逻辑的因子分析结果,强烈建议您先计算出因子值,手动进行必要的数据处理(去极值、标准化、中性化),然后再将处理后的因子值传入 analyze_factor 进行分析。
在 JoinQuant 中,标准的处理流程如下:
第一步:计算或获取原始因子值
您可以使用 calc_factors 计算自定义因子,或者使用 get_factor_values 获取因子库中的因子。
第二步:进行数据清洗与处理
使用 JoinQuant 提供的因子数据处理函数:
- 去极值:
winsorize或winsorize_med - 标准化:
standardlize - 中性化:
neutralize(通常用于剔除行业和市值的影响)
第三步:将处理后的数据传入 analyze_factor
将清洗后的 pandas.DataFrame 传入 analyze_factor 的 factor 参数。
代码示例
以下是一个完整的流程示例,展示了如何获取因子、处理数据并进行分析:
import pandas as pd
from jqfactor import get_factor_values, analyze_factor
from jqfactor import winsorize_med, standardlize, neutralize
from jqdata import get_index_stocks
# 1. 定义参数
start_date = '2023-01-01'
end_date = '2023-06-01'
stock_pool = get_index_stocks('000300.XSHG') # 以沪深300为例
factor_name = 'net_profit_to_total_operate_revenue_ttm' # 净利润与营业总收入之比
# 2. 获取原始因子值
# 返回的是一个 dict,提取对应的 DataFrame
raw_factor_df = get_factor_values(securities=stock_pool,
factors=[factor_name],
start_date=start_date,
end_date=end_date)[factor_name]
# 3. 因子数据处理 (按行处理,即截面处理 axis=1)
# 3.1 中位数去极值
processed_df = winsorize_med(raw_factor_df, scale=3, inclusive=True, inf2nan=True, axis=1)
# 3.2 标准化
processed_df = standardlize(processed_df, inf2nan=True, axis=1)
# 3.3 行业与市值中性化 (注意:neutralize 需要传入具体的日期,通常在回测/研究中需要按日期循环处理,或者使用 apply)
# 为了简化,这里展示单日处理逻辑,实际应用中需对 DataFrame 的每一行(每天)进行中性化
# 假设我们对 processed_df 进行逐行中性化:
def neutralize_daily(row):
date_str = row.name.strftime('%Y-%m-%d')
# 将单行 Series 转为 DataFrame 格式以符合 neutralize 要求
daily_df = pd.DataFrame(row).T
try:
neut_df = neutralize(daily_df, how=['jq_l1', 'market_cap'], date=date_str, axis=1)
return neut_df.iloc[0]
except:
return row # 如果当天数据不足导致中性化失败,返回原值或 NaN
final_factor_df = processed_df.apply(neutralize_daily, axis=1)
# 4. 进行单因子分析
# 将处理后的 DataFrame 传入 analyze_factor
far = analyze_factor(factor=final_factor_df,
start_date=start_date,
end_date=end_date,
universe='000300.XSHG',
industry='jq_l1',
quantiles=5,
periods=(1, 5, 20),
weight_method='avg')
# 5. 查看分析结果
print("月度IC:")
print(far.ic_monthly)
总结:
直接传入因子定义适合快速验证因子的原始表现。但如果要进行严谨的量化研究,构建稳健的 Alpha 模型,必须自己接管数据处理流程,先去极值、标准化、中性化,再将干净的因子值送入 analyze_factor 进行评估。