VAI TRÒ CỦA THU THẬP VÀ XỬ LÝ DỮ LIỆU

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.

TẠO HÀM KÉO DỮ LIỆU CHỨNG KHOÁN TỰ ĐỘNG

#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