VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 20
声望: 0

我们参考论坛,生成用于导入tick的脚本,数据库是MongoDB。

目前遇到的问题是:

  • 若使用offset-naive格式的tick时间导入,则脚本只能导入一天的数据。第二天的数据会因为在生成tickoverview时,出现“不能比较含时区和不含时区的datetime数据”的错误,而中止执行导入;

description

  • 若使用offset-aware格式的tick时间导入,则所有的数据虽能完成导入,但导入数据库后的时间值有错误。并导致tickoverview错误。

description

我们之前发帖,得到的答复是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()
Member
avatar
加入于:
帖子: 1475
声望: 105

建议去github仓库开个issue让官方查下吧,现在mongodb数据库的用户不多

Member
avatar
加入于:
帖子: 4719
声望: 287

1.现在官方版本通过csv导入、datafeed下载等方式保存数据都是加了时区的,所以自行导入数据也是需要加上时区信息的;
2.mongodb与其他数据库不同,虽然可以保存带时区的数据,存储的时候都转换成UTC时区了,但是读出来的时候还是你存进去的时区。查询的时候如果index里有datetime,参考vnpy_mongodb里load_bar_data/load_tick_data里的逻辑加上时区信息去查即可。overview也没有存错,保存的时候带有时区,读取的时候也带有同样时区的。自己在vnpy_mongodb里对应的创建overview和读取overview的地方打印看看就知道了。用mongodb自带图形界面看的话显示的是以UTC时区存储的时间,但是实际使用也是要读出来用的。

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】