在量化交易中,基于金融市场 L1/L2 报价和交易高频数据进行高频因子计算是一项常见的投研需求。随着金融市场数据量的不断增加,传统的关系数据库已经难以满足大规模数据的存储和查询需求。为了应对这一挑战,一部分用户选择了分布式文件系统,并使用 Pickle、Feather、Npz、Hdf5、以及 Parquet 等格式来存储数据,并结合 Python 进行量化金融计算。
虽然这些存储方案可以支持海量的高频数据,但也存在一些问题,例如数据权限管理困难、不同数据关联不便、检索和查询不便,以及需要通过数据冗余来提高性能等。此外,通过 Python 来读取计算,也需要耗费一些时间在数据传输上。
为解决这些问题,越来越多的券商和私募机构开始采用 DolphinDB 作为分析型的分布式时序数据库。DolphinDB 提供高效的数据存储和计算能力,使得高频数据的因子计算变得更加便捷和高效。
本文旨在对比 DolphinDB 一体化因子计算方案与 Python + 各类文件存储的性能差异。通过本文的对比,读者可以了解 DolphinDB 一体化因子计算的优势,并在实际应用中合理做出选择。
测试基础环境
软硬件信息
本次测试对比了通过 Python + 文件存储 和 DolphinDB 实现的因子计算。其中:
- Python + 文件存储因子计算方案依赖 Numpy, Pandas, DolphinDB, Multiprocessing 等库。
- DolphinDB 一体化因子计算方案以 DolphinDB Server 作为计算平台,本次测试使用了单节点部署方式 。
测试所需硬件、软件环境信息如下:
- 硬件环境
硬件名称 | 配置信息 |
---|---|
CPU | Intel(R) Xeon(R) Silver 4216 CPU @ 2.10GHz |
内存 | 128G |
硬盘 | SSD 500G |
- 软件环境
软件名称 | 版本信息 |
---|---|
操作系统 | CentOS Linux release 7.9.2009 (Core) |
DolphinDB | V 2.00.9.8 |
Python | V 3.7.6 |
Numpy | V 1.20.2 |
Pandas | V 1.3.5 |
测试数据
Level 2 行情数据是目前国内证券市场上最为完整,颗粒度最为精细的交易信息数据。其涵盖了在沪深两市上市的股票、可交易型基金、沪深交易所指数等投资标的。
本次测试选取了全市场 2021.02.01 这一个交易日的全部 Level2 历史行情快照数据,该数据包含 26632 支标的,总数据量约为 3100 万条。初始数据存于 DolphinDB 中,Pickle、Parquet 等格式的数据文件均可从 DolphinDB 中导出生成。
快照表测试数据在 DolphinDB 中共55个字段,部分字段展示如下:
字段名 | 数据类型 | |
---|---|---|
1 | SecurityID | SYMBOL |
2 | DateTime | TIMESTAMP |
3 | BidPrice | DOUBLE |
4 | BidOrderQty | INT |
5 | …… | …… |
部分数据示例如下:
SecurityID | DateTime | BidPrice | BidOrderQty |
---|---|---|---|
000155 | 2021.12.01T09:41:00.000 | [29.3000,29.2900,29.2800,29.2700,29.2600,29.2500,29.2400,29.2300,29.2200,29.2100] | [3700,11000,1400,1700,300,600,3800,200,600,1700] |
000688 | 2021.12.01T09:40:39.000 | [13.5300,13.5100,13.5000,13.4800,13.4700,13.4500,13.4400,13.4200,13.4000,13.3800] | [500,1200,102200,5500,700,47000,1000,6500,18400,1000] |
测试场景
本次测试使用的数据是全市场 2021.12.01 这一个交易日的全部 Level2 历史行情快照数据,其中 Pickle,Parquet,Feather,Hdf5 四种格式的数据都按标的代码分组存储,而 Npz 格式的数据是将所有数据均匀分成十二组后进行存储。以上的这些存储方式都是为了达到计算性能的最优,而暂不考虑存储性能。在实践过程中,可以自己选择不同的存储方式,如 HDFStore( )
函数可将多个 dataframe 存储为一个 hdf5 文件,压缩比的表现较好,然而并发读写的效率会有所下降。
因子计算与代码实现
本小节主要分为三个部分:高频因子(十档买卖委托均价线性回归斜率、十档净委买增额)介绍、在DolphinDB 中因子实现和 Python 中因子实现。
高频因子
- 十档买卖委托均价线性回归斜率
十档买卖委托均价即为十档买卖委托额之和除以十档买卖委托量之和:
十档买卖委托均价线性回归斜率为十档买卖委托均价对时间 t 的线性回归的斜率。
- 十档净委买增额
十档净委买增额因子指的是在有效十档范围内买方资金总体增加量,即所有买价变化量的总和:
有效十档范围内表示不考虑已不在十档范围内的档位,即表示只考虑以下区间的档位:
DolphinDB 中因子实现
- 十档买卖委托均价线性回归斜率
十档买卖委托均价线性回归斜率的计算需要的参数分别为 OfferOrderQty、BidOrderQty、OfferPrice、BidPrice 四个字段,均为数组向量数据类型,分别为买卖十档价格和十档委托数量。使用 rowSum
这一内建聚合函数提高了因子的计算效率。通过 linearTimeTrend
函数获取因子值对时间 t 的滑动线性回归斜率,该函数返回线性回归的截距和斜率。price.ffill().linearTimeTrend(lag1-1).at(1).nullFill(0).mavg(lag2, 1).nullFill(0)
表示获取十档买卖委托均价对时间t的线性回归的斜率。
@state
def level10_InferPriceTrend(bid, ask, bidQty, askQty, lag1=60, lag2=20){
inferPrice = (rowSum(bid*bidQty)+rowSum(ask*askQty))(rowSum(bidQty)+rowSum(askQty))
price = iif(bid[0] = temp["pmin"])&(temp[f"bid{i+1}"] = temp["pmin"])&(temp[f"prevbid{i+1}"]