Grupo 06:
En este taller aprenderás a crear un reporte reproducible con R Markdown (RStudio) analizando el comportamiento de Bitcoin (BTC) usando datos reales de Yahoo Finance. install.packages(c(“lubridate”, “rlang”, “vctrs”, “timechange”)) library(lubridate) Construiremos:
Requisito: conexión a internet (Yahoo Finance).
Usaremos el ticker: BTC-USD (Bitcoin en USD) desde Yahoo Finance.
# ============================================================
# DESCARGA BTC-USD DESDE YAHOO FINANCE
# - from: fecha inicial de descarga
# - auto.assign = FALSE: devuelve el objeto en lugar de guardarlo en el environment
# ============================================================
ticker <- "BTC-USD"
fecha_inicio <- as.Date("2023-01-01")
# Descarga (puede demorar unos segundos según conexión)
btc_xts <- quantmod::getSymbols(
Symbols = ticker,
src = "yahoo",
from = fecha_inicio,
auto.assign = FALSE
)
# Validación rápida: debe tener filas
stopifnot(NROW(btc_xts) > 0)
# Convertimos a tibble limpio
btc <- btc_xts |>
as.data.frame() |>
rownames_to_column("date") |>
as_tibble() |>
rename(
open = paste0(ticker, ".Open"),
high = paste0(ticker, ".High"),
low = paste0(ticker, ".Low"),
close = paste0(ticker, ".Close"),
volume = paste0(ticker, ".Volume"),
adjusted = paste0(ticker, ".Adjusted")
) |>
mutate(date = as.Date(date)) |>
arrange(date)
# Vista rápida
glimpse(btc)## Rows: 1,086
## Columns: 7
## $ date <date> 2023-01-01, 2023-01-02, 2023-01-03, 2023-01-04, 2023-01-05, …
## $ open <dbl> 16547.91, 16625.51, 16688.85, 16680.21, 16863.47, 16836.47, 1…
## $ high <dbl> 16630.44, 16759.34, 16760.45, 16964.59, 16884.02, 16991.99, 1…
## $ low <dbl> 16521.23, 16572.23, 16622.37, 16667.76, 16790.28, 16716.42, 1…
## $ close <dbl> 16625.08, 16688.47, 16679.86, 16863.24, 16836.74, 16951.97, 1…
## $ volume <dbl> 9244361700, 12097775227, 13903079207, 18421743322, 1369275856…
## $ adjusted <dbl> 16625.08, 16688.47, 16679.86, 16863.24, 16836.74, 16951.97, 1…
## # A tibble: 5 × 7
## date open high low close volume adjusted
## <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2023-01-01 16548. 16630. 16521. 16625. 9244361700 16625.
## 2 2023-01-02 16626. 16759. 16572. 16688. 12097775227 16688.
## 3 2023-01-03 16689. 16760. 16622. 16680. 13903079207 16680.
## 4 2023-01-04 16680. 16965. 16668. 16863. 18421743322 16863.
## 5 2023-01-05 16863. 16884. 16790. 16837. 13692758566 16837.
## # A tibble: 5 × 7
## date open high low close volume adjusted
## <date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2025-12-17 87848. 90265. 85316. 86144. 44243392914 86144.
## 2 2025-12-18 86144. 89413. 84436. 85463. 52667115348 85463.
## 3 2025-12-19 85476. 89339. 85108. 88103. 46733310561 88103.
## 4 2025-12-20 88102. 88497. 87925. 88344 14688196659 88344
## 5 2025-12-21 88340. 89011. 87666. 88297. 18405640192 88297.
# ============================================================
# VALIDACIONES
# ============================================================
# 1) Tipos
stopifnot(inherits(btc$date, "Date"))
# 2) Orden cronológico
stopifnot(isTRUE(all(diff(btc$date) >= 0)))
# 3) Duplicados de fecha (por si acaso)
btc <- btc |> distinct(date, .keep_all = TRUE)
# Rango de fechas y tamaño
min(btc$date)## [1] "2023-01-01"
## [1] "2025-12-21"
## [1] 1086
Retorno simple:
\[ r_t = \frac{P_t}{P_{t-1}} - 1 \]
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## -0.0868204 -0.0103730 0.0002861 0.0018389 0.0130973 0.1214426 1
KPIs rápidos (inline R):
ggplot(btc, aes(x = date)) +
geom_line(aes(y = close)) +
geom_line(aes(y = ma_7), linetype = "dashed") +
geom_line(aes(y = ma_30), linetype = "dotted") +
geom_line(aes(y = ma_90), linetype = "dotted") +
scale_y_continuous(labels = scales::comma) +
labs(
title = "Bitcoin (BTC-USD): Precio de cierre y promedios móviles",
subtitle = "MA 7 días (dashed), MA 30 días (dotted) y MA 90 días (dotted) - Fuente: Yahoo Finance",
x = "Fecha",
y = "Precio (USD)"
)ggplot(btc, aes(x = date, y = return)) +
geom_line() +
scale_y_continuous(labels = scales::percent_format(accuracy = 0.1)) +
labs(
title = "Bitcoin (BTC-USD): Retornos diarios",
subtitle = "Los picos reflejan días de movimientos bruscos",
x = "Fecha",
y = "Retorno diario"
)ggplot(btc, aes(x = date, y = vol_30)) +
geom_line() +
scale_y_continuous(labels = scales::percent_format(accuracy = 0.1)) +
labs(
title = "Bitcoin (BTC-USD): Volatilidad rolling 30 días",
subtitle = "Desv. estándar de retornos diarios (ventana móvil de 30 días)",
x = "Fecha",
y = "Volatilidad (sd)"
)Resumimos por mes:
close_fin: último precio del mesret_prom: retorno promedio diario del mes (aprox.)vol: volatilidad (sd) de retornos diarios del mesbtc_mensual <- btc |>
mutate(year_month = floor_date(date, unit = "month")) |>
group_by(year_month) |>
summarise(
n_dias = sum(!is.na(return)),
close_fin = last(close),
ret_prom = mean(return, na.rm = TRUE),
vol = sd(return, na.rm = TRUE),
.groups = "drop"
) |>
mutate(
close_fin = round(close_fin, 2),
ret_prom = round(ret_prom, 6),
vol = round(vol, 6)
)
kable(btc_mensual, caption = "Resumen mensual de BTC (Fuente: Yahoo Finance)")| year_month | n_dias | close_fin | ret_prom | vol |
|---|---|---|---|---|
| 2023-01-01 | 30 | 23139.28 | 0.011348 | 0.023726 |
| 2023-02-01 | 28 | 23147.35 | 0.000334 | 0.026163 |
| 2023-03-01 | 31 | 28478.48 | 0.007327 | 0.036150 |
| 2023-04-01 | 30 | 29268.81 | 0.001116 | 0.020467 |
| 2023-05-01 | 31 | 27219.66 | -0.002184 | 0.017867 |
| 2023-06-01 | 30 | 30477.25 | 0.004076 | 0.025073 |
| 2023-07-01 | 31 | 29230.11 | -0.001264 | 0.013072 |
| 2023-08-01 | 31 | 25931.47 | -0.003634 | 0.021277 |
| 2023-09-01 | 30 | 26967.92 | 0.001373 | 0.011710 |
| 2023-10-01 | 31 | 34667.78 | 0.008395 | 0.023681 |
| 2023-11-01 | 30 | 37712.75 | 0.003048 | 0.022270 |
| 2023-12-01 | 31 | 42265.19 | 0.003947 | 0.023371 |
| 2024-01-01 | 31 | 42582.61 | 0.000643 | 0.028747 |
| 2024-02-01 | 29 | 61198.38 | 0.012872 | 0.024830 |
| 2024-03-01 | 31 | 71333.65 | 0.005697 | 0.039216 |
| 2024-04-01 | 30 | 60636.86 | -0.005020 | 0.027916 |
| 2024-05-01 | 31 | 67491.41 | 0.003850 | 0.028702 |
| 2024-06-01 | 30 | 62678.29 | -0.002321 | 0.017098 |
| 2024-07-01 | 31 | 64619.25 | 0.001281 | 0.024803 |
| 2024-08-01 | 31 | 58969.90 | -0.002305 | 0.036792 |
| 2024-09-01 | 30 | 63329.50 | 0.002624 | 0.022475 |
| 2024-10-01 | 31 | 70215.19 | 0.003539 | 0.020570 |
| 2024-11-01 | 30 | 96449.05 | 0.011132 | 0.032485 |
| 2024-12-01 | 31 | 93429.20 | -0.000760 | 0.023394 |
| 2025-01-01 | 31 | 102405.02 | 0.003217 | 0.022896 |
| 2025-02-01 | 28 | 84373.01 | -0.006695 | 0.020156 |
| 2025-03-01 | 31 | 82548.91 | -0.000102 | 0.035319 |
| 2025-04-01 | 30 | 94207.31 | 0.004815 | 0.029011 |
| 2025-05-01 | 31 | 104638.09 | 0.003563 | 0.018852 |
| 2025-06-01 | 30 | 107135.34 | 0.000921 | 0.016752 |
| 2025-07-01 | 31 | 115758.20 | 0.002593 | 0.013885 |
| 2025-08-01 | 31 | 108236.71 | -0.001995 | 0.018706 |
| 2025-09-01 | 30 | 114056.09 | 0.001826 | 0.012734 |
| 2025-10-01 | 31 | 109556.16 | -0.001050 | 0.022486 |
| 2025-11-01 | 30 | 90394.31 | -0.006121 | 0.023348 |
| 2025-12-01 | 21 | 88297.14 | -0.000855 | 0.023515 |
fecha_inicio a "2023-01-01"ma_90)close, ma_30,
ma_90Obtén:
y muéstralos en el reporte.
top_pos <- btc |>
filter(!is.na(return)) |>
arrange(desc(return)) |>
select(date, close, return) |>
head(10)
top_neg <- btc |>
filter(!is.na(return)) |>
arrange(return) |>
select(date, close, return) |>
head(10)
kable(top_pos, caption = "Top 10 retornos positivos (BTC-USD)")| date | close | return |
|---|---|---|
| 2024-08-08 | 61710.14 | 0.1214426 |
| 2023-10-23 | 33086.23 | 0.1030989 |
| 2024-11-11 | 88701.48 | 0.1022352 |
| 2024-03-20 | 67913.67 | 0.0969250 |
| 2025-03-02 | 94248.35 | 0.0955045 |
| 2024-02-28 | 62504.79 | 0.0949353 |
| 2023-03-17 | 27423.93 | 0.0946458 |
| 2023-02-15 | 24307.84 | 0.0939227 |
| 2023-03-13 | 24197.53 | 0.0917519 |
| 2024-11-06 | 75639.08 | 0.0905357 |
| date | close | return |
|---|---|---|
| 2025-03-03 | 86065.67 | -0.0868204 |
| 2024-03-19 | 61912.77 | -0.0834336 |
| 2024-01-12 | 42853.17 | -0.0758146 |
| 2024-08-05 | 53991.46 | -0.0709865 |
| 2023-08-17 | 26664.55 | -0.0709792 |
| 2025-10-10 | 113214.37 | -0.0697685 |
| 2024-03-05 | 63801.20 | -0.0662840 |
| 2025-03-09 | 80601.04 | -0.0644603 |
| 2025-04-06 | 78214.48 | -0.0633534 |
| 2023-03-09 | 20363.02 | -0.0623931 |
vol_30).## R version 4.5.2 (2025-10-31 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 10 x64 (build 19044)
##
## Matrix products: default
## LAPACK version 3.12.1
##
## locale:
## [1] LC_COLLATE=Spanish_Peru.utf8 LC_CTYPE=Spanish_Peru.utf8
## [3] LC_MONETARY=Spanish_Peru.utf8 LC_NUMERIC=C
## [5] LC_TIME=Spanish_Peru.utf8
##
## time zone: America/Lima
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] scales_1.4.0 tibble_3.3.0 knitr_1.51 lubridate_1.9.4
## [5] ggplot2_4.0.1 dplyr_1.1.4 quantmod_0.4.28 TTR_0.24.4
## [9] xts_0.14.1 zoo_1.8-15
##
## loaded via a namespace (and not attached):
## [1] gtable_0.3.6 jsonlite_2.0.0 compiler_4.5.2 tidyselect_1.2.1
## [5] jquerylib_0.1.4 yaml_2.3.12 fastmap_1.2.0 lattice_0.22-7
## [9] R6_2.6.1 labeling_0.4.3 generics_0.1.4 curl_7.0.0
## [13] bslib_0.9.0 pillar_1.11.1 RColorBrewer_1.1-3 rlang_1.1.6
## [17] cachem_1.1.0 xfun_0.55 sass_0.4.10 S7_0.2.1
## [21] timechange_0.3.0 cli_3.6.5 withr_3.0.2 magrittr_2.0.4
## [25] digest_0.6.39 grid_4.5.2 rstudioapi_0.17.1 lifecycle_1.0.4
## [29] vctrs_0.6.5 evaluate_1.0.5 glue_1.8.0 farver_2.1.2
## [33] rmarkdown_2.30 tools_4.5.2 pkgconfig_2.0.3 htmltools_0.5.9
Yahoo Finance puede cambiar disponibilidad o límites. Si falla la descarga: