作为投资者,我们常听到的一句话是“不要把鸡蛋放入同一个篮子中”,可见分散投资可以降低风险,但如何选择不同的篮子、每个篮子放多少鸡蛋,便是见仁见智的事情了,量化投资就是解决这些问题的一种工具。
目前各种在线策略编程平台都支持Python语言,例如优矿、米筐、聚宽等,这也是我们选择Python进行量化投资的原因。
1 金融数据获取
我们可以通过多种途径获取金融数据,业内的许多公司会购买Wind、恒生聚源等数据提供商的数据库,若尚未入行,则也可以通过非常多的第三方策略平台获取免费数据,例如优矿、聚宽、米筐等。优矿依托通联数据,提供了丰富的数据信息,这里主要介绍如何在优矿中调用获取金融数据。
首先,可以在优矿官网(https://uqer.io)注册一个账号,然后单击“研究数据”模块,如图所示。
可以看到,这些数据基本涵盖了大部分金融数据,而且绝大部分是免费的。我们以一些最常用的金融数据来展示如何对它们进行调用。
单击“开始研究”模块,在左侧找到新建按钮,新建一个Notebook,再单击对应的Notebook,便进入Python代码的编辑环境。
我们将NoteBook左上角的模式设置为代码模式,开始调用数据。首先,打开一个浏览器新窗口并回到优矿的“研究数据”模块,寻找我们需要的数据。假定需要股票日行情数据,则我们既可以通过左边的一级选项一步一步地往下点来找到数据,也可以直接通过关键字在上方的搜索框中进行搜索。然后,我们找到了沪深股票的日行情数据,单击“展开详情”,结果如下图。
在详情中展示了各个参数的含义,例如,在输入时我们需要给出要调用哪些股票及在什么时间段的行情。而在返回值中,我们可选的行情不仅包括基本的高开低收、成交量、涨跌幅,也包括流通市值、VWAP等数据,应将所有选择返回的项传给field参数。在Notebook中的代码编写如图。
上图中,我们调取了平安银行与浦发银行在2015年5月13日的收盘价与总市值,返回的是一个DataFrame。需要注意的是,这里传入的股票代码是通联内部的编码,要在原股票代码的基础上加上后缀,例如对深市的股票加上后缀XSHE,对沪市的股票则加上后缀XSHG。当然,也支持直接传入股票代码,可以将原始股票的代码传入ticker参数。
除了某一天的截面数据,DataAPI也支持获取过去一时间段的数据,通过beginDate与endDate参数即可方便地获取。下图中,我们调取了平安银行与浦发银行从2018年1月17日至2018年1月19日的收盘价与总市值数据。
股票日行情DataAPI支持提取多只股票在某一时间段的数据,我们再来看看量化投资常用的因子数据。
在搜索因子中排名前两位的就是我们需要的DataAPI。可以看到有两个因子数据接口:一个用于获取多只股票在某一天的因子数据,另一个用于获取某只股票在历史上某一时间段的因子数据。可能是出于对数据量的考虑,并没有一个因子DataAPI可以直接调用多只股票在某一时间段的数据,所以我们在使用优矿的因子DataAPI时,应当考虑哪个DataAPI会更适合我们的需求。
如果只是想调用某一天的多只股票的因子数据,则应该使用如下DataAPI,如下图所示。
而如果想调用一只股票在某一时间段的因子数据,则应该使用另一个 DataAPI。
如果我们还是想获取多只股票在某一时间段的因子数据,则可以写循环来多次调用DataAPI,将它们全部取出来。
除了这些常用的金融数据,研究数据模块还包括财报数据、事件数据、期货数据等,我们可以通过搜索或者分类选项找到它们,在详情中对相应的参数有详细的解释。
2 数据整理
仅仅知道如何获取数据是不够的,我们还需要将原始数据整理成正确的、便于我们进一步使用的数据。下面展示一些常用的数据整理理念及Python的实现方法。
2.1 数据整合
数据整合指将不同数据源的数据进行汇总,形成可用于综合分析的表。
2.1.1 合并、追加
指向表中添加其他表中的字段或记录。例如,如果要分析一只股票站上其均线的情况,则需要知道其收盘价格及均线价格。当然,均线价格可以通过收盘价计算出来,但实际上在优矿因子库中已经有了均线因子,可以直接使用。现在的问题就变成了,如何将我们通过行情DataAPI与因子DataAPI调出来的数据合并?这个问题在Python中通过一两行代码即可解决。
上图所示,我们通过merge函数便把均线价格添加到行情表上了,再在这个表上判断当日是否站上均线就十分方便了。
2.1.2 数据透视
指将长表转换为宽表,将作业型表转换为分析型表。假设我们有一个包含多只股票在某一时间段的总市值数据的长表,是优矿行情DataAPI的返回结果类型,那么如何方便地求出这些股票每一天的市值之和呢?这时可以使用Python的数据透视表方法,将长表转换为宽表,之后运用DataFrame的sum方法即可很简单地解决这个问题。
如上所示,在DataAPI的原始返回数据结构中计算每天的市值之和是比较困难的,然而在转换数据格式后,分析和计算起来就十分方便了。
2.2 数据过滤
我们经常要对原始数据按某个指标进行过滤,例如在获取到了所有股票的PE后,仅想看PE大于0的股票(对于PE小于0的股票,该指标没有意义),这是非常常见的数据整理需求。
下图中,我们调取了所有A股在2018年1月19日的PE值,然后在DataFrame属性框中写筛选逻辑即可完成过滤。
2.3 数据探索与数据清洗
通常我们会认为ROE的值约为10%~30%,但实际上在调用所有股票的ROE因子进行分析时,我们发现并不是这么一回事。这里以ROE为例,介绍常用的数据探索方法及数据清洗方式。
我们在进行数据探索时,通常会先通过做一个简单的直方图来看看数据的分布。如下所示,真实的ROE分布可能与我们想象的并不一样,存在许多负值,并且大约存在-3~3的极端值。
可以再做一下boxplot图来看看结果,如下图。
通过上图的boxplot图也可以看出,在数据中存在很多异常值。当然这些异常值按照ROE的传统算法,可能并不算是错误的值。但如果要把ROE当作一个指标,进一步分析其对股票的未来收益或者其他方面的影响,则在建立回归或者其他模型时,就必须考虑到对异常值的处理,因为它对模型的影响可能很大。
这里我们以最常用的3倍标准差法为例,将超过3倍标准差的数据调整为3倍标准差。
可以看到,经过去极值处理后的数据全部在原始数据的3倍标准差内,分布不再有极端值,已处理后的因子建模将更加稳定,这也是数据挖掘中常常提及的“盖帽法”。
2.4 数据转化
除了数据清洗,为了建立模型,我们有时还需要进行数据转化。这里介绍两个常用的数据转化方法:数据标准化及设置哑变量。
2.4.1 数据标准化
数据标准化可以消除量纲及变量自身变异程度的影响,对很多模型来说都是十分重要的。常用的数据标准化有Min-max标准化和z-score标准化。
Min-max标准化的计算公式为:
z-score标准化的计算公式为:
Min-max标准化可以将标准化后的值统一到0~1;z-score标准化可以使标准化后的数据分布均值为0,方差为1。我们将去极化后的数据再进行一次标准化,如下图。
标准化永远不会改变数据原始的序数,它做的只是对数值大小的调整。若不看数值的话,则数据的分布并没有变化。
2.4.2 哑变量
除了标准化,我们在进行金融建模时的另一个常用的数据转化方法就是设置哑变量。例如,在将股票的行业信息加入建模分析时,依据原始分类是无法进行处理的,必须把它转化为0或1的变量。
上图中,我们首先调用通联数据的股票行业分类DataAPI,获取各股票的一级行业分类名字,然后通过一系列数据处理,生成每个行业的0或1的变量,这样才能把行业作为变量加入模型中进行分析。
当然,Pandas本身也有get_dummies函数,也可以瞬间对分类变量进行哑变量化,读者可自行查阅帮助文档学习。
相关图书《Python与量化投资:从基础到实战》
量化投资名师王小川主编、提供Python零基础入门及量化策略建模参考及实现、提供大型回测平台、代码直接实盘、可在线交流
作者:王小川 等
作者:博文视点
链接:https://www.jianshu.com/p/362d141a48de
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。