qlib量化投资平台(「华泰金工林晓明团队」微软AI量化投资平台Qlib体验-华泰人工智能系列之四十)__景合财经知识网_景合财经景合财经

景合财经
景合财经知识网站

qlib量化投资平台(「华泰金工林晓明团队」微软AI量化投资平台Qlib体验-华泰人工智能系列之四十)

林晓明S0570516010001

SFC No. BPY421 研究员

李子钰S0570519110003 研究员

何 康S0570519110003 研究员

王晨宇S0570119110038 联系人

报告发布时间:2020年12月22日

摘要

核心观点

本文介绍微软AI量化投资平台Qlib基础和进阶功能,对比传统量化策略开发流程和Qlib提供的解决方案,提炼Qlib特色及优势,并探讨笔者使用体会。Qlib于2020年9月公开初版源码,2020年12月获微软官网报道并引发热议。我们认为Qlib的主要优势在于:1)覆盖量化投资全过程,用户无需切换工具包或编程语言,降低AI算法使用门槛;2)从工程实现角度,对因子数据储存、因子计算等环节提出创新解决方案,提升运算性能和开发效率,或能解决量化投资研究中的部分痛点。

笔者使用体会:侧重量价选股,解决部分痛点,开源或推动技术发展

笔者使用Qlib的体会是,Qlib在“术”层面的创新要大于在“道”层面的创新。Qlib在宣传中称其为“业内首个AI量化投资开源平台”,而就目前公开的功能看,Qlib的核心是“量价因子结合AI模型选股流程”,在“道”的层面未脱离传统因子选股方法论。在“术”的层面, Qlib提出的数据存储方案、表达式引擎等工程创新一定程度上能够解决研究中的部分痛点。微软此次的开源尝试能够降低整个行业的学习和研发成本,或能推动量化投资行业的技术发展。

Qlib基础功能:以港股日频量价因子LightGBM选股策略为例

Qlib官方推荐的学习素材有GitHub文档和在线文档,包含A股日频量价因子AI选股策略案例,然而直接学习官方代码的“代入感”不强,并且官方代码绕过了很多“坑”,但研究者在实际学习使用时可能绕不开这些“坑”。为了帮助读者快速上手Qlib,我们参考官方代码,设计新的应用场景,以港股日频量价因子LightGBM选股策略为例,分Qlib安装、数据准备、因子生成、策略构建、结果展示各步骤,讲解Qlib基础功能。

Qlib进阶功能:自定义策略组件

我们以自定义因子、标签、数据预处理方式、AI模型为例讲解Qlib的进阶功能。AI选股模型包含因子生成和预处理、模型训练、策略回测等组件,在Qlib中这些组件通过工作流workflow串联在一起,每个组件均有对应参数控制。因此最简单的自定义策略方式是直接修改参数。另外,每个组件都有其对应源码,更灵活的自定义策略方式是修改源码或仿照源码创建新的继承类。

Qlib特色:覆盖量化投资全过程,拥有多项工程上的创新

Qlib的设计初衷之一在于覆盖量化投资的全过程,为用户的AI算法提供高性能的底层基础架构,降低AI算法的使用门槛,便于金融从业者使用。Qlib的“高性能底层基础架构”体现在多项工程上的创新,例如数据存储方案、表达式引擎和缓存系统。据论文Qlib: An AI-oriented Quantitative Investment Platform测试显示,Qlib在读取原始数据和生成因子任务上的性能表现优于传统关系型数据库MySQL、非关系型数据库MongoDB、时序数据库InfluxDB和HDF5。

风险提示:本文的港股AI选股策略仅作案例教学使用,不具备实际投资价值,例如未剔除低价股、低流动性股票,训练集和测试集较短,未进行参数优化等。Qlib仍在开发中,部分功能未加完善和验证,使用存在风险。人工智能挖掘市场规律是对历史的总结,市场规律在未来可能失效。人工智能技术存在过拟合风险。

本文研究导读

2020年9月,微软亚洲研究院在学术论文预印本平台arXiv发布论文Qlib: An AI-oriented Quantitative Investment Platform,公开其开发的业内首个AI量化投资开源平台Qlib,并在代码托管平台GitHub上开放源代码。2020年12月,微软亚洲研究院在官网报道该消息,一石激起千层浪。微软称Qlib“通过创建一个通用的技术平台,帮助实现量化投资流程的AI闭环”。

AI量化投资开源平台对于量化投资领域的意义不凡。一套标准化的代码能提升行业的研究效率,避免重复造轮子;代码开源使得研究者能够学习业内同行的先进经验,并根据实际需求自由修改和添加功能。投资者关心的问题是,Qlib是否如宣传得那么强大?Qlib包含哪些功能,有哪些使用场景?Qlib解决了传统量化策略开发流程中的哪些痛点?Qlib的实际使用体验如何?

带着上述问题,笔者将从实操层面一探究竟。本文第一部分以港股日频量价因子LightGBM选股策略为例,带领读者快速上手Qlib。第二部分深入讲解如何自定义策略中的各个组件,如自定义因子、标签、数据预处理方式、AI模型等环节。第三部分结合Qlib论文,介绍Qlib的特色以及相比传统量化策略开发流程的改进之处,最后谈谈笔者的使用体会。

我们认为,Qlib的主要优势在于:1)覆盖量化投资全过程,用户无需切换工具包或编程语言,降低AI算法使用门槛;2)从工程实现角度,对因子数据储存、因子计算等环节提出创新解决方案,提升运算性能和开发效率,或能解决量化投资研究中的部分痛点。

快速上手Qlib:以港股日频量价因子AI选股策略为例

Qlib安装

Qlib安装是读者容易遇到的第一个“坑”。首先推荐在Python 3.7及更新版的Python环境下安装。Qlib官方提供1)pip和2)setup.py两种安装方式。其中pip安装较为简单,在命令行直接运行pip install pyqlib即可,将自动安装最新的Qlib稳定版。不过笔者经Windows和 Mac系统下测试,更推荐setup.py方式。具体安装步骤如下。

安装Microsoft C++生成工具

Qlib运行依赖Microsoft Visual C++ 14.0,否则安装过程中会报如下错误:

error: Microsoft Visual C++ 14.0 is required. Get it with "Build Tools for Visual Studio": https://visualstudio.microsoft.com/downloads/

注意这里仅安装运行组件(Microsoft Visual C++ Redistributable)无法解决此问题,需要安装完整版Microsoft Visual Studio或者参考报错信息安装Microsoft C++生成工具。生成工具的下载链接为:https://visualstudio.microsoft.com/zh-hans/visual-cpp-build-tools/

安装生成工具过程中,需要点选部分选项,参考微软官方建议链接及下图:

https://docs.microsoft.com/en-us/answers/questions/136595/error-microsoft-visual-c-140-or-greater-is-require.html

setup.py安装

Qlib官方给出的setup.py安装方式如下。首先安装或更新numpy和cython库,在命令行运行pip install numpy和pip install --upgrade cython即可。

接下来的安装分两种情况:

1. 若已安装git并完成环境配置,在命令行运行下列指令即可:

git clone https://github.com/microsoft/qlib.git && cd qlib

python setup.py install

2.若未安装git,可在GitHub下载zip源码包(https://github.com/microsoft/qlib),解压缩至任意路径,如笔者放在C:/Users/username/anaconda3/Lib/site-packages/qlib,确保setup.py文件在该路径下,随后在该路径下启动命令行,运行如下指令即可:

python setup.py install

Qlib的setup.py安装方式将自动安装包含开发版在内的最新版。例如笔者在2020年12月14日安装的版本为0.6.1.dev0。笔者办公网络环境不支持git安装,故采用上述第二种方式,命令行安装过程如下图。

数据准备

get_data下载官方数据

Qlib提供A股和美股两类数据作学习测试使用。Qlib官方给出的A股数据下载方法为:在Qlib安装路径(如C:/Users/username/anaconda3/Lib/site-packages/qlib)启动命令行,运行如下get_data指令:

python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn

若读者采用pip方式安装Qlib,运行上述指令可能报错:ModuleNotFoundError: No module named 'qlib.tests'。解决方法为:在GitHub下载Qlib的zip源码包,将tests文件拷贝至安装路径。

笔者下载Qlib官方数据过程如上图所示。下载成功后,数据保存在如下路径:

C:/Users/username/.qlib/qlib_data/cn_data。

dump_all转换用户数据格式

除官方数据外,Qlib支持用户提供的csv格式数据,需要调用dump_all指令将csv格式数据转换为bin和txt格式。下面笔者以港股行情数据为例,展示数据格式转换的步骤。

将原始港股行情数据保存为上图形式,即每只股票存成一个csv文件,文件名为股票代码,文件夹命名为hk_data。数据从2008年初至2020年11月末,共计3739只股票(含权证,含已退市)。每个csv文件内部如下图所示。

股票csv数据需要至少包含下表所示字段。其中有两个“坑”需要注意:

1. 价格数据的要求在官方文档中未提及,笔者建议采用复权价格,原因在于后续数据标注(源码见qlib.contrib.data.handler)采用close或vwap计算股票未来收益率,且回测(源码见qlid.contrib.evaluate.backtest)使用close、open或vwap进行交易。

2. 数据需包含factor或change字段,否则运行Qlib官方提供的策略全流程范例代码examples/workflow_by_code.py时,策略收益和净值将出现异常。

除个股数据外,还需准备指数数据作为基准。笔者将恒生指数行情数据以和股票数据相同形式保存在相同路径下,命名为hkhsi.csv。回到Qlib安装路径,在命令行运行dump_all指令:

python scripts/dump_bin.py dump_all --csv_path ~/.qlib/csv_data/hk_data --qlib_dir ~/.qlib/qlib_data/hk_data --symbol_field_name stock_code --date_field_name date --include_fields open,high,low,close,volume,money,factor,vwap,change

上述dump_all指令包含如下参数:

1. symbol_field_name:csv文件中股票代码列名,此处为stock_code;

2. date_field_name:csv文件中日期列名,此处为date;

3. include_fields:其余字段名,注意逗号后不能有空格,否则数据转换将出现错误。

使用dump_all将用户csv数据格式转为bin数据格式的过程如下图所示。

转换完成后,新数据保存在如下路径:C:/Users/username/.qlib/qlib_data/hk_data。该路径下包含calendar、features和instruments三个子文件夹,分别存放交易日历、行情特征和股票池。其中行情特征为bin格式,这与传统量化策略开发使用的数据格式类型不同,Qlib数据存储方案的优势将在后文介绍。

港股日频量价因子生成

接下来我们将构建港股日频量价因子AI选股策略,核心环节之一是生成量价因子。Qlib提供两套自带的因子库,分别为Alpha158和Alpha360,分别包含158和360个Alpha因子。这里的因子库并非是计算好的因子值,而是一套生成因子的算法(Qlib中称表达式),因此可迁移至任意股票池。

初始化运行环境和原始数据读取

在Python中运行Qlib程序前,需要首先初始化运行环境,命令为qlib.init,参数provider_uri为港股数据所在路径,如下图所示。

调用qlib.data模块可读取原始数据。例如qlib.data.calendar命令可读取指定时间区间内交易日期;qlib.data.instruments命令可定义股票池,参数market=’all’代表选取全部个股构成股票池;qlib.data.list_instruments命令可以展示指定时间区间内的股票池,时间区间的意义在于,股票池可能会随时间动态变化,如指数成分股票池。

调用qlib.data.features模块可以获取指定股票指定日期指定字段数据,例如下图展示获取腾讯控股(0700 HK)在2020年1月初至11月底的日频后复权收盘价和成交量。需注意,Windows系统下Qlib安装路径以及数据文件默认在C盘,笔者的经验是读取数据的程序最好也在C盘下运行,否则获取feature时可能无响应。

自定义股票池

上述代码中,股票池定义为全部个股,这种定义方式存在两个问题。首先,我们的原始数据中包含恒生指数,但恒生指数是作为基准用,不参与到选股中,在计算因子和后续选股模型构建环节应予以剔除。其次,股票是否进入选股池需考虑其它因素,如A股选股模型通常剔除风险警示股票、次新股等,港股中的低价股也不适合纳入。

这里我们采用qlib.data.filter模块自定义股票池。首先,使用qlib.data.filter.NameDFilter命令进行股票名称静态筛选,参数name_rule_re为纳入股票代码的正则表达式,如HK[0-9!]表示以HK开头,后续为数字或感叹号的股票代码,感叹号代表目前已退市股票。其次,使用qlib.data.filter.ExpressionDFilter命令进行股票因子表达式的动态筛选,参数rule_expression为入选的因子表达式,如$close>=1代表收盘价应大于等于1元。随后,通过qlib.data.instruments命令的参数filter_pipe,将两个筛选条件组装到一起。

下图展示自定义股票池的过程,展示股票池(按数字排序)的后5个股票代码,相比于全股票池,自定义股票池缺少HKHSI(恒生指数)和HK9998(光荣控股,9998 HK,2020年7~11月收盘价均低于1元),表明我们的两步筛选起到作用。

Alpha158因子库

下面进入核心的因子计算部分。Qlib提供Alpha158和Alpha360两类量价因子库,用户也可根据需要自定义因子库。Alpha158和Alpha360的因子定义方式可以参考源码文件qlib/contrib/data/handler.py。我们以Alpha158为例进行展示说明。

生成Alpha158因子调用qlib.contrib.data.handler模块下的Alpha158类,具体命令为:

from qlib.contrib.data.handler import Alpha158

h = Alpha158(**data_handler_config)

其中参数data_handler_config相当于配置文件,字典类型,用来定义完整数据起止日期(start_time和end_time),拟合数据起止日期(fit_start_time和fit_end_time),股票池(instruments)等。拟合数据起止日期区间应为完整数据起止日期数据的子集。拟合数据日期(训练和验证集)和余下日期(测试集)在数据预处理的方式上有所不同,将在下章展开讨论。

执行上述指令后,程序将计算从start_time至end_time的当期因子值和下期收益,分别作为后续AI模型训练的特征和标签。在笔者运行环境下(CPU:Intel i5-8265U @ 1.60GHz;RAM:16.0GB),生成2020年1~11月港股日频158个因子的时间开销约为695秒。下图展示生成Alpha158因子过程以及158个因子简称。以前两个因子KMID和KLEN为例,查看源码知,KMID=(close-open)/open,其含义为日内涨跌幅,KLEN=(high-low)/open,其含义为日内振幅。

通过h.fetch(col_set=’label’)指令可获取标签。默认参数下,股票t日的标签对应t+2日收盘价相对于t+1日收盘价的涨跌幅,相当于t日收盘后发信号,t+1日收盘时刻开仓,t+2日收盘时刻平仓。如下图,2020年1月2日HK0001(长和;0001 HK)的标签值为-0.007423,对应2020年1月6日该股票涨跌幅为-0.7423%(2020年1月4~5日非交易日)。

通过h.fetch(col_set=’feature’)指令可获取特征。默认参数下,股票t日的特征对应t日收盘后计算出的因子值。下图展示部分股票部分交易日的部分因子值。

LightGBM选股策略构建

下面进入核心的选股策略构建部分,这一部分同样参考Qlib范例workflow_by_code_py,将范例代码中的A股策略改为港股策略。首先,导入后续将会调用的相关Qlib模块,如下图所示。

初始化环境和定义股票池的代码不再赘述,股票池采用全部港股(含权证),剔除作为基准的恒生指数。

接下来定义因子生成参数data_handler_config和模型训练参数task。因子生成参数前文已作介绍,不再赘述。模型训练参数task为字典类型,较复杂,也是整个模型的核心部分,又可以分为model和dataset两个字典。

第一项model为AI模型参数,必须包含class(AI模型名称)和module_path(AI模型所在路径)两个子键;kwargs为model的可选子键,通过kwargs设置指定AI模型的超参数。下图展示model的键、示例值与说明。这里我们选用固定超参数,不进行参数优化。

第二项dataset为数据集参数,必须包含class(数据集名称)和module_path(数据集所在路径)两个子键;kwargs为dataset的可选子键,通过kwargs设置指定数据集的参数。下图展示dataset的键、示例值与说明。

因子生成参数data_handler_config和模型训练参数task的代码实现过程如下所示。通过qlib.utils.init_instance_by_config命令将上述参数分别写入模型,分别返回模型model和数据集dataset。

完成模型训练参数定义后,调用qlib.workflow模块正式进行训练,依次执行如下命令:qlib.workflow.start开启训练;model.fit拟合模型;qlib.workflow.save_objects保存模型;qlib.workflow.get_recorder.id获取“实验”(即模型训练)记录的编号。下图展示模型训练的代码实现过程。笔者运行环境下,读入数据及数据预处理时间开销约为372秒,训练模型时间开销约为9秒。LightGBM模型迭代的实质是参数优化,当验证集损失连续50轮未降低时停止迭代,此处迭代71次后结束训练。

选股策略回测

接下来设置策略回测参数port_analysis_config,该参数为字典类型,又可以分为strategy和backtest两个子键。第一项strategy为策略参数,例如此处使用TopkDropout策略,每日等权持有topk=50只股票,同时每日卖出持仓股票中最新预测收益最低的n_drop=5只股票,买入未持仓股票中最新预测收益最高的n_drop=5只股票。第二项backtest为回测参数,用于设置涨跌停限制、起始资金、业绩比较基准、成交价格、交易费率等信息。

回测代码实现如上图所示。调用qlib.workflow模块正式进行回测,依次执行如下命令:qlib.workflow.start开启回测;qlib.workflow.get_recorder获取此前模型训练“实验”记录;recorder.load_object读取模型;qlib.workflow.get_recorder初始化回测“实验”记录;qlib.workflow.record_temp.SignalRecord初始化调仓信号;sr.generate生成调仓信号;qlib.workflow.record_temp.PortAnaRecord初始化回测及绩效分析;par.generate生成回测及绩效分析结果。

回测代码运行过程中,还显示部分预测结果。例如在测试集第一个交易日(2020年7月2日)对个股下期收益的预测值,如HK00001预测值为-0.018582;又如不扣费及扣费后的日均收益、日度波动率、年化收益、信息比率和最大回撤。

回测和绩效分析结果展示

完成策略回测后,调用qlib.contrib.report模块展示回测和绩效分析结果。展示前首先执行qlib.workflow.get_recorder获取回测“实验”记录,相关结果均储存为pkl格式,执行recorder.load_object读取预测结果pred.pkl、回测报告report_normal.pkl、仓位情况positions_normal.pkl和持仓分析port_analysis.pkl。

执行下列命令展示AI模型预测个股收益的IC和Rank IC值,可视化结果如下图所示。

label_df = dataset.prepare("test", col_set="label")

label_df.columns = ['label']

pred_label=pd.concat([label_df,pred_df],axis=1,sort=True).reindex(label_df.index)

analysis_position.score_ic_graph(pred_label)

执行analysis_position.report_graph(report_normal_df)展示回测净值相关结果。如下图所示,7张子图自上而下分别为:不扣费、扣费和基准净值;不扣费净值最大回撤;扣费净值最大回撤;不扣费和扣费超额收益净值;换手率;不扣费超额收益最大回撤;扣费超额收益最大回撤。观察知,选股模型在2020年7~10月超额收益较稳定,但在11月份出现回撤。

至此,我们走完了港股日频量价因子AI选股策略的全流程,希望帮助读者快速上手Qlib。下面我们将介绍Qlib进阶功能,如需自定义AI选股策略的组件,应如何通过代码实现。

Qlib进阶:自定义策略组件

下面我们讲解如何自定义策略。AI选股模型包含因子生成和预处理、模型训练、策略回测各组件。在Qlib中这些组件通过工作流workflow串联在一起,每个组件均有参数控制。因此最简单的自定义策略方式是直接修改参数。另外,每个组件都有其对应源码,更灵活的自定义策略方式是修改源码或者仿照源码创建新的继承类。

自定义特征

如果不满足于Qlib自带的Alpha158和Alpha360两个因子库,如何自定义新的特征(因子)?Alpha158和Alpha360的源码位于qlib.contrib.data.handler,这两个因子库继承了qlib.data.dataset.handler.DataHandlerLP类。DataHandlerLP类计算因子的核心方法是get_feature_config。通过修改get_feature_config以及它所调用的方法,可以自定义特征。

下图展示自定义特征代码,笔者定义了一个新的因子库类AlphaSimpleCustom,它继承了Alpha158类,共包含6个因子,分别为5/10/20/30/60日均线与当前收盘价比值以及MACD。定义单个因子的方式是直接写出该因子的表达式,例如5日均线可写作Mean($close,5),5日均线与收盘价比值可写作Mean($close,5)/$close。这种因子定义方式简洁直观,便于研究者构建新因子。

自定义标签

Alpha158因子库默认的标签定义方式为:股票t日的标签对应t+2日收盘价相对于t+1日收盘价的涨跌幅,相当于t日收盘后发信号,t+1日收盘时刻开仓,t+2日收盘时刻平仓。下面我们展示两种自定义标签方法。

如果希望以vwap价交易,将标签定义为t+2日vwap价相对于t+1日vwap价的涨跌幅,那么可以在设置模型训练参数task时,将task[‘dataset’][‘handler’][’class’]的值从Alpha158改为Alpha158vwap,同时在设置回测参数port_analysis_config时,将交易价格deal_price的值从close改为vwap即可,代码实现如下图。

更灵活的自定义标签方式是修改因子库源码。在DataHandlerLP类(即Alpha158因子库的父类)中,计算标签的核心方法是get_label_config,修改该方法可以自定义标签。如下图展示两个案例,分别以t+1日vwap价与t+2日vwap价之间的区间收益为标签,和以t+1日开盘价与t+6日开盘价之间的区间收益为标签。

更换数据预处理方法

Qlib中内置多种数据预处理方法,源码位于qlib.data.dataset.processor,包含样本处理、特征处理、异常值处理、缺失值填充和标准化共5大类13小类,如下表所示。

实际数据预处理是上述操作的任意组合。例如Alpha158和Alpha360因子库中,训练集和验证集的预处理是先剔除标签为缺失值的样本,再对标签(即收益)进行截面标准化;测试集的预处理是先将inf替换为均值,再进行Z分数标准化,最后将缺失值填充为0。下图为因子库数据预处理的源码,训练集和验证集对应learn_processors,测试集对应infer_processors,两者均为多项预处理操作组合而成的列表形式。

自定义数据预处理方法的较简单方式是直接修改数据集参数data_handler_config,增加learn_processors和 infer_processors两个键,值为目标预处理操作组合而成的列表。如上图所示,训练集和验证集的预处理是先剔除标签缺失的样本,再将每个截面的标签转换为rank序数;测试集的预处理是先提取指定的三个因子,再对因子做稳健Z分数标准化,最后将因子缺失值填充为0。

更换AI模型

Qlib内置了丰富的AI模型,官方文档称为Quant Model Zoo,源码位于qlib.contrib.model,支持的模型如下表所示。

如果希望使用Qlib内置模型,可以较方便地通过设置模型训练参数task下的AI模型参数model实现,模型本身的超参数也在model中设置。下图分别展示Lasso回归和XGBoost两类模型的参数设置过程。

如果希望使用的模型并未在Qlib提供的Quant Model Zoo中,可以创建新的类继承Model类,再通过参数model调用新创建的类。创建新类的关键是写模型拟合fit和模型预测predict两个方法。下图展示创建SVR支持向量回归类的过程。

其它功能

下面讨论用户可能关心的其它功能,这些功能有的尚未实现,有的已实现但源码尚未公开,有的源码或已公开但缺少文档。

预测和调仓频率均为日频,能否更换频率?若数据库为日频,目前可能无法直接通过设置参数的方式实现,相对可行的方式是重新通过dump_all方法读入月频或分钟频原始数据。

如何更新数据?据Qilb开发团队在GitHub上的讨论,目前团队内部已实现该功能,但暂未开源。

能否更换选股组合构建方式?目前仅开源TopkDropoutStrategy 一种已实现的组合构建方法,如需自定义组合构建方式,需要通过继承qlib.contrib.strategy.BaseStrategy类的方式创建新的策略类。

如何实现模型调参?在Qlib原始论文中提到Qlib提供调参引擎Hyperparameters Tuning Engine(HTE),同时笔者观察到源码包含qlib.contrib.tuner模块,但在官方文档里未公布使用方法。截至2020年12月22日,GitHub的产品线路图中包含自动调参(automatic parameter tuning)项目,预计该功能未来可能上线。

能否实现模型滚动训练,例如自动实现2008~2014年训练2015年测试,2009~2015年训练2016年测试,而非手动写循环?笔者在源码和官方文档中暂未找到相关功能。

Qlib特色及使用体会

本章我们将结合Qlib论文,介绍Qlib的特色以及相比传统量化策略开发流程的改进之处,最后谈谈笔者的使用体会。

Qlib覆盖量化投资全过程

传统量化投资策略开发

在传统AI量化投资策略开发过程中,策略各环节相对独立,部署在不同项目甚至于不同软件平台。以某团队人工智能选股模型开发流程为例:

1. 首先通过MATLAB获取原始数据,存成MAT格式文件;

2. 在MATLAB中计算因子,存成CSV格式文件;

3. 再转到Python平台,读取CSV文件,使用scikit-learn、XGBoost、TensorFlow和PyTorch包训练人工智能模型,得到预测值,存成CSV格式文件;

4. 再回到MATLAB平台进行策略回测和绩效分析。

上述开发流程实属繁琐,需要执行四个项目并切换两次编程语言。然而,这种看似“全局非最优”实际上是“局部最优”的结果:

1. 从数据存储的角度来说,MATLAB的MAT格式是一种不错的方案,v7.3以上版本MATLAB的MAT文件使用基于HDF5格式,MAT(HDF5)格式优点在于:

1) MATLAB 会对数据进行压缩以节省存储空间,尽管压缩和解压缩需要额外时间,但这是值得的,据MATLAB官方文档(链接如下)显示,某些情况下加载压缩数据比加载未压缩数据更快。

https://ww2.mathworks.cn/help/matlab/import_export/mat-file-versions.html

2) MAT格式便于传输和管理,只需将所有数据表打包成单个MAT文件即可。如果采用CSV格式,每张表(每个股票或每个交易日)单独存成一个文件,需要管理的文件数量过于庞大,不便于增删改查等管理操作。

2. 从计算因子的角度来说,MATLAB的矩阵数据类型是较为理想的方案。因子数据本质是一个三维数组,包含股票、交易日、因子三个维度,任取两个维度相当于从一个三维立体中切取一个二维平面。而计算因子往往可以通过二维矩阵运算实现,批量计算全部股票全部交易日的因子值,无需执行循环,运算效率较高。

近年来随着Python语言的普及,NumPy包的Ndarray格式也逐渐为广大使用者接受,NumPy在功能和语法上已经和MATLAB较为接近,但运算速度是NumPy的短板,即便使用Numba等加速包,总体看Python的NumPy仍比MATLAB慢一些。

3. 从训练AI模型的角度来说,Python相比于其它编程语言无疑具有显著优势,scikit-learn、XGBoost、TensorFlow和PyTorch包都是基于Python语言的成熟机器学习项目。Python的开源特性使得全世界研究者都能参与到开发中,及时共享最新AI算法,这种开放性是MATLAB等商业软件无法比拟的。

4. 从策略回测和绩效分析的角度来说,这部分对于运行效率和算法的依赖度较低,各种编程语言均能胜任。某团队使用MATLAB作为回测平台的原因主要是路径依赖,原始数据采用MAT格式保存,那么回测使用MATLAB也更方便。

Qlib的改进

Qlib的设计初衷之一就在于希望覆盖量化投资全过程,为用户的AI算法提供高性底层基础架构,降低AI算法使用门槛,便于金融从业者使用。“覆盖全过程”这一点更显示出其作为“平台”而不是“工具箱”的特性:从原始数据处理,到AI模型训练,再到投资组合的构建以及交易策略的生成全程使用,无需切换至其它编程软件或工具箱。Qlib提供的人工智能选股模型开发解决方案如下表所示。

Qlib在官方文档中展示其设计框架,如下图所示。自下而上共三层,分别为基础架构层(Infrastructure)、量化投资流程层(Workflow)和交互层(Interface),下面逐一介绍各自的功能和特色。

基础框架层:基础框架层从左下角的数据服务模块(Data Server)开始,数据服务模块帮助用户查询和加工原始数据;数据增强模块(Data Enhancement)提供一系列方法,让用户依据实际问题构建相应数据集;训练模块(Trainer)为AI算法提供灵活的接口,便于用户自定义训练模型;模型管理模块(Model Manager)便于用户管理众多AI模型;模型集成模块(Model Ensemble)能够实现模型集成,提升AI模型鲁棒性。

量化投资流程层:该层涵盖量化投资的整个工作流,信息抽取模块(Information Extractor)为AI模型提取有效数据,除因子之外,文本、图片、事件等都可以作为自定义信息输入到AI模型;预测模型(Forecast Model)接收数据后输出各种预测信号,如预期收益、预期风险等;投资组合生成模块(Portfolio Generator)根据预测模型输出结果生成目标投资组合;订单执行模块(Order Executor)是一套高度仿真的交易模拟系统,使得回测结果更贴近实盘交易。

交互层:最上层的交互层为底层系统提供用户友好界面,分析模块(Analyser)根据下层的预测信号、仓位、执行结果做出详细分析并可视化呈现。上一层的订单执行模块并不是简单的回测函数,而是设计成响应式的模拟器,能够支持强化学习等一些基于环境反馈的学习算法,而这些环境反馈正是来自交互层。

有意思的是,在Qlib原始论文Qlib: An AI-oriented Quantitative Investment Platform中,还提出了另一种各模块的拆解方式,如下图所示,自左向右分别为静态流程(Static Workflow)、动态建模(Dynamic Modeling)和分析模块(Analysis)。其中静态流程和分析模块属于常规模块(Normal Module),动态建模属于高度自定义模块(Highly user-customizable)。

静态流程涵盖此前提到的数据服务、数据增强、模型集成、投资组合生成和订单执行功能。如果仅仅使用训练完成后就不再更改的静态模型,静态流程通常已经能够满足用户需求。然而对量化投资而言,数据会在时间维度上扩展,今天的“样本外测试集”到明天就可能成为“样本内训练集”,因此模型的更新迭代就变得格外重要。

动态建模正是针对上述“痛点”而开发,包含模型生成器(Model Creator)、模型管理模块、集成模型生成器(Ensemble Creator)、投资组合生成器(Portfolio Generator Creator)和订单执行生成器(Order Executor Creator)。动态建模在Qlib论文中有提及,但截至2020年12月22日,该功能未在Qlib开源代码中体现,笔者推测该功能尚在开发中或者已开发完成但暂未开源。

分析模块又可分为Alpha分析、投资组合分析和交易分析三部分。Qlib论文对该模块未作介绍,笔者认为这样的拆分具有合理性。AI模型的Alpha并不等于实盘能获得的Alpha收益,从模型预测到构建投资组合再到交易执行,每一步都可能存在Alpha的“损耗”,因此有必要将三部分拆解开来分析。例如,如果模型Alpha较高但投资组合收益不理想,那么可推知组合构建方式需要改进;如果投资组合收益高但执行交易后收益不理想,那么可推知交易时机或交易算法需要改进。

工程创新:数据存储设计,表达式引擎,缓存系统

Qlib的“高性能底层基础架构”体现在多项工程上的创新,下面分别从数据存储方案(File Storage Design)、表达式引擎(Expression Engine)和缓存系统(Cache System)三方面展开介绍。

数据存储方案

因子选股的数据存在股票、时间、因子三个维度。传统因子数据存储方式有以MySQL为代表的关系型数据库,以MongoDB为代表的非关系型数据库,以InfluxDB为代表的时序数据库,以及NumPy数组、pandas数据集(保存为HDF5、pickle)等科学计算格式。这些数据存储方案各有长处和短板。

各类型数据库的长处在于查询及维护较为便捷,而这正是数据库的设计初衷。其中关系型数据库普适性较好,适用于各类型数据;非关系型数据库更适用于非结构化数据,如基金持仓数据等;时序数据库顾名思义更适用于时序数据。它们的短板是并非针对因子数据设计,因子是结构化的、兼具时序和面板属性的数据,和上述数据库的适用场景不完全匹配,因此会牺牲一定的效率。另外,当处理日内数据等更高频数据时,数据库的查询和计算速度较慢(并非没有解决办法,有商业付费数据库提供分布式集群方案)。

NumPy数组、pandas数据集、MATLAB矩阵也是常用的因子数据存储方案。这些数据类型正是为科学计算而设计,它们的优缺点刚好和数据库相反。由于这些数据类型均为矩阵形式,便于进行矩阵运算,适用于因子数据加工,计算效率较高。它们的短板是查询和维护效率较低。除此以外,MAT格式对除MATLAB以外的编程语言不友好。

总的来看,上述存储方案难以兼顾计算效率与查询便捷度。Qlib底层为此设计了专用的数据库,即日期索引+二进制文件的形式,将文件组织成一种树结构,数据存放在不同目录下的不同文件中,依据频率、属性和测度来分类。这种针对性的设计使它对金融数据的科学计算更为高效。

下图展示Qlib数据存储方案示意图。左半部分为数据存储结构,公共的时间轴存放于calendar.txt文件中,用于按时间查询的操作。右半部分显示所有属性值存放于一种紧凑的二进制文件中,共有(N+1)*4个比特,前4个比特存放时间戳信息,用于和时间轴中的时间作匹配,使得程序内部能按比特来取索引。这种数据存储方式适合于科学计算的文件结构,以及按时间顺序的数据组织结构,既能保证运算的高效,又能以低成本对数据进行增删改查操作。

Qlib研发团队将Qlib的数据存储方案与其它常用的数据存储方案进行比较。实验任务是从2007年至2020年每个交易日800只股票的原始行情数据(开、高、低、收、量)出发,创建一个包含14项因子数据集,以1)占用存储空间,2)读取数据、计算因子等步骤的时间开销为评判标准。

实验结果如上表所示,Qlib(即Qlib –E –D)占用存储空间和读取数据时间均低于关系型数据库MySQL、非关系型数据库MongoDB和时序数据库InfluxDB,仅高于HDF5格式,计算因子时间和运行总时间均低于MySQL、MongoDB、InfluxDB和HDF5,在数据存储方面展现出较高性能。

表达式引擎

表达式引擎主要用于因子生成,基于原始数据构建因子是经典研究方法,但新因子的构建往往开发成本和时间开销都较高。事实上,构建因子的过程无非是编写将原始数据映射成另一种数据的函数,这种函数能够拆分成一系列表达式的组合,表达式引擎的设计出发点正是基于此。

通过Qlib的表达式,用户能快速写出简洁而清晰的表达式来生成因子,不再需要写复杂而难以理解的数学函数。例如N日布林带可写作:

(MEAN($close,N)+2*STD($close,N)-$close)/MEAN($close,N)

又如MACD可写作:

(EMA($close, 12) - EMA($close, 26))/$close - EMA((EMA($close, 12) - EMA($close, 26))/$close, 9)/$close

缓存系统

缓存系统的设计也是Qlib的工程创新之一。计算机读取内存的速度快于读取磁盘的速度,而内存的容量则远小于磁盘容量。我们既无法将所有原始数据和运算过程中的数据都存在内存中,又不可能因为内存容量有限而放弃其读写高效的优势。

考虑到这点,Qlib设计了一套包含内存缓存(In-Memory Cache)和磁盘缓存(Disk Cache)在内的缓存系统。将因子表达式拆解成句法树,句法树节点的运算结果往往可以复用,因而存放在内存缓存中。而将表达式引擎计算结果和数据整合结果存放在磁盘缓存中。

使用体会:侧重量价选股,解决部分痛点,开源或推动技术发展

笔者使用Qlib一周的体会是,Qlib在“术”层面的创新要大于在“道”层面的创新。Qlib在宣传中称其为“业内首个AI量化投资开源平台”,而就目前公开的功能看,Qlib的核心是“量价因子结合AI模型选股流程”。笔者所期待的诸如AI在量化择时上的应用,以及高频交易环境下的强化学习模块,暂未出现在目前的开源代码中。可以说Qlib在“道”的层面并未脱离传统的因子选股方法论。

而在“术”的层面,笔者认为Qlib提出的解决方案颇有可圈可点之处。笔者在日常研究中常面临一些困惑:比如数据以何种方式存储,能够兼顾计算效率和查询便捷度,又如量价因子计算速度通常较慢。而Qlib的数据存储方案和表达式引擎这两处工程创新对笔者而言具有很高的借鉴价值。Qlib在“术”层面的创新一定程度上能够解决研究中的部分痛点。

笔者认为,不同层次研究者或能够从Qlib中各取所需。对于本领域的初学者而言,Qlib是不错的学习素材,从策略流程到程序设计均可提供参照,同时也节省重复造轮子的时间。对于有一定经验的研究者而言,Qlib在工程实现等角度的创新或能提供启发,并根据实际需求自由修改和添加功能。当然,对于经验更丰富的研究者而言,目前开源的Qlib模块可能仍偏基础,未来期待开源更多的进阶功能。

最后,笔者认为Qlib还有一大意义在于开源。量化投资的圈子整体较为封闭,研究者出于策略隐私性的考虑,通常不愿意分享自己的代码。而近三十年来,Linux、安卓、Python语言等开源项目的成功经验表明,开源能够降低整个行业的学习和研发成本,为行业进步提供源动力。微软此次的开源尝试或能推动量化投资行业的技术发展。

参考文献

Yang, X. , Liu, W. , Zhou, D. , Bian, J. , & Liu, T. Y. . (2020). Qlib: an ai-oriented quantitative investment platform. arXiv.

风险提示

本文的港股AI选股策略仅作案例教学使用,不具备实际投资价值,例如未剔除低价股、低流动性股票,训练集和测试集较短,未进行参数优化等。Qlib仍在开发中,部分功能未加完善和验证,使用存在风险。人工智能挖掘市场规律是对历史的总结,市场规律在未来可能失效。人工智能技术存在过拟合风险。

免责声明与评级说明

家电维修,空调维修,智能锁维修全国报修号码分享:可以直接拔打400-968-1665 全国各大城市均设网点。
赞(0) 打赏
欢迎转载分享:景合财经 » qlib量化投资平台(「华泰金工林晓明团队」微软AI量化投资平台Qlib体验-华泰人工智能系列之四十)
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

-景合财经

在线报修网点查询