• 转债列表筛选及与正股数据整合:qlib+fastapi


    百天计划之37篇,关于“AI智能量化投研平台”搭建。

    昨天我们把前端页面搭建完毕,可以展示简单的列表以及交易日频序列,这是最基础的第一步。

    今天重点要实现列表的筛选。

    筛选功能有基于基础信息的,比如市值,距离到日期还有多远,另外还有基于时间序列的,比如价格小于130,或者转股溢价率等等。

    01 基础查询

    到期日大于今天,且摘牌日期为空的,即为当前可以交易的,发行中的可转债列表,一共458支。

    02 正股价与转股价

    基础信息查询比较简单,而涉及的到日频数据的查询则相对复杂,比如我们需要最新的转股价,正股价,还是转债本身的价格。

    若是基于mongo本身去查询,性能比较高,若涉及复杂计算,比如MACD>0这样的技术指标更慢。如果使用传统数据库,则需要做数据预计算,然后更新到basic表里去备查。但是这样做,就非常不灵活,一般我们的查询是“临时起意”。

    这时,qlib的数据库就很好地派上用场了。

    qlib的初始化函数:

    def init_qlib(data_dir):
        provider_uri = data_dir
        qlib.init(provider_uri=provider_uri, region=REG_CN)

    在web框架里调用,需要使用 app.on_event fastapi的装饰器,只会在启动时运行一次:

    @app.on_event('startup')
    def init_app():
        init_qlib(DATA_DIR_QLIB_BOND)
    

    而后使用Qlib的数据查询,

    def query_df(start_date, end_date):
        expressionDFilter = ExpressionDFilter(rule_expression='$close>130')
        instruments = D.instruments(market='all')
    
        df = D.features(instruments, ['$close', '$close<130','Ref($close,20)'], start_time=start_date, end_time=end_date, freq='day')
        print(df)
        return df
    

    qlib最擅长的是时间序列计算,有预加载,缓存等功能,此外,它外针对财务数据,设计PIT格式(季度频次)。

    不过无法跨库查询,需要使用的数据,均需要入qlib_data库。

    不过就算使用mongodb这样的数据,若我们要使用全市场数据来回测“双低”策略,同样面临处理这样的数据。

    读出所有的数据,然后对应的code去读其正股价时间序列,而后concat在一起,然后再分别计算各种指标。若是指定几支转债是没有问题的,但需要考虑全市场选债,这个对于mongo而言就太慢了。

    03 构建正股信息

    basic:

    def build_stock_basic():
        df = get_stock_basic()
        df['_id'] = df['ts_code']
        write_df('stock_basic', df, drop_tb_if_exist=True)

    A股一共4900+支股票。

    daily:

    这里与转债的时间序列数据类似:

    def update_all_stock_daily():
        # 获取所有列表,有日期,从最近的日期开始读。
        items = list(get_db()['stock_basic'].find({}, {'ts_code': 1, '_id': 0}))
        if items and len(items) == 0:
            logger.error("读股票列表为空")
            return
        for i, item in enumerate(items):
            code = item['ts_code']
            logger.debug("{}-{}-{}".format(i, code, i / len(items)))
            date = get_daily_last_date(code, tb_name='stock_daily', code_field='code', date_field='date')
            logger.debug(date)
            df = get_symbol_data_with_factor(code, date)
            df['_id'] = df['code'] + '_' + df['date']
            print(df.tail())
            write_df('stock_daily', df)
            break

    04 难点:正股价如何整合到qlib_data中

    def get_stock_df_from_mongo(code, start_date=None):
        query_stock = {'code': '601818.SH'}
        if start_date:
            query_stock['date'] = {'$gte': start_date}
        df_stock = get_db()['stock_daily'].find(query_stock, {'o_close': 1, 'date': 1, '_id': 0})
    
        df_stock = pd.DataFrame(list(df_stock))
        df_stock.index = df_stock['date']
        del df_stock['date']
        df_stock.rename(columns={'o_close': 'stk_close'}, inplace=True)
        return df_stock

    把正股价读进来,与转债的数据融合后入qlib。

    由于转债数量不多,可以每天全量建索引也问题不大。增量的话,记录本次update的日期

    小结:

    1、今天完成了转债数据的基础查询,更重要的是,多维度数据整合到qlib数据。

    2、坚持并不容易,越早先的工作越是“低垂”之果,越往后越有难度,进入“爬坡”期。

    可转债列表页与日频交易数据呈现:fastapi+antV G2

    fastapi定时任务,增量构建可转债交易数据入mongo和qlib

    fastapi+mongo+qlib:体系化构建AI量化投研平台

    飞狐,科技公司CTO,用AI技术做量化投资;以投资视角观历史,解时事;专注个人成长与财富自由。

  • 相关阅读:
    Python实现AES算法和国密SM4算法
    与开发斗智斗勇的日子
    借助 ChatGPT 编写的 libbpf eBPF 工具开发实践教程: 通过例子学习 eBPF
    angular学习-组件通讯
    百度SEO优化TDK介绍(分析下降原因并总结百度优化SEO策略)
    [兔子私房课]MybatisPlus开发详解与项目实战01
    韶音骨传导耳机好不好用,韶音的骨传导耳机怎么样
    拿到直播平台的rtmp地址和推流码之后,用 nodejs写一个循环读取视频文件内容,这个地址推流
    Jetpack系列 -- LiveData源码原理解析(解决黏性问题)
    计算Qt中的QAudioOutput缓冲区未播放的音频字节数对应时长
  • 原文地址:https://blog.csdn.net/weixin_38175458/article/details/126726351