利用Python编程语言爬取A股所有历史行情数据,验证量化交易是否有效

背景

若要验证量化交易策略是否有效,需要有足够的历史行情数据作为支撑,故本文将使用Python编写爬虫对上证、深证全部股票的历史行情数据进行爬取。

目标

1.下载上证、深证所有股票历史行情数据到本地数据库

2.每日更新股票行情数据到本地数据库

3.数据库使用mysql

数据来源:

股票代码—https://www.banban.cn/gupiao/list_sh.html

股票行情数据—http://quotes.money.163.com/trade/lsjysj_600018.html

过程

  1. 获取所有股票代码

  2. 创建数据库STOCK,用于存储股票数据

  3. 以“s_股票代码”在数据库STOCK中创建/添加数据表,用于存储每只股票的历史行情数据

  4. 遍历各表,读取各表最后一条记录中的开盘日期;输入实际最新开盘日期;两日期比对,若日期为空则表为空 故下载该股全部历史数据,若日期不同,则表中数据非当前最新行情数据,故更新数据至实际最新开盘日期;若日期相同,则表明表中数据已是最新数据,故跳过。

  5. 将每只股票的历史行情数据对应存储到各表

利用Python编程语言爬取A股所有历史行情数据,验证量化交易是否有效_第1张图片

函数及解释

导入模块及设置headers

import requests,pymysql,re,datetime
import pandas as pd
from bs4 import BeautifulSoup
from sqlalchemy import create_engine
 
 
headers={
     
'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36'
}

DownStockCode()函数,获取所有股票代码,返回结果示例:[‘600002’,‘600003’…]

#获取所有上证、深证的股票代码,return:['600001','600002','600003'...]
def DownStockCode():
    print('开始获取上证、深证股票代码')
    count = 0
    stockcodeList=[]
    urlList = ['https://www.banban.cn/gupiao/list_sh.html','https://www.banban.cn/gupiao/list_sz.html']
    for url in urlList:
        res = requests.get(url=url,headers=headers)
        bs_res = BeautifulSoup(res.text,'html.parser')
        stocklist=bs_res.find('div',id='ctrlfscont').find_all('li')
        for stock in stocklist:
                    stockhref=stock.find('a')['href']
                    list_stockhref=stockhref.strip().split('/')
                    stock_code=list_stockhref[2]
                    stockcodeList.append(stock_code)
                    count += 1
                    print('当前已获取{}只股票代码'.format(count),end='\r')
    print('已获取所有上证、深证股票代码:{}个'.format(count))
    return stockcodeList 

CreateDatabase(host,user,password,dbname)函数,创建本地数据库STOCK

#创建数据库用于存储股票数据表
def CreateDatabase(host,user,password,dbname):
    db = pymysql.connect(
        host = host,
        user = user,
        password = password,
        port = 3306
    )
    cursor = db.cursor()
    sql = 'create database if not exists '+ dbname
    cursor.execute(sql)
    db.close()
    print('检查/创建本地存储数据库-STOCK')

CreateTable(host,user,password,dbname,codeList) 函数,根据股票代码 为每只股票创建、添加数据表

#根据股票代码,创建添加股票数据表,用于存储每只股票数据,table:s_600001
def CreateTable(host,user,password,dbname,codeList):
    print('开始检查/添加股票数据表')
    db = pymysql.connect(
        host = host,
        user = user,
        password = password,
        database = dbname
    )
    cursor = db.cursor()
    count = len(codeList)
    num =  0
    for code in codeList:
        num += 1
        sql = 'create table if not exists s_'+code+'(\
            stockName varchar(250) not null,\
            dateTime varchar(250) not null, \
            startPrice varchar(100), \
            maxPrice varchar(100), \
            minPrice varchar(100), \
            endPrice varchar(100), \
            diffPrice varchar(100), \
            diffPercent varchar(100), \
            turnoverAmount varchar(100), \
            amount varchar(100), \
            amplitude varchar(100), \
            turnoverPercent varchar(100))'
        cursor.execute(sql)
        print('检查/添加数据库表:s_{},{}/{}'.format(code,num,count),end='\r')
    db.close()    
    print('数据库表已检查/添加完毕!!!            ')

GetNearestDate(host,user,password,dbname) 函数,获取每个股票数据表中的最后一条记录 并提取开盘日期,返回结果示例:[[‘600001’,‘2020-12-3’],[‘600002’,‘NULL’]…]

#获取所有表名,遍历每个表并获取最新行情数据日期返回列表:[[股票代码,最新数据日期],['600001','2020-12-3'],['600002','NULL']]
def GetNearestDate(host,user,password,dbname):
    print('开始获取数据库表内股票的最后交易日期')
    count_empty = 0 #用于记录空表数量
    tablelist = [] #存储获取到的数据库表名
    nearestdatelist = []#存储股票代码和最新行情日期
    db = pymysql.connect(
        host = host,
        user = user,
        password = password,
        database = dbname
    )
    cursor = db.cursor()
    sql_showtables = 'show tables'
    cursor.execute(sql_showtables) #查询表名
    for i in cursor:
        tablelist.append(str(i)) #表名存储到列表
    for tablename in tablelist:
        code = re.sub('\D','',tablename)#取出表名中的数字,即股票代码code
        sql_s_dateTime = 'select * from s_'+code+' order by dateTime desc limit 1' #取出数据表最后一行记录
        lastrow = pd.read_sql(sql_s_dateTime,db) 
        if lastrow.empty:
            dateTime = 'Null'
            count_empty += 1
        else:
            dateTime = lastrow['dateTime'][0]
        nearestdatelist.append([code,dateTime])
        print('已获取:{} 的最后交易日期为:{}  当前获取进度:{}/{}     '.format(code,dateTime,len(nearestdatelist),len(tablelist)), end='\r') 
    db.close()    
    print('个股最后交易日期获取完毕,共计{}只股票,其中需下载全部数据的股票共{}只'.format(len(nearestdatelist),count_empty))
    return nearestdatelist    

你可能感兴趣的