Могу ли я импортировать историческую рыночную капитализацию с веб-сайта в R? - PullRequest
1 голос
/ 20 июня 2020

Я попытался импортировать историческую рыночную капитализацию акций с помощью getHisMktCap. Поскольку эта функция требует использования чисел в качестве символа тикера, мне она не подходит.

Я нашел веб-сайт, который показывает историческую рыночную капитализацию акций, и хочу импортировать его в R.

https://stockrow.com/interactive_chart/54e53957-2723-4e78-8b73-1b922e9d3300

enter image description here

Как видите, это из диаграммы. Я просто хочу установить рыночную капитализацию на день, 2015-10-30. Также у меня есть сотни тикеров.

Я пробовал с:

library(data.table)
mydat <- fread('https://stockrow.com/interactive_chart/54e53957-2723-4e78-8b73-1b922e9d3300')

, и он не импортирует данные из Интернета. Как я могу это сделать?

Ответы [ 2 ]

2 голосов
/ 21 июня 2020

Я опаздываю на это, но вот индивидуальное решение вашей конкретной c проблемы.

Это потребует, чтобы вы использовали RSelenium для получения данных HTML, которые содержат значения для chart indicators и chart tickers, которые необходимо передать в JSON API (?). Затем, используя jsonlite и httr, вы можете сформулировать запрос POST, который будет извлекать данные в формате JSON с этого URL-адреса. Наконец, данные могут быть отформатированы и нанесены на график в R.

Набор функций ниже сделает это за вас (последняя функция в блоке кода ниже зависит от предыдущих вспомогательных функций). srvisualize специально разработан для извлечения и построения данных из Stockrow. Все, что вам нужно предоставить, это ваш URL-адрес акции. Помимо построения графика, он возвращает необработанные теперь отформатированные данные (как объект data.frame; для нисходящего потока), данные графика (для настраиваемого построения) и идентификатор контейнера Docker (в котором Selenium браузер был развернут для загрузки URL; этот контейнер закрывается после завершения функции).

Предварительным условием для использования srvisualize является установка Docker, так как Selenium браузеры будут быть установленным и развернутым как Docker контейнеров до srvisualize. Примечание: если srvisualize умирает / аварийно завершается, вам придется go убить docker контейнер, который он запустил (если он запустил его) вручную (docker ID должен был быть напечатан на консоли R).

#AUXILIARY FUNCTIONS 1 & 2
#----

#Functions used to find the docker ID
#Courtesy https://stackoverflow.com/a/33384923/9494044
longest_string <- function(s){return(s[which.max(nchar(s))])}

lcsbstr_no_lib <- function(a, b) { 
  
  matches <- gregexpr("M+", drop(attr(adist(a, b, counts = TRUE), "trafos")))[[1]];
  lengths<- attr(matches, 'match.length')
  which_longest <- which.max(lengths)
  index_longest <- matches[which_longest]
  length_longest <- lengths[which_longest]
  longest_cmn_sbstr  <- substring(longest_string(c(a, b)), index_longest , index_longest + length_longest - 1)
  return(longest_cmn_sbstr) 
  
}

#----


#AUXILIARY FUNCTIONS 3 & 4
#----

startseleniumdocker <- function(){
  #Loading a Selenium web browser via docker
  #system("docker pull selenium/standalone-chrome", wait = TRUE)
  #system("docker run -d -p 4445:4444 -p 5901:5900 selenium/standalone-chrome", wait = TRUE)
  cat("Getting Selenium browser docker!\n")
  system("docker pull selenium/standalone-chrome-debug", wait = TRUE)
  Sys.sleep(4)
  cat("Starting docker container!\n")
  mydocker <- system("docker run -d -p 4445:4444 -p 5901:5900 selenium/standalone-chrome-debug", 
                     wait = TRUE, intern = TRUE)
  Sys.sleep(4)
  dockers <- paste0(system("docker ps", wait = TRUE, intern = TRUE), collapse = " ")
  #Storing the docker ID for later--to close the docker container upon function completion
  mydockerid <- lcsbstr_no_lib(dockers, mydocker)
  
  return(mydockerid)
}

stopseleniumdocker <- function(mydockerid){
  
  cat("Closing Selenium browser contained in docker", mydockerid, "\n")
  system(paste0("docker stop ", mydockerid), wait = TRUE, intern = TRUE)
  #Check if docker has been closed properly
  dockers <- paste0(system("docker ps", wait = TRUE, intern = TRUE), collapse = " ")
  if(lcsbstr_no_lib(dockers, mydockerid) != mydockerid) cat("Docker closed succesfully.")
  
}

#----


#MAIN FUNCTION
#----

#Start docker container, fetch + plot data from Stockrow, stop docker container
srvisualize <- function(url = NULL){
  
  require(RSelenium) #For getting HTML data
  require(devtools) #RSelenium dependency
  require(stringi) #RSelenium dependency
  require(jsonlite) #For parsing JSON data
  require(httr) #For getting JSON data
  require(ggplot2) #For plotting
  require(magrittr) #For plotting
  require(stringr)

  
  
  if(is.null(url)) stop("No URL provided!")
  #if(is.null(remDr)) stop("No Selenium remote driver provided!")
  
  #start docker
  mydockid <- startseleniumdocker()
  
  if(!is.null(mydockid)) cat("Selenium browser running from docker container", mydockid, "\nStarting remote driver!\n")
  
  #Starting remote driver
  remDr <- RSelenium::remoteDriver(port=4445L, browserName="chrome")
  Sys.sleep(10)
  #Opening the webpage
  remDr$open()
  
  if(!remDr$getStatus()$ready) stop("Something's wrong with Selenium, please check!")
  
  remDr$navigate(url)
  remDr$getCurrentUrl() #to check where we are
  cat("The current URL is: ", unlist(remDr$getCurrentUrl()), "\n")
  
  
  #Stockrow passes queries from the interactive_chart
  #to an internal API URL: https://stockrow.com/api/fundamentals.json
  #which returns the requested data (as a JSON)
  #There are only two things that define the request uniquely
  #Namely: the chart indicators and the tickers
  
  #So to get the interactive_chart data in R
  #We first need to scrape the chart indicaors
  #and the chart tickers from the webpage
  
  #Once we have these
  #we can reconstruct the request ourselves
  #and pass it to fundamentals.json
  #to get our data
  
  
  #First get the hidden chart indicator string
  webElem <- remDr$findElements(using = "name", value = "indicator-input")
  #chartindicators <- webElem[[1]]$getElementAttribute("value")
  chart_indicators <- unlist(lapply(webElem, function(x){x$getElementAttribute("value")}))
  chart_indicators
  
  #Then get the set of tickers for the plot
  webElem <- remDr$findElements(using = "name", value = "compare-input")
  #charttickers <- unlist(webElem$getElementAttribute("value"))
  chart_tickers <- unlist(lapply(webElem, function(x){x$getElementAttribute("value")}))
  chart_tickers
  
  #Also set the start_date for the data
  chart_start_date <- "1960-01-01T00:00:00.000+01:00"
  
  #Put the indicators, tickers, and a start_date value
  #into a list that will then be converted into a JSON string
  #with jsonlite::toJSON()
  reqargs <- list(indicators = chart_indicators, 
                  tickers = chart_tickers, 
                  start_date = chart_start_date)
  
  #Request URL
  jsonurl <- "https://stockrow.com/api/fundamentals.json"
  
  cat("Fetching data.\n")
  
  #Make the request with httr::POST()
  #Notice the application/json Content-Type specified
  #in the header
  #The JSON string composed earlier is submitted as the body
  #of the request
  chartdat <- httr::POST(jsonurl,
                         httr::add_headers(
                           "Content-Type" = "application/json;charset=utf-8"
                         ),
                         body = jsonlite::toJSON(reqargs)
  )
  
  #Check if the request was successful
  #i.e., status code 200
  if(httr::status_code(chartdat) == 200) cat("Data acquired!\n")
  
  
  #Get the contents
  chartdat <- httr::content(chartdat, as = "text")
  chartdat <- jsonlite::fromJSON(chartdat) 
  
  #Writing the data to a data.frame for plotting
  dat <- data.frame(name = c(), date = c(), value = c())
  
  for(i in 1:length(chartdat$series$name)){
    #i <- 1
    curdat <- as.data.frame(chartdat$series$data[i])
    names(curdat) <- c("date", "value")
    curdat$series <- rep_len(chartdat$series$name[i], nrow(curdat))
    #For some reason, the dates are off by 10 years.
    #So the chart_start_date value can't be used directly
    #to parse the datetime data in milliseconds to date-time
    #So a custom value is used here
    curdat$date <- as.POSIXct(curdat$date/1000, origin = "1969-12-31T00:00:00.000+01:00")
    
    dat <- rbind(dat, curdat)
    
  }
  
  
  
  #Plotting the data
  cat("Plotting data!\n")
  
  plotdat <- dat %>% 
    ggplot(aes(x = date, y = value/10^12, color = series)) + 
    geom_line() + 
    xlab("Date") + 
    ylab("Cash (trillion USD)")
  
  print(plotdat)
  cat("Done!\n")
  
  stopseleniumdocker(mydockid)
  
  
  return(list(dat, plotdat, mydockid))
  
}

#----

Вот несколько примеров работы функции:

С вашим URL:

url1 <- "https://stockrow.com/interactive_chart/54e53957-2723-4e78-8b73-1b922e9d3300"
url1_dat <- srvisualize(url = url1)

RPlot1

URL with two tickers:

url2 

RPlot2

URL with two indicators and two tickers:

url3 

RPlot3

One more example URL with random tickers and random indicators:

url4 

RPlot4

Конечно, здесь можно сделать гораздо больше, чтобы улучшить и улучшить функциональность и удобство использования srvisualize, но это только начало.

0 голосов
/ 20 июня 2020

Согласно сообществу stockrow, нет доступного API :

Привет, мы в настоящее время не предлагаем никаких API, поскольку наш поставщик данных не позволяет это. Если вас интересуют API фундаментальных данных, проверьте базу данных Sharadar SF1 на Quandl, она доступна по очень разумной цене.

Если мы последуем предложению в комментарии и посетим веб-сайт Quandl, мы увидим, что они предлагают специальный пакет R для их API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...