Comparación de paquetes R para obtener datos bursátiles: quantmod, tidyquant, pedquant

El mundo financiero está lleno de datos, desde precios de activos (acciones, divisas, derivados, criptomonedas) hasta información contable de empresas y estadísticas económicas. Obtener datos de calidad suele ser costoso, pero para el aprendizaje o la investigación personal existen alternativas gratuitas en R. En este artículo se comparan tres paquetes populares (quantmod, tidyquant y pedquant) para descargar datos históricos de acciones, complementados con las API de las plataformas Tushare y JoinQuant, y se discute la calidad de los datos.

1. Uso de paquetes R para obtener datos

(1) quantmod

quantmod es una herramienta clásica. La función getSymbols() obtiene datos de múltiples fuentes. A continuación se descargan datos de la acción de China Merchants Bank (código 600036.SS) desde Yahoo Finance:

library(quantmod)
cmb_quant <- getSymbols("600036.ss", src = "yahoo",
                        from = "2019-01-01", to = "2020-09-30",
                        auto.assign = FALSE)
head(cmb_quant, 3)
# Resultado: columnas Open, High, Low, Close, Volume, Adjusted

(2) tidyquant

tidyquant envuelve quantmod en un formato tidyverse (tibble).

library(tidyquant)
cmb_tq <- tq_get("600036.ss", get = "stock.prices",
                 from = "2019-01-01", to = "2020-09-30")
head(cmb_tq, 3)
# Resultado: tibble con symbol, date, open, high, low, close, volume, adjusted

(3) pedquant

Para el mercado chino, pedquant es una alternativa más fiable. Usa md_stock() con fuente de NetEase (163):

library(pedquant)
cmb_pd <- md_stock("600036.ss", from = "2019-01-01", to = "2020-09-30",
                   source = "163", adjust = NULL)
cmb_pd_tidy <- cmb_pd[[1]] %>% 
  as_tibble() %>%
  select(symbol, date, open, high, low, close, volume)
head(cmb_pd_tidy, 3)

Con adjust = "dividend" se obtienen precios ajustados por split y dividendos (forward adjustment).

2. Datos a través de plataformas de trading cuantitativo

(1) Tushare

Requiere registro y token. Se usa el paquete Tushare:

library(Tushare)
bar <- Tpro_bar(token = "tu_token")
cmb_ts <- bar(ts_code = "600036.SH", start_date = "20190101",
              end_date = "20200930")
head(cmb_ts, 3)
# Columnas: ts_code, trade_date, open, high, low, close, pre_close, change, pct_chg, vol, amount

Para precios ajustados forward se añade adj = "qfq".

(2) JoinQuant (聚宽)

Proporciona una función request personalizada. Ejemplo:

request <- function(method, ...) {
  # ... (código de autenticación y llamada)
}
cmb_jq <- request("get_price", code = "600036.XSHG", count = 427,
                  unit = "1d", end_date = "2020-09-30")
head(cmb_jq, 3)
# Columnas: date, open, close, high, low, volume, money, ...

Para ajuste forward, se añade fq_ref_date = "2020-09-30".

3. Problemas de calidad de los datos

Al comparar los datos obtenidos se observan diferencias notables.

  • quantmod/tidyquant: devuelven 425 filas en lugar de 427, faltando los días 2019-04-29 y 2019-04-30.
  • Ajuste forward (前复权): Los datos de pedquant difieren sistemáticamente de los de Tushare/JoinQuant. pedquant aplica una resta simple del dividendo al precio anterior, mientras que Tushare/JoinQuant usan factores de ajuste que preservan los rendimientos reales. Por ejemplo, en el periodo 2019-07-12 a 2020-07-09:
# Verificación del método de pedquant
precio_original <- cmb_pd[[1]] %>% filter(date >= "2019-07-12", date <= "2020-07-09")
precio_ajustado_pd <- md_stock("600036.ss", ..., adjust = "dividend")[[1]] %>%
  filter(date >= "2019-07-12", date <= "2020-07-09")
head(precio_original$close - 1.2, 3)  # igual a precio_ajustado_pd$close
# Pero los rendimientos diarios no se preservan

Usando un bucle iterativo para preservar los rendimientos se obtienen valores equivalentes a los de JoinQuant:

n <- nrow(precio_original)
adj_close <- numeric(n)
adj_close[n] <- precio_original$close[n] - 1.2
for (i in (n-1):1) {
  adj_close[i] <- adj_close[i+1] / (1 + 0.01 * precio_original$change_pct[i+1])
}
head(adj_close)  # coincide con JoinQuant

4. Ejemplos de web scraping

R dispone de potentes herramientas para extraer datos financieros directamente de la web.

(1) Datos intradiarios (k-line de minutos)

Usando la API de Sina:

library(jsonlite)
url <- "http://money.finance.sina.com.cn/quotes_service/api/json_v2.php/CN_MarketData.getKLineData?symbol=sh600036&scale=60&ma=no&datalen=500"
stock_json <- read_json(url)
stock_tbl <- bind_rows(stock_json)
stock_tbl[,2:6] <- apply(stock_tbl[,2:6], 2, as.numeric)
head(stock_tbl)
# Columnas: day, open, high, low, close, volume, ma_price5, ma_volume5

(2) Transacciones históricas detalladas

NetEase proporciona archivos xls:

url_xls <- "http://quotes.money.163.com/cjmx/2020/20200929/0600036.xls"
download.file(url_xls, destfile = "600036_20200929.xls")

Estos métodos ofrecen una base sólida para el análisis cuantitativo en R, aunque es crucial compredner las diferencias en los algoritmos de ajuste de precios para evitar conclusiones erróneas.

Etiquetas: R quantmod tidyquant pedquant Tushare

Publicado el 7-2 16:21