rqalpha源码--数据源和数据代理

基础数据源

如果在配置项中没有配置数据源 就将事件源设置为默认的数据源。 配置的默认数据源的位置是data/bundle/

    if not env.data_source:
        # print(f"配置的默认的数据源是:{config.base.data_bundle_path}") 
        env.set_data_source(BaseDataSource(config.base.data_bundle_path))

基础数据源的更新

在每次运行之后,会尝试更新数据源:

     try:
        update_bundle()
    except Exception as e:
        print(f"fail, reasion: {e}")

源码位置: main.py

def update_bundle(data_bundle_path=None, locale="zh_Hans_CN", confirm=True):
    # 设置语言环境
    set_locale(locale)
    # 指定默认的数据下载路径 若没有显式指定路径 即使用该路径
    default_bundle_path = os.path.abspath(os.path.expanduser("~/.rqalpha/bundle/"))
    if data_bundle_path is None:
        data_bundle_path = default_bundle_path
    else:
        # 在执行文件夹下面创建 bundle 文件夹用以存放数据
        data_bundle_path = os.path.abspath(os.path.join(data_bundle_path, './bundle/'))
    # 如果指定的文件夹中已存在 不是默认文件夹 且不为空
    # 向用户确认是否进行删除
    if (confirm and os.path.exists(data_bundle_path) and data_bundle_path != default_bundle_path and
            os.listdir(data_bundle_path)):
        # click.confirm 的作用是展示一个  [y/N]: y 的选项 用户选 y 返回 True
        click.confirm(_(u"""
[WARNING]
Target bundle path {data_bundle_path} is not empty.
The content of this folder will be REMOVED before updating.
Are you sure to continue?""").format(data_bundle_path=data_bundle_path), abort=True)  # 否定的答案将终止程序

    day = datetime.date.today()
    # 创建临时文件
    tmp = os.path.join(tempfile.gettempdir(), 'rq.bundle')

    while True:
        url = 'http://7xjci3.com1.z0.glb.clouddn.com/bundles_v3/rqbundle_%04d%02d%02d.tar.bz2' % (
            day.year, day.month, day.day)
        six.print_(_(u"try {} ...").format(url))
        r = requests.get(url, stream=True)
        if r.status_code != 200:
            # 下载当天的最新数据 如果没有的话 就把时间向前推进一天
            day = day - datetime.timedelta(days=1)
            continue

        out = open(tmp, 'wb')
        total_length = int(r.headers.get('content-length'))

        # 在终端显示进度条
        with click.progressbar(length=total_length, label=_(u"downloading ...")) as bar:
            for data in r.iter_content(chunk_size=8192):
                bar.update(len(data))
                out.write(data)

        out.close()
        break
    # 先下载到临时文件夹里面 然后将用户指定的文件夹清空 将临时文件压缩放入
    shutil.rmtree(data_bundle_path, ignore_errors=True)
    os.makedirs(data_bundle_path)
    tar = tarfile.open(tmp, 'r:bz2')
    tar.extractall(data_bundle_path)
    tar.close()
    os.remove(tmp)
    six.print_(_(u"Data bundle download successfully in {bundle_path}").format(bundle_path=data_bundle_path))

数据源接口

数据源类会实现 AbstractDataSource 中定义的接口,可以通过调用 env.set_data_source 来替换默认的数据源。通过 :class:DataProxy 进一步进行了封装,向上层提供更易用的接口。
比如说:
get_all_instruments: 获取全部的合约代码
get_trading_calendar: 获取交易日历
get_yield_curve: 获取国债利率
get_dividend:获取股票和期货的分红信息等 …
源码位置: interface.py [AbstractDataSource]

在这里插入图片描述

这里实现的就是去读取我们更新拉下来的数据,然后将数据处理封装成接口,提供给策略使用。这里的读取和封装方式此处暂不分析。数据源我们可以换成任何来源,数据文件或者数据库。
可以通过该数据封装类直接调用获取数据:

from data.base_data_source import BaseDataSource

bb = BaseDataSource("/Users/furuiyang/codes/trade/data/bundle")

# 获取某只股票基金的分红信息
res1 = bb.get_dividend("000949.XSHE")
print(res1, type(res1))

数据代理

通过 env.set_data_proxy(DataProxy(env.data_source)) 为env 设置数据代理。

数据代理是对数据源的一层封装,同时通过继承 InstrumentMixin, TradingDatesMixin 实现对股票和交易时间的一些数据的获取。

源码: data/data_proxy.py
data/trading_dates_mixin.py
data/instrument_mixin.py

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值