Lección 5.8.4 · 60 min
Modelos fundacionales en finanzas: qué dice la evidencia
Un modelo fundacional que gana un ranking no tiene por qué batir a prever cero. Esta lección lee con lupa dos estudios recientes sobre rentabilidades, resume la evidencia sobre volatilidad y repite la prueba con Chronos-Bolt y TimesFM-2.5 en una serie cuyo rendimiento es impredecible por construcción, con Diebold-Mariano y corrección por pruebas múltiples.
- Módulo
- 5.8 · Modelos fundacionales de series temporales
- Duración
- 60 min
Lecciones del nivel 5
5.1 · Fundamentos de ML aplicados a finanzas
5.2 · Ingeniería de características
5.3 · Etiquetado y muestreo
- 5.3.1 Etiquetado de horizonte fijo y sus problemas
- 5.3.2 Método de la triple barrera: etiquetas que imitan una operación
- 5.3.3 Meta-labeling: un modelo para el lado y otro para el tamaño
- 5.3.4 Unicidad de las etiquetas, pesos por solapamiento y bootstrap secuencial
- 5.3.5 Muestreo por eventos: el filtro CUSUM simétrico
5.4 · Validación para series financieras
5.5 · Modelos clásicos
- 5.5.1 Regresiones regularizadas: Ridge, Lasso, Elastic Net y logística
- 5.5.2 Árboles de decisión, Random Forest y bagging
- 5.5.3 Gradient boosting: XGBoost, LightGBM y CatBoost
- 5.5.4 Optuna y el riesgo de sobreajustar la validación
- 5.5.5 Aprendizaje no supervisado: PCA, clustering y autoencoders
- 5.5.6 Learning to rank para la selección de acciones
5.6 · Deep learning con Keras 3
5.7 · Deep learning con PyTorch
- 5.7.1 PyTorch: tensores, autograd y el bucle de entrenamiento
- 5.7.2 Arquitecturas de series: TCN, N-BEATS, PatchTST e iTransformer
- 5.7.3 Modelos probabilísticos: pérdida cuantílica, DeepAR e intervalos
- 5.7.4 Redes de grafos para relaciones entre activos
- 5.7.5 Optimización de carteras end-to-end: capas diferenciables y pérdida de Sharpe
5.8 · Modelos fundacionales de series temporales
- 5.8.1 Modelos fundacionales de series: preentrenar una vez, prever sin entrenar
- 5.8.2 Las familias de modelos fundacionales: arquitectura, datos y licencia
- 5.8.3 Uso práctico: contexto, cuantiles, covariables y ajuste fino
- 5.8.4 Modelos fundacionales en finanzas: qué dice la evidencia
- 5.8.5 Laboratorio: modelos fundacionales frente a GARCH, HAR y LightGBM
5.9 · Aprendizaje por refuerzo
5.10 · Interpretabilidad, robustez y riesgo de modelo
La pregunta difícil: el rendimiento de mañana
Las lecciones 5.8.1 a 5.8.3 explicaron qué es un modelo fundacional de series, qué familias hay (Chronos, TimesFM, Moirai, Kronos…) y cómo se usan sin reentrenar. Esta lección pregunta otra cosa: qué se sabe de su rendimiento en finanzas, y en concreto en la tarea que más interesa a quien opera, prever la rentabilidad.
Es la prueba más dura posible para un modelo preentrenado. Las rentabilidades diarias tienen una relación señal/ruido bajísima, colas gruesas, cambios de régimen y casi ninguna autocorrelación (lección 1.6.2). Un modelo que ha aprendido patrones de miles de series de tráfico, energía o ventas encuentra en ellas poco que reconocer, y lo poco que haya lo arbitran otros participantes. La pregunta honesta no es «¿qué modelo gana?» sino «¿gana alguno a prever cero, con qué seguridad estadística y con qué valor después de costes?». Una afirmación de que un modelo «predice» tiene que recorrer esta cadena entera:
Fuente Mermaid
flowchart TB A[Previsión] --> B[Pérdida y baseline] B --> C[Test robusto] C --> D[Pruebas múltiples] D --> E[Costes y capacidad] E --> F[Conclusión]
Cada eslabón tiene su trampa. La baseline debe ser la ingenua (rentabilidad cero o media histórica), no otro modelo complejo. La pérdida decide qué se premia: el error cuadrático castiga los días extremos, el absoluto apunta a la mediana. El test tiene que tener en cuenta que las pérdidas de días consecutivos o de horizontes solapados no son independientes. Con muchos modelos, activos y variantes, alguno sale significativo por azar (lección 5.4.4). Y una previsión ligeramente mejor puede no pagar los costes de operarla (lección 5.1.3).
El benchmark de 2026: rankings frente a paseo aleatorio
El temario cita un benchmark publicado en arXiv el 25 de junio de 2026: «Pretrained Time-Series Foundation Models for Financial Return Forecasting», de Miquel Noguer i Alonso y Rodolfo Pereira Franklin (Artificial Intelligence Finance Institute), arXiv:2606.27100. Lo que sigue sale de la página del resumen y del PDF de la versión 1, leídos el 2026-10-23. El diseño:
| Elemento | Valor en el artículo |
|---|---|
| Activos | AAPL, AMZN, GOOG, JPM y META; cierres ajustados diarios de Yahoo Finance (2014-09-15 a 2026-02-15) |
| Objetivos | Rentabilidad lineal y logarítmica (10 tareas: 5 acciones × 2 objetivos) |
| Modelos preentrenados (sin reentrenar) | TimeGPT, TimeGPT-LH, TimesFM-2.5, Moirai-2.0, Chronos (v1) y Chronos-2 |
| Modelos entrenados por acción | NBEATS, NHITS, PatchTST, iTransformer y KAN (entrenamiento 2014-09 a 2024-08) |
| Evaluación | 10 ventanas con origen móvil entre agosto de 2024 y febrero de 2026; horizonte de 20 sesiones; contexto de 512 para todos |
| Métrica | Error absoluto medio (EAM); skill = 1 − EAM / EAM del paseo aleatorio de rentabilidad cero |
| Test | Diebold-Mariano unilateral con la corrección de Harvey, Leybourne y Newbold; p sin corregir por pruebas múltiples |
Los resultados que repite el temario están en el artículo tal cual: los modelos preentrenados ganan 8 de las 10 tareas, y Moirai-2.0 y TimesFM-2.5 tienen los mejores rankings medios, 2,9 y 3,1 (tabla 4; les siguen Chronos con 3,4, Chronos-2 con 3,9, iTransformer con 4,3 y KAN con 5,4). iTransformer, entrenado desde cero, gana las dos tareas de META. Y el resumen lo dice sin rodeos: «gains over the random-walk benchmark are small and sparse» (las mejoras frente al paseo aleatorio son pequeñas y escasas).
La figura dibuja la tabla 5 del artículo: el skill del ganador de cada tarea. En seis de las diez (AAPL, JPM y META, en los dos objetivos) el mejor modelo de la comparación tiene un error absoluto mayor que el de prever rentabilidad cero: skill de −2,9 a −5,2 %. Las cuatro mejoras están en AMZN (8,6 y 8,2 %) y GOOG (22,9 y 22,8 %). El test de Diebold-Mariano unilateral (tabla 7) solo rechaza la hipótesis de «igual o peor que el paseo aleatorio» en dos casos, Chronos en AMZN y Moirai-2.0 en GOOG, los dos con p = 0,0421; en TimesFM-2.5 con AAPL y JPM, p = 0,9999. En la tabla 4, cada uno de los cuatro modelos preentrenados con mejor ranking tiene skill positiva en 4 de las 10 tareas; los dos entrenados desde cero, en ninguna.
Tres lecturas que el propio artículo apoya:
- Ranking no es predictibilidad. Ordenar once modelos dice cuál es el menos malo, no si alguno sirve. El resumen lo formula así: «strong rankings need not imply economically meaningful predictability in noisy markets».
- La significación es exploratoria. Las pruebas cubren varios modelos, acciones y objetivos y los p se dan sin corregir; los autores piden leer los casos significativos «as exploratory evidence rather than as family-level discoveries» y reconocen que muchas diferencias entre los primeros del ranking están en el suelo de ruido de la ventana de prueba (unas 200 sesiones).
- No es una prueba de trading. El artículo evalúa error de previsión, no utilidad: calibración, rotación, costes y capacidad quedan fuera, y los autores dicen expresamente que sus resultados no deben leerse como evidencia de alfa.
El otro estudio: estrategias con miles de acciones
El temario cita «otro estudio» en el que las estrategias con estos modelos rinden menos que modelos de referencia específicos. Es «Re(Visiting) Time Series Foundation Models in Finance», de Eghbal Rahimikia (Universidad de Mánchester), Hao Ni (UCL) y Weiguan Wang (Universidad de Shanghái), arXiv:2511.18578, publicado el 23 de noviembre de 2025; las cifras son del PDF de la versión 1. Su diseño es muy distinto del anterior: rentabilidades diarias en exceso de unas 10 000 acciones de EE. UU. (más de 18 millones de observaciones), evaluación fuera de muestra de 2001 a 2023 con modelos reestimados cada año, ventanas de 5, 21, 252 y 512 sesiones, y carteras larga-corta por deciles, con pesos iguales y rebalanceo diario, construidas con las previsiones de cada modelo. Los modelos de referencia son lineales (MCO, Lasso, Ridge, Elastic Net, PCR), de árboles (XGBoost, CatBoost, LightGBM) y dos redes pequeñas; el mejor, CatBoost.
Los resultados del modo sin reentrenar (zero-shot) usan las versiones públicas de Chronos (v1, de tiny a large) y de TimesFM (versión 1 de 200 millones de parámetros y versión 2 de 500 millones), no Chronos-Bolt ni TimesFM-2.5. Con ventana de 512 sesiones y sin costes, la mejor configuración, Chronos large, da una rentabilidad anualizada del 20,17 % y un Sharpe de 2,92; la mejor de TimesFM, −1,47 % y −0,18; CatBoost con la misma ventana, 47,25 % y 6,46. En bondad de ajuste, con ventana de 512, el R² fuera de muestra de Chronos large es −1,37 % y el de TimesFM de 500 millones, −2,80 %; el de CatBoost, en la media de las cuatro ventanas, −0,10 %. El ajuste fino con datos financieros no cierra la diferencia. Lo que sí la reduce es preentrenar desde cero con rentabilidades, año a año y sin ver el futuro: Chronos small preentrenado así llega al 36,84 % y a un Sharpe de 5,42.
La figura añade lo que el estudio muestra al meter costes: con 20 puntos básicos o más, todas las carteras larga-corta pasan a Sharpe negativo, sea cual sea el modelo. El Sharpe medio de CatBoost en las cuatro ventanas cae de 6,44 sin costes a −3,62 con 20 puntos básicos y a −13,59 con 40. Un Sharpe de 6 sin costes en una cartera que se rehace cada día sobre miles de acciones es un resultado estadístico (la señal existe), no una estrategia.
| Benchmark de 2026 | Rahimikia, Ni y Wang (2025) | |
|---|---|---|
| Universo | 5 acciones grandes | ≈ 10 000 acciones de EE. UU. (y 7 mercados más) |
| Periodo de prueba | ago. 2024 a feb. 2026 (10 ventanas) | 2001-2023 |
| Horizonte | 20 sesiones | 1 sesión |
| Modelos fundacionales | TimeGPT, TimesFM-2.5, Moirai-2.0, Chronos, Chronos-2 | Chronos v1, TimesFM v1 y v2, y doce más |
| Referencias | Redes entrenadas por acción y paseo aleatorio | Lineales, árboles y redes con todo el panel |
| Medida | Error absoluto, skill, Diebold-Mariano | R², acierto, carteras, Sharpe con y sin costes |
| Conclusión de los autores | Útiles como punto de partida; no fuente fiable de alfa | Sin reentrenar rinden poco; el preentrenamiento financiero ayuda |
Un detalle metodológico de este segundo estudio vale para cualquier trabajo con modelos públicos: los autores advierten (nota 17) de que, según los datos con que se preentrenó cada modelo, puede haber sesgo de anticipación: si el corpus de preentrenamiento contiene las mismas series financieras del periodo de prueba, el modelo ha visto el futuro. Por eso preentrenan sus propios modelos sin solapamiento. En los datos sintéticos de este curso el problema no existe: ninguna de estas series estaba en el preentrenamiento de Chronos-Bolt ni de TimesFM-2.5.
Volatilidad: donde sí hay estructura
La conclusión del temario («útiles para volatilidad, covariables y series con estructura») tiene apoyo, con matices. Dos trabajos recientes, de los que aquí se cita solo lo que dicen sus resúmenes en arXiv:
- Brini (2026), arXiv:2607.05291, compara nueve modelos fundacionales sin reentrenar con ocho especificaciones econométricas (la familia HAR incluida) en 50 activos de acciones, divisas y futuros: «Foundation models do not deliver a uniform gain». Promediando por activo frente a un Log-HAR bien especificado, solo un modelo pequeño (Tiny Time Mixers) lo bate en todos los horizontes y por poco; una recalibración de Mincer-Zarnowitz muestra que buena parte de la ventaja a corto plazo es de escala, no de dinámica; y la media simple de ese modelo y el Log-HAR entra en el Model Confidence Set en el 98-100 % de los activos.
- Goel, Pasricha, Magris y Kanniainen (2025), arXiv:2505.111631Nota 1 · Goel, A., Pasricha, P., Magris, M. y Kanniainen, J. (2025): Foundation Time-Series AI Model for Realized Volatility Forecasting, arXiv:2505.11163, https://arxiv.org/abs/2505.11163., evalúan TimesFM en volatilidad: sin reentrenar es «a reasonable baseline», y con un ajuste fino incremental supera a los modelos tradicionales con pruebas de Diebold-Mariano y Giacomini-White.
La volatilidad tiene lo que a las rentabilidades les falta: persistencia, memoria larga y una forma reconocible (agrupamiento, reversión a la media) que se parece a la de muchas series del preentrenamiento. Por eso un modelo fundacional la prevé de forma razonable sin ajuste, y por eso mismo un HAR de cuatro parámetros es un rival durísimo. La lección 5.8.5 lo mide con un laboratorio completo.
La prueba en casa: rendimientos impredecibles por construcción
Los estudios usan datos reales, en los que nadie sabe cuánta predictibilidad hay. Los datos sintéticos del curso
permiten algo que ningún paper puede: probar los modelos donde la respuesta es conocida. En vol5_diario.parquet
(README de los datos del nivel 5, sección «Control») la media condicional del rendimiento es constante:
exactamente, con colas gruesas y asimetría. Ningún modelo puede batir a la media histórica salvo
por azar. Es el control perfecto para un modelo fundacional: si «encuentra» algo, está midiendo ruido.
El protocolo imita al del benchmark, con origen móvil y sin fugas: en cada origen el modelo recibe las 512 sesiones anteriores (de a ) y prevé . Para que la lección corra en un par de minutos en CPU se toma una de cada 40 sesiones de 2018 a 2025 en los seis activos; en una investigación de verdad se usarían todos los días y más series.
Fuente Mermaid
flowchart LR A["512 sesiones"] --> B[Modelo sin ajuste] B --> C["Previsión de r_t"] C --> D["Pérdida vs base"]
import numpy as np
import pandas as pd
d = pd.read_parquet("vol5_diario.parquet")
ACT = list(d["activo"].unique())
g = d.groupby("activo", sort=False)
r = {a: x["rendimiento"].to_numpy() for a, x in g}
rv = {a: x["rv_5min"].to_numpy() for a, x in g}
fechas = pd.DatetimeIndex(d.loc[d["activo"] == "indice", "fecha"])
CTX = 512 # contexto: 512 sesiones
corte = fechas.searchsorted(pd.Timestamp("2018-01-02"))
orig = np.arange(corte, len(fechas), 40) # una de cada 40 sesiones
act = np.repeat(ACT, len(orig))
y = np.concatenate([r[a][orig] for a in ACT])
ctx = [r[a][t - CTX:t].astype("float32") for a in ACT for t in orig]
media = np.concatenate([[r[a][:t].mean() for t in orig] for a in ACT])
print(f"{len(orig)} orígenes por activo, {len(y)} previsiones, "
f"{fechas[orig[0]].date()} a {fechas[orig[-1]].date()}")51 orígenes por activo, 306 previsiones, 2018-01-02 a 2025-12-16Hay dos baselines. La del benchmark, el paseo aleatorio sobre el precio, que equivale a prever rentabilidad cero. Y la de la literatura de predictibilidad (Campbell y Thompson, 2008; Welch y Goyal, 20082Nota 2 · Welch, I. y Goyal, A. (2008): A Comprehensive Look at the Empirical Performance of Equity Premium Prediction. The Review of Financial Studies 21(4), 1455-1508, https://doi.org/10.1093/rfs/hhm014.), la media histórica de los rendimientos hasta el día anterior. Los dos modelos se usan sin reentrenar (cómo se cargan y se configuran, en la lección 5.8.3), con la mediana como previsión puntual.
import torch
torch.manual_seed(0)
torch.use_deterministic_algorithms(True)
from chronos import BaseChronosPipeline
import timesfm
chronos = BaseChronosPipeline.from_pretrained(
"amazon/chronos-bolt-small", device_map="cpu", dtype=torch.float32)
q, _ = chronos.predict_quantiles(
inputs=[torch.tensor(c) for c in ctx], prediction_length=1,
quantile_levels=[0.1, 0.5, 0.9])
f_ch = q[:, 0, 1].numpy().astype(float) # mediana prevista
tfm = timesfm.TimesFM_2p5_200M_torch.from_pretrained(
"google/timesfm-2.5-200m-pytorch", torch_compile=False)
tfm.compile(timesfm.ForecastConfig(
max_context=CTX, max_horizon=16, normalize_inputs=True,
use_continuous_quantile_head=True, per_core_batch_size=len(ctx)))
punto, _ = tfm.forecast(horizon=1, inputs=ctx)
f_tf = punto[:, 0].astype(float)
prev = {"cero": np.zeros_like(y), "media": media,
"chronos": f_ch, "timesfm": f_tf}
pd.DataFrame({k: [np.std(v) / np.std(y), 100 * np.mean(v > 0)]
for k, v in prev.items()},
index=["desv. / desv. de r", "% previsiones > 0"]).round(3) cero media chronos timesfm
desv. / desv. de r 0.0 0.028 0.072 0.112
% previsiones > 0 0.0 83.333 62.745 68.301per_core_batch_size=len(ctx) hace que TimesFM procese las 306 series de una vez: el valor por defecto, 1, las pasa
de una en una y en CPU multiplica el tiempo. Las previsiones de los dos modelos son pequeñas, como deben ser: su
desviación típica es el 7,2 % (Chronos) y el 11,2 % (TimesFM) de la del rendimiento, más que la de la media histórica
(2,8 %) pero muy lejos de lo que haría falta para explicar algo. Las dos se inclinan al alza (el 63 % y el 68 % de
las previsiones son positivas), como la media, que lo es en el 83 % de los orígenes porque cinco de los seis activos
tienen μ > 0.
Skill frente a prever cero
El skill es el del benchmark: , y su versión con el error cuadrático medio (ECM). Con la media histórica como base y el ECM, es el fuera de muestra de Campbell y Thompson:
def skill(f, base, m, perdida):
"""1 - pérdida media del modelo / pérdida media de la base, en %."""
L = (lambda p: (y[m] - p[m]) ** 2) if perdida == "ecm" else (
lambda p: np.abs(y[m] - p[m]))
return 100 * (1 - L(f).mean() / L(base).mean())
filas = {}
for a in ACT:
m = act == a
filas[a] = {f"{k}_{p}": skill(prev[k], prev["cero"], m, p)
for k in ["media", "chronos", "timesfm"]
for p in ["ecm", "eam"]}
t = pd.DataFrame(filas).T
t.loc["media de activos"] = t.mean()
t.round(2) media_ecm media_eam chronos_ecm chronos_eam timesfm_ecm timesfm_eam
indice -1.02 0.31 -6.55 -2.45 -1.72 -0.16
accion 0.12 1.26 -0.44 0.76 1.07 -0.76
bono 0.08 0.15 -3.63 -1.75 -6.33 -2.83
oro 0.94 -0.35 -0.38 -2.50 2.94 -0.43
divisa -0.79 -0.53 3.88 2.03 2.38 0.89
cripto 1.01 0.43 2.28 1.86 -0.88 -1.12
media de activos 0.06 0.21 -0.81 -0.34 -0.42 -0.74El cuadro se parece mucho al del benchmark: skill de unos pocos puntos, unas veces positiva y otras negativa. Chronos va del −6,55 % (índice, ECM) al +3,88 % (divisa); TimesFM, del −6,33 % (bono) al +2,94 % (oro). En la media de los seis activos, los dos pierden frente a prever cero con las dos pérdidas (de −0,34 a −0,81 %), y la media histórica queda en tablas (+0,06 y +0,21 %). Si este cuadro saliera de datos reales, alguien podría escribir que «TimesFM mejora un 2,9 % en el oro» o «Chronos un 3,9 % en divisas». Aquí se sabe que no hay nada que mejorar: esas cifras son el tamaño del ruido con 51 previsiones.
Diebold-Mariano y la corrección por pruebas múltiples
Para saber si una diferencia de pérdidas es ruido hace falta un test. El de Diebold y Mariano (1995) compara las pérdidas de dos previsiones del mismo objetivo, , y contrasta si su media es cero con una varianza que admite autocorrelación (la de largo plazo, , con autocovarianzas hasta para un horizonte ):
es la corrección de Harvey, Leybourne y Newbold (1997) para muestras pequeñas, que se compara con una t de Student de grados de libertad; es la que usa el benchmark de 2026. Aquí y la hipótesis alternativa es unilateral: el modelo pierde menos que la base ().
from scipy import stats
def dm(l_mod, l_base, h=1):
"""Diebold-Mariano con la corrección de Harvey, Leybourne y
Newbold. H1 unilateral: el modelo tiene menos pérdida."""
dd = l_mod - l_base
n = len(dd)
u = dd - dd.mean()
var = u @ u / n
for k in range(1, h): # autocovarianzas hasta h-1
var += 2 * (u[k:] @ u[:-k]) / n
t = dd.mean() / np.sqrt(var / n)
t *= np.sqrt((n + 1 - 2 * h + h * (h - 1) / n) / n)
return t, stats.t.cdf(t, df=n - 1)
pruebas = []
for a in ACT:
m = act == a
for k in ["chronos", "timesfm"]:
for b in ["cero", "media"]:
for p, L in [("ecm", np.square), ("eam", np.abs)]:
t_, p_ = dm(L(y[m] - prev[k][m]), L(y[m] - prev[b][m]))
pruebas.append((a, k, b, p, t_, p_))
pr = pd.DataFrame(pruebas, columns=["activo", "modelo", "base",
"perdida", "t", "p"])
print(len(pr), "pruebas; p < 0,05:", (pr["p"] < 0.05).sum())
pr.sort_values("p").head(4).round(3)48 pruebas; p < 0,05: 1
activo modelo base perdida t p
34 divisa chronos media ecm -1.704 0.047
32 divisa chronos cero ecm -1.551 0.064
41 cripto chronos cero eam -1.512 0.068
43 cripto chronos media eam -1.486 0.072Seis activos, dos modelos, dos baselines y dos pérdidas son 48 pruebas, y una sale «significativa»: Chronos frente a la media en la divisa, con el error cuadrático, t = −1,704 y p = 0,047. Es el activo con μ = 0 y sin ninguna dependencia entre rendimiento y volatilidad (ρ = 0 en el README): el menos predecible de los seis. Con 48 pruebas al 5 % se esperan unos 2,4 rechazos aunque nada funcione (algo menos aquí, porque las pruebas comparten datos y están correlacionadas). La figura muestra las 48:
La mayoría de los estadísticos son positivos: los modelos pierden más que las baselines, lo esperable cuando una previsión añade varianza sin información. La forma estándar de controlar el error de toda la familia es ajustar los p. Holm (1979) los ordena y compara el menor con , el siguiente con , etc.; es uniformemente más potente que Bonferroni y no supone independencia.
from statsmodels.stats.multitest import multipletests
rech, p_holm, _, _ = multipletests(pr["p"], alpha=0.05, method="holm")
print("rechazos con Holm:", rech.sum(),
"| p ajustado mínimo:", round(p_holm.min(), 3))rechazos con Holm: 0 | p ajustado mínimo: 1.0Ningún rechazo sobrevive: el p ajustado mínimo es 1 (0,047 × 48 pasa de 1 y se trunca). Es la misma lógica que el Deflated Sharpe de la lección 5.4.4 aplicada a pruebas de previsión. Y sirve para leer el benchmark: dos rechazos con p = 0,0421 en una familia de modelos, acciones y objetivos tampoco sobrevivirían a Holm, como sus autores reconocen al pedir que se lean como exploratorios.
La ilusión de los niveles
Un error que aparece en demostraciones de modelos fundacionales con datos financieros: alimentar el modelo con el precio y medir el acierto sobre el precio. La celda construye un precio con los rendimientos de cada activo, le pide a Chronos el precio de mañana y lo compara con dos cosas: la media del precio en la muestra (el R² habitual) y el precio de ayer (el paseo aleatorio). Después traduce la previsión a rendimiento implícito, .
precio = {a: 100 * np.cumprod(1 + r[a]) for a in ACT}
ctx_p = [precio[a][t - CTX:t].astype("float32")
for a in ACT for t in orig]
qp, _ = chronos.predict_quantiles(
inputs=[torch.tensor(c) for c in ctx_p], prediction_length=1,
quantile_levels=[0.5])
p_ch = qp[:, 0, 0].numpy().astype(float)
p_hoy = np.concatenate([precio[a][orig] for a in ACT])
p_ayer = np.concatenate([precio[a][orig - 1] for a in ACT])
def r2(obs, f, base):
sse, sst = np.sum((obs - f) ** 2), np.sum((obs - base) ** 2)
return 100 * (1 - sse / sst)
filas = {}
for a in ACT:
m = act == a
r_impl = p_ch[m] / p_ayer[m] - 1 # rendimiento implícito
filas[a] = {
"R2_precio": r2(p_hoy[m], p_ch[m], p_hoy[m].mean()),
"EAPM_chronos": 100 * np.mean(np.abs(p_ch[m] / p_hoy[m] - 1)),
"EAPM_ayer": 100 * np.mean(np.abs(p_ayer[m] / p_hoy[m] - 1)),
"R2_rend_impl": r2(y[m], r_impl, media[m])}
pd.DataFrame(filas).T.round(2) R2_precio EAPM_chronos EAPM_ayer R2_rend_impl
indice 99.82 0.82 0.74 -22.38
accion 99.77 1.02 0.92 -0.48
bono 99.37 0.34 0.31 -42.84
oro 99.84 0.59 0.45 -40.46
divisa 98.94 0.38 0.36 -16.07
cripto 99.27 2.92 2.70 -17.85El R² del precio va del 98,94 al 99,84 %, y un error absoluto porcentual medio (EAPM) del 0,3 al 2,9 % suena preciso. Las dos cifras son una ilusión: el precio es tan persistente que repetir el de ayer da un EAPM menor que el de Chronos en los seis activos (0,74 frente a 0,82 % en el índice, 2,70 frente a 2,92 % en la cripto). El rendimiento que implica la previsión pierde contra la media histórica en todos, con un R² de −0,48 a −42,84 %: al prever el nivel, el modelo añade ruido al precio de ayer. La figura de la cabecera pone esta fila junto a las otras.
El mismo modelo donde hay estructura
El contraste final usa el mismo Chronos-Bolt, los mismos orígenes y el mismo contexto, pero con el logaritmo de la
varianza realizada en lugar del rendimiento. En vol5 esa serie sigue un HAR en logaritmos con persistencia 0,92: hay
mucha estructura que aprender del pasado. La base vuelve a ser la media histórica, ahora del log de la RV.
ctx_v = [np.log(rv[a][t - CTX:t]).astype("float32")
for a in ACT for t in orig]
qv, _ = chronos.predict_quantiles(
inputs=[torch.tensor(c) for c in ctx_v], prediction_length=1,
quantile_levels=[0.5])
v_ch = qv[:, 0, 0].numpy().astype(float)
lv = np.log(np.concatenate([rv[a][orig] for a in ACT]))
lv_media = np.concatenate([[np.log(rv[a][:t]).mean() for t in orig]
for a in ACT])
r2_v = {a: r2(lv[act == a], v_ch[act == a], lv_media[act == a])
for a in ACT}
r2_r = {a: r2(y[act == a], f_ch[act == a], media[act == a])
for a in ACT}
pd.DataFrame({"R2_log_RV": r2_v, "R2_rendimiento": r2_r}).round(1) R2_log_RV R2_rendimiento
indice 67.7 -5.5
accion 24.1 -0.6
bono 48.6 -3.7
oro 56.0 -1.3
divisa 29.2 4.6
cripto 44.8 1.3Con la volatilidad, el mismo modelo sin ningún ajuste explica entre el 24,1 % (acción) y el 67,7 % (índice) de la varianza del log de la RV fuera de muestra; con el rendimiento, entre el −5,5 y el +4,6 %. La figura de la cabecera resume las cuatro filas con la media de los seis activos: 99,5 % para el precio (ilusión), 45,1 % para el log de la RV (estructura real), −0,9 % para el rendimiento (nada) y −23,3 % para el rendimiento implícito en el precio (peor que nada). Que el R² de la volatilidad sea alto no dice todavía si el modelo es bueno: hay que compararlo con lo que haría un HAR o un GARCH en las mismas fechas y con la pérdida adecuada. Eso es el laboratorio de la lección 5.8.5.
Cómo leer un estudio de modelos fundacionales en finanzas
| Pregunta | Señal de alarma | En los estudios de la lección |
|---|---|---|
| ¿Contra qué baseline? | Solo contra otros modelos complejos | El benchmark incluye el paseo aleatorio; Rahimikia et al., modelos lineales y de árboles |
| ¿Qué objetivo? | Precios en niveles | Rentabilidades en los dos |
| ¿Qué pérdida y qué test? | Sin test, o un test que ignora la dependencia | Diebold-Mariano con HLN en el primero |
| ¿Cuántas pruebas? | p sueltos entre decenas de combinaciones | p sin corregir en el primero, reconocido por los autores |
| ¿Cuánto dura la prueba? | Una sola ventana corta | ≈ 200 sesiones frente a 23 años |
| ¿Solapamiento con el preentrenamiento? | Modelos públicos sobre series públicas del periodo de prueba | Advertido y evitado en Rahimikia et al. |
| ¿Valor económico? | Sharpe sin costes | Negativo con 20 puntos básicos en Rahimikia et al. |
Errores típicos
- Confundir ranking con predictibilidad. El mejor de once modelos puede ser peor que prever cero; en el benchmark de 2026 lo es en seis de diez tareas.
- Evaluar precios en niveles. Un R² del 99 % y un EAPM del 1 % no dicen nada si el precio de ayer da lo mismo o menos.
- Quedarse con el único p < 0,05 de 48. En el control de la lección, el único «significativo» está en el activo con la media exactamente constante.
- Olvidar la baseline adecuada. El paseo aleatorio y la media histórica son difíciles de batir en rentabilidades; un modelo que no se compara con ellas no ha demostrado nada.
- Leer el Sharpe sin costes de una cartera diaria. Con rotación diaria sobre miles de acciones, 20 puntos básicos convierten un Sharpe de 6 en uno negativo.
- Ignorar el posible solapamiento. Un modelo público preentrenado con series financieras puede haber visto el periodo de prueba de los datos reales.
Ejercicios
- Repite el protocolo del benchmark con Chronos-Bolt: horizonte de 20 sesiones, error absoluto medio sobre las 20 sesiones de cada origen y skill frente a prever cero, con los mismos orígenes (salvo el último, al que no le quedan 20 sesiones). ¿Cambia la conclusión? Como los orígenes están separados 40 sesiones, las ventanas no se solapan y basta en Diebold-Mariano con la pérdida media de cada origen.
Solución
H = 20
o20 = orig[:-1]
ctx20 = [r[a][t - CTX:t].astype("float32") for a in ACT for t in o20]
q20, _ = chronos.predict_quantiles(
inputs=[torch.tensor(c) for c in ctx20], prediction_length=H,
quantile_levels=[0.5])
f20 = q20[:, :, 0].numpy().astype(float) # (orígenes, 20)
y20 = np.array([r[a][t:t + H] for a in ACT for t in o20])
a20 = np.repeat(ACT, len(o20))
eam_m = np.abs(y20 - f20).mean(axis=1) # EAM por origen
eam_0 = np.abs(y20).mean(axis=1)
filas = {}
for a in ACT:
m = a20 == a
t_, p_ = dm(eam_m[m], eam_0[m])
sk = 100 * (1 - eam_m[m].mean() / eam_0[m].mean())
filas[a] = {"skill_%": sk, "t": t_, "p": p_}
pd.DataFrame(filas).T.round(3) skill_% t p
indice 0.703 -1.137 0.131
accion 0.281 -0.743 0.231
bono -0.011 0.035 0.514
oro -0.930 2.250 0.986
divisa -0.408 2.396 0.990
cripto -0.227 0.615 0.729No cambia. Con el horizonte y la métrica del benchmark, el skill de Chronos frente a prever cero va del −0,93 % (oro) al +0,70 % (índice), y ningún p unilateral baja de 0,13. En el oro y la divisa el estadístico es positivo y grande (t = 2,25 y 2,40): ahí el modelo es peor que prever cero, y un test bilateral lo diría con p < 0,05. Sumar 20 sesiones no crea información: la previsión de cada paso sigue sin poder anticipar un rendimiento cuya media condicional es constante. Con 50 orígenes por activo y error absoluto, el ruido es del mismo orden que en el benchmark.
- Simula el problema de las pruebas múltiples: genera 2 000 «modelos» de ruido puro para el índice (previsiones normales con la desviación típica de las de Chronos en ese activo) y prueba cada uno contra la media histórica con el error cuadrático. ¿Qué fracción da p < 0,05? ¿Cuál es el p del mejor?
Solución
rng = np.random.default_rng(5)
m = act == "indice"
ruido = rng.normal(0, f_ch[m].std(), size=(2000, m.sum()))
l_base = (y[m] - media[m]) ** 2
ps = np.array([dm((y[m] - f) ** 2, l_base)[1] for f in ruido])
print(f"p < 0,05: {np.mean(ps < 0.05):.1%} | mejor p: {ps.min():.4f}"
f" | con Holm: {multipletests(ps, method='holm')[0].sum()}")p < 0,05: 4.2% | mejor p: 0.0004 | con Holm: 0Un 4,2 % de los modelos de ruido «mejora» a la media con p < 0,05; algo menos del 5 % nominal porque un ruido añadido a la previsión empeora el error cuadrático en esperanza. El mejor tiene p = 0,0004, un resultado que en un paper parecería contundente; con Holm sobre los 2 000, ninguno sobrevive. Es la versión extrema de lo que pasa al probar muchos modelos, contextos, cuantiles y activos y publicar el mejor: sin el número de intentos, un p pequeño no significa nada (lecciones 2.5.4 y 5.4.4).
- Sin código: un artículo afirma que «un modelo fundacional sin reentrenar consigue un Sharpe de 3 en una estrategia larga-corta diaria con las 500 acciones del S&P 500, 2020-2024, frente a 0,4 del momentum». ¿Qué preguntas harías antes de creerlo?
Solución
Primero, las de la cadena de evidencia. ¿Hay costes? Con rebalanceo diario de 500 acciones, la rotación es enorme y
20 puntos básicos bastaron para hacer negativo un Sharpe de 6 en Rahimikia, Ni y Wang. ¿El periodo de prueba estaba en
el preentrenamiento? Los modelos públicos se preentrenaron con corpus que pueden incluir precios de acciones de
EE. UU. de esos años: sería sesgo de anticipación. ¿Cuántas configuraciones (modelo, tamaño, contexto, horizonte,
cuantil, regla de cartera) se probaron antes de esta? El Sharpe habría que deflactarlo por ese número (lección 5.4.4).
¿Las 500 acciones son las del índice en cada fecha o las de hoy (supervivencia)? ¿Es significativa la diferencia con el
momentum en una prueba emparejada? Y una comprobación barata que se puede hacer en casa: pasar el mismo pipeline por
una serie con media impredecible, como el control de vol5, y ver si también «gana».
Footnotes
-
Goel, A., Pasricha, P., Magris, M. y Kanniainen, J. (2025): Foundation Time-Series AI Model for Realized Volatility Forecasting, arXiv:2505.11163, https://arxiv.org/abs/2505.11163. ↩
-
Welch, I. y Goyal, A. (2008): A Comprehensive Look at the Empirical Performance of Equity Premium Prediction. The Review of Financial Studies 21(4), 1455-1508, https://doi.org/10.1093/rfs/hhm014. ↩
Respuesta plegada en cada pregunta
Autoevaluación
En el benchmark de 2026 (arXiv:2606.27100), Moirai-2.0 y TimesFM-2.5 logran los mejores rankings medios (2,9 y 3,1) entre once modelos. ¿Qué se puede concluir de ese dato?
- AQue los dos predicen las rentabilidades diarias mejor que el paseo aleatorio
- BQue ganan en las diez tareas del estudio
- CQue ordenan mejor que el resto de modelos de la comparación, lo que no implica batir a prever cero: en seis de las diez tareas el ganador tiene skill negativa frente al paseo aleatorio
- DQue sus previsiones generan valor económico después de costes
Ver respuesta
Respuesta C. Que ordenan mejor que el resto de modelos de la comparación, lo que no implica batir a prever cero: en seis de las diez tareas el ganador tiene skill negativa frente al paseo aleatorio
El ranking compara modelos entre sí. La tabla 5 del artículo muestra que el ganador de AAPL, JPM y META (en rentabilidades lineales y logarítmicas) tiene un error absoluto mayor que el de prever rentabilidad cero, y el test de Diebold-Mariano solo rechaza en dos casos. Los propios autores escriben que un ranking fuerte no implica predictibilidad con significado económico.
En la lección se hacen 48 pruebas de Diebold-Mariano (6 activos, 2 modelos, 2 baselines, 2 pérdidas) y una da p = 0,047: Chronos frente a la media histórica en la divisa. ¿Cómo se interpreta?
- AComo un falso positivo esperable: con 48 pruebas al 5 % lo raro sería no tener ninguno, con Holm no sobrevive y en esa serie la media condicional es constante por construcción
- BComo prueba de que Chronos capta algo en las divisas que los demás activos no tienen
- CComo señal de que hay que operar la divisa con Chronos y vigilarlo
- DComo un error del test, que solo vale con más de 1 000 observaciones
Ver respuesta
Respuesta A. Como un falso positivo esperable: con 48 pruebas al 5 % lo raro sería no tener ninguno, con Holm no sobrevive y en esa serie la media condicional es constante por construcción
Con 48 pruebas independientes al 5 % se esperan unos 2,4 rechazos aunque nada funcione. La corrección de Holm lleva el p ajustado mínimo a 1. Y la respuesta conocida del generador dice que E[r_t | t−1] = μ exactamente: no hay nada que encontrar.
Chronos-Bolt, alimentado con el precio en vez del rendimiento, da un R² del 98,9 al 99,8 % en los seis activos. ¿Por qué no es una buena noticia?
- APorque el R² solo vale para modelos lineales
- BPorque 51 orígenes por activo son pocos para medir el R²
- CPorque el modelo está sobreajustado a los datos de 2018-2025
- DPorque el precio es tan persistente que cualquier previsión cercana al precio de ayer tiene un R² del 99 %; la comparación útil es con el precio de ayer, al que Chronos no bate en error porcentual, y su rendimiento implícito da un R² del −23 % de media
Ver respuesta
Respuesta D. Porque el precio es tan persistente que cualquier previsión cercana al precio de ayer tiene un R² del 99 %; la comparación útil es con el precio de ayer, al que Chronos no bate en error porcentual, y su rendimiento implícito da un R² del −23 % de media
El R² de un nivel se mide frente a la media del nivel en la muestra, una referencia absurda para una serie con raíz unitaria. El error absoluto porcentual de Chronos es mayor que el de repetir el precio de ayer en los seis activos, y el rendimiento que implica su previsión pierde frente a la media histórica en todos.
Rahimikia, Ni y Wang (arXiv:2511.18578) publican un Sharpe de 6,46 para la cartera larga-corta de CatBoost sin costes (ventana de 512) y una media de −3,62 con 20 puntos básicos. ¿Qué conclusión es correcta?
- AQue CatBoost es una estrategia excelente si se opera con un broker barato
- BQue una cartera larga-corta por deciles rebalanceada cada día sobre miles de acciones rota tanto que el Sharpe sin costes no dice nada del neto; y que los modelos fundacionales sin reentrenar ya quedaban muy por debajo antes de costes
- CQue los costes afectan igual a cualquier estrategia y no cambian la comparación
- DQue el estudio demuestra que los modelos fundacionales funcionan mejor con costes
Ver respuesta
Respuesta B. Que una cartera larga-corta por deciles rebalanceada cada día sobre miles de acciones rota tanto que el Sharpe sin costes no dice nada del neto; y que los modelos fundacionales sin reentrenar ya quedaban muy por debajo antes de costes
Los autores dicen que con 20 puntos básicos o más todas las carteras larga-corta pasan a Sharpe negativo, sea cual sea el modelo. Antes de costes, Chronos large sin reentrenar daba 2,92 y TimesFM de 500 millones −0,18, frente a 6,46 de CatBoost.
Con la evidencia de esta lección, ¿qué uso de un modelo fundacional de series tiene más respaldo en finanzas?
- APrever el rendimiento de mañana de una acción y operar su signo
- BSustituir a todos los modelos econométricos sin compararlos
- CPrever la volatilidad o series con estructura como una baseline más, comparada con un HAR con pruebas formales, y con escepticismo ante la predicción directa de rentabilidades
- DGenerar precios futuros para calcular el VaR
Ver respuesta
Respuesta C. Prever la volatilidad o series con estructura como una baseline más, comparada con un HAR con pruebas formales, y con escepticismo ante la predicción directa de rentabilidades
En volatilidad hay estructura (memoria larga, agrupamiento) y el mismo Chronos-Bolt explica entre el 24 y el 68 % de la varianza del log de la RV en los datos del curso. Aun así, en un estudio con 50 activos reales los modelos fundacionales no mejoran de forma uniforme al Log-HAR (Brini, 2026). En rentabilidades, las mejoras son pequeñas, escasas y no sobreviven a los costes.
Ideas clave
- Un ranking entre modelos no es una mejora frente a una baseline ingenua. En el benchmark de 2026, Moirai-2.0 y TimesFM-2.5 tienen los mejores rankings medios (2,9 y 3,1), pero el ganador de seis de las diez tareas pierde frente a prever rentabilidad cero y Diebold-Mariano solo rechaza en dos casos, con p sin corregir.
- En el estudio de Rahimikia, Ni y Wang, Chronos y TimesFM sin reentrenar quedan muy por debajo de CatBoost en carteras larga-corta (Sharpe 2,92 y −0,18 frente a 6,46, sin costes); con 20 puntos básicos de coste todas las carteras, también la de CatBoost, pasan a Sharpe negativo.
- En una serie con media condicional constante, Chronos-Bolt y TimesFM-2.5 producen previsiones con un 7-11 % de la desviación del rendimiento y skill media negativa frente a prever cero; de 48 pruebas, una da p < 0,05 y ninguna sobrevive a Holm.
- Prever precios en niveles es una ilusión: R² del 99 % que no baten al precio de ayer y un rendimiento implícito con R² del −23 % de media.
- El mismo modelo explica entre el 24 y el 68 % de la varianza del log de la varianza realizada: los modelos fundacionales sirven donde hay estructura, y aun ahí hay que compararlos con un HAR (lección 5.8.5).
- Para leer un estudio: baseline ingenua, pérdida, test con dependencia, corrección por pruebas múltiples, solapamiento con el preentrenamiento, costes y capacidad.
Recursos
Libros
- Noguer i Alonso, M. y Pereira Franklin, R. (2026): Pretrained Time-Series Foundation Models for Financial Return Forecasting (arXiv:2606.27100)
- Rahimikia, E., Ni, H. y Wang, W. (2025): Re(Visiting) Time Series Foundation Models in Finance (arXiv:2511.18578)
- Brini, A. (2026): Forecasting Realized Volatility with Time Series Foundation Models: A Comparison with Econometric Benchmarks (arXiv:2607.05291)
- Diebold, F. X. y Mariano, R. S. (1995): Comparing Predictive Accuracy. Journal of Business & Economic Statistics 13(3), 253-263
- Harvey, D., Leybourne, S. y Newbold, P. (1997): Testing the equality of prediction mean squared errors. International Journal of Forecasting 13(2), 281-291
- Campbell, J. Y. y Thompson, S. B. (2008): Predicting Excess Stock Returns Out of Sample. The Review of Financial Studies 21(4), 1509-1531