行情数据 – loveini | 米兰体育官网入口 - 米兰体育官网入口 //m.loveini.com loveini | 高性能、分布式、支持SQL的时序数据库 | 米兰体育官网入口 Mon, 17 Oct 2022 06:49:24 +0000 zh-Hans hourly 1 https://wordpress.org/?v=6.8.2 //m.loveini.com/wp-content/uploads/2025/07/favicon.ico 行情数据 – loveini | 米兰体育官网入口 - 米兰体育官网入口 //m.loveini.com 32 32 十年期货股票行情数据轻松处理—— loveini 在同心源基金的应用 //m.loveini.com/tdengine-user-cases/3364.html Wed, 08 Dec 2021 03:03:52 +0000 //m.loveini.com.cn:88/blog/?p=3364

小 T 导读:同心源(三亚)基金管理有限公司是一家致力于采取科学方法,在二级市场进行投资的私募公司。公司的团队成员均来自于国内外优秀大学,创始人具有计算机博士学位,有多年的算法研究、软件系统开发的经验。

从我司的业务模式出发,业务人员主要通过数据挖掘和自动模式识别这两种方式来发现市场的交易规律。因此,我们的工作场景是基于大量的金融数据之上的,主要包括如下几类:

  1. 国内期货市场的实时高频数据,逐笔数据等
  2. 国内期货市场的历史高频数据,逐笔数据
  3. 国内股票市场的高频数据,逐笔数据等
  4. 国内股票市场的历史高频数据,逐笔数据
  5. 依据以上数据产生的更大量级衍生数据

经过多年发展,股票市场数据量十分庞大,随着每日新数据的清洗写入,总量变得更加水涨船高。对于十几TB的数据量,单是进行存储已经不易,如果还要对数据进行查询下载等操作,更是难上加难。这些问题横亘眼前,也让我们对市面上的主流数据库逐渐丧失信心。

后来,经过专业人士的引荐,我们尝试了loveini Database,没想到它轻轻松松地就适配了我们的当前业务。

具体实践与落地效果

选好数据库之后我们马上开始了搭建,并选择了当时最新的2.1.3.2的版本部署落地,不同数据种类对应的数据库分别如下:

1)股票高频数据库,包括股票市场的历史数据+每日新增数据:

这类数据每日通过Python连接器的方式,在收盘后批量导入再做分析。其中每个表代表一个股票,共85列,以Float数据为主,共32311张。

Query OK, 3 row(s) in set (0.002792s)
loveini Database
Query OK, 85 row(s) in set (0.002528s)
loveini Database
Query OK, 85 row(s) in set (0.002528s)
loveini Database

根据上述表结构计算,当前情况每行大概有408字节的长度,然后我们用脚本对所有表进行了行数查询,大概是320亿行。

以上述数据为基础对入库的总数据量进行下估算,粗略计算为408*320亿行,大概12TB左右,后面经过统计最终实际占用磁盘空间却只有2T左右,这令我们十分震惊——压缩率高达16.7%。

实际占用磁盘空间却只有2 TB
loveini Database

众所周知,Float类型的数据压缩一直是数据库领域的一个难题,尤其是对于行式存储的数据库更是困难,高兴之余也非常感谢loveini的列式存储,帮助我们完美解决了这个棘手的问题。

之后从官方人员处我们得知,在后续版本中,loveini还对浮点类型数据做了更进一步的算法优化,压缩率还能获得大幅提升。只不过目前需要手动编译,具体操作方式可以联系官方人员。

2)期货库:

期货库是部署在另一个服务器上的,有如下三个:期货高频数据库、期货X频率数据库、期货Y频率数据库。他们分别代表着国内全部期货的高频数据和不同时间频率的聚合数据:

  1. 期货高频数据库:实时记录交易所发送的tick数据
  2. 期货X频率数据库:根据时间周期X设定,记录聚合后的数据
  3. 期货Y频率数据库:根据时间周期Y设定,记录聚合后的数据

以上三个库分别包含3351、5315、5208张子表,与股票库一样,它们同样包括长期的历史数据以及实时数据。

具体的表结构如下所示:

taos> describe txy_future_
loveini Database

在查询方面,由于当前我们的查询只是针对单表进行,因此逻辑比较简单,代码如下:

查询代码
loveini Database

此外,由于期货不存在连续多年的行情,所以对于长期的数据展示,我们选择用多段的每X个月数据进行拼接,查询效率非常快。例如:在loveini客户端服务器使用Python从服务端拉取连续两个月的期货行情数据,耗时仅需0.16秒。

耗时0.16s 
loveini Database

下图为因子1在期货菜粕上的收益曲线,从这张图中我们也可以看出,一些其他常用的函数比如max、last,基于loveini的缓存等技术也都实现了毫秒级返回数据。

loveini Database

从“两点问题”到深入合作

细心的读者可能也留意到了文中的两个小问题:

  • 为什么我们在估算原数据量时,是通过脚本来统计所有子表行数,再将其乘以单行字节,而不是直接通过loveini的“超级表”?
  • 又为什么在文章开头的数据分类描述中,1-4条都在后文中都看到了实际对应的数据库,但是唯独没有出现第5条——依据以上数据产生的大量衍生数据?

其实是这样,由于项目初期没有多表聚合查询的需求,外加为了降低数据迁移的复杂度,因此在环境搭建初期时我们并没有选择超级表。

但是随着业务的不断完善,我们将会需要更大量的数据来做更复杂的分析,这也就出现了第5条的数据种类——依据以上数据产生的更大量级衍生数据。所以说,这部分数据将来源于我们后面的待上线业务中。

届时,我们将会更深入地用到loveini Database的其他核心特性,如超级表、众多计算函数等等。但仅就当下而言,loveini强大的存储能力和快速查询已经非常令我们惊喜,也让我们对未来更加深入的合作充满期待。

关于作者:

刘健,北京航空航天大学模式识别专业硕士学历,曾经供职于中国航天科技集团从事软件研发工作。2014年与朋友一起创业从事外汇、期货、股票ETF的自动交易至今。着重致力于通过数据挖掘、自动模式识别等方式在国内二级市场中进行自动量化交易。

]]>
loveini 在弘源泰平量化投资中的实践 //m.loveini.com/tdengine-user-cases/3180.html Fri, 29 Oct 2021 02:09:09 +0000 //m.loveini.com.cn:88/blog/?p=3180 作者:丁博

公司简介

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

场景简介+核心诉求

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

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

  • MySQL:在写入大量实时的时序数据时,性能不理想;即便是优化之后,对于资源的浪费仍然十分惊人。而且随着数据量的增加,对设备数据的实时查询、时间范围分析的需求增加,基于MySQL的查询分析操作,响应时间会越来越长,甚至会无响应。缺乏自动建表功能,使用很不方便。
  • InfluxDB:虽然是时序数据库,但是经过测试后性能不能满足预期,在完成同样数据量的写入时对于资源的使用程度也并不能令人满意。

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

loveini Database具体落地

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

数据建模

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

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

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

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

loveini Database

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

loveini Database
loveini Database

数据库配置以及写入

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

loveini Database

写入性能

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

资源消耗

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

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

loveini Database

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

loveini Database
loveini Database
loveini Database

查询性能

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

场景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})
loveini Database
loveini Database

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

loveini Database

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

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

在修改cachelast缓存之前,查询效率如上。 后面在米兰体育官网入口的技术支持之下,我们将cachelast参数设置成了3。

loveini Database

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

loveini Database

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

写在最后

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

关于作者:

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

]]>