写点什么

TDengine 在弘源泰平量化投资中的实践

作者:TDengine
  • 2022 年 5 月 18 日
  • 本文字数:1977 字

    阅读完需:约 6 分钟

公司简介

深圳市弘源泰平资产管理有限公司组建于 2016 年,团队核心成员来自于知名高校,有丰富的资产配置与策略构建的实践经验。弘源泰平以套戥交易绝对收益型配置工具为起点,致力于为用户提供流动性好、费率公允的资产配置工具。产品线全面、丰富,涵盖股、债、商品等各大类资产,通胀、趋势等各类因子。

场景简介+核心诉求

我们的量化交易系统每天要接收大量的行情数据,也要基于行情产生大量的决策信号。这些数据都需要及时存下来,供盘中和盘后使用。

传统存放行情数据的方式有文件系统、关系型数据库或者文档数据库。我们尝试了 MySQL 和知名的时序数据库 InfluxDB,但是性能都没有达到预期。分别遇到了如下问题:

  • MySQL:在写入大量实时的时序数据时,性能不理想;即便是优化之后,对于资源的浪费仍然十分惊人。而且随着数据量的增加,对设备数据的实时查询、时间范围分析的需求增加,基于 MySQL 的查询分析操作,响应时间会越来越长,甚至会无响应。缺乏自动建表功能,使用很不方便。

  • InfluxDB:虽然是时序数据库,但是经过测试后性能不能满足预期,在完成同样数据量的写入时对于资源的使用程度也并不能令人满意。

最后,我们改用 TDengine 彻底解决了实时写入大量数据点和快速查询的问题。

TDengine 具体落地

对于策略研究员而言,历史行情和信号是交易策略研究的重要素材。下面以行情数据和策略信号数据为案例予以介绍。


数据建模

首先,将行情数据和信号数据分别存储。在 TDengine 中分别创建了一个行情数据库和信号数据库。

虽然是时序数据库,但是 TDengine 使用了关系型数据库的模型,建库,建表,使用 SQL,十分便于传统关系型数据库的用户入手。并且,他们还很有创意地设计了超级表的概念,与我们的场景十分契合。

因为所有行情数据结构相同,行情库中只需要一个超级表,下面每个工具(衍生品基金等)对应一个子表。比如 CU2101 表示 2021 年 1 月份到期的铜期货交易合约。在合约到期之前,都会有行情数据写入。下面重点介绍策略信号数据库。

信号库有两张超级表,分别对应合约级别信号和策略级别信号,每个交易信号对应一张子表,当前共有 40,000 多张表,表结构分别如下所示:

下面是信号库执行 show tables 的截图:



数据库配置以及写入

我们选用的 TDengine 版本是 2.2.0.0,由于单机版尚无压力,目前还不需要集群。此外,机器有 40 核,而 TDengine 的每一个 vnode 又是拥有独立运行线程的工作单元。所以,根据文章《这几个神秘参数,教你TDengine集群的正确使用方式》,我调整了 minTablesPerVnode、tableIncStepPerVnode 和 maxVgroupsPerDb 参数,让 vnode 的数量恰好等于 CPU 核数,让每个核独立运行一个线程,实现了数据的合理化分布,以争取达到最佳性能。


写入性能

当前,我们大概每秒写入 3 万行数据。单节点 TDengine 可以十分轻松地实现这个级别数据量的写入。同时,消耗服务器资源又比 InfluxDB 与 MySQL 小的多。因此,即便未来业务扩大,我们也不需要担心额外的硬件成本。


资源消耗

我们当前的服务器配置如下:64G 内存+40 核 1.8GHz CPU+机械硬盘。

在业务运行期间,taosd 的 %CPU 只有 4%上下浮动,进程使用的物理内存百分比为 11.2%。虽然内存占用稍多,但这是由于我们的 vnode 配置的比较多,每个 vnode 都有自己固定的内存缓冲区。因此,后续即便是继续大量增加新表或者加大写入量,内存占用也不会有明显的浮动了。

截至目前,通过 TDengine 录入的两个信号表已经写入了 82 亿条数据,原数据大概为 92GB,实际占用存储空间为 20G 左右,压缩率高达 23%,如果是整型数据应该还会更高。




查询性能

除了写入与存储,使用 TDengine 做日常查询的速度也十分优秀,即便是对于几十亿级别的大表,也是毫秒级响应。我们来看两个场景。

场景 1:查询特定策略信号下一段时间的均值。

select avg(v) from stgbox.strategy_signal where stg_name = '{stg_id}' and signal_name ='{signal_name}' and ts >= '{from_date} 00:00:00' and ts <= '{to_date} 23:59:59.999' interval({interval})


以下是我们用场景 1 查询出的数据进行可视化分析的示例。

场景 2:查询满足模糊查询条件的信号的最新值。

select name,last(v) from stgbox.global_signal where name like '%keyword%' group by name。


在修改 cachelast 缓存之前,查询效率如上。

后面在涛思数据的技术支持之下,我们将 cachelast 参数设置成了 3。

再执行了同样的查询,查询效率得到了很大提升:

这两个都是我们比较典型的查询场景,TDengine 完美地匹配了我们对功能以及性能上的需求。


写在最后

我们目前对 TDengine 的使用还处于初级阶段,TDengine 不仅仅是时序数据库,还可以作为消息队列,支持数据订阅。以后我们会探索将 TDengine 用于更多的业务场景,以更好地服务于我们的各类分析与交易执行。


关于作者:

丁博,弘源泰平量化工程师。目前负责公司交易执行系统、交易策略信号系统和交易组合管理系统的研发。



想了解更多 TDengine Database 的具体细节,欢迎大家在GitHub上查看相关源代码。

发布于: 刚刚阅读数: 3
用户头像

TDengine

关注

高性能、分布式、支持SQL的时序数据库 2021.11.04 加入

官网:http://www.taosdata.com GitHub:https://github.com/taosdata/TDengine

评论

发布
暂无评论
TDengine在弘源泰平量化投资中的实践_数据库_TDengine_InfoQ写作社区