本文介绍微软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:AnAI-orientedQuantitativeInvestmentPlatform测试显示,Qlib在读取原始数据和生成因子任务上的性能表现优于传统关系型数据库MySQL、非关系型数据库MongoDB、时序数据库InfluxDB和HDF5。
风险提示:本文的港股AI选股策略仅作案例教学使用,不具备实际投资价值,例如未剔除低价股、低流动性股票,训练集和测试集较短,未进行参数优化等。Qlib仍在开发中,部分功能未加完善和验证,使用存在风险。人工智能挖掘市场规律是对历史的总结,市场规律在未来可能失效。人工智能技术存在过拟合风险。
本文研究导读
2020年9月,微软亚洲研究院在学术论文预印本平台arXiv发布论文Qlib:AnAI-orientedQuantitativeInvestmentPlatform,公开其开发的业内首个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安装是读者容易遇到的第一个“坑”。首先推荐在Python3.7及更新版的Python环境下安装。Qlib官方提供1)pip和2)setup.py两种安装方式。其中pip安装较为简单,在命令行直接运行pipinstallpyqlib即可,将自动安装最新的Qlib稳定版。不过笔者经Windows和Mac系统下测试,更推荐setup.py方式。具体安装步骤如下。
安装MicrosoftC++生成工具
Qlib运行依赖MicrosoftVisualC++14.0,否则安装过程中会报如下错误:
setup.py安装
Qlib官方给出的setup.py安装方式如下。首先安装或更新numpy和cython库,在命令行运行pipinstallnumpy和pipinstall--upgradecython即可。
接下来的安装分两种情况:
1.若已安装git并完成环境配置,在命令行运行下列指令即可:
pythonsetup.pyinstall
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指令:
pythonscripts/get_data.pyqlib_data--target_dir~/.qlib/qlib_data/cn_data--regioncn
笔者下载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指令:
pythonscripts/dump_bin.pydump_all--csv_path~/.qlib/csv_data/hk_data--qlib_dir~/.qlib/qlib_data/hk_data--symbol_field_namestock_code--date_field_namedate--include_fieldsopen,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.features模块可以获取指定股票指定日期指定字段数据,例如下图展示获取腾讯控股(0700HK)在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(光荣控股,9998HK,2020年7~11月收盘价均低于1元),表明我们的两步筛选起到作用。
Alpha158因子库
下面进入核心的因子计算部分。Qlib提供Alpha158和Alpha360两类量价因子库,用户也可根据需要自定义因子库。Alpha158和Alpha360的因子定义方式可以参考源码文件qlib/contrib/data/handler.py。我们以Alpha158为例进行展示说明。
生成Alpha158因子调用qlib.contrib.data.handler模块下的Alpha158类,具体命令为:
fromqlib.contrib.data.handlerimportAlpha158
h=Alpha158(**data_handler_config)
其中参数data_handler_config相当于配置文件,字典类型,用来定义完整数据起止日期(start_time和end_time),拟合数据起止日期(fit_start_time和fit_end_time),股票池(instruments)等。拟合数据起止日期区间应为完整数据起止日期数据的子集。拟合数据日期(训练和验证集)和余下日期(测试集)在数据预处理的方式上有所不同,将在下章展开讨论。
通过h.fetch(col_set=’label’)指令可获取标签。默认参数下,股票t日的标签对应t+2日收盘价相对于t+1日收盘价的涨跌幅,相当于t日收盘后发信号,t+1日收盘时刻开仓,t+2日收盘时刻平仓。如下图,2020年1月2日HK0001(长和;0001HK)的标签值为-0.007423,对应2020年1月6日该股票涨跌幅为-0.7423%(2020年1月4~5日非交易日)。
通过h.fetch(col_set=’feature’)指令可获取特征。默认参数下,股票t日的特征对应t日收盘后计算出的因子值。下图展示部分股票部分交易日的部分因子值。
LightGBM选股策略构建
初始化环境和定义股票池的代码不再赘述,股票池采用全部港股(含权证),剔除作为基准的恒生指数。
接下来定义因子生成参数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。
选股策略回测
接下来设置策略回测参数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;又如不扣费及扣费后的日均收益、日度波动率、年化收益、信息比率和最大回撤。
回测和绩效分析结果展示
执行下列命令展示AI模型预测个股收益的IC和RankIC值,可视化结果如下图所示。
pred_label=pd.concat([label_df,pred_df],axis=1,sort=True).reindex(label_df.index)
analysis_position.score_ic_graph(pred_label)
至此,我们走完了港股日频量价因子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模型,官方文档称为QuantModelZoo,源码位于qlib.contrib.model,支持的模型如下表所示。
如果希望使用Qlib内置模型,可以较方便地通过设置模型训练参数task下的AI模型参数model实现,模型本身的超参数也在model中设置。下图分别展示Lasso回归和XGBoost两类模型的参数设置过程。
如果希望使用的模型并未在Qlib提供的QuantModelZoo中,可以创建新的类继承Model类,再通过参数model调用新创建的类。创建新类的关键是写模型拟合fit和模型预测predict两个方法。下图展示创建SVR支持向量回归类的过程。
其它功能
下面讨论用户可能关心的其它功能,这些功能有的尚未实现,有的已实现但源码尚未公开,有的源码或已公开但缺少文档。
预测和调仓频率均为日频,能否更换频率?若数据库为日频,目前可能无法直接通过设置参数的方式实现,相对可行的方式是重新通过dump_all方法读入月频或分钟频原始数据。
如何更新数据?据Qilb开发团队在GitHub上的讨论,目前团队内部已实现该功能,但暂未开源。
能否更换选股组合构建方式?目前仅开源TopkDropoutStrategy一种已实现的组合构建方法,如需自定义组合构建方式,需要通过继承qlib.contrib.strategy.BaseStrategy类的方式创建新的策略类。
如何实现模型调参?在Qlib原始论文中提到Qlib提供调参引擎HyperparametersTuningEngine(HTE),同时笔者观察到源码包含qlib.contrib.tuner模块,但在官方文档里未公布使用方法。截至2020年12月22日,GitHub的产品线路图中包含自动调参(automaticparametertuning)项目,预计该功能未来可能上线。
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)格式优点在于:
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),下面逐一介绍各自的功能和特色。
基础框架层:基础框架层从左下角的数据服务模块(DataServer)开始,数据服务模块帮助用户查询和加工原始数据;数据增强模块(DataEnhancement)提供一系列方法,让用户依据实际问题构建相应数据集;训练模块(Trainer)为AI算法提供灵活的接口,便于用户自定义训练模型;模型管理模块(ModelManager)便于用户管理众多AI模型;模型集成模块(ModelEnsemble)能够实现模型集成,提升AI模型鲁棒性。
量化投资流程层:该层涵盖量化投资的整个工作流,信息抽取模块(InformationExtractor)为AI模型提取有效数据,除因子之外,文本、图片、事件等都可以作为自定义信息输入到AI模型;预测模型(ForecastModel)接收数据后输出各种预测信号,如预期收益、预期风险等;投资组合生成模块(PortfolioGenerator)根据预测模型输出结果生成目标投资组合;订单执行模块(OrderExecutor)是一套高度仿真的交易模拟系统,使得回测结果更贴近实盘交易。
交互层:最上层的交互层为底层系统提供用户友好界面,分析模块(Analyser)根据下层的预测信号、仓位、执行结果做出详细分析并可视化呈现。上一层的订单执行模块并不是简单的回测函数,而是设计成响应式的模拟器,能够支持强化学习等一些基于环境反馈的学习算法,而这些环境反馈正是来自交互层。
有意思的是,在Qlib原始论文Qlib:AnAI-orientedQuantitativeInvestmentPlatform中,还提出了另一种各模块的拆解方式,如下图所示,自左向右分别为静态流程(StaticWorkflow)、动态建模(DynamicModeling)和分析模块(Analysis)。其中静态流程和分析模块属于常规模块(NormalModule),动态建模属于高度自定义模块(Highlyuser-customizable)。
动态建模正是针对上述“痛点”而开发,包含模型生成器(ModelCreator)、模型管理模块、集成模型生成器(EnsembleCreator)、投资组合生成器(PortfolioGeneratorCreator)和订单执行生成器(OrderExecutorCreator)。动态建模在Qlib论文中有提及,但截至2020年12月22日,该功能未在Qlib开源代码中体现,笔者推测该功能尚在开发中或者已开发完成但暂未开源。
分析模块又可分为Alpha分析、投资组合分析和交易分析三部分。Qlib论文对该模块未作介绍,笔者认为这样的拆分具有合理性。AI模型的Alpha并不等于实盘能获得的Alpha收益,从模型预测到构建投资组合再到交易执行,每一步都可能存在Alpha的“损耗”,因此有必要将三部分拆解开来分析。例如,如果模型Alpha较高但投资组合收益不理想,那么可推知组合构建方式需要改进;如果投资组合收益高但执行交易后收益不理想,那么可推知交易时机或交易算法需要改进。
工程创新:数据存储设计,表达式引擎,缓存系统
Qlib的“高性能底层基础架构”体现在多项工程上的创新,下面分别从数据存储方案(FileStorageDesign)、表达式引擎(ExpressionEngine)和缓存系统(CacheSystem)三方面展开介绍。
数据存储方案
各类型数据库的长处在于查询及维护较为便捷,而这正是数据库的设计初衷。其中关系型数据库普适性较好,适用于各类型数据;非关系型数据库更适用于非结构化数据,如基金持仓数据等;时序数据库顾名思义更适用于时序数据。它们的短板是并非针对因子数据设计,因子是结构化的、兼具时序和面板属性的数据,和上述数据库的适用场景不完全匹配,因此会牺牲一定的效率。另外,当处理日内数据等更高频数据时,数据库的查询和计算速度较慢(并非没有解决办法,有商业付费数据库提供分布式集群方案)。
NumPy数组、pandas数据集、MATLAB矩阵也是常用的因子数据存储方案。这些数据类型正是为科学计算而设计,它们的优缺点刚好和数据库相反。由于这些数据类型均为矩阵形式,便于进行矩阵运算,适用于因子数据加工,计算效率较高。它们的短板是查询和维护效率较低。除此以外,MAT格式对除MATLAB以外的编程语言不友好。
总的来看,上述存储方案难以兼顾计算效率与查询便捷度。Qlib底层为此设计了专用的数据库,即日期索引+二进制文件的形式,将文件组织成一种树结构,数据存放在不同目录下的不同文件中,依据频率、属性和测度来分类。这种针对性的设计使它对金融数据的科学计算更为高效。
表达式引擎
通过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-MemoryCache)和磁盘缓存(DiskCache)在内的缓存系统。将因子表达式拆解成句法树,句法树节点的运算结果往往可以复用,因而存放在内存缓存中。而将表达式引擎计算结果和数据整合结果存放在磁盘缓存中。
使用体会:侧重量价选股,解决部分痛点,开源或推动技术发展
笔者使用Qlib一周的体会是,Qlib在“术”层面的创新要大于在“道”层面的创新。Qlib在宣传中称其为“业内首个AI量化投资开源平台”,而就目前公开的功能看,Qlib的核心是“量价因子结合AI模型选股流程”。笔者所期待的诸如AI在量化择时上的应用,以及高频交易环境下的强化学习模块,暂未出现在目前的开源代码中。可以说Qlib在“道”的层面并未脱离传统的因子选股方法论。
而在“术”的层面,笔者认为Qlib提出的解决方案颇有可圈可点之处。笔者在日常研究中常面临一些困惑:比如数据以何种方式存储,能够兼顾计算效率和查询便捷度,又如量价因子计算速度通常较慢。而Qlib的数据存储方案和表达式引擎这两处工程创新对笔者而言具有很高的借鉴价值。Qlib在“术”层面的创新一定程度上能够解决研究中的部分痛点。
Yang,X.,Liu,W.,Zhou,D.,Bian,J.,&Liu,T.Y..(2020).Qlib:anai-orientedquantitativeinvestmentplatform.arXiv.
本文的港股AI选股策略仅作案例教学使用,不具备实际投资价值,例如未剔除低价股、低流动性股票,训练集和测试集较短,未进行参数优化等。Qlib仍在开发中,部分功能未加完善和验证,使用存在风险。人工智能挖掘市场规律是对历史的总结,市场规律在未来可能失效。人工智能技术存在过拟合风险。
本公众号研究报告有关内容摘编自已经发布的研究报告的,若因对报告的摘编而产生歧义,应以报告发布当日的完整内容为准。如需了解详细内容,请具体参见华泰证券所发布的完整版报告。
本公众号内容基于作者认为可靠的、已公开的信息编制,但作者对该等信息的准确性及完整性不作任何保证,也不对证券价格的涨跌或市场走势作确定性判断。本公众号所载的意见、评估及预测仅反映发布当日的观点和判断。在不同时期,华泰证券可能会发出与本公众号所载意见、评估及预测不一致的研究报告。
在任何情况下,本公众号中的信息或所表述的意见均不构成对客户私人投资建议。订阅人不应单独依靠本订阅号中的信息而取代自身独立的判断,应自主做出投资决策并自行承担投资风险。普通投资者若使用本资料,有可能会因缺乏解读服务而对内容产生理解上的歧义,进而造成投资损失。对依据或者使用本公众号内容所造成的一切后果,华泰证券及作者均不承担任何法律责任。
金融周期系列研究(资产配置)
【华泰金工林晓明团队】2020年中国市场量化资产配置年度观点——周期归来、机会重生,顾短也兼长20200121
【华泰金工林晓明团队】量化资产配置2020年度观点——小周期争明日,大周期赢未来20200116
【华泰金工林晓明团队】风险预算模型如何度量风险更有效-改进风险度量方式稳定提升风险模型表现的方法
【华泰金工林晓明团队】周期双底存不确定性宜防守待趋势——短周期底部拐头机会渐增,待趋势明朗把握或更大20191022
【华泰金工林晓明团队】二十年一轮回的黄金投资大周期——黄金的三周期定价逻辑与组合配置、投资机会分析20190826
【华泰金工林晓明团队】如何有效判断真正的周期拐点?——定量测度实际周期长度提升市场拐点判准概率
【华泰金工林晓明团队】基钦周期的长度会缩短吗?——20190506
【华泰金工林晓明团队】二十载昔日重现,三四年周期轮回——2019年中国与全球市场量化资产配置年度观点(下)
【华泰金工林晓明团队】二十载昔日重现,三四年周期轮回——2019年中国与全球市场量化资产配置年度观点(上)
【华泰金工林晓明团队】周期轮动下的BL资产配置策略
【华泰金工林晓明团队】周期理论与机器学习资产收益预测——华泰金工市场周期与资产配置研究
【华泰金工林晓明团队】市场拐点的判断方法
【华泰金工林晓明团队】2018中国与全球市场的机会、风险·年度策略报告(上)
【华泰金工林晓明团队】基钦周期的量化测度与历史规律·华泰金工周期系列研究
【华泰金工林晓明团队】周期三因子定价与资产配置模型(四)——华泰金工周期系列研究
【华泰金工林晓明团队】周期三因子定价与资产配置模型(三)——华泰金工周期系列研究
【华泰金工林晓明团队】周期三因子定价与资产配置模型(二)——华泰金工周期系列研究
【华泰金工林晓明团队】周期三因子定价与资产配置模型(一)——华泰金工周期系列研究
【华泰金工林晓明团队】华泰金工周期研究系列·基于DDM模型的板块轮动探索
【华泰金工林晓明团队】市场周期的量化分解
【华泰金工林晓明团队】周期研究对大类资产的预测观点
【华泰金工林晓明团队】金融经济系统周期的确定(下)——华泰金工周期系列研究
【华泰金工林晓明团队】金融经济系统周期的确定(上)——华泰金工周期系列研究
【华泰金工林晓明团队】全球多市场择时配置初探——华泰周期择时研究系列
行业指数频谱分析及配置模型:市场的周期分析系列之三
【华泰金工林晓明团队】市场的频率——市场轮回,周期重生
【华泰金工林晓明团队】市场的轮回——金融市场周期与经济周期关系初探
周期起源
【华泰金工林晓明团队】企业间力的产生、传播和作用效果——华泰周期起源系列研究之八
【华泰金工林晓明团队】耦合振子同步的藏本模型——华泰周期起源系列研究之七
【华泰金工林晓明团队】周期在供应链管理模型的实证——华泰周期起源系列研究之六
【华泰金工林晓明团队】不确定性与缓冲机制——华泰周期起源系列研究报告之五
【华泰金工林晓明团队】周期是矛盾双方稳定共存的结果——华泰周期起源系列研究之四
【华泰金工林晓明团队】周期是不确定性条件下的稳态——华泰周期起源系列研究之三
【华泰金工林晓明团队】周期趋同现象的动力学系统模型——华泰周期起源系列研究之二
【华泰金工林晓明团队】从微观同步到宏观周期——华泰周期起源系列研究报告之一
FOF与金融创新产品
【华泰金工林晓明团队】养老目标基金的中国市场开发流程--目标日期基金与目标风险基金产品设计研究
【华泰金工】生命周期基金GlidePath开发实例——华泰FOF与金融创新产品系列研究报告之一
因子周期(因子择时)
【华泰金工林晓明团队】市值因子收益与经济结构的关系——华泰因子周期研究系列之三
【华泰金工林晓明团队】周期视角下的因子投资时钟--华泰因子周期研究系列之二
【华泰金工林晓明团队】因子收益率的周期性研究初探
择时
【华泰金工林晓明团队】波动率与换手率构造牛熊指标——华泰金工量化择时系列
【华泰金工林晓明团队】A股市场低开现象研究
【华泰金工林晓明团队】华泰风险收益一致性择时模型
【华泰金工林晓明团队】技术指标与周期量价择时模型的结合
【华泰金工林晓明团队】华泰价量择时模型——市场周期在择时领域的应用
中观基本面轮动
【华泰金工林晓明团队】行业配置落地:指数增强篇——华泰中观基本面轮动系列之十
【华泰金工林晓明团队】行业配置策略:拥挤度视角——华泰中观基本面轮动系列之九
【华泰金工林晓明团队】行业配置策略:景气度视角——华泰中观基本面轮动系列之八
【华泰金工林晓明团队】行业配置策略:趋势追踪视角——华泰中观基本面轮动系列之七
【华泰金工林晓明团队】行业配置策略:宏观因子视角——华泰中观基本面轮动系列之六
【华泰金工林晓明团队】行业全景画像:投入产出表视角——华泰中观基本面轮动系列之五
【华泰金工林晓明团队】行业全景画像:改进杜邦拆解视角——华泰中观基本面轮动系列之四
【华泰金工林晓明团队】行业全景画像:风格因子视角——华泰中观基本面轮动系列之三
【华泰金工林晓明团队】行业全景画像:宏观因子视角——华泰中观基本面轮动系列之二
【华泰金工林晓明团队】确立研究对象:行业拆分与聚类——华泰中观基本面轮动系列之一
行业轮动
【华泰金工林晓明团队】不同协方差估计方法对比分析(二)——华泰行业轮动系列报告之十三
【华泰金工林晓明团队】拥挤度指标在行业配置中的应用——华泰行业轮动系列报告之十二
【华泰金工林晓明团队】基于投入产出表的产业链分析——华泰行业轮动系列报告之十一
【华泰金工林晓明团队】不同协方差估计方法对比分析——华泰行业轮动系列报告之十
【华泰金工林晓明团队】景气度指标在行业配置中的应用——华泰行业轮动系列报告之九
【华泰金工林晓明团队】再探周期视角下的资产轮动——华泰行业轮动系列报告之八
【华泰金工林晓明团队】“华泰周期轮动”基金组合改进版——华泰行业轮动系列报告之七
【华泰金工林晓明团队】“华泰周期轮动”基金组合构建——华泰行业轮动系列之六
【华泰金工林晓明团队】估值因子在行业配置中的应用——华泰行业轮动系列报告之五
【华泰金工林晓明团队】动量增强因子在行业配置中的应用——华泰行业轮动系列报告之四
【华泰金工林晓明团队】财务质量因子在行业配置中的应用——华泰行业轮动系列报告之三
【华泰金工林晓明团队】周期视角下的行业轮动实证分析——华泰行业轮动系列之二
【华泰金工林晓明团队】基于通用回归模型的行业轮动策略——华泰行业轮动系列之一
Smartbeta
【华泰金工林晓明团队】重剑无锋:低波动SmartBeta——华泰SmartBeta系列之四
【华泰金工林晓明团队】投资优质股票:红利类SmartBeta——华泰SmartBeta系列之三
【华泰金工林晓明团队】博观约取:价值和成长SmartBeta——华泰SmartBeta系列之二
【华泰金工林晓明团队】SmartBeta:乘风破浪趁此时——华泰SmartBeta系列之一
【华泰金工林晓明团队】Smartbeta在资产配置中的优势——华泰金工Smartbeta专题研究之一
多因子选股
【华泰金工林晓明团队】华泰单因子测试之历史分位数因子——华泰多因子系列之十三
【华泰金工林晓明团队】桑土之防:结构化多因子风险模型——华泰多因子系列之十二
【华泰金工林晓明团队】华泰单因子测试之海量技术因子——华泰多因子系列之十一
【华泰金工林晓明团队】因子合成方法实证分析——华泰多因子系列之十
【华泰金工林晓明团队】华泰单因子测试之一致预期因子——华泰多因子系列之九
【华泰金工林晓明团队】华泰单因子测试之财务质量因子——华泰多因子系列之八
【华泰金工林晓明团队】华泰单因子测试之资金流向因子——华泰多因子系列之七
【华泰金工林晓明团队】华泰单因子测试之波动率类因子——华泰多因子系列之六
【华泰金工林晓明团队】华泰单因子测试之换手率类因子——华泰多因子系列之五
【华泰金工林晓明团队】华泰单因子测试之动量类因子——华泰多因子系列之四
【华泰金工林晓明团队】华泰单因子测试之成长类因子——华泰多因子系列之三
【华泰金工林晓明团队】华泰单因子测试之估值类因子——华泰多因子系列之二
【华泰金工林晓明团队】华泰多因子模型体系初探——华泰多因子系列之一
【华泰金工林晓明团队】五因子模型A股实证研究
【华泰金工林晓明团队】红利因子的有效性研究——华泰红利指数与红利因子系列研究报告之二
人工智能
【华泰金工林晓明团队】WGAN生成:从单资产到多资产——华泰人工智能系列之三十八
【华泰金工林晓明团队】舆情因子和BERT情感分类模型——华泰人工智能系列之三十七
【华泰金工林晓明团队】相对生成对抗网络RGAN实证——华泰人工智能系列之三十六
【华泰金工林晓明团队】再探AlphaNet:结构和特征优化——华泰人工智能系列之三十四
【华泰金工林晓明团队】数据模式探索:无监督学习案例——华泰人工智能系列之三十三
【华泰金工林晓明团队】AlphaNet:因子挖掘神经网络——华泰人工智能系列之三十二
【华泰金工林晓明团队】生成对抗网络GAN初探——华泰人工智能系列之三十一
【华泰金工林晓明团队】从关联到逻辑:因果推断初探——华泰人工智能系列之三十
【华泰金工林晓明团队】另类标签和集成学习——华泰人工智能系列之二十九
【华泰金工林晓明团队】基于量价的人工智能选股体系概览——华泰人工智能系列之二十八
【华泰金工林晓明团队】揭开机器学习模型的“黑箱”——华泰人工智能系列之二十七
【华泰金工林晓明团队】遗传规划在CTA信号挖掘中的应用——华泰人工智能系列之二十六
【华泰金工林晓明团队】市场弱有效性检验与择时战场选择——华泰人工智能系列之二十五
【华泰金工林晓明团队】投石问路:技术分析可靠否?——华泰人工智能系列之二十四
【华泰金工林晓明团队】再探基于遗传规划的选股因子挖掘——华泰人工智能系列之二十三
【华泰金工林晓明团队】基于CSCV框架的回测过拟合概率——华泰人工智能系列之二十二
【华泰金工林晓明团队】基于遗传规划的选股因子挖掘——华泰人工智能系列之二十一
【华泰金工林晓明团队】必然中的偶然:机器学习中的随机数——华泰人工智能系列之二十
【华泰金工林晓明团队】偶然中的必然:重采样技术检验过拟合——华泰人工智能系列之十九
【华泰金工林晓明团队】机器学习选股模型的调仓频率实证——华泰人工智能系列之十八
【华泰金工林晓明团队】人工智能选股之数据标注方法实证——华泰人工智能系列之十七
【华泰金工林晓明团队】再论时序交叉验证对抗过拟合——华泰人工智能系列之十六
【华泰金工林晓明团队】人工智能选股之卷积神经网络——华泰人工智能系列之十五
【华泰金工林晓明团队】对抗过拟合:从时序交叉验证谈起
【华泰金工林晓明团队】人工智能选股之损失函数的改进——华泰人工智能系列之十三
【华泰金工林晓明团队】人工智能选股之特征选择——华泰人工智能系列之十二
【华泰金工林晓明团队】人工智能选股之Stacking集成学习——华泰人工智能系列之十一
【华泰金工林晓明团队】宏观周期指标应用于随机森林选股——华泰人工智能系列之十
【华泰金工林晓明团队】人工智能选股之循环神经网络——华泰人工智能系列之九
【华泰金工林晓明团队】人工智能选股之全连接神经网络——华泰人工智能系列之八
【华泰金工林晓明团队】人工智能选股之Python实战——华泰人工智能系列之七
【华泰金工林晓明团队】人工智能选股之Boosting模型——华泰人工智能系列之六
【华泰金工林晓明团队】人工智能选股之随机森林模型——华泰人工智能系列之五
【华泰金工林晓明团队】人工智能选股之朴素贝叶斯模型——华泰人工智能系列之四
【华泰金工林晓明团队】人工智能选股之支持向量机模型——华泰人工智能系列之三
【华泰金工林晓明团队】人工智能选股之广义线性模型——华泰人工智能系列之二
指数增强基金分析
【华泰金工林晓明团队】再探回归法测算基金持股仓位——华泰基金仓位分析专题报告
【华泰金工林晓明团队】酌古御今:指数增强基金收益分析
【华泰金工林晓明团队】基于回归法的基金持股仓位测算
【华泰金工林晓明团队】指数增强方法汇总及实例——量化多因子指数增强策略实证
基本面选股
【华泰金工林晓明团队】华泰价值选股之相对市盈率港股模型——相对市盈率港股通模型实证研究
【华泰金工林晓明团队】华泰价值选股之FFScore模型
【华泰金工林晓明团队】相对市盈率选股模型A股市场实证研究
【华泰金工林晓明团队】华泰价值选股之现金流因子研究——现金流因子选股策略实证研究
【华泰金工林晓明团队】华泰基本面选股之低市收率模型——小费雪选股法A股实证研究
【华泰金工林晓明团队】华泰基本面选股之高股息率模型之奥轩尼斯选股法A股实证研究
基金定投
【华泰金工林晓明团队】大成旗下基金2018定投策略研究
【华泰金工林晓明团队】布林带与股息率择时定投模型——基金定投系列专题研究报告之四
【华泰金工林晓明团队】基金定投3—马科维茨有效性检验
【华泰金工林晓明团队】基金定投2—投资标的与时机的选择方法