获取数据
上一篇的流程图中介绍了大致思路,实际实现的时候,数据需要分成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")