Two TWSE-listed common stocks (no ETFs, funds or
preferred shares), one row each from the TWSE ISIN register
(strMode = 2). The ISIN site was returning HTTP 404, so the
rows come from the ISIN data mirrored in the twstock
package.
isin <- read.csv(text = r"-(stock_id,stock_name,listing_date,industry,isin
2317,鴻海,1991-06-18,其他電子業,TW0002317005
2330,台積電,1994-09-05,半導體業,TW0002330008)-",
colClasses = "character", encoding = "UTF-8") %>%
mutate(listing_date = as.Date(listing_date),
label = paste0(stock_id, " ", c("Hon Hai", "TSMC")))
knitr::kable(isin %>% select(stock_id, stock_name, listing_date, industry, isin))
| stock_id | stock_name | listing_date | industry | isin |
|---|---|---|---|---|
| 2317 | 鴻海 | 1991-06-18 | 其他電子業 | TW0002317005 |
| 2330 | 台積電 | 1994-09-05 | 半導體業 | TW0002330008 |
isin %>%
mutate(years_listed = as.numeric(Sys.Date() - listing_date) / 365.25) %>%
ggplot(aes(label, years_listed, fill = label)) +
geom_col(width = 0.5, show.legend = FALSE) +
geom_text(aes(label = paste0(round(years_listed, 1), " yrs\n(", format(listing_date, "%Y-%m-%d"), ")")),
vjust = -0.3) +
scale_fill_manual(values = c("#c0392b", "#1f4e79")) +
scale_y_continuous(expand = expansion(mult = c(0, 0.2))) +
labs(title = "How long each company has been listed on the TWSE",
x = NULL, y = "Years since listing") +
theme_minimal(base_size = 13)
Daily closing prices pulled live from FinMind
(TaiwanStockPrice), rebased to 100 at the start so the two
companies can be compared. A free token avoids rate limits:
Sys.setenv(FINMIND_TOKEN = "your_token").
get_px <- function(id) {
q <- list(dataset = "TaiwanStockPrice", data_id = id,
start_date = format(Sys.Date() - 365 * 3, "%Y-%m-%d"))
tok <- Sys.getenv("FINMIND_TOKEN"); if (nzchar(tok)) q$token <- tok
r <- tryCatch(GET("https://api.finmindtrade.com/api/v4/data", query = q, timeout(60)),
error = function(e) NULL)
if (is.null(r) || status_code(r) != 200) return(NULL)
d <- fromJSON(content(r, "text", encoding = "UTF-8"))$data
if (is.null(d) || !nrow(d)) return(NULL)
d %>% transmute(stock_id = id, date = as.Date(date), close)
}
px <- bind_rows(lapply(isin$stock_id, get_px))
if (nrow(px) == 0) {
cat("FinMind price data unavailable right now. Re-knit with a token or later.")
} else {
px <- px %>% left_join(isin %>% select(stock_id, label), by = "stock_id") %>%
group_by(label) %>% arrange(date) %>% mutate(index = close / first(close) * 100) %>% ungroup()
ggplot(px, aes(date, index, colour = label)) +
geom_line(linewidth = 0.9) +
geom_hline(yintercept = 100, linetype = "dashed", colour = "grey50") +
scale_colour_manual(values = c("#c0392b", "#1f4e79")) +
labs(title = "Closing price, rebased to 100 (last 3 years)", x = NULL, y = "Index (start = 100)",
colour = NULL, caption = "Source: FinMind TaiwanStockPrice") +
theme_minimal(base_size = 13) + theme(legend.position = "top")
}
Sources: TWSE ISIN register (via twstock 1.5.1),
FinMind API v4.