我们参考论坛,生成用于导入tick的脚本,数据库是MongoDB。
目前遇到的问题是:
- 若使用offset-naive格式的tick时间导入,则脚本只能导入一天的数据。第二天的数据会因为在生成tickoverview时,出现“不能比较含时区和不含时区的datetime数据”的错误,而中止执行导入;
- 若使用offset-aware格式的tick时间导入,则所有的数据虽能完成导入,但导入数据库后的时间值有错误。并导致tickoverview错误。
我们之前发帖,得到的答复是vnpy在将datetime导入时,会做自动的时区转换。
因此,我们的理解就是,原始的datetime即便是不含时区的也无所谓,会自动处理。但是实际用save_tick_data()导入时,发现官方的脚本是在用导入后含有时区的datetime,和原始不含时区的datetime直接比较。因此必然报错;
但如果我们自行转换原始的datetime,添加时区信息。官方脚本在写入数据库后,这个值会被改写,小了8小时。因此,自觉上认为是官方的脚本可能有bug。
我们数据的第一条是:
2020-02-03 08:59:00.157000+08:00
写入mongodb后,对应的第一条变成了:
2020-02-03T00:59:00.157+00:00
我们的脚本代码:
import os # 导入标准库,后续要使用其listdir()
import csv # 导入csv库,后续要使用其DictReader()
from datetime import datetime, time # 用于处理datetime类型
import pytz
### vnpy中的模块导入
from vnpy.trader.constant import Exchange # 导入交易所的缩写
from vnpy.trader.database import get_database # 导入get_database()获取对象,使用对象的save_tick_data()
from vnpy.trader.object import TickData # 导入object模块中的TickData数据对象的定义
def run_load_csv():
"""
遍历同一文件夹内所有csv文件,并且载入到数据库中
"""
for file in os.listdir("."):
if not file.endswith(".csv"):
continue
print("载入文件:", file)
csv_load(file)
def csv_load(file):
"""
读取csv文件内容,并写入到数据库中
"""
with open(file,'r') as f:
reader = csv.reader(f)
ticks = [] # 用于存放所合成的tick数据
start = None
count = 0
# 遍历迭代器,其实items就是每一行的内容,是个list
for items in reader:
# 生成dt时间
date = items[3]
second = items[4]
millisecond = items[5]
standard_time = date + " " + second + "." + millisecond
dt = datetime.strptime(standard_time, "%Y%m%d %H:%M:%S.%f")
# 添加时区信息
db_tz = pytz.timezone("Asia/Shanghai")
dt = dt.astimezone(db_tz)
# 筛选无效时间段
if dt.time() < time(8,59,0) or dt.time() > time(15,0,0):
continue
elif dt.time() > time(10,15,0) and dt.time() < time(10,30,0):
continue
elif dt.time() > time(11,30,0) and dt.time() < time(13,30,0):
continue
# 生成单条tick
tick = TickData(
symbol = 'c2005',
datetime = dt,
exchange = Exchange.DCE,
last_price = float(items[6]),
last_volume = float(items[7]),
high_price = float(items[8]),
low_price = float(items[9]),
open_price = float(items[10]),
ask_price_1 = float(items[13]),
ask_volume_1 = float(items[14]),
bid_price_1 = float(items[15]),
bid_volume_1 = float(items[16]),
limit_up = float(items[17]),
limit_down = float(items[18]),
open_interest = float(items[19]),
turnover = float(items[20]),
pre_close = float(items[21]),
gateway_name = "DB",
)
ticks.append(tick)
count += 1
if not start:
start = dt
end = dt
data_manager = get_database()
data_manager.save_tick_data(ticks)
print("插入数据",start,"-",end,"总数量:",count)
if __name__ == "__main__":
run_load_csv()