獲取數據
上一篇的流程圖中介紹了大致思路,實際實現的時候,數據需要分成2個部分,歷史數據和每日更新的數據。其中每日更新的數據量較小,直接從第三方數據網站獲取,單線程爬蟲即可搞定;歷史數據用來做模型訓練,所涉及的體量較大。
本篇着重解決歷史數據的問題:
- 一、大宗交易的歷史數據
這裏通過多線程爬蟲實現,具體思路如下:
以下爲主入口代碼,其他代碼略微有些多,暫時不上傳了:
# main方法的代碼
ipqueue = Queue()
days = checkProxyDays()
# 超過2天就從網上獲取代理,否則從本地獲取代理
if days > 2:
getProxyFromWeb(ipqueue)
else:
getProxyFromCsv(ipqueue)
t = Thread(target=startSpider, args=(ipqueue,))
t.start()
while gQuit == False:
print ('gQuit:', gQuit)
if ipqueue.qsize() < 100:
getProxyFromWeb(ipqueue)
time.sleep(2)
二、交易軟件中股票每日交易數據
通過本地軟件導出歷史數據(csv格式,如SH600009.csv),字段如下:- 交易日期;
- 股票代碼;
- 開盤價;
- 最高價
- 最低價
- 收盤價
- 交易量
- 交易金額
導出到本地時,共約3500個文件,這裏使用SQL SERVER的SSIS服務導入(也可以用kettle了)。囉嗦下SSIS的優點,批量複製,速度快;缺點,單進程。需要在SSIS中完成的功能,派生列(文件名插入到數據中),時間段篩選(只要2017年以後的數據),數據轉換(轉換放在後面,減少轉換次數),循環導入。SSIS的數據流如下:
由於單進程的缺點,3500個文件導了4個小時(開關連接、過濾轉換消耗了太多時間),在考慮不全的情況下一返工,10個小時就花掉了,所以後來在模型完成後,補充歷史數據的時候用了第二種方法。使用R的並行計算(parallel),直接截取數據(大概只有20多個交易日的數據),把所有數據整合成一個文件,然後再導入數據庫。代碼如下:
library(parallel)
library(plyr)
extractFun <- function(i){
filieName <- paste0(folderPath, '\\', fileList[i])
stockCode <- substring(fileList[i], 3, 8)
dat <- read.csv(filieName, header = F)
res <- NULL
tryCatch({
ind <- which(dat$V1 >= startDate & is.na(dat$V2)==FALSE)
if(length(ind) > 0)
res <- cbind(StockCode=stockCode, dat[ind, ])
}, warning = function(w) {
warning-handler-code
}, error = function(e) {
error-handler-code
return
}, finally = {
return(res)
})
}
result1 <- NULL
system.time({
fileList <- list.files('E:\\gupiaoshuju')
x <- 1:length(fileList)
cl <- makeCluster(4)
clusterEvalQ(cl, {
options(stringsAsFactors = F)
folderPath <- 'E:\\gupiaoshuju'
startDate <- '2018/01/10'
fileList <- list.files(folderPath)
})
result1 <- parLapply(cl, x, extractFun)
res.df <- do.call('c',result1)
stopCluster(cl)
})
result2 <- NULL
combineResult <- function(x){
rbind(result2, x)
}
result <- ldply(result1)
colnames(result)[2:8] <- c("TradeDate", "PriceOpen", "PriceMax", "PriceMin", "PriceClose", "Volume", "Amount")