多因子模型在量化交易中被广泛运用,它通过分析多种因子与股票表现、收益率之间的关系,建立了一套量化选股的体系,从而能帮助投资者在股票池中更全面、准确地选出优质股票,实现超额回报。
多因子模型需要大量的不同风格的因子输入,尤其是引入机器学习后,我们需要上千甚至上万的因子作为特征输入。一家金融机构往往专注于挖掘可以带来超额收益 Alpha 的因子,一些最基本、最普遍使用的因子如果有高质量的实现,并且共享,将大大节省资源,提高投研效率,真正实现降本增效。
DolphinDB 实现多个因子库的出发点就在于此。今天,我们将为大家带来基于 DolphinDB 实现的国泰君安 191 Alpha 因子库。该因子库来源于国泰君安2017年6月份公布的研报《基于短周期价量特征的多因子选股体系——数量化专题之九十三》,属于短周期价量因子。
为了方便用户计算因子,我们用 DolphinDB 脚本实现了所有 191 个因子的函数,并封装在模块 gtja191Alpha 中。
完整使用教程、数据和代码均已发布在知乎。
gtja191Alpha 模块中的所有因子都是基于矩阵开发的,故所有的函数的入参均为矩阵。下文将结合实际因子为大家介绍该模块具体用法。
数据准备
对于数据,需要保证当前数据的表字段名与模块字段名一致。
为了方便使用,我们可以先准备一个辅助模块 gtja191Prepare.dos 来帮助统一字段名。调用辅助模块前,需将该辅助模块放置在 gtja191Alpha 同级目录下。一般来说,数据准备阶段,用户需调用辅助模块中的 prepareData 函数将数据与标准字段名称对齐。
辅助模块中有三类函数:
- prepareData 函数,可将数据与标准字段的名称对齐。函数的参数中,rawData 为使用的数据源,startTime 与 endTime 为需要的数据的起始时间和结束时间,其余参数为现有字段名与标准字段的对应名称。
- gtjaPrepare 函数,将表中字段提取成计算所需的矩阵并用字典存储。
- gtjaCalAlpha# 函数,最终计算函数,会调用 gtjaPrepare 函数及 gtja191Alpha 模块中的计算函数。
- 载入模块和数据方法如下,data 即为准备好的数据:
use gtja191Alpha
use gtja191Prepare
login('admin', '123456')
rawData = loadText("/YOUR_DIR/datatest.csv")
startTime = timestamp(2010.01.01)
endTime = timestamp(2010.01.31)
data = prepareData(rawData=rawData, startTime=startTime, endTime=endTime, securityidName="securityid", tradetimeName="tradetime", openName="open", closeName="close", highName="high", lowName="low", volumeName="vol", vwapName="vwap", indexCloseName="index_close", indexOpenName="index_open")
计算调用
gtja191Alpha 模块中的所有因子均为矩阵入参,故用户需先准备矩阵,再调用对应的 gtjaAlpha# 函数,返回的结果亦为矩阵。
以国泰君安 Alpha 第1号因子为例,计算方法如下:
use gtja191Alpha
open, close, vol = panel(data.tradetime, data.securityid, [data.open, data.close, data.vol])
res = gtjaAlpha1(open, close, vol)
//or you can use dictionary
input = dict(`open`close`vol, panel(data.tradetime, data.securityid, [data.open, data.close, data.vol]))
res = gtjaAlpha1(input.open, input.close, input.vol)
为了更加便于用户计算,省去查询参数这一步骤,因子计算辅助函数模块 gtja191Prepare.dos 提供了所需的矩阵准备函数 gtjaPrepare 和计算函数 gtjaCalAlpha#,用户可将其作为模块导入。
以 gtjaAlpha 第 1 号因子为例,辅助模块内的函数如下:
def gtjaPrepare(data, startTime, endTime){
t = select securityid, tradetime, vol, low, high, close, open, vwap, index_close, index_open from data where tradetime between startTime : endTime
return dict(`vol`low`high`close`open`vwap`index_close`index_open, panel(t.tradetime, t.securityid, [t.vol, t.low, t.high, t.close, t.open, t.vwap, t.index_close, t.index_open]))
}
def gtjaCalAlpha1(data, startTime, endTime){
input = gtjaPrepare(data, startTime, endTime)
return gtja191Alpha::gtjaAlpha1(input.open,input.close,input.vol)
}
//调用方法如下:
use gtja191Prepare
res = gtjaCalAlpha1(data, startTime, endTime)
实时流计算使用范例
国泰君安 191 Alpha 因子中大多数因子的实现方式都较为复杂,在流计算中,需要创建多个引擎级联完成。DolphinDB 提供了一个解析引擎 streamEngineParser 来代替人工创建并串联多个引擎,大大提高效率。除此之外,gtja191Alpha 模块也实现了批流一体,即做流计算时无需修改计算代码,直接在流引擎 streamEngineParser 中调用即可。
以国泰君安 Alpha 第 1 号因子为例,以下是如何调用 gtja191Alpha 模块,实现流计算:
1、首先定义输入输出的表结构:
inputSchema = table(1:0, ["SecurityID","TradeTime","open","close","vol"], [SYMBOL,TIMESTAMP,DOUBLE,DOUBLE,DOUBLE])
resultStream = table(10000:0, ["SecurityID","TradeTime","factor"], [SYMBOL,TIMESTAMP,DOUBLE])
2、调用 gtja191Alpha 模块,并在 streamEngineParser 中使用 gtjaAlpha1 函数:
use gtja191Alpha
metrics = <[SecurityID,gtjaAlpha1(open,close,vol)]>
streamEngine = streamEngineParser(name="gtjaAlpha1Parser", metrics=metrics, dummyTable=inputSchema, outputTable=resultStream, keyColumn="SecurityID", timeColumn=`tradetime, triggeringPattern='keyCount', triggeringInterval=4000)
3、将数据注入引擎,即可在 resultStream 输出表中查看结果:
streamEngine.append!((select SecurityID, TradeTime, close, high, low from data order by TradeTime))
//check the result
res = exec factor from resultStream pivot by TradeTime, SecurityID
本文介绍了 gtja191Alpha 模块的用法。该模块用 DolphinDB 内置函数实现了 国泰君安 191 Alpha 因子,具有简单便捷、批流一体的特点。
除了国泰君安 191 Alpha 因子库外,DolphinDB 还实现了一系列其他常用因子库,并为用户提供了高性能的高频多因子存储解决方案。2022年12月1日(周四)晚7点半,DolphinDB 创始人周小华博士与数据分析负责人毛忻玥,将在直播间开讲,为大家带来有关「高频多因子库存储最佳实践」的深入分享。