# ¿Duplicar los escenarios Monte Carlo mejora de verdad el riesgo de cola? Prueba con 12 ETF

> Canonical: https://vxi.me/es/posts/monte-carlo-scenarios-tail-risk-12-etf/
> Locale: es-es
> Published: 2026-10-23
> Updated: 2026-10-23
> Markdown: https://vxi.me/es/posts/monte-carlo-scenarios-tail-risk-12-etf.md

<figure class="quant-scenario-hero not-prose" lang="es-es">
<picture><source media="(prefers-reduced-motion: reduce) and (max-width: 640px)" srcset="/images/posts/monte-carlo-scenarios-tail-risk-12-etf/scenario-fidelity.mobile.still.es-es.svg" type="image/svg+xml"><source media="(prefers-reduced-motion: reduce)" srcset="/images/posts/monte-carlo-scenarios-tail-risk-12-etf/scenario-fidelity.still.es-es.svg" type="image/svg+xml"><source media="(max-width: 640px)" srcset="/images/posts/monte-carlo-scenarios-tail-risk-12-etf/scenario-fidelity.mobile.es-es.svg" type="image/svg+xml"><img src="/images/posts/monte-carlo-scenarios-tail-risk-12-etf/scenario-fidelity.es-es.svg" alt="12 ETF: seis razones ES 0,671–0,768; caídas conjuntas Gaussian 0,3180 frente a la referencia 0,4211." width="1200" height="700" loading="eager" fetchpriority="high" decoding="async" style="display:block;width:100%;height:auto"></picture>
<figcaption>Gráfico: Duplicar escenarios reduce la variación de muestreo, no la brecha de caídas simultáneas Gaussian. El OOS aparte evalúa tres VaR diarios.</figcaption>
</figure>

Cuando un modelo de riesgo Monte Carlo produce cifras inestables, la solución que suena más sencilla es duplicar los escenarios. Pero ¿qué información sobre el riesgo aportan realmente otras 756 observaciones simuladas? Quería separar dos cosas que solemos confundir: obtener un número más estable y reproducir mejor las pérdidas extremas del mercado.

Hice la comparación con **precios históricos reales de 12 ETF, seis métodos de generación y 50 semillas aleatorias emparejadas**. Al pasar de 756 a 1.512 observaciones por simulación, la dispersión de algunas estimaciones se redujo. Sin embargo, la tasa de caídas simultáneas del generador Gaussian siguió cerca de **0.3180**, frente al **0.4211** de la muestra histórica de entrenamiento.

Por “caídas simultáneas” entiendo algo concreto: **cuando SPY tiene un día realmente malo, ¿qué proporción de los otros ETF tiene también un día realmente malo?** Primero fijo, para cada ETF, el umbral de su peor 5% de rentabilidades diarias del período de entrenamiento. No recalculo el umbral dentro de cada simulación para que el resultado parezca mejor.

Al evaluar un generador de escenarios, me hago tres preguntas distintas: **¿Se estabiliza el cálculo al generar más observaciones? ¿Se conserva la estructura de pérdidas conjuntas y de días malos consecutivos? ¿Están calibrados los umbrales de riesgo fuera de la muestra?** Las dos primeras se estudian frente al mismo período histórico fijo. La tercera corresponde a otro experimento, más limitado, con VaR de un día: no es una clasificación fuera de muestra de los seis generadores.

## Doce ETF y una ventana de entrenamiento fija de 756 días

Utilicé el [Huge Stock Market Dataset](https://www.kaggle.com/datasets/borismarjanovic/price-volume-data-for-all-us-stocks-etfs) de Boris Marjanovic. Su descripción indica licencia CC0 y precios ajustados por dividendos y desdoblamientos. Elegí doce ETF que cubren renta variable, deuda pública, crédito, oro, materias primas, dólar y sector inmobiliario. Mirar únicamente SPY no permitiría estudiar bien las caídas entre clases de activos. La lista de símbolos aparece al final.

Crucé las fechas con precios Close ajustados de los doce archivos originales y **no rellené valores ausentes**. En esta versión de Kaggle, HYG comienza el 2007-04-11, por lo que el período común va del **2007-04-11 al 2017-11-10, con 2.668 fechas de precios**. Convertí los precios a rentabilidades simples diarias y calculé cada día el promedio equiponderado de los doce ETF. No cambié la definición de cartera durante el estudio.

Los generadores usan exclusivamente las **primeras 756 rentabilidades diarias** como entrenamiento, unos tres años de negociación que incluyen la crisis de 2008. Quise que todos los métodos vieran exactamente la misma historia, no que cada uno eligiera la ventana más favorable. Los grados de libertad de Student-t quedaron fijados en cinco, sin ajustarlos después de mirar el rendimiento fuera de muestra.

| Método | Cómo genera las rentabilidades simuladas |
| --- | --- |
| Gaussian | Normal multivariante con medias y covarianzas estimadas en el entrenamiento |
| Student-t df=5 | t multivariante de cinco grados de libertad, con covarianza igualada a la histórica |
| IID Bootstrap | Muestreo independiente y con reemplazo de filas diarias completas de ETF |
| Moving-block 5 / 20 / 60 | Muestreo de bloques consecutivos de 5, 20 o 60 días |

El primer error que quería evitar era **confundir la suerte de dos tiradas de números aleatorios con el efecto del tamaño muestral**. Utilicé las mismas 50 semillas, **1000–1049**, para cada método. En cada réplica generé primero 1.512 observaciones y reutilicé **las primeras 756 de esa misma secuencia** para la comparación pequeña. Dicho sin tecnicismos: vuelvo a extraer escenarios de un historial de 756 días; generar más observaciones no crea otros 756 días de mercado real.

Student-t tiene otra trampa. Si cambio a una distribución de “colas gruesas” pero olvido ajustar su varianza, también aumento la volatilidad total y la comparación deja de ser justa. Mi implementación usa un factor de Cholesky de la covarianza de entrenamiento para obtener normales correlacionadas y las multiplica por `√(3/χ²₅)`, donde χ²₅ es una variable chi-cuadrado con cinco grados de libertad. Equivale a usar una matriz de escala t igual a **3/5 de la covarianza histórica**. Sin ese ajuste, la covarianza simulada se infla a **5/3** de la buscada.

## Qué mejoró realmente al duplicar los escenarios

Empecé por el ES(5%) de un día, la rentabilidad media dentro del peor 5% de observaciones. Calculé un ES para cada semilla y comparé la **desviación estándar entre los 50 resultados** con 1.512 observaciones frente a 756. Así puedo medir el ruido del muestreo sin fingir que estoy midiendo la capacidad del modelo para conocer el futuro.

| Generador | Cociente de desviaciones estándar de ES entre semillas: 1.512 / 756 |
| --- | ---: |
| Gaussian | 0.718 |
| Student-t df=5 | 0.671 |
| IID Bootstrap | 0.746 |
| Moving-block 5 | 0.768 |
| Moving-block 20 | 0.681 |
| Moving-block 60 | 0.734 |

Los seis cocientes están entre **0.671 y 0.768**, todos por debajo de uno: en estas 50 réplicas emparejadas las estimaciones de ES quedaron más agrupadas. `1/√2≈0.707` sirve para hacerse una idea del efecto habitual de duplicar una muestra, aunque un estadístico de cola como ES no tiene por qué seguir exactamente esa velocidad.

La tasa de caídas simultáneas no respondió igual. Seleccioné los días simulados en los que SPY caía por debajo de su **umbral fijo del 5% del entrenamiento**; para cada uno conté qué fracción de los otros once ETF también caía por debajo de sus propios umbrales fijos, y promedié esos días. El error medio de Gaussian respecto a la referencia pasó de alrededor de **−0.1036 con N=756** a **−0.1031 con N=1.512**: prácticamente sin cambio.

Más sorteos hicieron el cálculo más estable, pero no enseñaron al generador a producir las caídas conjuntas que le faltaban.

## IID Bootstrap recuerda quién cayó el mismo día, pero pierde las rachas de volatilidad

Reproducir el porcentaje de caídas compartidas en un solo día no implica reproducir cómo se encadenan varios días malos. Todos los indicadores siguientes se calculan sobre la **rentabilidad diaria de la cartera equiponderada de doce ETF**. La autocorrelación de primer retardo de las rentabilidades absolutas, **ACF(1)**, sirve para observar, de forma aproximada, si las grandes oscilaciones se agrupan. El ES a 60 días y la caída máxima miran trayectorias más largas.

Antes de calcular hay que evitar otro error: **sumar simplemente 60 porcentajes diarios no reproduce la pérdida acumulada con capitalización**. Deslicé una ventana de 60 días, avanzando uno a uno por la secuencia generada, y calculé la rentabilidad de cada ventana con `∏(1+rₜ)-1`. El ES de 60 días es la media del 5% de ventanas con menor rentabilidad. La caída máxima se calcula primero sobre la trayectoria de riqueza compuesta de cada ventana; después tomo el percentil 5 de esas caídas máximas.

Estos son los **promedios de 50 semillas con N=1.512**, junto a la referencia de la misma historia de entrenamiento:

| Origen del escenario | Caídas conjuntas | ACF(1) de rentabilidad absoluta | ES(5%) a 60 días | Percentil 5 de caída máxima a 60 días |
| --- | ---: | ---: | ---: | ---: |
| Referencia de entrenamiento | 0.4211 | 0.3000 | -21.01% | -25.45% |
| Gaussian | 0.3180 | -0.0011 | -15.77% | -16.53% |
| Student-t df=5 | 0.3549 | -0.0005 | -15.97% | -17.00% |
| IID Bootstrap | 0.4265 | 0.0059 | -15.15% | -16.26% |
| Block 5 | 0.4209 | 0.2408 | -14.45% | -15.75% |
| Block 20 | 0.4227 | 0.2842 | -16.54% | -18.56% |
| Block 60 | 0.4113 | 0.2684 | -17.49% | -20.48% |

No hace falta leer todas las celdas. IID Bootstrap extrae **una fila completa de rendimientos del mismo día**. Por eso su tasa de caídas conjuntas, **0.4265**, se parece mucho a la referencia **0.4211**. Pero al muestrear las fechas independientemente elimina gran parte de la dependencia temporal: ACF(1) cae hasta **0.0059**, frente a **0.3000** en la historia.

En otras palabras, recuerda **qué activos pueden bajar juntos**, pero casi olvida **si los movimientos fuertes se producen varios días seguidos**.

Con Block 20, ACF(1) sube a **0.2842**, cerca de la referencia histórica. Block 60 desplaza el ES de 60 días desde el **−15.15%** de IID hasta **−17.49%**, aunque la referencia sigue en **−21.01%**. Los bloques más largos tampoco ganan siempre: Block 5 produce en esta muestra un ES de 60 días incluso menos negativo que IID.

¿Por qué superponer las ventanas de 60 días? Sin solapamiento, los 756 días de entrenamiento solo proporcionan unos **12** tramos de 60 días, y la secuencia de 1.512 proporciona unos **25**. No me fiaría mucho de estimar el peor 5% a partir de una docena de tramos independientes. Con una ventana móvil diaria obtengo **697 ventanas** de entrenamiento y **1.453 ventanas** generadas. Pero comparten muchísimos días: no son 697 y 1.453 eventos de riesgo independientes. Además, el entrenamiento incluye 2008, así que **−21.01% es una referencia de esa historia concreta, no un objetivo universal que haya que acertar exactamente**.

## Moving-block: las uniones entre bloques no son el mismo problema que los extremos de la muestra

Cuando vi subir la ACF con los bloques, mi primera explicación parecía obvia: “conserva el orden de los días”. Al revisar el muestreador tuve que separar dos efectos que había mezclado.

El primero son las **uniones entre bloques**. Dentro de cada bloque los días son consecutivos en la historia, pero el siguiente bloque puede saltar a otra fecha muy lejana. Para bloques de longitud L, alrededor de `1/L` de las parejas de días consecutivos cruza una unión. Bajo una aproximación simplificada de bloques independientes concatenados, la autocorrelación de retardo uno se atenúa en un factor del orden de `1−1/L`. Sobre la ACF de referencia **0.3000**, sale aproximadamente **0.240 para L=5** y **0.285 para L=20**, cerca de los resultados observados **0.2408** y **0.2842**. Con L=60 no encaja tan bien. Es una intuición sobre el mecanismo, no una sustitución de los datos.

El segundo efecto es que **las fechas de los extremos del entrenamiento tienen menos oportunidades de aparecer**. En un Moving-block ordinario, no circular, los comienzos de bloque permitidos van de `0` a `756−L`. Las fechas cercanas a los bordes pertenecen a menos bloques posibles que las interiores, y los pesos por posición pueden diferir hasta un factor de L. Para comprobar cuánto importaba aquí, ejecuté un contraste adicional de Circular Block, con comienzos uniformes y la posibilidad de enlazar el final de la historia con el principio, manteniendo las 50 semillas.

| Longitud de bloque | ACF(1): normal / circular | ES a 60 días: normal / circular |
| --- | --- | --- |
| 5 | 0.2408 / 0.2411 | -14.45% / -14.35% |
| 20 | 0.2842 / 0.2884 | -16.54% / -16.37% |
| 60 | 0.2684 / 0.2792 | -17.49% / -17.23% |

La diferencia es modesta. Para Block 20, ACF pasó de **0.2842 a 0.2884** y el ES de 60 días de **−16.54% a −16.37%**. Los pesos de los extremos son distintos, pero **en estos datos no explican la mayor parte de la diferencia entre Block e IID**. Circular, además, crea artificialmente una unión entre el último y el primer día del entrenamiento: no es mejor por definición.

Ese contraste me obligó a no achacar todos los cambios del método Block a una única causa. Se puede consultar el [documento sobre Circular Block Resampling](https://statistics.stanford.edu/technical-reports/circular-block-resampling-procedure-stationary-data) para el contexto metodológico.

## VaR de un día: tres métodos fallan la calibración en todo el período fuera de muestra

Ahora cambio a una pregunta más limitada: **cuando llega el siguiente día real, ¿estaba bien calibrado el umbral de pérdida estimado?** No intento clasificar fuera de muestra a los seis generadores anteriores. Solo comparo **tres métodos de VaR a un día**: el cuantil empírico histórico, Gaussian y Student-t de cinco grados de libertad. Para cada fecha objetivo vuelvo a estimar el umbral con las **756 rentabilidades reales inmediatamente anteriores** de la cartera. No sigo usando el primer período fijo de la simulación.

El cuantil del 5% de t5 también está ajustado a la varianza de entrenamiento. Un “exceso” de VaR significa que la rentabilidad real del día siguiente cae por debajo del umbral del 5% previsto por el modelo. Hay **1.911 días objetivo distintos**, sin solapamiento diario:

| Método de VaR al 95% a un día | Excesos | Tasa de exceso | p de Kupiec | p de independencia de Christoffersen |
| --- | ---: | ---: | ---: | ---: |
| Cuantil histórico empírico | 52 | 2.72% | 6.16e-7 | 0.0145 |
| Gaussian | 51 | 2.67% | 3.16e-7 | 0.0122 |
| Student-t df=5 | 62 | 3.24% | 1.75e-4 | 0.0171 |

Con una tasa nominal del 5%, en 1.911 días esperaríamos de media unos **95.55** excesos. Los tres métodos tuvieron solo **51–62**. **Menos excesos no significa que la calibración haya superado las pruebas.** Kupiec comprueba la frecuencia incondicional; Christoffersen, la independencia de los excesos. En ambos casos los valores p son pequeños.

La conclusión corresponde a **todo el período de 1.911 días**. Las primeras ventanas móviles todavía contienen la crisis de 2008, que desaparece gradualmente de las ventanas posteriores. No hice en esta ocasión una prueba separada por regímenes de mercado. Los excesos en dos días consecutivos fueron solo **5 / 5 / 6** por método, un dato que conviene considerar al interpretar el test de independencia.

Tampoco metí a la fuerza el ES de 60 días de Block 60 en esta tabla. Un test OOS a 60 días exige definir objetivos de pérdida multidiarios y tratar la fuerte dependencia entre ventanas solapadas. No terminé un diseño que me convenciera para ese caso; copiar sin más Kupiec o Christoffersen desde el VaR diario daría una falsa sensación de rigor. Por eso aquí presento solo VaR a un día.

Student-t deja otra observación contraintuitiva: que tenga “colas gruesas” no implica que su VaR sea siempre más conservador. Con df=5 y varianza igualada, el cuantil izquierdo estandarizado al 5% es aproximadamente **−1.56085**, más cerca de cero que el de Gaussian (**−1.64485**). El nombre de la distribución no basta para conocer el sentido del umbral a cualquier nivel de confianza.

## Dónde gastaría el próximo presupuesto de simulación

La próxima vez que alguien proponga duplicar escenarios porque “las cifras no son estables”, antes preguntaría tres cosas: **¿Es puro ruido de muestreo? ¿El generador conserva las caídas simultáneas y las pérdidas seguidas que importan? ¿Hay una prueba OOS de calibración para el horizonte de riesgo real?** Duplicar simulaciones responde principalmente a la primera.

Si mañana tuviera que elegir entre Block 20, Block 60 y Student-t para respaldar el control de riesgo en producción, **no coronaría a ninguno con esta comparación histórica fija**. Que la ACF de Block 20 se parezca al pasado no demuestra una buena cobertura futura. La cola más gruesa de Student-t tampoco garantiza un VaR al 95% más conservador. Primero elegiría el horizonte y luego lo contrastaría fuera de muestra.

Me quedo con dos hallazgos: el desfase de Gaussian en las caídas conjuntas sobrevivió a la duplicación y el ensayo de Circular Block me hizo recortar una explicación demasiado cómoda. Ante un proveedor que anuncia “un millón de escenarios de riesgo”, preguntaría: **¿Qué observaciones reales está repitiendo y qué estructuras de riesgo ha conservado?**

Para empezar con un ejemplo de cola más pequeño y reproducible, también escribí sobre [cómo un NaN cambia el denominador de la muestra de cola para CVaR en vectorbt](/posts/vectorbt-nan-cvar-tail-sample-test-assertions/), con un ejercicio sintético en Python.

---

*Fuente y parámetros fijos: Kaggle Huge Stock Market Dataset v3; SPY, IWM, EFA, EEM, TLT, IEF, LQD, HYG, GLD, DBC, UUP y VNQ. Fechas comunes de precios de cierre ajustados: 2007-04-11 a 2017-11-10, 2.668 filas, sin rellenar fechas ausentes. SHA-256 del CSV fijo: `0a20c095f0d9400fbf7d30e17a0c664716f147c460b03bf5439cd980ef8bf38a`. El estudio de escenarios utiliza 756 rendimientos diarios de entrenamiento y 50 semillas emparejadas; la evaluación separada de VaR diario tiene 1.911 objetivos. Comparación de métodos de modelado histórico del riesgo; no constituye asesoramiento de inversión.*
