Baostock学习系列2:批量下载股市日交易明细

背景

准备进行股票的量化分析,苦于没有日交易数据,找了好多方法,最终才想到用baostock下载数据。
原因主要有如下三点:

  • 1 通过平安银行或者通达信软件导出的txt需要解析处理起来非常麻烦(主要还是本人下载的明细还会出现要重复行数据);
  • 2 Tushare现在搞的是社区,需要花积分贡献积分,本人没钱,想先”白嫖“一段时间锻炼一下自己,再考虑加入;
  • 3 Baostock 的包简单实用,更为关键的是体系已经搭建完了,直接用就行。

批量下载股市交易明细

流程拆解

思路:不断增加天数,调用baostock接口按天下载股市交易明细

代码实现

日期循环

config_start_day = '2018-09-27'   # 'YYYY-MM-DD'
config_end_day = '2022-04-04'     # 'YYYY-MM-DD'

start_day = datetime.datetime.strptime(config_start_day, "%Y-%m-%d")
end_day = datetime.datetime.strptime(config_end_day, "%Y-%m-%d")

# print(check_is_trading_day(start_day.strftime('%Y-%m-%d')))


while (int( time.mktime(start_day.timetuple())) <= int( time.mktime(end_day.timetuple()))) :
	start_day = time_offset_cal(start_day, 1, 'day')  # 这里利用自定义函数实现日期加1天
	print(datetime.datetime.strftime(start_day , "%Y-%m-%d"))

time_offset_cal()自定义函数

输入参有两个:

  1. input_time:输入数据类型为: datetime.datetime
  2. offset: 输入为时间偏移量可正、可负,正为在原时间上加,负为在原时间上减
  3. time_type: 输入类型为时间偏移量的单位(year、week、 month、 day、 hour、minute、 second、microsecond、 millisecond)
def time_offset_cal(input_time, offset, time_type): # input_time 类型为: datetime.datetime  offset 为 int 整数
    if time_type == 'year':
        re_dt = input_time + relativedelta(years=offset)
        return re_dt
    elif time_type == 'week':
        re_dt = input_time + datetime.timedelta(weeks=offset)
        return re_dt
    elif time_type == 'month':
        re_dt = input_time + relativedelta(months=offset)
        return re_dt
    elif time_type == 'day':
        re_dt = input_time + datetime.timedelta(days=offset)
        return re_dt
    elif time_type == 'hour':
        re_dt = input_time + datetime.timedelta(hours=offset)
        return re_dt
    elif time_type == 'minute':
        re_dt = input_time + datetime.timedelta(minutes=offset)
        return re_dt
    elif time_type == 'second':
        re_dt = input_time + datetime.timedelta(seconds=offset)
        return re_dt
    elif time_type == 'microsecond':
        re_dt = input_time + datetime.timedelta(microseconds=offset)
        return re_dt
    elif time_type == 'millisecond':
        re_dt = input_time + datetime.timedelta(milliseconds=offset)
        return re_dt
    else:
        print("error")

判断输入日期是否交易日

使用函数 check_is_trading_day()

check_is_trading_day()

def check_is_trading_day(input_date):  # 输入日期格式  yyyy-mm-dd
    lg = bs.login()   # 登陆系统
    if lg.error_code != '0' :
        print('login respond error_code:'+lg.error_code)    # 显示登陆返回信息
        print('login respond  error_msg:'+lg.error_msg)     # 显示登陆返回信息
    else:
        rs = bs.query_trade_dates(start_date=input_date, end_date=input_date)  # 调用 baostock 的 query_trade_dates 函数
        if rs.error_code != '0':
            print('query_trade_dates respond error_code:'+rs.error_code)            # 返回错误编码
            print('query_trade_dates respond  error_msg:'+rs.error_msg)             # 返回错误信息
        else:
            try:
                is_trading_day = int(rs.get_row_data()[1])      # 返回结果为str 此处进行强制转换为整型 1 和 0 用于表示是否交易日
            except:
                is_trading_day = 0
                bs.login()
            else:
                bs.logout()
            return is_trading_day

下载对应日期的交易明细

输入参数:
date 格式: yyyy-mm-dd
path 格式: 下载文件路径

downloadDayData()

def downloadDayData(date, path):
    starttime = datetime.datetime.now()   #设置 开始时间
    bs.login()

    # 获取指定日期的指数、股票数据
    stock_rs = bs.query_all_stock(date)
    stock_df = stock_rs.get_data()
    data_df = pd.DataFrame()
    for code in stock_df["code"]:
        # print("Downloading :" + code)
        k_rs = bs.query_history_k_data_plus(code, "date,code,open,high,low,close,preclose,volume,amount,adjustflag,turn,tradestatus,pctChg,peTTM,psTTM,pcfNcfTTM,pbMRQ,isST", date, date)
        data_df = pd.concat([data_df,k_rs.get_data()])
        # data_df = data_df.append(k_rs.get_data())    # append 在最新的python 3.9 不适用了
    bs.logout()
    data_df.to_csv(path, encoding="utf-8", index=False)
    endtime = datetime.datetime.now()   #设置 结束时间
    print("运行时间:" + str((endtime - starttime).seconds) + "秒===========>>>" + "已完成"+ date+ "数据下载")

通过逻辑判断是否交易日和是否已经下载过

使用逻辑”与“进行判断,如果”交易日“存在且”文件未下载“执行交易明细下载

if check_is_trading_day(start_day.strftime('%Y-%m-%d')) == 1 & (not os.path.exists(os.path.join("./download",  start_day.strftime('%Y-%m-%d')+".csv"))):

最终代码呈现

在这里插入图片描述
上述的代码源码可以直接下载在本地执行,windows及linux 均可直接执行。
(下载效率不高,毕竟人家做的是开源,且嫖且珍惜。)

源码地址

  • 1
    点赞
  • 4
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页
评论

打赏作者

「已注销」

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值