Activo elegido: Exxon Mobil Corporation (XOM), accion negociada en la Bolsa de Nueva York (NYSE), en dolares estadounidenses.
Pregunta de investigacion: ¿Un modelo de series de tiempo nos ayuda a decidir si conviene comprar acciones de XOM durante los proximos tres meses?
Muestra: de 31/01/2015 a 30/09/2026, con 141 observaciones mensuales.
Capital disponible: USD 100,000. Horizonte de cada inversion: 3 meses.
Resultado principal: el modelo seleccionado con la muestra de entrenamiento fue SARIMAX_110_100. Desde la fecha de corte 30/09/2023, la regla lleva a MANTENER EFECTIVO porque el rendimiento previsto a tres meses es -2.04%. Esto es una decision basada en un pronostico, no una rentabilidad asegurada.
Exxon Mobil es una empresa energetica con negocios relacionados con petroleo, gas y productos derivados. Se eligio XOM porque tiene precios historicos disponibles y su actividad esta relacionada economicamente con el mercado del crudo. Cotiza como XOM en la NYSE (Exxon Mobil, 2026).
Utilizamos el cierre ajustado de XOM de Yahoo Finance (quantmod) y el precio mensual del crudo WTI de FRED (serie MCOILWTICO, suministrada por EIA). Los precios de la accion representan USD por accion; el WTI se mide en USD por barril. Si se utiliza cierre ajustado, el precio incorpora ajustes reportados por el proveedor; si se utiliza cierre sin ajustar, pueden no estar reflejados los dividendos y otros eventos (Yahoo Finance, s. f.; EIA, s. f.).
Tres hechos economicos para interpretar la muestra:
Estos hechos sirven para dar contexto, pero por si solos no prueban que causaron cada cambio en la cotizacion de XOM.
Hipotesis y regla fijadas antes de observar test: compraremos XOM solo si el modelo pronostica una apreciacion superior al 1% en tres meses. Si no supera 1%, dejaremos los USD 100,000 en efectivo. Se supone efectivo con rendimiento 0%, sin comisiones ni impuestos. Compararemos esta regla con comprar y mantener XOM y con conservar efectivo.
Se usa frecuencia mensual para reducir ruido de los cambios diarios y tener un ejercicio manejable. En XOM se toma el ultimo cierre ajustado disponible de cada mes. En WTI se utiliza el precio promedio mensual publicado por FRED; no son exactamente la misma forma de agregacion y esa es una limitacion.
knitr::kable(head(base,8), digits=2, caption="Primeras observaciones de la muestra")
| fecha | precio | wti |
|---|---|---|
| 2015-01-31 | 53.47 | 47.22 |
| 2015-02-28 | 54.56 | 50.58 |
| 2015-03-31 | 52.38 | 47.82 |
| 2015-04-30 | 53.84 | 54.45 |
| 2015-05-31 | 52.94 | 59.27 |
| 2015-06-30 | 51.69 | 59.82 |
| 2015-07-31 | 49.22 | 50.90 |
| 2015-08-31 | 47.19 | 42.87 |
cat("Observaciones:",n_total,"\n")
## Observaciones: 141
cat("Faltantes en base final:",sum(!stats::complete.cases(base)),"\n")
## Faltantes en base final: 0
cat("Meses duplicados:",anyDuplicated(base$fecha),"\n")
## Meses duplicados: 0
ggplot2::ggplot(base,ggplot2::aes(x=fecha,y=precio))+
ggplot2::geom_line(color="steelblue", linewidth=0.7)+
ggplot2::labs(title=paste("XOM:", tipo_precio, "mensual"),x="Fecha",y="USD por accion")+
ggplot2::theme_minimal()
base$retorno_pct <- c(NA,100*diff(log(base$precio)))
ggplot2::ggplot(base,ggplot2::aes(x=fecha,y=retorno_pct))+
ggplot2::geom_col(fill="gray40")+
ggplot2::labs(title="Rendimientos logaritmicos mensuales de XOM",
x="Fecha",y="% mensual")+ggplot2::theme_minimal()
r <- diff(log(base$precio))
estadisticas <- data.frame(
estadistico=c("Promedio precio (USD)","Mediana precio (USD)",
"Precio minimo (USD)","Precio maximo (USD)",
"Retorno mensual promedio (%)", "Volatilidad mensual (%)",
"Volatilidad anual aproximada (%)"),
valor=c(mean(base$precio),median(base$precio),min(base$precio),max(base$precio),
100*mean(r),100*sd(r),100*sd(r)*sqrt(12)))
knitr::kable(estadisticas, digits=2)
| estadistico | valor |
|---|---|
| Promedio precio (USD) | 73.02 |
| Mediana precio (USD) | 56.58 |
| Precio minimo (USD) | 25.52 |
| Precio maximo (USD) | 167.43 |
| Retorno mensual promedio (%) | 0.80 |
| Volatilidad mensual (%) | 7.67 |
| Volatilidad anual aproximada (%) | 26.57 |
Interpretacion basica: los precios presentan variaciones con el tiempo. La volatilidad mensual de los rendimientos es aproximadamente 7.67%. En meses con movimientos grandes aumenta la incertidumbre de una inversion. Es importante recordar que el valor pasado no determina el valor futuro.
Transformacion Box-Cox. Evaluamos lambda solo con train. Por claridad economica usamos el logaritmo natural del precio: sus diferencias se parecen a rendimientos.
lambda_estimado <- forecast::BoxCox.lambda(stats::ts(train$precio, frequency=12), method="guerrero")
cat("Lambda Box-Cox estimada en train:",round(lambda_estimado,3),"\n")
## Lambda Box-Cox estimada en train: 1.044
cat("Transformacion elegida: log(precio), equivalente a lambda = 0.\n")
## Transformacion elegida: log(precio), equivalente a lambda = 0.
Interpretacion: una lambda proxima a cero apoya usar logaritmos. Si la lambda observada no se aproxima a cero, mantenemos el logaritmo por comparabilidad de rendimientos e indicamos que no es necesariamente la transformacion optima bajo el criterio Box-Cox.
AR y MA. Un AR(1) usa la observacion anterior: \(y_t=c+\phi_1 y_{t-1}+\varepsilon_t\). Un MA(1) usa el error anterior: \(y_t=c+\varepsilon_t+\theta_1\varepsilon_{t-1}\).
Operador rezago y diferenciacion. Si \(Ly_t=y_{t-1}\), entonces \((1-L)y_t=y_t-y_{t-1}\). Cuando la serie presenta tendencia, diferenciarla ayuda a trabajar con cambios en lugar de niveles. Para \(d\) diferencias se escribe \((1-L)^dy_t\). Aquí \(y_t=\log(P_t)\), y \(\Delta y_t\) aproxima el rendimiento mensual.
ARIMA(p,d,q). Combinando los componentes anteriores:
\[\underbrace{(1-\phi_1 L-\cdots-\phi_pL^p)}_{AR(p)}(1-L)^d y_t = c+\underbrace{(1+\theta_1L+\cdots+\theta_qL^q)}_{MA(q)}\varepsilon_t.\]
ARIMAX. Incluye una variable externa \(X_t\), en este caso \(\log(WTI_t)\):
\[\phi(L)(1-L)^d[y_t-\beta X_t]=\theta(L)\varepsilon_t.\]
\(\beta\) representa una relacion estadistica condicional, no una prueba de causalidad. Con \(d=1\), se modelan diferencias logaritmicas tanto del precio de XOM como de la variable externa. El WTI puede ayudar porque el mercado de petroleo esta relacionado con el negocio de XOM. Para proyectar ARIMAX tambien necesitamos predecir el WTI, ya que no conocemos su valor futuro.
SARIMAX. Añade patrones estacionales con periodo \(s=12\) para datos mensuales:
\[\Phi(L^{12})\phi(L)(1-L)^d(1-L^{12})^D[y_t-\beta X_t]=\Theta(L^{12})\theta(L)\varepsilon_t.\]
\((p,d,q)(P,D,Q)_{12}\) diferencia la dinamica habitual de la estacional. No se da por hecho que haya estacionalidad: se revisan graficos y ACF/PACF y se estima un candidato estacional para compararlo.
ARCH/GARCH. Si la variabilidad de los errores cambia con el tiempo, se puede trabajar con una varianza condicional:
\[\varepsilon_t=\sigma_t z_t,\qquad \sigma_t^2=\omega+\alpha\varepsilon_{t-1}^2+\beta\sigma_{t-1}^2.\]
En GARCH(1,1), \(\omega>0\), \(\alpha\geq 0\), \(\beta\geq 0\) y, para varianza incondicional finita, usualmente \(\alpha+\beta<1\). Este trabajo se concentra en pronosticar el precio con ARIMA/ARIMAX/SARIMAX; GARCH se plantea como posible extension si aparece heterocedasticidad.
Dividimos la base cronologicamente en 75% train y 25% test. Esto deja 105 meses para estimar los modelos y 36 meses para comprobarlos. La fecha de corte \(T_0\) es 30/09/2023. Ningun dato de test se utiliza para escoger o calibrar el modelo inicial.
knitr::kable(data.frame(conjunto=c("Train","Test"),
inicio=c(as.character(min(train$fecha)),as.character(min(test$fecha))),
final=c(as.character(max(train$fecha)),as.character(max(test$fecha))),
meses=c(n_train,n_test)))
| conjunto | inicio | final | meses |
|---|---|---|---|
| Train | 2015-01-31 | 2023-09-30 | 105 |
| Test | 2023-10-31 | 2026-09-30 | 36 |
Pruebas de estacionariedad: ADF contrasta raiz unitaria (hipotesis nula: no estacionaria). KPSS contrasta estacionariedad (hipotesis nula: estacionaria). Se miran ambas, no solamente una.
pruebas <- data.frame(serie=c("Log-precio","Diferencia de log-precio"),
p_ADF=c(tseries::adf.test(y_train)$p.value,
tseries::adf.test(diff(y_train))$p.value),
p_KPSS=c(tseries::kpss.test(y_train, null="Level")$p.value,
tseries::kpss.test(diff(y_train),null="Level")$p.value))
knitr::kable(pruebas,digits=4)
| serie | p_ADF | p_KPSS |
|---|---|---|
| Log-precio | 0.9407 | 0.0425 |
| Diferencia de log-precio | 0.0100 | 0.1000 |
Interpretacion: en ADF, un valor p menor que 0.05 favorece rechazar la raiz unitaria; en KPSS, un valor p mayor que 0.05 es compatible con estacionariedad. Por eso probamos ARIMA con \(d=1\). Si los resultados discrepan, es una señal de cautela, no una prueba absoluta.
par(mfrow=c(2,2))
acf(y_train, main="ACF del log-precio",lag.max=24)
pacf(y_train,main="PACF del log-precio",lag.max=24)
acf(diff(y_train),main="ACF del log-retorno",lag.max=24)
pacf(diff(y_train),main="PACF del log-retorno",lag.max=24)
par(mfrow=c(1,1))
Lectura sencilla de ACF/PACF: si aparecen barras fuera de las bandas de referencia, puede existir dependencia en ciertos rezagos. Por eso se prueban manualmente ordenes AR(1), MA(1), ARMA(1,1), versiones con WTI y alternativas estacionales. El periodo 12 se evalua como posibilidad, no se impone como resultado confirmado.
mostrar <- tabla_modelos
mostrar$AICc <- round(mostrar$AICc,2)
mostrar$BIC <- round(mostrar$BIC,2)
mostrar$p_Ljung_Box <- round(mostrar$p_Ljung_Box,4)
knitr::kable(mostrar, caption="Modelos candidatos estimados solo con train")
| modelo | AICc | BIC | parametros | p_Ljung_Box | residuos_compatibles | |
|---|---|---|---|---|---|---|
| ARIMAX_011 | ARIMAX_011 | -231.83 | -221.66 | 3 | 0.0179 | FALSE |
| SARIMAX_110_100 | SARIMAX_110_100 | -231.71 | -219.10 | 4 | 0.0716 | TRUE |
| ARIMAX_110 | ARIMAX_110 | -231.63 | -221.45 | 3 | 0.0104 | FALSE |
| ARIMA_010 | ARIMA_010 | -223.85 | -218.68 | 1 | 0.4855 | TRUE |
| ARIMA_011 | ARIMA_011 | -221.76 | -214.07 | 2 | 0.4317 | TRUE |
| ARIMA_110 | ARIMA_110 | -221.76 | -214.07 | 2 | 0.4297 | TRUE |
| ARIMA_111 | ARIMA_111 | -219.61 | -209.44 | 3 | 0.3711 | TRUE |
| SARIMA_011_011 | SARIMA_011_011 | -166.19 | -158.90 | 2 | 0.2548 | TRUE |
Eleccion: se considero el AICc (menor es mejor), el BIC, cuantos parametros se utilizan y si el test de Ljung-Box deja residuos sin autocorrelacion notable. Primero se prefieren modelos con p de Ljung-Box mayor a 0.05 y, entre ellos, el de menor AICc. El resultado fue SARIMAX_110_100. Esta regla fue fijada antes de comprobar los pronosticos en test.
coeficientes <- modelo_final$coef
se_coef <- sqrt(diag(modelo_final$var.coef))
tabla_coef <- data.frame(parametro=names(coeficientes),
estimacion=as.numeric(coeficientes),
error_estandar=as.numeric(se_coef),
p_aprox=2*stats::pnorm(-abs(as.numeric(coeficientes)/se_coef)))
knitr::kable(tabla_coef, digits=4, caption="Coeficientes del modelo elegido")
| parametro | estimacion | error_estandar | p_aprox | |
|---|---|---|---|---|
| ar1 | ar1 | -0.1504 | 0.0995 | 0.1308 |
| sar1 | sar1 | -0.1501 | 0.0983 | 0.1269 |
| drift | drift | 0.0051 | 0.0057 | 0.3742 |
| logWTI | logWTI | 0.2103 | 0.0574 | 0.0003 |
Interpretacion: los coeficientes muestran como se relacionan los cambios recientes, los errores pasados y, si aplica, el WTI con el precio de XOM. Un valor p pequeno puede indicar evidencia estadistica, pero no convierte la relacion en causalidad economica.
Los residuos son la parte que el modelo no logro explicar. Idealmente no deben mostrar un patron temporal claro ni una autocorrelacion importante.
par(mfrow=c(2,2))
plot(res_final,type="l",main="Residuos del modelo",xlab="Mes (train)",ylab="Error")
acf(res_final,main="ACF de residuos",lag.max=24)
hist(res_final,main="Histograma",xlab="Error",col="gray85",border="white")
qqnorm(res_final,main="Grafico Q-Q"); qqline(res_final,col="red")
par(mfrow=c(1,1))
ljung <- stats::Box.test(res_final,lag=18,type="Ljung-Box",
fitdf=min(length(modelo_final$coef),10))
e2 <- res_final^2
aux_arch <- lm(e2[-1] ~ e2[-length(e2)])
arch_lm <- (length(e2)-1)*summary(aux_arch)$r.squared
p_arch <- pchisq(arch_lm,df=1,lower.tail=FALSE)
tabla_diag <- data.frame(
prueba=c("Ljung-Box (autocorrelacion)","Jarque-Bera (normalidad)",
"ARCH LM aproximada (varianza)") ,
p_valor=c(ljung$p.value,p_jb,p_arch))
knitr::kable(tabla_diag,digits=4)
| prueba | p_valor |
|---|---|
| Ljung-Box (autocorrelacion) | 0.0716 |
| Jarque-Bera (normalidad) | 0.0000 |
| ARCH LM aproximada (varianza) | 0.0010 |
Interpretaciones sencillas:
Para evaluar fuera de muestra, pronosticamos el conjunto test sin introducir sus precios en el modelo. La proyeccion del WTI utilizada como regresor tambien parte solo de train, mediante un paseo aleatorio con deriva. Asi evitamos usar un WTI futuro observado que el inversionista no conoceria en \(T_0\).
Compararemos todos los candidatos sobre las mismas fechas. MAE y RMSE estan en USD por accion; MAPE, en porcentaje; MASE compara el MAE con el cambio medio mensual de train. El benchmark naive mantiene el ultimo precio visto.
knitr::kable(tabla_errores,digits=3, caption="Errores fuera de muestra: horizonte test completo")
| modelo | MAE | RMSE | MAPE | MASE | |
|---|---|---|---|---|---|
| 6 | ARIMAX_011 | 13.301 | 15.660 | 11.174 | 4.149 |
| 5 | ARIMAX_110 | 13.374 | 15.680 | 11.257 | 4.172 |
| 4 | ARIMA_111 | 13.511 | 15.718 | 11.416 | 4.215 |
| 3 | ARIMA_011 | 13.537 | 15.726 | 11.446 | 4.223 |
| 2 | ARIMA_110 | 13.543 | 15.728 | 11.453 | 4.225 |
| 1 | ARIMA_010 | 13.594 | 15.743 | 11.513 | 4.241 |
| 8 | SARIMAX_110_100 | 11.801 | 15.805 | 9.390 | 3.682 |
| 7 | SARIMA_011_011 | 16.124 | 18.003 | 14.375 | 5.030 |
| 9 | NAIVE | 15.575 | 24.008 | 11.527 | 4.859 |
El menor RMSE del bloque test correspondio a ARIMAX_011. No coincide con el modelo seleccionado en train; esto demuestra que mejor ajuste historico no garantiza mejor pronostico. Se presenta esta comparacion como evaluacion, no como excusa para volver a seleccionar el modelo despues de mirar test.
pr <- pronosticos_test[[nombre_final]]
grafico_test <- data.frame(fecha=test$fecha, real=test$precio,
modelo=pr$central, li95=pr$li95, ls95=pr$ls95,
naive=rep(tail(train$precio,1),n_test))
ggplot2::ggplot(grafico_test,ggplot2::aes(x=fecha))+
ggplot2::geom_ribbon(ggplot2::aes(ymin=li95,ymax=ls95),fill="gray70",alpha=.35)+
ggplot2::geom_line(ggplot2::aes(y=real,color="Real"),linewidth=.9)+
ggplot2::geom_line(ggplot2::aes(y=modelo,color="Modelo"),linewidth=.8)+
ggplot2::geom_line(ggplot2::aes(y=naive,color="Naive"),linetype="dashed")+
ggplot2::scale_color_manual(values=c("Real"="black","Modelo"="blue","Naive"="gray40"))+
ggplot2::labs(title="Pronostico fuera de muestra e intervalo del 95%",
x="Fecha",y="USD por accion",color="Serie")+
ggplot2::theme_minimal()
Interpretacion: la banda gris muestra valores compatibles con la incertidumbre del modelo, condicionada a la trayectoria proyectada del WTI. Si los precios reales se alejan bastante, el modelo no capturo algun cambio del mercado. No se deben interpretar los intervalos como garantias.
Nuestro corte historico \(T_0\) es 30/09/2023. En ese momento solo conocemos train. La regla se evalua con el precio ajustado de cierre 106.55 USD y un horizonte de tres meses.
resultado_inversion <- data.frame(
concepto=c("Precio en T0 (USD)","Precio pronosticado a 3 meses (USD)",
"Retorno pronosticado (%)","Umbral de compra (%)",
"Capital estrategia al cabo de 3 meses (USD)",
"Capital comprar y mantener 3 meses (USD)",
"Capital solo efectivo 3 meses (USD)"),
resultado=c(precio_corte,tail(pred_corte$central,1),
100*retorno_previsto,100*umbral_compra,
capital_real_3m,capital_compra_y_mantener_3m,capital_inicial))
knitr::kable(resultado_inversion,digits=2)
| concepto | resultado |
|---|---|
| Precio en T0 (USD) | 106.55 |
| Precio pronosticado a 3 meses (USD) | 104.37 |
| Retorno pronosticado (%) | -2.04 |
| Umbral de compra (%) | 1.00 |
| Capital estrategia al cabo de 3 meses (USD) | 100000.00 |
| Capital comprar y mantener 3 meses (USD) | 85809.02 |
| Capital solo efectivo 3 meses (USD) | 100000.00 |
cat("Decision del modelo:",decision,"\n")
## Decision del modelo: MANTENER EFECTIVO
Interpretacion: la senal es MANTENER EFECTIVO. Es importante evaluar el resultado sin cambiar la regla despues de observar los datos reales. Los valores monetarios son simulados; no representan operaciones realizadas.
Para dar una comparacion adicional, repetimos el ejercicio trimestralmente en test. En cada fecha se reestima la misma estructura de modelo con datos disponibles hasta ese mes, y se pronostican tres meses nuevos; nunca usamos datos posteriores a la fecha de la decision. Se ignoran las fracciones de mes que queden al final de test.
registro_vista <- registro
registro_vista$retorno_previsto <- round(100*registro$retorno_previsto,2)
registro_vista$retorno_observado <- round(100*registro$retorno_observado,2)
registro_vista$capital <- round(registro$capital,2)
names(registro_vista)[3:5] <- c("Previsto_pct","Decision","Observado_pct")
knitr::kable(registro_vista,caption="Backtest trimestral fuera de muestra")
| fecha_inicio | fecha_fin | Previsto_pct | Decision | Observado_pct | capital |
|---|---|---|---|---|---|
| 2023-09-30 | 2023-12-31 | -2.04 | Efectivo | -14.19 | 100000.00 |
| 2023-12-31 | 2024-03-31 | 1.81 | Comprar | 17.34 | 117343.77 |
| 2024-03-31 | 2024-06-30 | 1.03 | Comprar | -0.16 | 117157.07 |
| 2024-06-30 | 2024-09-30 | 1.52 | Comprar | 2.64 | 120254.65 |
| 2024-09-30 | 2024-12-31 | 3.86 | Comprar | -7.48 | 111261.62 |
| 2024-12-31 | 2025-03-31 | 1.05 | Comprar | 11.55 | 124111.78 |
| 2025-03-31 | 2025-06-30 | 1.04 | Comprar | -8.52 | 113532.97 |
| 2025-06-30 | 2025-09-30 | 0.71 | Efectivo | 5.57 | 113532.97 |
| 2025-09-30 | 2025-12-31 | 3.37 | Comprar | 7.67 | 122235.56 |
| 2025-12-31 | 2026-03-31 | -0.04 | Efectivo | 41.92 | 122235.56 |
| 2026-03-31 | 2026-06-30 | 3.90 | Comprar | -18.87 | 99171.74 |
| 2026-06-30 | 2026-09-30 | 1.60 | Comprar | 19.81 | 118817.37 |
resultados_capital <- data.frame(estrategia=c("Regla de pronostico","Comprar y mantener XOM",
"Siempre efectivo"),
capital_final=c(capital_backtest,capital_buyhold,capital_cash))
resultados_capital$rendimiento_pct <- 100*(resultados_capital$capital_final/capital_inicial-1)
knitr::kable(resultados_capital,digits=2,
caption="Resultado del mismo periodo y con capital inicial de USD 100000")
| estrategia | capital_final | rendimiento_pct |
|---|---|---|
| Regla de pronostico | 118817.4 | 18.82 |
| Comprar y mantener XOM | 152752.3 | 52.75 |
| Siempre efectivo | 100000.0 | 0.00 |
Lectura: en este backtest, comprar y mantener XOM igualo o supero a la regla de pronosticos. Esto no demuestra que vaya a ocurrir igual en el futuro. Los resultados cambian si hay comisiones, impuestos o un horizonte distinto.
Se simulan 2,000 trayectorias vistas desde \(T_0\) durante exactamente 3 meses, el mismo horizonte de la decision. Las simulaciones usan el modelo entrenado antes de test y, para ARIMAX/SARIMAX, simulan tambien el WTI. Si Jarque-Bera rechaza normalidad, se utiliza bootstrap de residuos; de lo contrario, innovaciones normales ajustadas.
tabla_sim <- data.frame(
indicador=c("Media precio futuro (USD)","Mediana precio futuro (USD)",
"Precio futuro p5 (USD)","Precio futuro p50 (USD)",
"Precio futuro p95 (USD)","Probabilidad precio menor al de entrada (%)",
"Media capital final (USD)", "Capital final p5 (USD)",
"Capital final p50 (USD)","Capital final p95 (USD)",
"Probabilidad de perdida de cartera (%)"),
valor=c(mean(precio_sim),median(precio_sim),unname(q_precio),
100*prob_perder_precio, mean(capital_sim), unname(q_capital),
100*prob_perder_cartera))
knitr::kable(tabla_sim,digits=2)
| indicador | valor |
|---|---|
| Media precio futuro (USD) | 105.61 |
| Mediana precio futuro (USD) | 104.02 |
| Precio futuro p5 (USD) | 85.13 |
| Precio futuro p50 (USD) | 104.02 |
| Precio futuro p95 (USD) | 132.40 |
| Probabilidad precio menor al de entrada (%) | 57.10 |
| Media capital final (USD) | 100000.00 |
| Capital final p5 (USD) | 100000.00 |
| Capital final p50 (USD) | 100000.00 |
| Capital final p95 (USD) | 100000.00 |
| Probabilidad de perdida de cartera (%) | 0.00 |
ggplot2::ggplot(data.frame(precio=precio_sim),ggplot2::aes(x=precio))+
ggplot2::geom_histogram(bins=35,fill="gray65",color="white")+
ggplot2::geom_vline(xintercept=precio_corte,color="red",linetype="dashed")+
ggplot2::labs(title="Distribucion simulada del precio de XOM a 3 meses",
x="Precio final (USD)",y="Numero de simulaciones")+
ggplot2::theme_minimal()
Interpretacion sencilla: segun la simulacion, la probabilidad de que el precio de XOM sea inferior al de entrada es 57.10%. El 90% central de precios simulados se ubica aproximadamente entre USD 85.13 y USD 132.40 (percentiles 5 y 95). La probabilidad simulada de perdida para la cartera segun MANTENER EFECTIVO es 0.00%. Si se decide conservar efectivo y se supone rentabilidad cero, la perdida simulada de la cartera sera cero bajo este supuesto simplificado.
Respuestas a las siete preguntas del enunciado:
Conclusion final: el ejercicio permite organizar una decision de inversion con criterios previos y probarla contra resultados que no se usaron en el entrenamiento. El resultado depende del periodo elegido y de los supuestos. Seria util estudiar mas variables y, si aparece volatilidad agrupada, modelos GARCH.
Referencias en formato APA (comprobar formato y fecha de consulta con el grupo):
Paquetes principales: quantmod (descarga), forecast
(modelos/pronosticos/simulacion), tseries (pruebas), zoo (fechas),
ggplot2 (graficos), knitr y rmarkdown (informe). El codigo completo esta
en el archivo .Rmd, las tablas se exportan a
datos/ y las simulaciones utilizan
set.seed(1234).
cat("Version de R:",as.character(getRversion()),"\n")
## Version de R: 4.6.1
cat("Paquetes usados y versiones:\n")
## Paquetes usados y versiones:
for (p in paquetes) cat(" - ",p,": ",as.character(utils::packageVersion(p)),"\n",sep="")
## - quantmod: 0.4.29
## - forecast: 9.0.2
## - tseries: 0.10.63
## - zoo: 1.9.1
## - ggplot2: 4.0.3
## - knitr: 1.51
## - rmarkdown: 2.32
Durante el desarrollo de este trabajo utilizamos herramientas de inteligencia artificial como apoyo para mejorar y perfeccionar los códigos en R, organizar la estructura del documento y facilitar la conexión directa con Yahoo Finance para obtener los datos históricos necesarios.
Esta herramienta nos permitió encontrar soluciones de programación más eficientes, corregir errores y adaptar los códigos a las necesidades de cada análisis.
El equipo fue responsable de comprender los procedimientos, revisar los resultados obtenidos y desarrollar las interpretaciones y conclusiones del trabajo. La inteligencia artificial se utilizó principalmente como una herramienta de apoyo técnico para facilitar la programación y mejorar el desarrollo del ejercicio.
Consideramos que su uso fue un complemento para nuestro aprendizaje, ya que nos permitió concentrarnos en comprender y aplicar los conceptos de econometría financiera.