量化投资vnpy —— 更改数据库存储,使数据存储到指定集合/数据表

在使用VNPY时,只有两张表,一个是bar数据,一个是tick,实际使用中,这个数据库文件可能相当大,检索很费时。并看到有人也遇到了同样的困惑,建议vnpy-2.0.9 用关系型数据库

于是,我尝试基于vnpy 2.0.8,修改数据为 MongoDB,并将数据保存至指定的 Collection,同时保证当未指定 Collection 时,数据仍保存在原有的数据表中。适用于 tick数据 和 bar 数据。分享出来,如有错误,希望指正。

更改数据库为 MongoDB

注意在MongoDB中需要创建新数据库,如“vnpytest”,然后在全局配置对话框中,修改相关配置(或直接修改vnpy运行目录 .vntrader 下的 vt_setting.json 文件):

"database.driver": "mongodb",
"database.database": "vnpytest",
"database.host": "localhost",
"database.port": 27017,
"database.user": "",
"database.password": "",
"database.authentication_source": ""

注意输入上述内容到配置对话框中时,请忽略引号。修改完毕保存后,请重新启动VN Trader,检查相关配置是否已经修改成功。

保存数据至指定的 mongodb collection

数据来源可以是 csv 文件,也可以从开源数据如 tushare (https://tushare.pro/register?reg=347489) 获取,等等,这里不再给出。

  1. 新建py文件,写入主函数
from vnpy.trader.database import database_manager
from vnpy.trader.object import BarData
from vnpy.trader.constant import Interval, Exchange


def ts2bar(df, collection_name=None):
    bars = []
    for i in range(df.shape[0]):
        bar = BarData(
            symbol=df.ts_code[i].split('.')[0],
            exchange=exc,
            datetime=df.trade_date[i],
            interval=Interval.DAILY,
            volume=df.vol[i],
            open_price=df.open[i],
            high_price=df.high[i],
            low_price=df.low[i],
            close_price=df.close[i],
            gateway_name='DB',
        )
        bars.append(bar)
    collection_name = collection_name
    print('Saving data to database ...')
    database_manager.save_bar_data(bars, collection_name)
  1. 修改 vnpy/trader/database/database.py 中的 save_bar_datasave_tick_data
@abstractmethod
def save_bar_data(
    self,
    datas: Sequence["BarData"],
    collection_name: str = None,
):
    pass

@abstractmethod
def save_tick_data(
    self,
    datas: Sequence["TickData"],
    collection_name: str = None,
):
    pass 
  1. 修改 vnpy/trader/database/database_mongo.py 中的 save_bar_datasave_tick_data
    def save_bar_data(self, datas: Sequence[BarData], collection_name: str = None):
        for d in datas:
            ...

            if collection_name is None:
                (
                    DbBarData.objects(
                        symbol=d.symbol, interval=d.interval.value, datetime=d.datetime
                    ).update_one(upsert=True, **updates)
                )
            else:
                with switch_collection(DbBarData, collection_name):
                    (
                        DbBarData.objects(
                            symbol=d.symbol, interval=d.interval.value, datetime=d.datetime
                        ).update_one(upsert=True, **updates)
                    )

    def save_tick_data(self, datas: Sequence[TickData], collection_name: str = None):
        for d in datas:
            ...
            
            if collection_name is None:
                (
                    DbTickData.objects(
                        symbol=d.symbol, exchange=d.exchange.value, datetime=d.datetime
                    ).update_one(upsert=True, **updates)
                )
            else:
                with switch_collection(DbTickData, collection_name):
                    (
                        DbTickData.objects(
                            symbol=d.symbol, exchange=d.exchange.value, datetime=d.datetime
                        ).update_one(upsert=True, **updates)
                    )

对于 MySQL 数据库,修改方法应该是类似的。

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值