Tick数据的清洗

发布时间 2023-09-06 11:22:59作者: C羽言

程序筛选

测试的品种如下

'''
# 以下日盘交易时间一样 9:00-10:15、10:30-11:30、13:30-15:00
郑商所 日夜盘 'FG401' 21:00-23:00
郑商所 无夜盘 'AP310'
大商所 日夜盘 'i2401' 21:00-23:00
大商所 无夜盘 'jd2310'
上期所 日夜盘 'rb2310' 21:00-23:00
上期所 日夜盘 'cu2309' 21:00-凌晨1:00
上期所 日夜盘 'au2310' 21:00-凌晨2:30
上期所 无夜盘 'wr2310'
广期所 无夜盘 'si2310'
能源中心 日夜盘 'sc2310' 21:00-凌晨2:30
能源中心 日夜盘 'bc2310' 21:00--凌晨1:00
能源中心 日夜盘 'lu2311' 21:00-23:00
能源中心 无夜盘 'ec2404'
# 中金所 均无夜盘
‘IF2309’ 9:30-11:30、13:00-15:00
‘TL2312’ 9:15-11:30、13:00-15:15

# 集合竞价时间
日盘品种(指无夜盘的品种)的集合竞价时间是8:55-8:59
夜盘品种的集合竞价时间是20:55-20:59,有夜盘的品种日盘不再进行集合竞价。

# 结算时间:
每个交易日的结算时间为下午16:30-19:30,
'''
subID = ['FG401', 'AP310', 'i2401', 'jd2310', 'rb2310', 'cu2309', 'au2310', 'wr2310', 'si2310', 'sc2310', 'bc2310', 'lu2311', 'ec2404', 'IF2309', 'TL2312']

将之前下载到csv的tick数据用程序提取出来,并根据规则来校验tick数据的有效性

import os, csv
from datetime import datetime

# 从目录下读取所有的测试合约
dpath = './ticktest'
fpaths = [os.path.join(dpath, x) for x in os.listdir(dpath)]
data_list = []
for fpath in fpaths:
    with open(fpath, encoding='utf-8') as f:
        reader = csv.reader(f)
        for row in reader:
            data_list.append(row)
print(f'totals:{len(data_list)}')

# 提取无效数据
invalid_list1 = []
invalid_list2 = []
invalid_list3 = []
for row in data_list:
    dt = datetime.strptime(row[8], '%Y-%m-%d %H:%M:%S')
    nowdt = datetime.strptime(row[9], '%Y-%m-%d %H:%M:%S')
    dtstamp = int(dt.timestamp())
    nowdtstamp = int(nowdt.timestamp())
    dthm = dt.strftime('%H%M')
    nowdthm = nowdt.strftime('%H%M')

    if nowdt.day in [2, 3]:  # 9月2号和3号是周六周日,测试有没有推送数据
        invalid_list1.append(row)
    if not ((nowdthm >= '0900' and nowdthm <= '1500') or nowdthm >= '2100' or (nowdthm >= '0000' and nowdthm <= '0230')):  # 实际时间不在交易时间段内
        invalid_list2.append(row)
        if (dthm >= '0900' and dthm <= '1500') or dthm >= '2100' or (dthm >= '0000' and dthm <= '0230'):  # tick时间却在交易时间段内
            invalid_list3.append(row)

with open('result_ticktest.csv', 'w', newline='') as f:
    csv.writer(f).writerows(invalid_list1)
with open('result_ticktest2.csv', 'w', newline='') as f:
    csv.writer(f).writerows(invalid_list2)
with open('result_ticktest3.csv', 'w', newline='') as f:
    csv.writer(f).writerows(invalid_list3)

数据观察

周六有数据,实际是周五的夜盘,最晚到凌晨2:30结束,周日没有数据,一切正常。

数据结构:交易日、tick更新时间、合约代码、交易所代码、最新价、成交量、持仓量、今收盘、实际日期和tick时间的合并、实际日期和时间。

AP310 属于郑商所

8:55是集合竞价时间,程序化一般用不上。

收盘前的数据,最后1笔的tick时间是14:59:59秒,实际系统时间超过15点。今收盘的无效值是0,出现有效值说明当天行情结束。

19:30结算时间结束,直到集合竞价前,基本上是无效数据。

本地时间准确的前提下,行情时间和本地时间相差很大,肯定是无效数据。一般超过3分钟即是无效数据。这里无效数据的推送时间并不固定,但基本是晚上19:30后和早上7:30后。

20230830,14:59:59,AP310,CZCE,8928.0,68773,97754.0,0.0,2023-08-30 14:59:59,2023-08-30 14:59:59
20230830,14:59:59,AP310,CZCE,8928.0,68773,97754.0,8928.0,2023-08-30 14:59:59,2023-08-30 15:00:04
20230830,19:08:41,AP310,CZCE,8928.0,0,97754.0,0.0,2023-08-30 19:08:41,2023-08-30 19:30:18
20230831,19:08:41,AP310,CZCE,8928.0,0,97754.0,0.0,2023-08-31 19:08:41,2023-08-31 07:40:31
20230831,08:55:00,AP310,CZCE,8928.0,0,97754.0,0.0,2023-08-31 08:55:00,2023-08-31 08:55:00
20230831,19:08:46,AP310,CZCE,8781.0,0,81372.0,0.0,2023-08-31 19:08:46,2023-08-31 19:57:11
20230901,19:08:46,AP310,CZCE,8781.0,0,81372.0,0.0,2023-09-01 19:08:46,2023-09-01 07:44:12

au2310属于上期所

8:59日盘集合竞价时间,20:59夜盘集合竞价时间,

收盘前的数据,无效值用 double的上限值表示即1.7976931348623157e+308,最后1笔15:00出现今收盘有效值,当天结束。

15:16推送的数据持仓量有变化,应该不算无效数据,不过程序化一般用不上。有时候16点后还会推送1笔,数据跟15点后推送的完全一样,

晚上19:30后和早上7:30后,集合竞价前,推送的数据有个特征,行情时间和本地时间相差很大,属于无效数据。

小数位特别长的数据,一般保留2位小数截断即可(不要四舍五入)可以节省存储空间。个别品种的小数要保留3位,比如国债期货。至于4位的暂时没见过,所以可以统一保留3位小数截断。

double的上限值可以替换成0.0,跟郑交所一样,可以节省存储空间。

7:40推送了夜盘最后1笔,本地时间和tick时间相差大的肯定是无效数据。

20230830,14:59:59,au2310,SHFE,461.48,143858,88395.0,1.7976931348623157e+308,2023-08-30 14:59:59,2023-08-30 15:00:00
20230830,15:00:00,au2310,SHFE,461.48,143858,88395.0,461.48,2023-08-30 15:00:00,2023-08-30 15:00:02
20230830,15:16:18,au2310,SHFE,461.48,143858,88397.0,461.48,2023-08-30 15:16:18,2023-08-30 15:16:19
20230831,18:34:43,au2310,SHFE,461.48,0,88397.0,1.7976931348623157e+308,2023-08-30 18:34:43,2023-08-30 19:30:18
20230831,20:59:00,au2310,SHFE,462.6,132,88398.0,1.7976931348623157e+308,2023-08-30 20:59:00,2023-08-30 20:59:01
20230831,02:30:00,au2310,SHFE,462.30000000000007,49265,85314.0,1.7976931348623157e+308,2023-08-31 02:30:00,2023-08-31 07:40:31
20230831,08:59:00,au2310,SHFE,462.26,49278,85315.0,1.7976931348623157e+308,2023-08-31 08:59:00,2023-08-31 08:59:01

20230901,14:59:58,au2310,SHFE,462.46000000000004,88305,69172.0,1.7976931348623157e+308,2023-09-01 14:59:58,2023-09-01 14:59:59
20230901,14:59:59,au2310,SHFE,462.46000000000004,88305,69172.0,1.7976931348623157e+308,2023-09-01 14:59:59,2023-09-01 15:00:00
20230901,15:00:00,au2310,SHFE,462.46000000000004,88305,69172.0,462.46000000000004,2023-09-01 15:00:00,2023-09-01 15:00:01
20230901,15:19:25,au2310,SHFE,462.46000000000004,88338,69182.0,462.46000000000004,2023-09-01 15:19:25,2023-09-01 15:19:26
20230901,16:01:26,au2310,SHFE,462.46000000000004,88338,69182.0,462.46000000000004,2023-09-01 16:01:26,2023-09-01 16:01:27
20230904,19:15:06,au2310,SHFE,462.46,0,69182.0,1.7976931348623157e+308,2023-09-01 19:15:06,2023-09-01 19:33:16