【量化交易笔记】15.因子的来源和生成

前言

现在市场上很多基金,特别是量化的基金,多带有“多因子”配置,策略等,这些基金策略实际上与之前《13.实盘交易策略制定与实施》是一致的,在量化交易,因子作为交易的基础(数据源),起着重要作用。从本文开始,从最简单的一个因子开始,讲解产生、使用、作用和检验,本文就这些因子是如何产生的,来做一个详细说明。

获取数据

为了获取数据方便,直接使用量化平台的数据,国内开放的量化平台有聚宽、果仁、‌米筐、‌优矿等,我这里有使用的是“聚宽”平台。

小伙伴们有这样的一个认知:“某日该股票价格上涨,且主力资金净流入的话,次日股价,可能上涨;否则下跌”,因此暂以资金流入/流出数据做为因子,进行实验验证,现以招商银行(600036)为例。

#导入jqdata的全部函数
from jqdata import *
#使用get_money_flow函数获取
df = get_money_flow('600036.XSHG',
                    fields = ['date',
                             #股票代码
                           'sec_code',
                             #涨跌幅
                           'change_pct',
                             #主力金额,包括超大单和大单
                           'net_amount_main',
                             #主力成交额占总成交额的比例
                           'net_pct_main'],
                    #设置好起止日期
                    start_date = '2023-03-09',
                    end_date = '2025-03-09')
#查看数据
df.head()
-datesec_codechange_pctnet_amount_mainnet_pct_main
02023-03-09600036.XSHG-1.17-18056.3680-9.3621
12023-03-10600036.XSHG-1.55-30406.6513-15.4844
22023-03-13600036.XSHG0.06-6289.9216-3.0741
32023-03-14600036.XSHG-1.34-28301.3136-13.0485
42023-03-15600036.XSHG0.87-21240.4128-8.9221

特征工程

给这个的数据增加两个新的字段,其中一个是up_or_down,用来表示当日股价是上涨还是下跌。如果change_pct(涨幅)这个字段为正数,说明股价上涨,则up_or_down用1来表示,反之,用0表示,代表当日股价下跌。
类似地,我们用money_in_out字段表示主力资金净流入还是净流出。如果net_amount_main大于0,说明主力资金净流入,则在money_in_out字段用1表示:反之说明主力资金净流出,money_in_out字段用0表示。示例代码如下:

#增加一个字段,记录股价上涨还是下跌
#如果股价上涨,则以1标记,否则以0标记
df['up_or_down'] = np.where(df['change_pct']>0,1,0)
#在增加一个字段,记录主力资金净流入还是流出
#如果净流入,标记为1,否则标记为0
df['money_in_out'] = np.where(df['net_amount_main']>0,1,0)
#检查是否成功
df.head()
-datesec_codechange_pctnet_amount_mainnet_pct_mainup_or_downmoney_in_out
02023-03-09600036.XSHG-1.17-18056.3680-9.362100
12023-03-10600036.XSHG-1.55-30406.6513-15.484400
22023-03-13600036.XSHG0.06-6289.9216-3.074110
32023-03-14600036.XSHG-1.34-28301.3136-13.048500
42023-03-15600036.XSHG0.87-21240.4128-8.922110

计算

现在我们有了两个新的特征,能够体现股价的涨跌和主力资金的流入/流出情况,下面就可以用这两个新的特征来计算“瓦氏因子”了,咱们先说说思路,如果我们把两个特征相乘,则当股价上涨,且主力资金净流入时,因子值就是up_or_down 乘以 money_in_ out,也就是1X1,结果是1;而其他情况,“瓦氏因子”的数值都为0。例如,股价下跌但主力资金净流入,“瓦氏因子”为0x1,结果为0。同时,为了后面便于模型训练,我们还要做一个标签(即次日股票上涨还是下跌),存储在next_day 字段中。代码如下:

#瓦氏因子来了,用两个自增的字段相乘,得出因子值
df['factor_wa'] = df['up_or_down'] * df['money_in_out']
#再把次日涨跌作为预测标签存储到‘next_day’字段
df['next_day'] = df['up_or_down'].shift(-1)
#检查是否成功
df.head()
-datesec_codechange_pctnet_amount_mainnet_pct_mainup_or_downmoney_in_outfactor_wanext_day
02023-03-09600036.XSHG-1.17-18056.3680-9.36210000.0
12023-03-10600036.XSHG-1.55-30406.6513-15.48440001.0
22023-03-13600036.XSHG0.06-6289.9216-3.07411000.0
32023-03-14600036.XSHG-1.34-28301.3136-13.04850001.0
42023-03-15600036.XSHG0.87-21240.4128-8.92211000.0

准备训练

#还是请出已经熟悉的KNN算法
from sklearn.neighbors import KNeighborsClassifier
#导入数据集拆分工具
from sklearn.model_selection import train_test_split
#当然还需要有pandas
import pandas as pd
#数据集中把日期、股票代码,以及我们添加的特征去掉
dataset = df.drop(['date', 
                   'sec_code',
                   'up_or_down',
                   'money_in_out'],
                  axis=1)
#检查是否成功
dataset.head()
-change_pctnet_amount_mainnet_pct_mainfactor_wanext_day
0-1.17-18056.3680-9.362100.0
1-1.55-30406.6513-15.484401.0
20.06-6289.9216-3.074100.0
3-1.34-28301.3136-13.048501.0
40.87-21240.4128-8.922100.0
#将‘next_day’以外的字段,作为数据集的特征
X = dataset.drop(['next_day'],axis=1)[:-1]
#将‘next_day’作为数据集的标签
y = dataset['next_day'][:-1]
#将数据集拆分为训练集与验证集
X_train, X_test, y_train, y_test =\
train_test_split(X, y, random_state = 574)
#创建KNN分类器,n_neighbors参数依然取95
knn = KNeighborsClassifier(n_neighbors=95)
#使用训练集训练模型
knn.fit(X_train, y_train)
#打印训练集中模型准确率
print(knn.score(X_train, y_train))
#打印验证集中模型准确率
print(knn.score(X_test,y_test))

0.5429362880886427
0.49586776859504134

小结

这里的结果并不是很理想,准确率只有0.4958% 与盲猜并不多,不过没关系,咱简单的用了几个因子,进行了建模,而实际因子有上百个,甚至上千个,这些因子怎么来帮助我们的选择股票呢,这个需要选择标的问题,而不是上面的仅仅对一支股票进行分析,而对一类股票进行分析,选择分数高的,或排名前的股票进行投资。

在聚宽平台上有专用的因子库,来获取相应的因子值。

选择标的

思路是选超大盘股,净利润率高,且高速成长的
get_all_securities 查询到全部指数

#指定get_all_securities的types参数为index
#即可查询全部指数
indices = get_all_securities(types=['index'])
#查看前二十条结果
indices.head(20)
-display_namenamestart_dateend_datetype
000001.XSHG上证指数SZZS1991-07-152200-01-01index
000002.XSHGA股指数AGZS1992-02-212200-01-01index
000003.XSHGB股指数BGZS1992-02-212200-01-01index
000004.XSHG工业指数GYZS1993-05-032200-01-01index
000005.XSHG商业指数SYZS1993-05-032200-01-01index
000006.XSHG地产指数DCZS1993-05-032200-01-01index
000007.XSHG公用指数GYZS1993-05-032200-01-01index
000008.XSHG综合指数ZHZS1993-05-032200-01-01index
000009.XSHG上证380SZ3802010-11-292200-01-01index
000010.XSHG上证180SZ1802002-07-012200-01-01index
000011.XSHG基金指数JJZS2000-06-092200-01-01index
000012.XSHG国债指数GZZS2003-01-022200-01-01index
000013.XSHG上证企业债指数QZZS2003-06-092200-01-01index
000015.XSHG红利指数HLZS2005-01-042200-01-01index
000016.XSHG上证50SZ502004-01-022200-01-01index
000017.XSHG新综指XZZ2006-01-042200-01-01index
000018.XSHG180金融180JR2007-12-102200-01-01index
000019.XSHG治理指数ZLZS2008-01-022200-01-01index
000020.XSHG中型综指ZXZZ2008-05-122200-01-01index
000021.XSHG180治理180ZL2008-09-102200-01-01index
  • 获取市值因子
#这里需要导入聚宽因子库的get_factor_values函数
from jqfactor import get_factor_values
#导入聚宽的因子分析库
from jqfactor import analyze_factor
#使用get_factor_values函数获取沪深300成分股的市值
factor_mc=get_factor_values(securities=get_index_stocks('000300.XSHG'), factors=['market_cap'],
                  end_date='2025-03-09',count=1)['market_cap']
#检查结果
factor_mc.T.head()
code2025-03-07 00:00:00
000001.XSHE2.264671e+11
000002.XSHE8.983824e+10
000063.XSHE1.783780e+11
000100.XSHE8.957622e+10
000157.XSHE7.185378e+10
  • 获取现金流因子
  • 获取净利率因子
  • 获取净利润增长因子
#get_factor_values中
#factors参数传入cash_flow_to_price_ratio
#即可获得市现率的倒数
factor_cfp = get_factor_values(securities = get_index_stocks('000300.XSHG'),
                           factors = ['cash_flow_to_price_ratio'],
                              end_date = '2025-03-09',
                              count = 1)['cash_flow_to_price_ratio']
#使用net_profit_ratio作为factors参数
#即可查询到企业的净利润率
factor_npr = get_factor_values(securities = get_index_stocks('000300.XSHG'),
                              factors = ['net_profit_ratio'],
                              end_date = '2025-03-09',
                              count = 1)['net_profit_ratio']
#使用net_profit_growth_rate作为factors参数
#即可查询到企业的净利润增长率
factor_npgr = get_factor_values(securities = get_index_stocks('000300.XSHG'),
                               factors = ['net_profit_growth_rate'],
                               end_date = '2025-03-09',
                               count = 1)['net_profit_growth_rate']

因子打包

将获取的因子打包成一个dataframe

#新建一个DataFrame,和前面市值数据保持同样的序号
factors = pd.DataFrame(index = factor_mc.T.index)
#在新的DataFrame中创建4个字段
#分别把市值、市现率倒数、净利润率、净利润增长率存储到其中
factors['mc'] = factor_mc.T['2025-03-07 00:00:00']
factors['cfp'] = factor_cfp.T['2025-03-07 00:00:00']
factors['npr'] = factor_npr.T['2025-03-07 00:00:00']
factors['npgr'] = factor_npgr.T['2025-03-07 00:00:00']
#检查结果
factors.head()
codemccfpnprnpgr
000001.XSHE2.264671e+11-0.0971570.313151-0.040068
000002.XSHE8.983824e+10-0.266219-0.042926-1.541587
000063.XSHE1.783780e+11-0.1288660.068885-0.095796
000100.XSHE8.957622e+10-0.065272-0.015927-1.484159
000157.XSHE7.185378e+10-0.0095820.0914240.299958

处理缺失值

#为了计算,先把数据中的空值去掉
factors = factors.dropna()
#检查下是否还有空值
factors.isnull().sum()

标准化、降维

由于市值数据值特别大,会直接影响结果,因此需要进行标准化

#因为各因子数值的量纲差异较大
#需要做一点简单的缩放处理
from sklearn.preprocessing import StandardScaler
#导入scikit-learn中的PCA主成分分析工具
from sklearn.decomposition import PCA
#创建StandardScaler实例,会将数据量纲压缩到同一个区间中
scaler = StandardScaler()
#使用StandardScaler缩放原始的因子值
factors_scl = scaler.fit_transform(factors)
#接下来使用PCA,提取主成分数量指定为1
pca = PCA(n_components = 1)
#使用缩放后的数据进行拟合
pca.fit(factors_scl)
#查看pca给各因子分配的权重
pca.components_

array([[0.17034834509272317, 0.6941037872659619, 0.6899014299868211,
0.11505386012367508]])
最后生成的pca降成一维的值,简单的说,这一列就代表前面4列因子的值

#在factors数据表中添加一个pca字段
#存储提取出来的主成分
factors['pca'] = pca.transform(factors_scl)
#看一下主成分数值最高的5只股票
factors.sort_values(by='pca', ascending = False).head(10)
codemccfpnprnpgrpca
000617.XSHE8.204709e+100.56618712.261549-0.08155313.831990
600000.XSHG2.976311e+110.8192690.2612020.1280754.400846
601916.XSHG7.827421e+100.8391370.2361630.0281494.366769
000166.XSHE1.272029e+110.6077920.2281190.4315983.164233
600015.XSHG1.142692e+110.5884080.2939620.0384193.094389
300059.XSHE3.695396e+110.1693452.618757-0.0120453.090468
601169.XSHG1.241093e+110.5633490.3794360.0121873.041558
600674.XSHG7.316785e+10-0.0159453.2945030.1261832.565690
601939.XSHG2.125093e+120.2563050.4453210.0067802.485684
600036.XSHG1.098829e+120.3383870.4435940.0054002.395596

结论

  1. 最终我们将前面的4个因子,降维【“浓缩”】成一个新的列pca,来代表前面4个因子。
  2. 因此,pca 值最大,可以认为其代码股票就越好,所以选择pca最大的股票作为我们的标的,完成了选股策略。
  3. 上述只是一个简单的思路,在实际的实践中,有很多的思路和方法,使用不同的因子或算法,找到最适合自己的投资组合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/983869.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决在windows中docker拉取镜像出现的问题

解决在windows中docker拉取镜像出现的问题 docker pull minio/minio 出现报错: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while await…

MySQL基本建表操作

目录 1,创建数据库db_ck 1.1创建表 1.2 查看创建好的表 2,创建表t_hero 2.1 先进入数据库Db_Ck 2.1.1 这里可以看是否进入数据库: 2.2 创建表t_Hero 2.2.1 我们可以先在文本文档里面写好然后粘贴进去,因为直接写的话,错了要重新开始 …

使用Arduino和ESP8266进行基于物联网的垃圾箱监控

使用 Arduino 和 ESP8266 的基于 IOT 的垃圾箱监控系统 在这个 DIY 中,我们将制作一个基于 IOT 的垃圾箱/垃圾监控系统,该系统将通过网络服务器告诉我们垃圾桶是空的还是满的,并且您可以通过互联网从世界任何地方了解“垃圾桶”或“垃圾箱”的状态。它将非常有用,可以安装…

【Academy】HTTP 请求走私 ------ HTTP request smuggling

HTTP 请求走私 ------ HTTP request smuggling 1. 什么是 HTTP 请求走私?2. HTTP 请求走私漏洞是如何产生的?3. 如何执行 HTTP 请求走私攻击3.1 CL.TE 漏洞3.2 TE.CL 漏洞3.3 TE.TE 行为:混淆 TE 标头 4. 如何识别和确认 HTTP 请求走私漏洞4.…

元脑服务器的创新应用:浪潮信息引领AI计算新时代

浪潮信息的元脑 R1 服务器现已全面支持开源框架 SGLang,能够在单机环境下实现 DeepSeek 671B 模型的高并发性能,用户并发访问量超过1000。通过对 SGLang 最新版本的深度适配,元脑 R1 推理服务器在运行高性能模型时,展现出卓越的处…

蓝桥备赛(13)- 链表和 list(下)

一、动态链表 - list (了解) new 和 delete 是非常耗时的操作 在算法比赛中,一般不会使使用 new 和 delete 去模拟实现一个链表。 而且STL 里面的 list 的底层就是动态实现的双向循环链表,增删会涉及 new 和 delete,效率不高,竞赛…

【VUE2】第二期——生命周期及工程化

目录 1 生命周期 1.1 介绍 1.2 钩子 2 可视化图表库 3 脚手架Vue CLI 3.1 使用步骤 3.2 项目目录介绍 3.3 main.js入口文件代码介绍 4 组件化开发 4.1 组件 4.2 普通组件注册 4.2.1 局部注册 4.2.2 全局注册 1 生命周期 1.1 介绍 Vue生命周期:就是…

正则表达式梳理(基于python)

正则表达式(regular expression)是一种针对字符串匹配查找所定义的规则模式,独立于语言,但不同语言在实现上也会存在一些细微差别,下面基于python对常用的相关内容进行梳理。 文章目录 一、通用常识1.通配符ps.反义 2.…

《C++ 构造、拷贝构造与析构函数:对象的诞生、克隆与消逝之旅》

类的6个默认成员函数 构造函数 是对一个对象实例化时的初始化 例如在C语言中写的堆的时候要初始化StackInit,而c祖师爷写的构造函数本质上就是自动调用初始化。 构造函数默认构造函数自己写的(符合规定的显示表达式) 注:一般情况下…

使用服务器搭建无门槛ChatGPT WEB应用LobeChat

一、服务器实例配置 ‌实例选型‌ ‌推荐配置‌:‌2核4GB内存‌,保障AI推理和并发访问的流畅性‌67。‌操作系统‌:选择 ‌Ubuntu 22.04 LTS‌,适配Docker环境与LobeChat依赖库‌23。‌安全组规则‌:开放以下端口&…

C/S架构与B/S架构

一、定义与核心区别 C/S架构(Client/Server,客户端/服务器) 客户端需安装专用软件(如QQ、企业ERP系统),直接与服务器通信。服务器端通常包括数据库和业务逻辑处理1。特点:客户端承担部分计算任务…

鸿蒙Next-应用检测、安装以及企业内部商店的实现

一、企业内部应用检测和更新升级 A应用检测是否安装B应用 canOpenApp():boolean{ try { let link schB://com.example.test/open; // 替换成你目标应用的link串儿 let canOpen bundleManager.canOpenLink(link); console.log("canOpen:"canOpen…

车载网络测试-DBC文件解读

目录 1 背景2 DBC结构2.1 Networks2.2 ECUs(Electronic Control Units)2.3 Network Nodes2.4 Message(报文)2.4.1 Message定义、作用、示例2.4.2 报文Attribute(属性)2.4.2.1 常见的报文Attributes2.4.2.2 …

《A++ 敏捷开发》- 18 软件需求

需求并不是关于需求 (Requirements are not really about requirements) 大家去公共图书馆寄存物品,以前都是扫二维码开箱,有些图书馆升级了使用指纹识别。 “是否新方法比以前好?”我问年轻的开发人员。 “当然用指纹识别好。新技术&#x…

SQL经典查询

查询不在表里的数据,一张学生表,一张学生的选课表,要求查出没有选课的学生? select students.student_name from students left join course_selection on students.student_idcourse_selection.student_id where course_selecti…

大语言模型进化论:从达尔文到AI的启示与展望

文章大纲 引言大语言模型中的“进化论”思想体现遗传变异过度繁殖和生存斗争大模型“过度繁殖”与“生存竞争”机制解析**一、过度繁殖:技术迭代的指数级爆发****二、生存竞争:计算资源的达尔文战场****三、生存竞争胜出关键要素****四、行业竞争格局演化趋势**核心结论自然选…

SSM架构 +Nginx+FFmpeg实现rtsp流转hls流,在前端html上实现视频播放

序言: 本文介绍通过SSM架构 NginxFFmpeg实现rtsp流转hls流,在前端html上实现视频播放功能。此方法可用于网络摄像头RTSP视频流WEB端实时播放。(海康和大华都可以),我使用的是海康 步骤一:安装软件 FFmpeg…

Hadoop管理页看不到任务的问题

这个yarn分配任务了但是为空 在$HADOOP_HOME/conf/mapred-site.xml 原来的配置文件基础之上添加&#xff1a; <property><name>mapreduce.framework.name</name><value>yarn</value></property> 重启之后就好了

腾讯云TBDS获金融信创实验室全项适配认证 打造国产化大数据平台标杆

点击蓝字⬆ 关注我们 本文共计1605字 预计阅读时长5分钟 近日&#xff0c;腾讯云大数据套件软件TBDS V5.3、数据仓库TCHouse V3.0通过金融信创生态实验室&#xff08;以下简称“实验室”&#xff09;的适配验证。 本测试基于典型金融业务场景&#xff0c;在全信创环境下&#x…

人工智能神经网络基本原理

MP 神经元数学模型 MP 模型是神经网络领域的早期模型&#xff0c;它模仿了神经元的基本结构和工作原理。 人工神经元是一个多输入、单输出的信息处理单元&#xff0c;是对生物神经元的建模。建模方式可以有很多种&#xff0c;不同的建模方式就意味着不同的人工神经元结构。 比…