news 2026/5/13 14:34:42

期货多因子策略开发入门_因子挖掘与组合实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
期货多因子策略开发入门_因子挖掘与组合实践

免责声明:本文基于个人学习经验整理,仅供技术交流参考,不构成投资建议。


一、前言

从事期货量化交易二十年,我最大的感悟是:单一因子的策略越来越难赚钱了。

多因子策略通过组合多个因子,可以提高策略的稳健性。今天这篇文章,我来分享一下期货多因子策略的开发入门


二、什么是多因子策略?

多因子策略的核心思想:


三、常用期货因子

3.1 动量因子

defcalc_momentum(df,period=20):"""动量因子:过去N日收益率"""df['momentum']=df['close'].pct_change(period)returndf['momentum']

3.2 波动率因子

importnumpyasnpdefcalc_volatility(df,period=20):"""波动率因子:过去N日收益率标准差"""returns=df['close'].pct_change()df['volatility']=returns.rolling(period).std()returndf['volatility']

3.3 均线偏离因子

defcalc_ma_deviation(df,period=20):"""均线偏离因子:价格相对均线的偏离度"""ma=df['close'].rolling(period).mean()df['ma_deviation']=(df['close']-ma)/mareturndf['ma_deviation']

3.4 成交量因子

defcalc_volume_ratio(df,period=20):"""成交量比率因子:当前成交量/平均成交量"""avg_volume=df['volume'].rolling(period).mean()df['volume_ratio']=df['volume']/avg_volumereturndf['volume_ratio']

3.5 RSI因子

defcalc_rsi(df,period=14):"""RSI因子"""delta=df['close'].diff()gain=delta.where(delta>0,0)loss=-delta.where(delta<0,0)avg_gain=gain.rolling(period).mean()avg_loss=loss.rolling(period).mean()rs=avg_gain/avg_loss df['rsi']=100-(100/(1+rs))returndf['rsi']

四、因子计算完整示例

fromtqsdkimportTqApi,TqAuthimportpandasaspdimportnumpyasnp api=TqApi(auth=TqAuth("账户","密码"))symbol="SHFE.rb2505"klines=api.get_kline_serial(symbol,60*60*24,500)# 日线api.wait_update()# 转为DataFramedf=klines.to_dataframe()# 计算各因子defcalc_all_factors(df):"""计算所有因子"""# 1. 动量因子df['momentum_5']=df['close'].pct_change(5)df['momentum_20']=df['close'].pct_change(20)# 2. 波动率因子returns=df['close'].pct_change()df['volatility']=returns.rolling(20).std()# 3. 均线偏离ma20=df['close'].rolling(20).mean()df['ma_deviation']=(df['close']-ma20)/ma20# 4. 成交量比率avg_vol=df['volume'].rolling(20).mean()df['volume_ratio']=df['volume']/avg_vol# 5. RSIdelta=df['close'].diff()gain=delta.where(delta>0,0).rolling(14).mean()loss=(-delta.where(delta<0,0)).rolling(14).mean()df['rsi']=100-100/(1+gain/loss)# 6. 价格位置(相对近期高低点)high_20=df['high'].rolling(20).max()low_20=df['low'].rolling(20).min()df['price_position']=(df['close']-low_20)/(high_20-low_20)returndf df=calc_all_factors(df)print(df[['datetime','close','momentum_20','volatility','rsi']].tail(10))api.close()

五、因子标准化

不同因子的量级不同,需要标准化:

defstandardize_factors(df,factor_cols):"""因子标准化(Z-score)"""forcolinfactor_cols:mean=df[col].rolling(60).mean()std=df[col].rolling(60).std()df[f'{col}_zscore']=(df[col]-mean)/stdreturndf factor_cols=['momentum_20','volatility','ma_deviation','volume_ratio','rsi']df=standardize_factors(df,factor_cols)

六、因子组合

6.1 等权组合

defequal_weight_score(df,factor_cols):"""等权因子组合"""zscore_cols=[f'{col}_zscore'forcolinfactor_cols]df['composite_score']=df[zscore_cols].mean(axis=1)returndf

6.2 自定义权重

defweighted_score(df,factor_weights):"""加权因子组合"""score=0forfactor,weightinfactor_weights.items():score+=df[f'{factor}_zscore']*weight df['composite_score']=scorereturndf# 使用weights={'momentum_20':0.3,'ma_deviation':0.25,'rsi':0.2,'volume_ratio':0.15,'volatility':0.1,}df=weighted_score(df,weights)

七、多因子策略实现

fromtqsdkimportTqApi,TqAuth,TqBacktest,TqSimfromdatetimeimportdateimportpandasaspd# 参数SYMBOL="SHFE.rb2505"ENTRY_THRESHOLD=1.0# 开仓阈值EXIT_THRESHOLD=-0.5# 平仓阈值VOLUME=1# 因子权重FACTOR_WEIGHTS={'momentum_20':0.3,'ma_deviation':0.25,'rsi_factor':0.2,# RSI转换后的因子'volume_ratio':0.15,'volatility':0.1,}api=TqApi(TqSim(),backtest=TqBacktest(start_dt=date(2024,1,1),end_dt=date(2025,6,30)),auth=TqAuth("账户","密码"))klines=api.get_kline_serial(SYMBOL,60*60,500)# 1小时K线position=api.get_position(SYMBOL)print("多因子策略启动...")whileTrue:api.wait_update()ifapi.is_changing(klines):iflen(klines)<60:continuedf=klines.to_dataframe()# 计算因子df['momentum_20']=df['close'].pct_change(20)ma20=df['close'].rolling(20).mean()df['ma_deviation']=(df['close']-ma20)/ma20 df['volume_ratio']=df['volume']/df['volume'].rolling(20).mean()returns=df['close'].pct_change()df['volatility']=returns.rolling(20).std()# RSI转换(RSI>70做空因子,RSI<30做多因子)delta=df['close'].diff()gain=delta.where(delta>0,0).rolling(14).mean()loss=(-delta.where(delta<0,0)).rolling(14).mean()rsi=100-100/(1+gain/loss)df['rsi_factor']=(50-rsi)/50# 标准化到-1到1# 标准化因子forfactorinFACTOR_WEIGHTS.keys():mean=df[factor].rolling(60).mean()std=df[factor].rolling(60).std()df[f'{factor}_zscore']=(df[factor]-mean)/std# 计算综合得分score=0forfactor,weightinFACTOR_WEIGHTS.items():zscore=df[f'{factor}_zscore'].iloc[-1]ifpd.notna(zscore):score+=zscore*weight# 交易逻辑ifposition.pos_long==0andposition.pos_short==0:ifscore>ENTRY_THRESHOLD:api.insert_order(SYMBOL,"BUY","OPEN",VOLUME)print(f"做多 | 得分:{score:.2f}")elifscore<-ENTRY_THRESHOLD:api.insert_order(SYMBOL,"SELL","OPEN",VOLUME)print(f"做空 | 得分:{score:.2f}")elifposition.pos_long>0:ifscore<EXIT_THRESHOLD:api.insert_order(SYMBOL,"SELL","CLOSE",position.pos_long)print(f"平多 | 得分:{score:.2f}")elifposition.pos_short>0:ifscore>-EXIT_THRESHOLD:api.insert_order(SYMBOL,"BUY","CLOSE",position.pos_short)print(f"平空 | 得分:{score:.2f}")

八、因子分析

8.1 因子IC分析

defcalc_factor_ic(df,factor_col,forward_returns_col,period=20):"""计算因子IC(信息系数)"""# 计算未来收益df['forward_return']=df['close'].pct_change(period).shift(-period)# 计算IC(相关系数)ic=df[factor_col].rolling(60).corr(df['forward_return'])returnic.mean(),ic.std()# 使用ic_mean,ic_std=calc_factor_ic(df,'momentum_20','forward_return')print(f"动量因子 IC均值:{ic_mean:.4f}, IC标准差:{ic_std:.4f}")print(f"IC_IR:{ic_mean/ic_std:.4f}")

8.2 因子相关性

importseabornassnsimportmatplotlib.pyplotasplt# 计算因子相关性矩阵factor_cols=['momentum_20','ma_deviation','volatility','volume_ratio','rsi']corr_matrix=df[factor_cols].corr()# 绘制热力图plt.figure(figsize=(10,8))sns.heatmap(corr_matrix,annot=True,cmap='coolwarm',center=0)plt.title('因子相关性矩阵')plt.show()

九、总结

期货多因子策略开发的核心步骤:

  1. 因子挖掘:发现有预测能力的因子
  2. 因子计算:正确计算各因子值
  3. 因子标准化:统一因子量级
  4. 因子组合:通过权重组合多个因子
  5. 策略实现:基于综合得分做交易决策
  6. 因子分析:分析因子有效性和相关性

从使用体验来说,我目前用TqSdk做因子策略开发,主要因为数据获取方便,回测和实盘代码一致。

希望这篇入门教程对你有所帮助!


声明:本文基于个人学习经验整理,仅供技术交流参考,不构成任何投资建议。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 21:42:58

Labview 与阿特拉斯开放式通讯:网口读取扭矩值全解析

Labview与阿特拉斯开放式通讯 网口读取扭矩值 包括Labview程序、阿特拉斯调试软件、开放式通讯测试软件、开放式通讯协议、PM4000手册。在工业自动化和设备监测领域&#xff0c;准确读取扭矩值至关重要。今天咱们就来唠唠如何通过 Labview 与阿特拉斯开放式通讯&#xff0c;利用…

作者头像 李华
网站建设 2026/5/9 9:51:01

等级设定:企业应如何定义等级标准、本地策略与特殊路由优化路径

定义传输资源等级标准、部署本地化传输策略、实施特殊需求路由优化管理 摘要 为企业IT部门、信息化负责人及运维团队提供价值&#xff1a;通过可视化运行监控系统&#xff0c;结合等级设定的传输资源管理体系&#xff0c;支撑系统规划、标准化交付与平台化运维&#xff0c;实…

作者头像 李华
网站建设 2026/5/13 10:00:03

C语言fscanf用法详解:如何从文件读取格式化数据

$fscanf是C标准库中用于从文件流进行格式化输入的核心函数&#xff0c;它根据指定的格式字符串从文件中读取数据并存入对应变量。对于需要精确解析文本文件内容的开发者而言&#xff0c;掌握其用法能极大提升数据处理的效率和可靠性。本文将深入探讨其具体用法、关键细节和常见…

作者头像 李华
网站建设 2026/5/9 21:46:05

findwindowexa函数用法详解与常见问题解决指南

在Windows编程中&#xff0c;findwindowexa是一个关键但常被误解的API函数。它用于在复杂的窗口层次结构中精确定位子窗口&#xff0c;对于自动化测试、UI操作和外部程序控制等场景至关重要。理解其工作原理和正确用法&#xff0c;能有效避免许多常见的编程陷阱。 findwindowex…

作者头像 李华
网站建设 2026/5/9 18:42:49

CNN输出尺寸设计指南:从原理到实战,告别尺寸不匹配!

CNN输出尺寸设计指南&#xff1a;从原理到实战&#xff0c;告别尺寸不匹配&#xff01; 引言 在构建卷积神经网络&#xff08;CNN&#xff09;时&#xff0c;你是否曾为复杂的输出尺寸计算而头疼&#xff1f;是否在模型拼接时频繁遭遇“尺寸不匹配”的错误&#xff1f;输出尺…

作者头像 李华