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

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

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

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

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

01 基础查询

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

转债列表筛选及与正股数据整合:qlib+fastapi_第1张图片

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而言就太慢了。

转债列表筛选及与正股数据整合:qlib+fastapi_第2张图片

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+支股票。

转债列表筛选及与正股数据整合:qlib+fastapi_第3张图片

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

转债列表筛选及与正股数据整合:qlib+fastapi_第4张图片

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技术做量化投资;以投资视角观历史,解时事;专注个人成长与财富自由。

你可能感兴趣的:(建立自己的算法交易事业,fastapi,数据库,mongodb)