本文首先在东方财富网上爬取当前上海股票和深圳股票的所有股票代码,然后利用网易股票上的接口拉取每支股票从上市以来的历史成交数据,最后通过某一支股票的历史交易数据采用svm分类算法,对数据进行训练,进行涨跌趋势预测。
1. 爬取所有股票代码
如下图所示,通过查看页面源码可以发现a标签下的href属性结尾都是以sh|z + 股票代码 + .html形式结尾,所以通过正则表达式和requests库很容易爬取到所有股票列表。

def getHTMLText(url):
try:
r = requests.get(url)
r.raise_for_status()
r.encoding = r.apparent_encoding
return r.text
except:
return ""
def getStockList(lst, stockURL):
html = getHTMLText(stockURL)
soup = BeautifulSoup(html, 'html.parser')
a = soup.find_all('a')
for i in a:
try:
href = i.attrs['href']
lst.append((re.findall(r"[s][hz]\d{6}", href)[0])[2:])
except:
continue
2. 下载股票历史交易数据
2.1 得到当前股票上市日期
如下股票上市日期的信息在class="table_bg001 border_box limit_sale table_details" 的table标签下,此处可以通过BeautifulSoup模块find_all函数来进行定位。

def getStockStartDate(stockCode):
html = getHTMLText("http://quotes.money.163.com/f10/gszl_" + stockCode + ".html#01f02")
soup = BeautifulSoup(html, 'html.parser')
try:
a = soup.find_all('table', class_="table_bg001 border_box limit_sale table_details")[1]
except:
return time.strftime("%Y%m%d")
cnt = 0;
date = ""
for tr in a.children:
if isinstance(tr, bs4.element.Tag):
tds = tr('td')
cnt = cnt + 1
if(cnt ==2):
date = tds[1].string.replace("-","")
break;
return date
2.2 下载从上市日期到今天的交易数据
下载数据就比较简单了,直接通过网易股票接口,然后以股票代码命名在csv文件格式进行存储。
def getHistoryTradeInfo(stockCode):
download_url = "http://quotes.money.163.com/service/chddata.html?code=0" + stockCode + "&start=" + getStockStartDate(stockCode) + "&end=" + time.strftime("%Y%m%d") + "&fields=TCLOSE;HIGH;LOW;TOPEN;LCLOSE;CHG;PCHG;TURNOVER;VOTURNOVER;VATURNOVER;TCAP;MCAP"
data = requests.get(download_url)
f = open('histotry/' + stockCode + '.csv', 'wb')
for chunk in data.iter_content(chunk_size=10000):
if chunk:
f.write(chunk)


3. 趋势预测
通过上面的步骤已经顺利拿到了所有上市和深市自上市以来的交易数据,下面就是最关键的趋势预测了。本部分以600196为例,查看csv文件可以看到该股票已有四千多个交易日,我们可以选取前150个交易日的开盘价,收盘价,最高价,最低价以及成交量和当天开盘价作为影响股票当天涨跌的751个特征,然后利用已有数据进行80%作为训练,20%作为测试,进行交叉验证。
import pandas as pd
import numpy as np
from sklearn import svm
from sklearn.model_selection import train_test_split
data=pd.read_csv('600196.csv',encoding='gbk',parse_dates=[0],index_col=0)
data.sort_index(0,ascending=True,inplace=True)
dayfeature=150
featurenum=5*dayfeature
x=np.zeros((data.shape[0]-dayfeature,featurenum+1))
y=np.zeros((data.shape[0]-dayfeature))
for i in range(0,data.shape[0]-dayfeature):
x[i,0:featurenum]=np.array(data[i:i+dayfeature] \
[[u'收盘价',u'最高价',u'最低价',u'开盘价',u'成交量']]).reshape((1,featurenum))
x[i,featurenum]=data.ix[i+dayfeature][u'开盘价']
for i in range(0,data.shape[0]-dayfeature):
if data.ix[i+dayfeature][u'收盘价']>=data.ix[i+dayfeature][u'开盘价']:
y[i]=1
else:
y[i]=0
clf=svm.SVC(kernel='sigmoid') # ‘linear’‘poly’‘sigmoid’ 'rbf'
result = []
for i in range(5):
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2)
clf.fit(x_train, y_train)
result.append(np.mean(y_test == clf.predict(x_test)))
print("svm classifier accuacy:")
print(result)

本次实验运用了三个核函数做实验,准确率如上力数据所示。5次交叉
验证的准确率相近,均为53%左右。
网友评论