Point-In-Time数据库
章节大纲
-
时间点 (Point-in-Time) 数据库
简介
在进行任何形式的历史市场分析时,时间点数据是一个非常重要的考量因素。
例如,假设我们正在回测一个交易策略,并使用过去五年的历史数据作为输入。我们的模型假设每天收盘时交易一次,我们计算回测中 2020 年 1 月 1 日的交易信号。那时,我们应该只拥有 2020 年 1 月 1 日、2019 年 12 月 31 日、2019 年 12 月 30 日等的数据。
在金融数据(尤其是财务报告)中,同一份数据可能会随着时间的推移被多次修改。如果我们在历史回测中只使用最新版本的数据,就会发生数据泄露。时间点数据库旨在解决这个问题,以确保用户在任何历史时间戳都能获取正确版本的数据。它将保持在线交易和历史回测的性能一致。
数据准备
Qlib 提供了一个爬虫来帮助用户下载金融数据,然后是一个转换器将数据转储为 Qlib 格式。请按照
scripts/data_collector/pit/README.md
下载和转换数据。此外,您还可以在那里找到一些额外的用法示例。PIT 数据的基于文件的设计
Qlib 为 PIT 数据提供了一种基于文件的存储方式。
对于每个特征,它包含 4 列,即 date、period、value 和 _next。每一行对应一个声明。
文件名类似
XXX_a.data
的每个特征的含义:-
date:声明的发布日期。
-
period:声明所属的时期。(例如,在大多数市场中,这将是季度频率)
-
如果是年度,它将是一个对应年份的整数。
-
如果是季度,它将是一个类似
<year><index of quarter>
的整数。最后两位小数表示季度索引。其他位表示年份。
-
-
value:描述的值。
-
_next:下一个字段出现的字节索引。
除了特征数据,还包含一个索引文件
XXX_a.index
以加快查询性能。声明按 date 升序排列,从文件的开头开始。
# XXXX.data 的数据格式 array([(20070428, 200701, 0.090219 , 4294967295), (20070817, 200702, 0.13933 , 4294967295), (20071023, 200703, 0.24586301, 4294967295), (20080301, 200704, 0.3479 , 80), (20080313, 200704, 0.395989 , 4294967295), (20080422, 200801, 0.100724 , 4294967295), (20080828, 200802, 0.24996801, 4294967295), (20081027, 200803, 0.33412001, 4294967295), (20090325, 200804, 0.39011699, 4294967295), (20090421, 200901, 0.102675 , 4294967295), (20090807, 200902, 0.230712 , 4294967295), (20091024, 200903, 0.30072999, 4294967295), (20100402, 200904, 0.33546099, 4294967295), (20100426, 201001, 0.083825 , 4294967295), (20100812, 201002, 0.200545 , 4294967295), (20101029, 201003, 0.260986 , 4294967295), (20110321, 201004, 0.30739301, 4294967295), (20110423, 201101, 0.097411 , 4294967295), (20110831, 201102, 0.24825101, 4294967295), (20111018, 201103, 0.318919 , 4294967295), (20120323, 201104, 0.4039 , 420), (20120411, 201104, 0.403925 , 4294967295), (20120426, 201201, 0.112148 , 4294967295), (20120810, 201202, 0.26484701, 4294967295), (20121026, 201203, 0.370487 , 4294967295), (20130329, 201204, 0.45004699, 4294967295), (20130418, 201301, 0.099958 , 4294967295), (20130831, 201302, 0.21044201, 4294967295), (20131016, 201303, 0.30454299, 4294967295), (20140325, 201304, 0.394328 , 4294967295), (20140425, 201401, 0.083217 , 4294967295), (20140829, 201402, 0.16450299, 4294967295), (20141030, 201403, 0.23408499, 4294967295), (20150421, 201404, 0.319612 , 4294967295), (20150421, 201501, 0.078494 , 4294967295), (20150828, 201502, 0.137504 , 4294967295), (20151023, 201503, 0.201709 , 4294967295), (20160324, 201504, 0.26420501, 4294967295), (20160421, 201601, 0.073664 , 4294967295), (20160827, 201602, 0.136576 , 4294967295), (20161029, 201603, 0.188062 , 4294967295), (20170415, 201604, 0.244385 , 4294967295), (20170425, 201701, 0.080614 , 4294967295), (20170728, 201702, 0.15151 , 4294967295), (20171026, 201703, 0.25416601, 4294967295), (20180328, 201704, 0.32954201, 4294967295), (20180428, 201801, 0.088887 , 4294967295), (20180802, 201802, 0.170563 , 4294967295), (20181029, 201803, 0.25522 , 4294967295), (20190329, 201804, 0.34464401, 4294967295), (20190425, 201901, 0.094737 , 4294967295), (20190713, 201902, 0. , 1040), (20190718, 201902, 0.175322 , 4294967295), (20191016, 201903, 0.25581899, 4294967295)], dtype=[('date', '<u4'), ('period', '<u4'), ('value', '<f8'), ('_next', '<u4')]) # - 每行包含 20 字节 # XXXX.index 的数据格式。它由两部分组成 # 1) 数据的起始索引。所以信息的第一部分会像 2007 # 2) 剩余的索引数据会像下面的信息 # - 数据指示一个周期内第一次数据更新的**字节索引**。 # - 例如:因为字节 80 和 100 处的信息都对应 200704,所以记录了第一次出现的字节索引(即 100)。 array([ 0, 20, 40, 60, 100, 120, 140, 160, 180, 200, 220, 240, 260, 280, 300, 320, 340, 360, 380, 400, 440, 460, 480, 500, 520, 540, 560, 580, 600, 620, 640, 660, 680, 700, 720, 740, 760, 780, 800, 820, 840, 860, 880, 900, 920, 940, 960, 0, 1020, 1060, 4294967295], dtype=uint32)
已知限制:
-
目前,PIT 数据库是为季度或年度因子设计的,可以处理大多数市场中财务报告的基本数据。
-
Qlib 利用文件名来识别数据类型。名称类似
XXX_q.data
的文件对应于季度数据。名称类似XXX_a.data
的文件对应于年度数据。 -
PIT 的计算并非以最佳方式执行。PIT 数据计算的性能有很大的提升潜力。
-