量化投资分析-Tushare数据获取

文章目录

  • 1. 数据源介绍
  • 2. Tushare安装
  • 3. 数据获取与保存
    • 3.1 获取上市公司列表
    • 3.2 开市日期获取
    • 3.3 获取某一只股票股票的历史数据
  • 4. 对tushare进行再封装
  • 4. 总结

1. 数据源介绍

在量化投资分析中,数据源始终是最基础部分。有一些研究者往往是从网络爬虫开始的。通过scrapy等python爬虫框架或者MATLAB进行数据爬取,这是非常不可取的,我们既然研究量化投资分析,应该首采用尽可能简单的方式获取到足够的历史数据。最好能够在几分钟内,上手所有自己需要的数据。Tushare实现的就是这样的任务,在没有网络爬虫基础和实战经验下,研究者能够通过它提供的API轻松获取到大量历史数据。

TuShare是一个免费、开源的python财经数据接口包。主要实现对股票等金融数据从数据采集、清洗加工 到 数据存储的过程,能够为金融分析人员提供快速、整洁、和多样的便于分析的数据,为他们在数据来源方面极大地减轻了工作 量,使他们更加专注于策略和模型的研究与实现上。tushare pro,数据更稳定质量更高,可获取沪深股票行情、财务、市场参考等数据,以及指数(含国外股指)、基金、期货、期权、宏观经济、行业经济等财经数据,为我们节省了大量宝贵时间。此外,近期还增加了新闻联播的文本数据,为文本分析和数据挖掘提供了很好的素材。新版本需要注册获取token才能免费使用。官方获取网址. 。

考虑到Python pandas包在金融量化分析中体现出的优势,TuShare返回的绝大部分的数据格式都是pandas DataFrame类型,非常便于用pandas/NumPy/Matplotlib进行数据分析和可视化。当然,如果您习惯了用Excel或者关系型数 据库做分析,您也可以通过TuShare的数据存储功能,将数据全部保存到本地后进行分析。应一些用户的请求,从0.2.5版本开始,TuShare同时 兼容Python 2.x和Python 3.x,对部分代码进行了重构,并优化了一些算法,确保数据获取的高效和稳定。

2. Tushare安装

tushare包的安装方式,有很多种,都很简单。
方式1:pypi中直接获取

pip install tushare

若在国内下载tushare超时,可以通过临时修改为清华pip源的方式安装

pip install tushare -i https://pypi.tuna.tsinghua.edu.cn/simple

方式2 :源码安装
首先访问 https://pypi.python.org/pypi/tushare/ 下载源码 ,进入到项目的目录下执行
python setup.py install

方式3:GitHub 获取源码

访问https://github.com/waditu/tushare,将项目下载或者clone到本地,进入到项目的目录下,
执行python setup.py install

tushare版本升级方式:
pip install tushare --upgrade
查看tushare当前版本:

import tushare
print(tushare.__version__)

3. 数据获取与保存

下面以股票行情数据为例,展示下tushare如何获取数据。股票行情数据以股票行情数据为例,简要介绍如何获取数据。

3.1 获取上市公司列表

pro = ts.pro_api()

#查询当前所有正常上市交易的股票列表
data = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,list_date')

tushare返回的data数据为pandas.DataFrame格式

    ts_code     symbol     name     area industry    list_date
0     000001.SZ  000001  平安银行   深圳       银行  19910403
1     000002.SZ  000002   万科A   深圳     全国地产  19910129
2     000004.SZ  000004  国农科技   深圳     生物制药  19910114
3     000005.SZ  000005  世纪星源   深圳     房产服务  19901210
4     000006.SZ  000006  深振业A   深圳     区域地产  19920427
5     000007.SZ  000007   全新好   深圳     酒店餐饮  19920413
6     000008.SZ  000008  神州高铁   北京     运输设备  19920507
7     000009.SZ  000009  中国宝安   深圳      综合类  19910625
8     000010.SZ  000010  美丽生态   深圳     建筑施工  19951027
9     000011.SZ  000011  深物业A   深圳     区域地产  19920330
10    000012.SZ  000012   南玻A   深圳       玻璃  19920228
11    000014.SZ  000014  沙河股份   深圳     全国地产  19920602
12    000016.SZ  000016  深康佳A   深圳     家用电器  19920327
13    000017.SZ  000017  深中华A   深圳     文教休闲  19920331
14    000018.SZ  000018  神州长城   深圳     装修装饰  19920616
15    000019.SZ  000019  深深宝A   深圳      软饮料  19921012
16    000020.SZ  000020  深华发A   深圳      元器件  19920428
17    000021.SZ  000021   深科技   深圳     电脑设备  19940202
18    000022.SZ  000022  深赤湾A   深圳       港口  19930505
19    000023.SZ  000023  深天地A   深圳     其他建材  19930429
20    000025.SZ  000025   特力A   深圳     汽车服务  19930621

3.2 开市日期获取

pro = ts.pro_api()
df = pro.trade_cal(exchange='', start_date='20180101', end_date='20181231')

返回的数据

    	exchange  cal_date  	is_open
0           SSE  20180101        0
1           SSE  20180102        1
2           SSE  20180103        1
3           SSE  20180104        1
4           SSE  20180105        1
5           SSE  20180106        0
6           SSE  20180107        0
7           SSE  20180108        1
8           SSE  20180109        1
9           SSE  20180110        1
10          SSE  20180111        1
11          SSE  20180112        1
12          SSE  20180113        0
13          SSE  20180114        0
14          SSE  20180115        1
15          SSE  20180116        1
16          SSE  20180117        1
17          SSE  20180118        1
18          SSE  20180119        1
19          SSE  20180120        0
20          SSE  20180121        0

3.3 获取某一只股票股票的历史数据

pro = ts.pro_api()
df = pro.query('daily', ts_code='000001.SZ', start_date='20180701', end_date='20180718')

打印获取的数据:

 ts_code trade_date  open  high   low  close  pre_close  change    pct_chg  vol        amount
0  000001.SZ   20180718  8.75  8.85  8.69   8.70       8.72   -0.02       -0.23   525152.77   460697.377
1  000001.SZ   20180717  8.74  8.75  8.66   8.72       8.73   -0.01       -0.11   375356.33   326396.994
2  000001.SZ   20180716  8.85  8.90  8.69   8.73       8.88   -0.15       -1.69   689845.58   603427.713
3  000001.SZ   20180713  8.92  8.94  8.82   8.88       8.88    0.00        0.00   603378.21   535401.175
4  000001.SZ   20180712  8.60  8.97  8.58   8.88       8.64    0.24        2.78  1140492.31  1008658.828
5  000001.SZ   20180711  8.76  8.83  8.68   8.78       8.98   -0.20       -2.23   851296.70   744765.824
6  000001.SZ   20180710  9.02  9.02  8.89   8.98       9.03   -0.05       -0.55   896862.02   803038.965
7  000001.SZ   20180709  8.69  9.03  8.68   9.03       8.66    0.37        4.27  1409954.60  1255007.609
8  000001.SZ   20180706  8.61  8.78  8.45   8.66       8.60    0.06        0.70   988282.69   852071.526
9  000001.SZ   20180705  8.62  8.73  8.55   8.60       8.61   -0.01       -0.12   835768.77   722169.579

这里只是简单地列举了一些常用的数据获取API,更多API可以参考官方网址获取

4. 对tushare进行再封装

再封装的目的是通过封装,循环获取所有股票的所有历史数据,这里演示的Demo可以直接拷贝使用

import tushare as ts
import scipy.io as sio
import datetime
import numpy as np
import pandas as pd
import time
from tqdm import tqdm
import os
# print(ts.__version__)

"""注意:
1.函数在获取文件的时候会出现网络等错误,导致鲁棒性不好。需要修改,如果获取不成功就多读几次
2.每次更新数据都要把旧的数据读进内存,然后append到新数据中,再写入文件.这样会消耗更长时间来操作文件
ts_code 	str 	股票代码
trade_date 	str 	交易日期
open 	    float 	开盘价
high 	    float 	最高价
low 	    float 	最低价
close 	    float 	收盘价
pre_close 	float 	昨收价
change 	    float 	涨跌额
pct_chg 	float 	涨跌幅 (未复权,如果是复权请用 通用行情接口 )
vol 	    float 	成交量 (手)
amount 	    float 	成交额 (千元)
"""
def updateAllStockHistoryData(pro):

    stock_list = pd.read_excel("./data/stock_list_from_tushare.xlsx")
    pbar = tqdm(total=stock_list.shape[0])
    
    i = 0

    for index, sl in stock_list.iterrows():
        # 如果这个文件不存在,就直接从网上获取所有数据,然后写入
        if not os.path.exists("./data/stock_data_"+str(sl.ts_code)+".xlsx"):
            stock_daily_data = pro.daily(ts_code = sl.ts_code, start_date = sl.list_date,
                                          end_date = datetime.datetime.now().strftime('%Y%m%d'))
            stock_weekly_data = pro.weekly(ts_code=sl.ts_code, start_date=sl.list_date,
                                           end_date=datetime.datetime.now().strftime('%Y%m%d'),
                                           fields='ts_code,trade_date,close,open,high,low,pre_close,change,pct_chg,vol,amount')
            stock_monthly_data = pro.monthly(ts_code=sl.ts_code, start_date=sl.list_date,
                                             end_date=datetime.datetime.now().strftime('%Y%m%d'),
                                             fields='ts_code,trade_date,close,open,high,low,pre_close,change,pct_chg,vol,amount')
            with pd.ExcelWriter("./data/stock_data_"+str(sl.ts_code)+".xlsx",engine="openpyxl") as writer:
                stock_daily_data.to_excel(writer, sheet_name = 'daily')
                stock_weekly_data.to_excel(writer, sheet_name = 'weekly')
                stock_monthly_data.to_excel(writer, sheet_name = 'monthly')
                print("stock: " + str(sl.ts_code) +" file is downloaded from tushare")
        else:
            # 如果存在这个文件就读取出来看首行日期,然后根据首行日期-当前日期进行获取数据,append进去
            try:
                stock_daily_data_old = pd.read_excel("./data/stock_data_"+str(sl.ts_code)+".xlsx", sheet_name='daily')
                stock_weekly_data_old = pd.read_excel("./data/stock_data_"+str(sl.ts_code)+".xlsx", sheet_name='weekly')
                stock_monthly_data_old = pd.read_excel("./data/stock_data_"+str(sl.ts_code)+".xlsx", sheet_name='monthly')
                last_date = str(stock_daily_data_old.trade_date[0])
                delta_one_day = datetime.timedelta(days=1)
                last_date = datetime.datetime.strptime(last_date,"%Y%m%d")+delta_one_day
                last_date = last_date.strftime('%Y%m%d')

                stock_daily_data = pro.daily(ts_code = sl.ts_code, start_date = last_date,
                                             end_date = datetime.datetime.now().strftime('%Y%m%d'))
                stock_daily_data = stock_daily_data.append(stock_daily_data_old)
                stock_weekly_data = pro.weekly(ts_code=sl.ts_code, start_date=last_date,
                                               end_date=datetime.datetime.now().strftime('%Y%m%d'),
                                               fields='ts_code,trade_date,close,open,high,low,pre_close,change,pct_chg,vol,amount')
                stock_weekly_data = stock_weekly_data.append(stock_weekly_data_old)
                stock_monthly_data = pro.monthly(ts_code=sl.ts_code, start_date=last_date,
                                                 end_date=datetime.datetime.now().strftime('%Y%m%d'),
                                                 fields='ts_code,trade_date,close,open,high,low,pre_close,change,pct_chg,vol,amount')
                stock_monthly_data = stock_monthly_data.append(stock_monthly_data_old)
                # stock_monthly_data = pro.
                # stock_year_data = 
                with pd.ExcelWriter("./data/stock_data_"+str(sl.ts_code)+".xlsx", engine="openpyxl") as writer:
                    stock_daily_data.to_excel(writer, sheet_name = 'daily')
                    stock_weekly_data.to_excel(writer, sheet_name = 'weekly')
                    stock_monthly_data.to_excel(writer, sheet_name = 'monthly')
                    time.sleep(0.02)
                    print("stock: " + str(sl.ts_code) +" file is updated from tushare")
            finally:
                pass

        pbar.update(i)
        i = i + 1

    pbar.close
    return 0



# 更新大盘指数日指标
'''
ts_code         str     Y   TS代码
trade_date      str     Y   交易日期
total_mv        float   Y   当日总市值(元)
float_mv        float   Y   当日流通市值(元)
total_share     float   Y   当日总股本(股)
float_share     float   Y   当日流通股本(股)
free_share      float   Y   当日自由流通股本(股)
turnover_rate   float   Y   换手率
turnover_rate_f float   Y   换手率(基于自由流通股本)
pe              float   Y   市盈率
pe_ttm          float   Y   市盈率TTM
pb              float   Y   市净率
'''
def updateMarketIndexHistoryDataFromTushare(pro):

    writer = pd.ExcelWriter("./data/market_index_history_data" + ".xlsx", engine="openpyxl")
    ts_codes = ['000001.SH', '000300.SH', '000905.SH', '399001.SZ', '399005.SZ', '399006.SZ', '399016.SZ', '399300.SZ']
    fields = 'ts_code, trade_date, total_mv, float_mv, total_share, float_share, free_share, turnover_rate, turnover_rate_f, pe, pe_ttm, pb'
    if not os.path.exists("./data/market_index_history_data" + ".xlsx"):
        for ts_code in ts_codes:
            Market_Index = pro.index_dailybasic(ts_code = ts_code, start_date='20040101', end_date = datetime.datetime.now().strftime('%Y%m%d'), fields=fields)
            Market_Index.to_excel(writer, sheet_name=ts_code)
        writer.save()
        print("File: market_index_history_data is downloaded.")
    else:
        for ts_code in ts_codes:
            Market_Index_old = pd.read_excel("./data/market_index_history_data" + ".xlsx", sheet_name=ts_code)
            last_date = str(Market_Index_old.trade_date[0])
            delta_one_day = datetime.timedelta(days=1)
            last_date = datetime.datetime.strptime(last_date, "%Y%m%d") + delta_one_day
            last_date = last_date.strftime('%Y%m%d')

            Market_Index_new = pro.index_dailybasic(ts_code = ts_code, start_date=last_date, end_date = datetime.datetime.now().strftime('%Y%m%d'), fields=fields)
            Market_Index_new = Market_Index_new.append(Market_Index_old)
            Market_Index_new.to_excel(writer, sheet_name=ts_code)
        writer.save()
        print("File: market_index_history_data is updated.")
    return 0


# 获取上市公司列表
def updateStockList(pro):
    # Query the stock list(正常上市公司列表)
    stock_list = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,fullname,enname,market, exchange,curr_type,list_status,list_date,list_date')
    stock_list.to_excel("./data/stock_list_from_tushare.xlsx")
    return 0

# 获取历史交易日历
def updateTradeCalenda(pro):
    #
    # Query the trade calendar(获取历史交易日历)
    trade_calendar = pro.trade_cal(exchange='', start_date='20180101', end_date=datetime.datetime.now().strftime('%Y%m%d'))
    trade_calendar.to_excel("./data/trade_calendar_from_tushare.xlsx")
    return 0

if __name__ == '__main__':
    
    # Initialize the pro interface
    pro = ts.pro_api('your_token')
    print("Trying to download data form tushare...")

    # 获取当前上市公司列表
    updateStockList(pro)

    # 获取历史交易日历
    updateTradeCalenda(pro)

    # 更新所有股票日,周,月K历史数据
    # updateAllStockHistoryData(pro)

    # 更新大盘指数历史数据
    updateMarketIndexHistoryDataFromTushare(pro)

简单介绍一下文件中的子函数:

  1. 通过调用updateAllStockHistoryData()更新所有上市公司从上市以来,到最近一天期间所有日K,周K和月K历史数据,保存到文件同级目录data/文件夹下
  2. 通过调用updateMarketIndexHistoryDataFromTushare()函数,获取大盘指数数据,包括['000001.SH', '000300.SH', '000905.SH', '399001.SZ', '399005.SZ', '399006.SZ', '399016.SZ', '399300.SZ']

量化投资分析-Tushare数据获取_第1张图片
全部运行结束后,我们就可以得到所有股票的全部历史数据,一共825M左右
量化投资分析-Tushare数据获取_第2张图片

4. 总结

通过已有的数据源,我们可以简单的获取到大量数据(825M),而不需要从头学习网络爬虫。节省了大量时间。为了让大家更好的利用tushare工具,获取更多关于tushare数据获取的内容,我会在这片博客中不断填充。大家如果有好的封装,可以在底下评论。我会测试,整理并及时发布到该博客中。

你可能感兴趣的:(量化投资分析,数据分析,python,大数据,机器学习,人工智能)