Chúng ta không thể phủ nhận vai trò của dữ liệu là một tài nguyên vô cùng quí gía. Tuy nhiên không phải lúc nào người phân tích dữ liệu cũng có được nguồn dữ liệu một cách thuận lợi bởi dữ liệu tồn tại ở nhiều định dạng, hình thái khác nhau và không phải nguồn dữ liệu lúc nào cũng chuẩn định dạng như ta mong muốn mà phải trải qua quá trình thu thập và làm sạch dữ liệu. Quá trình đó đòi hỏi ở data scientist không chỉ kĩ năng phân tích mà còn là kĩ năng xử lý dữ liệu, kĩ năng IT để có thể lấy data từ nhiều nguồn trong đó có những nguồn rất rộng như các website.
Trên thế giới từ lâu đã có những gói dữ liệu cho phép người sử dụng clone data chứng khoán từ các nguồn đáng tin cậy như quantmod. Tuy nhiên tại Việt Nam do những nguyên nhân hạn chế về cộng đồng nhỏ hẹp, nhu cầu sử dụng chưa cao nên chưa có bất kì một project nào cho phép kéo dữ liệu chứng khoán từ R. Vì thế trong bài viết này mình sẽ hướng dẫn mọi người cách tạo cho riêng mình một hàm có thể kéo dữ liệu cho bất kì một mã chứng khoán nào theo ngày từ nguồn dữ liệu đáng tin cậy là bảng giá của vndirect: https://www.vndirect.com.vn.
#import cac goi du lieu da
library(rvest)
library(httr)
library(stringr)
library(magrittr)
library(dplyr)
#tao ham getSymbols
getSymbols <- function(symbol, from, to){
#day la form-data se duoc gui len url
fd <- list(
searchMarketStatisticsView.symbol= symbol,
strFromDate = dateChar(from),
strToDate = dateChar(to)
)
url <- "https://www.vndirect.com.vn/portal/thong-ke-thi-truong-chung-khoan/lich-su-gia.shtml"
#gui request len url tren
resp <- POST(url,body = fd,encode = "form")
#truy cap vao cac html_node de lay gia chung khoan
tmp <- resp %>% read_html() %>% html_nodes(xpath='//*[@id="tab-1"]/div[2]/ul') %>%
html_children() %>% html_text()
#boc tach cac node dua vao html
noDays <- length(tmp)
cname <- c("DATE","CHANGE.PERCENT1","CHANGE.PERCENT2","OPEN","HIGH","LOW","CLOSE","AVERAGE","CLOSE.ADJUST","MATCH.VOLUME","RECONCILE.VOLUME")
symbol <- matrix(nrow = 0,ncol = 11,byrow = TRUE,dimnames = list(c(),cname))
for(i in 2:noDays){
row <- str_replace_all(tmp[i],"\t","") %>% str_replace_all("\n"," ") %>%
gsub(' +',' ',.) %>% str_trim() %>%
str_split(" ") %>% unlist() %>% str_split(" ") %>% unlist() %>% as.vector()
symbol <- rbind(symbol,row)
}
rownames(symbol) <- seq(1,noDays-1,1)
symbol <- data.frame(symbol)
symbol[,1]<- as.Date(symbol[,1],"%Y-%m-%d")
symbol[,2:11] <- apply(symbol[,2:11],2,as.numeric)
return(symbol)
}
#tao ham xu ly dateTime tu dang date sang string
dateChar <- function(dateTime){
dateTime %<>% as.Date() %>% format(.,format = "%d/%m/%Y")
return(dateTime)
}
#goi ham getSymbols de xem ket qua tra ve
getSymbols("VCB","2017-12-01","2017-12-31")
## Note: no visible binding for global variable '.'
## Note: no visible binding for global variable '.'
## DATE CHANGE.PERCENT1 CHANGE.PERCENT2 OPEN HIGH LOW CLOSE
## 1 2017-12-28 1.60 0.030476190 52.50 54.90 52.50 54.10
## 2 2017-12-27 1.10 0.021400778 51.40 52.80 51.10 52.50
## 3 2017-12-26 0.00 0.000000000 51.50 51.70 50.50 51.40
## 4 2017-12-25 0.60 0.011811024 51.00 51.70 50.80 51.40
## 5 2017-12-22 2.30 0.047422680 48.20 50.80 48.05 50.80
## 6 2017-12-21 -0.50 0.010204082 49.00 49.20 48.50 48.50
## 7 2017-12-20 1.25 0.026178010 47.75 49.35 47.40 49.00
## 8 2017-12-19 -0.05 0.001046025 47.90 48.45 47.35 47.75
## 9 2017-12-18 1.80 0.039130435 47.00 48.20 46.60 47.80
## 10 2017-12-15 0.70 0.015452539 45.30 46.50 45.20 46.00
## 11 2017-12-14 1.30 0.029545455 44.00 45.50 43.90 45.30
## 12 2017-12-13 -0.70 0.015659955 45.00 45.10 43.70 44.00
## 13 2017-12-12 0.10 0.002242152 45.30 45.40 41.60 44.70
## 14 2017-12-11 -2.45 0.052072264 46.00 46.90 44.60 44.60
## 15 2017-12-08 -0.55 0.011554622 47.60 47.60 46.50 47.05
## 16 2017-12-07 -0.40 0.008333333 48.00 48.00 46.70 47.60
## 17 2017-12-06 -0.10 0.002079002 48.00 48.30 47.10 48.00
## 18 2017-12-05 -1.30 0.026315789 49.00 50.00 48.10 48.10
## 19 2017-12-04 1.10 0.022774327 48.50 49.40 48.30 49.40
## 20 2017-12-01 0.00 0.000000000 48.60 48.90 48.00 48.30
## AVERAGE CLOSE.ADJUST MATCH.VOLUME RECONCILE.VOLUME
## 1 53.76 54.10 2321870 NA
## 2 52.04 52.50 2214360 NA
## 3 51.15 51.40 1701570 NA
## 4 51.20 51.40 1491740 NA
## 5 49.82 50.80 4459390 238540
## 6 48.83 48.50 1547200 NA
## 7 48.60 49.00 2587600 67500
## 8 47.70 47.75 1958480 NA
## 9 47.44 47.80 2349430 NA
## 10 45.93 46.00 2574240 NA
## 11 44.70 45.30 2166840 NA
## 12 44.53 44.00 1177420 NA
## 13 44.29 44.70 2440280 NA
## 14 45.96 44.60 1447900 NA
## 15 46.90 47.05 1517040 167000
## 16 47.24 47.60 2737090 NA
## 17 47.66 48.00 2102030 NA
## 18 49.10 48.10 1975550 NA
## 19 48.81 49.40 1939700 NA
## 20 48.37 48.30 2085760 252800