3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
要将 JoinQuant(聚宽)获取的数据转换为 Alphalens 所需的格式,核心在于将因子的 DataFrame 转换为 MultiIndex Series(多重索引序列),并准备好对应的价格数据。
Alphalens 的核心函数 get_clean_factor_and_forward_returns 需要两个主要输入:
(date, asset),值为因子值。date,列为 asset,值为收盘价。以下是具体的操作步骤和代码示例。
get_factor_values 或 get_fundamentals,得到的是一个 DataFrame(索引为日期,列为股票代码)。.stack() 方法将宽表(DataFrame)转换为长表(MultiIndex Series)。get_price 获取收盘价 DataFrame。alphalens.utils.get_clean_factor_and_forward_returns。以下代码可以在聚宽的研究环境中直接运行:
# -*- coding: utf-8 -*-
import pandas as pd
import alphalens
from jqdata import *
from jqfactor import get_factor_values
# 1. 设定参数
stock_pool = get_index_stocks('000300.XSHG') # 股票池:沪深300
start_date = '2023-01-01'
end_date = '2023-03-01'
# 2. 获取因子数据 (以市盈率 PE_ratio 为例)
# get_factor_values 返回一个字典,key是因子名,value是DataFrame(index=date, columns=asset)
factor_data_dict = get_factor_values(
securities=stock_pool,
factors=['pe_ratio'],
start_date=start_date,
end_date=end_date
)
factor_df = factor_data_dict['pe_ratio']
# 3. 【关键步骤】转换因子格式
# Alphalens 需要 MultiIndex Series (date, asset)
# 使用 stack() 将列转为二级索引
factor_series = factor_df.stack()
# 为索引命名,有助于 Alphalens 识别(可选,但推荐)
factor_series.index.names = ['date', 'asset']
# 4. 获取价格数据
# 注意:价格数据的结束日期需要比因子结束日期晚,以便计算未来的收益率
# 这里多取 20 天的数据
price_end_date = (pd.to_datetime(end_date) + pd.Timedelta(days=30)).strftime('%Y-%m-%d')
prices_df = get_price(
list(stock_pool),
start_date=start_date,
end_date=price_end_date,
fields=['close']
)['close']
# 确保价格数据的索引也是 datetime 类型,并且时区处理一致(通常聚宽返回的是 naive datetime)
prices_df.index = pd.to_datetime(prices_df.index)
# 5. 生成 Alphalens 所需的清洗后数据
# periods 定义了我们要分析持有 1天、5天、10天 的收益
factor_data_clean = alphalens.utils.get_clean_factor_and_forward_returns(
factor=factor_series,
prices=prices_df,
quantiles=5, # 分成 5 组
periods=[1, 5, 10], # 计算 1, 5, 10 日后的收益
max_loss=0.35 # 允许丢弃数据的最大比例
)
# 6. 查看结果或进行绘图
print("转换后的数据前5行:")
print(factor_data_clean.head())
# 示例:生成全部分析图表(在 Notebook 中运行会显示图表)
# alphalens.tears.create_full_tear_sheet(factor_data_clean)
.stack())聚宽的 get_factor_values 返回的数据结构如下(DataFrame):
000001.XSHE 000002.XSHE ...
2023-01-04 6.5 8.2
2023-01-05 6.6 8.1
...
Alphalens 需要的格式如下(MultiIndex Series):
date asset
2023-01-04 000001.XSHE 6.5
000002.XSHE 8.2
2023-01-05 000001.XSHE 6.6
000002.XSHE 8.1
...
Pandas 的 stack() 函数正是用于完成这种“宽表变长表”的转换。
Alphalens 需要计算“未来收益率”(Forward Returns)。如果你计算的是 periods=[1, 5, 10],那么对于因子数据中的最后一天,Alphalens 需要往后查找至少 10 个交易日的价格数据来计算收益。因此,获取 prices 时,end_date 必须晚于因子的 end_date。
聚宽返回的日期通常是不带时区信息(Naive Datetime)的,这通常能直接配合 Alphalens 使用。如果遇到时区报错,可以尝试统一转换为 UTC:
# 如果需要统一时区
factor_series.index = factor_series.index.set_levels(factor_series.index.levels[0].tz_localize('UTC'), level=0)
prices_df.index = prices_df.index.tz_localize('UTC')
但在大多数聚宽研究环境中,直接使用默认格式即可。
Q: 为什么运行 get_clean_factor_and_forward_returns 时提示价格数据不足?
A: 这是因为计算未来收益率需要未来的价格。例如,要计算因子在 3月1日 的 10日预期收益,必须拥有 3月1日 之后至少 10 个交易日的价格数据。请确保 get_price 的 end_date 比因子的 end_date 往后延足够多的天数。
Q: 如果我的因子数据包含 NaN 或 Inf 怎么办?
A: get_clean_factor_and_forward_returns 函数内部会自动处理部分无效数据。你可以通过参数 max_loss 控制允许丢弃的数据比例(默认 35%)。如果无效数据过多,建议在传入 Alphalens 之前使用 Pandas 的 dropna() 或 fillna() 进行预处理。
Q: 如何处理多因子?
A: Alphalens 一次只能分析一个因子。如果你有多个因子,需要对每个因子分别执行上述转换流程,或者将它们合并成一个大的 DataFrame 后,通过循环对每一列进行 stack() 和分析。