python tushare日线行情、每日指标、财务指标数据合并

前言:
距离上一篇文章好快又过了一个月了,这段时间大体深入学了点backtrader回测的内容,感觉有点难,在写tushare数据处理过程遇到了数据合并这一难题,首先tushare的收盘价开盘价获取得到的数据是以下这样的,

df_daily = ts.pro_bar(ts_code=stock_code, start_date='20150101', end_date='20210203', adj='qfq', freq='D')

在这里插入图片描述
然后股票每日指标数据行情是这样的

    df_stockind = pro.daily_basic(ts_code=stock_code, start_date='20150101', end_date='20210203', adj='qfq', freq='D',
                    fields='trade_date, pe, pb, turnover_rate, volume_ratio')

在这里插入图片描述
最后财务数据居然是这样的

df_fina = pro.fina_indicator(ts_code=stock_code, start_date='20150101')

在这里插入图片描述
简直要兔血。
之所以要合并,是因为我是打算回测股票的投资组合,其中包括了基本面的股票筛选,比如ROE大于多少之类的,处理起来有点烦,今天一点一点的print调试,目前得出了以下效果,写出来给大家参考下,如果有更好方法希望给个建议,以下都是自己一个人摸着石头过河的。
在这里插入图片描述
在这里插入图片描述
代码如下:

import tushare as ts
import pandas as pd
# pd.set_option()就是pycharm输出控制显示的设置
pd.set_option('expand_frame_repr', False)  # True就是可以换行显示。设置成False的时候不允许换行
pd.set_option('display.max_columns', None)  # 显示所有列
# pd.set_option('display.max_rows', None)  # 显示所有行
pd.set_option('colheader_justify', 'centre')  # 显示居中
ts.set_token('到tushare官网注册token,财务数据至少800积分才可以调取,目前我的积分是2000')
#  初始化pro接口
pro = ts.pro_api()
df_basic_all = pro.stock_basic(exchange='', list_status='L')  # 获取所有上市公司的信息为全部上市公司回测做准备
for stock_code in df_basic_all['ts_code']:
    print(stock_code)
    df_daily = ts.pro_bar(ts_code=stock_code, start_date='20150101', end_date='20210203', adj='qfq', freq='D')  # 获取每日数据
    df_daily = df_daily.drop(['pre_close', 'change', 'pct_chg', 'amount'], axis=1)
    df_stockind = pro.daily_basic(ts_code=stock_code, start_date='20150101', end_date='20210203', adj='qfq', freq='D',
                    fields='trade_date, pe, pb, turnover_rate, volume_ratio')  # 获取每日基本指标数据

    df_fina = pro.fina_indicator(ts_code=stock_code, start_date='20150101')  # 获取财务数据
    # 将ann_date列即公告日期(财务数据公布的那一天)更名,为后面数据合并提供依据,且减少数据处理
    df_fina = df_fina.rename(columns={'ann_date': 'trade_date'})
    df_fina = df_fina[['trade_date', 'roe']]
    # 先合并每日数据跟每日基本指标数据
    df_first = pd.merge(left=df_daily, right=df_stockind, on='trade_date', how='outer')
    '''因为tushare获取财务数据的格式时阶段性的,跟日k线数据进行合并需要特殊的处理,
    问题1:财务数据根据trade_date合并后只有公布的那一天有数据,比如20201210公布财务数据,然后20201211那一天是NaN空值
    问题2:合并时有时候财务数据公布时恰好股票是休息日,那么日k线数据是NaN空值。
    解决1:使用df.fillna(method='ffill', inplace=True)函数向后面的日期填充数据,直到下一财务数据公布
    解决2:填充完财务数据后删除收盘价或开盘价或最高价数据为NaN的那一行数据(即停牌或休息日),注意解决1跟解决2的顺序,不可颠倒'''

    df_all = pd.merge(left=df_first, right=df_fina, on='trade_date', how='outer')
    df_all.set_index('trade_date', inplace=True)  # 设置索引覆盖原来的数据
    df_all = df_all.sort_index(ascending=True)  # 将时间顺序升序,符合时间序列
    # 使用向前填充缺失的数据,就是说假如000001.sz今天20200202公布了财务数据,ROE为8.544,那么明天20200203至到下一财务数据公布日都是8.544
    df_all.roe.fillna(method='ffill', inplace=True)
    df_all = df_all[df_all['close'].notna()]  # 删除停牌数据

    print(df_all)

2021.2.4再次更新:
改进了如下细节问题
在这里插入图片描述
改完后:
在这里插入图片描述

import tushare as ts
import pandas as pd
import time
from datetime import datetime, timedelta
# pd.set_option()就是pycharm输出控制显示的设置
pd.set_option('expand_frame_repr', False)  # True就是可以换行显示。设置成False的时候不允许换行
pd.set_option('display.max_columns', None)  # 显示所有列
# pd.set_option('display.max_rows', None)  # 显示所有行
pd.set_option('colheader_justify', 'centre')  # 显示居中
ts.set_token('到tushare官网注册token,财务数据至少800积分才可以调取,目前我的积分是2000')
#  初始化pro接口
pro = ts.pro_api()
df_basic_all = pro.stock_basic(exchange='', list_status='L')  # 获取所有上市公司的信息为全部上市公司回测做准备
input_start_date = '20150101'
input_end_date = '20210203'
# 以下财务数据获取的是上一年的时间日期,之所以这样做是因为今年的1月1日在pro.fina_indicator函数里你是得不到1月1日这一天的财务数据的
input_lastyear_date = datetime.strptime(input_start_date, '%Y%m%d') - timedelta(days=365)  # str转time
input_fina_start_date = datetime.strftime(input_lastyear_date, '%Y%m%d')  # time转str
# print(datetime.strptime(input_start_date, '%Y%m%d') - timedelta(days=365))
for stock_code in df_basic_all['ts_code']:
    print(stock_code)
    # 获取每日数据
    df_daily = ts.pro_bar(ts_code=stock_code, start_date=input_start_date, end_date=input_end_date, adj='qfq', freq='D')
    df_daily = df_daily.drop(['pre_close', 'change', 'pct_chg', 'amount'], axis=1)
    # 获取每日基本指标数据
    df_stockind = pro.daily_basic(ts_code=stock_code, start_date=input_start_date, end_date=input_end_date, adj='qfq',
                                  freq='D', fields='trade_date, pe, pb, turnover_rate, volume_ratio')
    # 获取财务数据
    # 假设start_date='20150101',结果将只获得2015年的财务数据,结果将导致直到2015年第一季度数据发布时,前面的日期财务数据都是NaN
    df_fina = pro.fina_indicator(ts_code=stock_code, start_date=input_fina_start_date)
    # print(df_fina)
    # 将ann_date列即公告日期(财务数据公布的那一天)更名,为后面数据合并提供依据,且减少数据处理
    df_fina = df_fina.rename(columns={'ann_date': 'trade_date'})
    df_fina = df_fina[['trade_date', 'roe']]
    # 先合并每日数据跟每日基本指标数据
    df_first = pd.merge(left=df_daily, right=df_stockind, on='trade_date', how='outer')
    '''因为tushare获取财务数据的格式时阶段性的,跟日k线数据进行合并需要特殊的处理,
    问题1:财务数据根据trade_date合并后只有公布的那一天有数据,比如20201210公布财务数据,然后20201211那一天是NaN空值
    问题2:合并时有时候财务数据公布时恰好股票是休息日,那么日k线数据是NaN空值。
    解决1:使用df.fillna(method='ffill', inplace=True)函数向后面的日期填充数据,直到下一财务数据公布
    解决2:填充完财务数据后删除收盘价或开盘价或最高价数据为NaN的那一行数据(即停牌或休息日),注意解决1跟解决2的顺序,不可颠倒'''

    df_all = pd.merge(left=df_first, right=df_fina, on='trade_date', how='outer')
    df_all.set_index('trade_date', inplace=True)  # 设置索引覆盖原来的数据
    df_all = df_all.sort_index(ascending=True)  # 将时间顺序升序,符合时间序列
    # 使用向前填充缺失的数据,就是说假如000001.sz今天20200202公布了财务数据,ROE为8.544,那么明天20200203至到下一财务数据公布日都是8.544
    df_all.roe.fillna(method='ffill', inplace=True)
    df_all = df_all[df_all['close'].notna()]  # 删除停牌数据
	time.sleep(1.2)  # 加个休眠时间,财务数据积分不够每分钟好像只能获取80条数据,上个保险,不然等你运行半个小时后突然冒出来说你积分不够,瞬间要崩溃
    print(df_all)
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wilburzzz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值