从交易所获取的中国期货数据,往往存在数据不干净、冗余重复、字段错误、非交易时间推送等诸多问题。从 Tick Data 计算汇总得到 Bar Datadaily + minute),前提是要保证我们得到的数据是真实、准确、可靠的。因此,在数据入库前的数据清理步骤至关重要。这就好比是医生在进入手术室前需要(必要)先进行全面的消毒清理,才能拿起刀子。

目前可用的数据主要包括两部分:

  • 历史数据:这部分数据主要由 FromDC 提供,起止时间为 2010。04.16 ~ 2019.11.01。其中,2010 年份的数据格式比较特别。
  • 实时数据:目前,我们在上期所提供的 CTP 交易接口的基础上,开发了一套用于接收交易实时数据的程序,内嵌到交易系统,能够保证实时获取交易的分笔数据。

以下是我在管理公司的期货数据库时,总结出来的部分数据清理经验。之所以用白纸(website)黑字(blog),一方面方便日后回顾,另一方面也希望对后来者有一定的启示。


数据错误

错误来源

从数据来源上看,造成数据错误的原因,无非有两个

  • 交易所推送数据错误:有可能是交易所服务器不稳定、网络传输中断、数据感染等
  • 本地接收数据错误:数据编码不一致、数据写入文件不正确、字段不匹配等

非交易时段

所谓的非交易时段,既包括非交易日期,也包括非交易时间。即从交易所推送的数据非当时交易日期数据,有可能是服务器推送测试数据,或者网络中断造成数据拥堵。

  • 在本地接收数据的程序里面,添加一个字段为 TimeStamp,即对每一笔接收得到的数据,标记时间戳。后期的处理数据时,如果这个时间戳与交易所推送的数据日期有差异,则进行排除。从交易端的可靠性来看,这个时间差不应该超过 1分钟,否则数据失效。
  • 对于 UpdaTime,需要限定在交易时间内,即日盘交易时间段、夜盘交易时间段。如果不在这两个交易时间段的数据,需要排除。

交易所测试数据

为了测试系统、修复程序错误等,交易所往往会推送部分测试数据。千万要谨记,这些数据仅做测试使用,并非真实的交易数据。因此,这部分测试数据需要从我们的数据库删除掉。

  • 数据为负:这包括价格数据和数量数据,如LastPriceOpenPriceHighestPriceLowestPriceClosePriceVolumeTurnoverBidPriceBidVolumeAskPriceAskVolumeOpenInterest。这个很容易理解,因为这些变量的范围本身应该是 \( [0, N )\),其中 \(N \in \mathbf{R}^{+} \) 。因此,任何这类变量为负数的数据行,都需要删除掉。
  • 数据标签为 e+301 等异常大的数据,真实的 \(N < \mathbf{\bar{N}} \) 。
  • 排除价格或数量变量小于 0 的数据
  • 排除数据异常大的、明显是交易所用于测试目的、而非真实交易产生的数据

数据冗余

所谓的冗余数据,也叫做重复数据,指的是交易所重复推送多次的数据,这样的数据本质上不会有新的信息更新,属于多余的数据噪音。

重复的数据

对于相同字段的数据,交易所推送多次,或者本地程序写入多次

信息无更新(熵减)

从理论上讲,交易所推送的数据按照 500 MilliSec,即 .5 second 的频率来更新推送。对于这部分数据,如果没有多余的信息量更新,比如除了时间,其他所有的字段字段都没有改动,这实质上也是算冗余的数据,也是需要考虑排除的。

  • 使用函数检测相同行的数据并进行排除
  • 只保留符合熵减原则的数据

数据不合逻辑

对于每一条由真实交易产生的数据,都应该符合一定的逻辑结构。而对于那些不符合金融逻辑的数据,可能是存在问题的,需要排除。

  • 每条价格和数量的数据都有有意义的:比如 BidPriceAskPrice必须在一定的变动范围内,即,\(x \in [LowerLimitPrice,UpperLimitPrice]\);而且不同的叫价相对顺序是对的
  • 涨停板时,有以下条件成立:
    • \(LastPrice = BidPrice = UpperLimitPrice\)
    • \(BidVolume > 0\) 且 \(AskVolume = 0\)
  • 跌停板时,有以下条件成立:
    • \(LastPrice = AskPrice = LowerLimitPrice\)
    • \(BidVolume = 0\) 且 \(AskVolume > 0\)
  • 非涨跌停板时,要求 \(BidVolume \neq 0\) 且 \(AskVolume \neq 0\)
  • 交易所推送的 VolumeTurnover 两个字段的数据,实际上是计算累计加总的数值,即每发生一笔交易,就累计增加数值。因此
    • Volume 符合严格单调递增
    • Turnover 符合严格单调递增