3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 PTrade 平台搭建多因子模型时,因子的数据预处理(去极值、标准化)与截面回归是因子分析和选股的核心步骤。通过对因子进行清洗,可以消除异常值(Outliers)与量纲差异对预测结果的干扰。
get_fundamentals 提取多只标的的财务因子或估值指标(如 PB、ROE、PE 等)。statsmodels 或 numpy 进行 OLS 线性回归,获取因子收益率(因子载荷)。以下代码展示了在 PTrade 的 before_trading_start 或 handle_data 事件中提取沪深 300 成分股的估值与盈利因子,进行 MAD 去极值、Z-score 标准化以及 OLS 截面回归的过程:
import numpy as np
import pandas as pd
import statsmodels.api as sm
def initialize(context):
# 设置参考基准与股票池
set_benchmark('000300.SS')
g.security = '000300.SS'
# 定时在盘前运行因子计算与回归分析
run_daily(context, factor_analysis, time='9:15')
def factor_analysis(context):
# 1. 获取沪深300成分股列表
stocks = get_index_stocks('000300.XBHS')
if not stocks:
return
# 2. 获取财务/估值因子数据 (以PB和ROE为例)
# balance_statement/valuation 等表可通过 get_fundamentals 查询
df_val = get_fundamentals(stocks, 'valuation', fields=['pb'])
df_profit = get_fundamentals(stocks, 'profit_ability', fields=['roe'])
if df_val.empty or df_profit.empty:
log.info("未获取到足够的因子数据")
return
# 合并因子数据
factors_df = pd.DataFrame({
'pb': df_val['pb'],
'roe': df_profit['roe']
}).dropna()
# 3. 因子预处理:中位数去极值 (MAD)
def mad_de_extreme(series, n=3):
median = series.median()
mad = (series - median).abs().median()
max_limit = median + n * 1.4826 * mad
min_limit = median - n * 1.4826 * mad
return np.clip(series, min_limit, max_limit)
# 4. 因子预处理:Z-score 标准化
def z_score_standardize(series):
mean = series.mean()
std = series.std()
if std == 0:
return series - mean
return (series - mean) / std
# 对每个因子依次进行去极值与标准化
processed_factors = pd.DataFrame()
for col in factors_df.columns:
de_ext = mad_de_extreme(factors_df[col])
processed_factors[col] = z_score_standardize(de_ext)
# 5. 获取未来一期的截面收益率作为因变量 Y (假设以过去5天历史收益率替代测试)
hist_price = get_history(5, frequency='1d', field='close', security_list=list(processed_factors.index))
# 计算近期收益率
returns = (hist_price.iloc[-1] - hist_price.iloc[0]) / hist_price.iloc[0]
# 对齐因子数据与收益率数据
data = processed_factors.copy()
data['returns'] = returns
data = data.dropna()
# 6. 截面 OLS 回归
X = data[['pb', 'roe']]
X = sm.add_constant(X) # 添加常数项
Y = data['returns']
model = sm.OLS(Y, X).fit()
# 7. 输出截面回归结果
log.info("--- 截面回归系数 (因子收益率) ---")
log.info(model.params)
log.info("--- 回归 p 值 ---")
log.info(model.pvalues)
log.info("--- R-squared ---")
log.info(model.rsquared)
def handle_data(context, data):
pass
get_fundamentals 提取财务因子时,部分股票可能因未披露或数据停牌返回 NaN,必须使用 .dropna() 进行清理。