本身自己做开发,又刚好对股票有一些兴趣,最近刚好又在学python,python尤其擅长数据分析、数据爬取于是打算用python获取A股所有上市公司历史交易数据,包括指数。但网上找了半天,几乎没有现成的拷贝过来就能用的代码,我说的是免费的,不过功夫不负有心人,最终还是找到了两个办法。以下两种方法是针对有python编程基础的人,没有编程基础的人直接去淘宝搜索A股历史交易记录吧,大淘宝果然啥都有,码农的杂货铺他们家的数据还不错,关键是便宜,废话不多说,下面上代码。

1、方法一从ricequant获取,ricequant是一个量化平台交易网站,在网站上注册一个账号,在我的研究中新建一个python脚本,代码如下,直接运行,之后会在服务端生成一个csv文件。这个csv文件很大,大概500M左右,大家可以在网上下载一个emeditor大文本编辑器,查看对应内容。

主要字段含义如下:
        date:交易日期
        open:开盘价
        high:最高价
        close:收盘价
        low:最低价
        volume:成交量
        amount:成交额
        code:股票代码或指数代码。

import pandas as pd
file = r'record.txt'
#A股所有上市公司
datas = all_instruments(type='CS')
list = datas['order_book_id'].tolist()
df1 = pd.DataFrame(columns = list)
df1.loc[0] = datas['symbol'].tolist()
#df2 = pd.DataFrame(columns = list)
df2 = pd.DataFrame()
for index,row in datas.iterrows():
        id=datas.loc[index]['order_book_id']
        print(id)
       # if '300144' in id:
        //股票上市时间
        startDate=datas.loc[index]['listed_date']
        print(id+'--'+startDate)
        try:         
            #循环获取股票价格,时间范围为start_date到end_date,格式为dataframe
            pInfo = get_price(id,start_date=startDate, end_date='2018-10-10', adjust_type='none')
            #给dataframe增加一列
            pInfo['code']=id
            #dataframe写入文件,追加方式
            pInfo.to_csv('A_allStockAll.csv',mode='a')
        except BaseException:
             with open(file, 'a') as f:
                 f.write(id+'_'+startDate+'_\r\n')
                 f.close()
        pass
        continue
print("suc")
#frames = [df1, df2]
#result = pd.concat(frames)
#df2.to_csv('df2.csv')
#print(type(list))
#for id in list:
#    print(list.loc[index])
    #df2[id] = get_price(id,start_date='2013-01-04', end_date='2018-09-09', #adjust_type='none')['ClosingPx']
#frames = [df1, df2]
#result = pd.concat(frames)
#result.to_csv('stoneClosingPx_0809.csv')

需要说明的是以上获取的是上市公司股票的指数,不包括指数。指数数据可以从网易股票财经下载,选择开始时间,结束时间,需要哪个指数下载哪个指数的数据就可以了。

方法2.通过tushare获取,tushare可以在网上搜索,也有安装教程,通过tushare获取历史纪录很简单,下面直接看代码:

这个方法楼主试了很多次都没有成功,可能数据量太大了,经常超时,报406。需要说明的是tushare是一个客户端软件,所有的请求都是从客户端发起,以爬虫的形式然后请求新浪财经、凤凰财经的数据,频繁请求会被这些网站暂时封禁IP,406就是这个错误,所以虽然贴出了代码,还是希望大家用第一种方法。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
#20080512   002230
import numpy as np
import pandas as pd
import tushare as ts
import datetime
import math
import os
import time
from dateutil.relativedelta import relativedelta
def days(str1,str2):
    date1=datetime.datetime.strptime(str1[0:10],"%Y-%m-%d")
    date2=datetime.datetime.strptime(str2[0:10],"%Y-%m-%d")
    num=(date1-date2).days
    return num
def months(str1,str2):
    year1=datetime.datetime.strptime(str1[0:10],"%Y-%m-%d").year
    year2=datetime.datetime.strptime(str2[0:10],"%Y-%m-%d").year
    month1=datetime.datetime.strptime(str1[0:10],"%Y-%m-%d").month
    month2=datetime.datetime.strptime(str2[0:10],"%Y-%m-%d").month
    num=(year1-year2)*12+(month1-month2)
    return num
currDateStr='2018-10-10'
file = r'./record.txt'
#获取所有上市公司列表
allStock = ts.get_stock_basics();##pd.read_csv("../data/stock_basics.csv",dtype={'code':str,'timeToMarket':str}, names=["code","name","industry","area","pe","outstanding","totals","totalAssets","liquidAssets","fixedAssets","reserved","reservedPerShare","esp","bvps","pb","timeToMarket","undp","perundp","rev","profit","gpr","npr","holders"])
#循环上市公司,根据上市时间获取开始交易时间
for index,row in allStock.iterrows():
    #上市时间
    dateStart=str(allStock.loc[index]['timeToMarket'])
    code=allStock.loc[index]['code']
    dateStart1=dateStart[0:4]+'-'+dateStart[4:6]+'-'+dateStart[6:8]
    date = datetime.datetime.strptime(dateStart1,'%Y-%m-%d')
    gapMonth=months(currDateStr,dateStart1)
    gapYear=math.ceil(gapMonth/12)
    #如果一次性获取会超时,因此要分解时间
    for i in range(gapYear):
        strDateS1=dateStart1
        date=date+relativedelta(years=1)
        endDateS1=date.strftime('%Y-%m-%d')
        if months(endDateS1,currDateStr)>1:
            endDateS1=currDateStr
        try:
            print(strDateS1+"到"+endDateS1)
            csvFile='F:/paythonWork/stock_data/'+code+'_'+strDateS1+'_'+endDateS1+'.csv'
            if not os.path.exists(csvFile):
                if days(strDateS1,'2016-01-01')>1:
                     rs=ts.get_hist_data(code,start=strDateS1,end=endDateS1)
                     rs.to_csv(csvFile)
                     time.sleep(1)
                else:
                    rs=ts.get_h_data(code,start=strDateS1,end=endDateS1)
                    rs.to_csv(csvFile)
                    time.sleep(30)
            date=(date+relativedelta(days=1))
            dateStart1= date.strftime('%Y-%m-%d')

        except BaseException:
            with open(file, 'w+') as f:
             f.write(code+'_'+strDateS1+'_'+endDateS1+'\r\n')
             f.close()
        pass
        continue


    print(dateStart+'code'+code)
    # try:
    #     rs=ts.get_hist_data(code,start=dateStart,end="2018-09-07")
    #     rs.to_csv('F:/paythonWork/stock_data/'+code+'_'+dateStart+'.csv')
    # except BaseException:
    #     with open(file, 'w+') as f:
    #      f.write(code+",")
    #      f.close()
    #     pass
    # continue

关于数据的更新:

数据的更新应该就简单了吧,楼主就不废话了。

发表评论