Cómo hacer backtesting de lending sin look-ahead
¿Cómo se hace un backtesting de una estrategia de lending o looping sin aplicar los parámetros de hoy a datos pasados? Reconstruyendo cada parámetro del que depende la estrategia a partir de los eventos del propio protocolo, fechando cada cambio por el bloque que lo ejecutó. Un solo colateral en un solo mercado de Aave muestra por qué las fuentes habituales se quedan cortas:
- El foro fecha un cambio semanas antes de tiempo. El umbral de liquidación de WBTC en Aave V3 Optimism subió 34 días después de publicarse la propuesta.
- Una propuesta puede dar un valor de partida erróneo. Decía que la penalización por liquidación era del 10 %. La blockchain mostraba un 9,4 % desde hacía tres semanas.
- Una foto diaria no ve estados que duran horas. Durante 73 minutos del 30 de octubre de 2026, se podía depositar WBTC, pero no contaba nada como colateral.
- El modelo de tipos también cambia. Durante 64 horas, el tramo empinado de la curva de tipos de USDC bajó del 10 % al 6 %.
Datos a 5 de noviembre de 2026. Cada cifra onchain enlaza a la transacción que la fijó.
Por qué engañan los parámetros de hoy
Un mercado de préstamos funciona con reglas que la gobernanza cambia continuamente: loan-to-value (LTV, lo máximo que se puede pedir prestado contra un colateral), umbral de liquidación (el punto a partir del cual se puede liquidar una posición), penalización por liquidación, límites, el modelo de tipos de interés y si una reserva está congelada (sin nuevos depósitos ni préstamos). En Aave, una posición se puede liquidar en cuanto su health factor baja de 1:
Health factor = (valor del colateral × umbral de liquidación medio ponderado) / valor prestado
Si pasas una posición de 2023 por un umbral posterior, el backtesting liquida posiciones distintas en momentos distintos. Es sesgo de anticipación (look-ahead): la prueba usa información que no existía el día de la operación. Le importa a un desk que prueba un looping y a un curator que comprueba cómo habrían aguantado los mercados de su vault. Los datos macroeconómicos resuelven el mismo problema con añadas (vintages). El ALFRED de la Fed de St. Louis permite recuperar cada publicación de datos económicos tal como estaba disponible en una fecha concreta. Los parámetros de un protocolo necesitan el mismo tratamiento, y la blockchain ya los guarda.
Un ejemplo fechado: WBTC en Aave V3 Optimism
Este es cada cambio del LTV, el umbral de liquidación y la penalización por liquidación de WBTC en Aave V3 Optimism, más su estado de congelación, leído del contrato de configuración del protocolo:
| Fecha (UTC) | LTV | Umbral de liq. | Penalización | Cambio |
|---|---|---|---|---|
| 11 mar 2022 | 70 % | 75 % | 10 % | Alta |
| 1 mar 2023 | 70 % | 75 % | 9,4 % | Rebaja de penalización |
| 25 abr 2023 | 73 % | 78 % | 8,5 % | AIP-206 |
| 5 sep 2023 | 73 % | 78 % | 7,5 % | Rebaja de penalización |
| 29 oct 2026, 23:03 | 0 % | 78 % | 7,5 % | Congelada |
| 30 oct 2026, 12:44 | 0 % | 78 % | 7,5 % | Descongelada, LTV aún a 0 |
| 30 oct 2026, 13:57 | 73 % | 78 % | 7,5 % | LTV restaurado |
El histórico muestra cuatro cosas.
1. Fecha cada cambio por el bloque que lo ejecutó
Chaos Labs, entonces uno de los gestores de riesgo de Aave, propuso subir el umbral de WBTC del 75 % al 78 %. El cambio tardó cinco semanas en llegar a la blockchain:
- 22 de marzo de 2023: propuesta publicada en el foro.
- 31 de marzo: cierra la votación offchain en Snapshot.
- 22 de abril: la AIP-206 se ejecuta en Ethereum, tras una votación onchain del 18 al 21 de abril.
- 25 de abril, 17:35 UTC: en vigor en Optimism, a través del bridge executor que lleva las decisiones de Ethereum a la L2.
Fechado por la publicación en el foro, un backtesting aplica el cambio 34 días antes de tiempo. Por el resultado de Snapshot, 25 días antes. Por la ejecución en Ethereum, 3 días antes.
Una posición hipotética muestra lo que está en juego. Toma 100.000 $ en WBTC contra 70.000 $ de deuda en stablecoins, el máximo que permitía un LTV del 70 %, y deja de lado los intereses acumulados. Tras una caída del 8 % de WBTC, el health factor es 0,99 con un umbral del 75 %, expuesta a liquidación, y 1,03 con el 78 %. Y una estrategia que pide prestado todo lo que puede toma un préstamo mayor con el nuevo LTV del 73 %, así que los dos backtestings ni siquiera tienen la misma posición.
2. Lee los valores del contrato, no de la propuesta
La propuesta del 22 de marzo indica como penalización por liquidación vigente de WBTC un 10 % y propone un 8,5 %. En la blockchain era del 9,4 % desde el 1 de marzo de 2023, cuando entró en vigor una propuesta anterior de Gauntlet. La rebaja que se ejecutó en abril fue de 0,9 puntos, no de los 1,5 que describe la propuesta. Usa el foro para saber por qué cambió un parámetro y el contrato para saber cuánto valía.
3. Registra los estados que duran horas
El 29 de octubre de 2026, tras el exploit de una hot wallet de Binance, las multisigs que Aave reserva para emergencias congelaron 175 reservas de Aave V3 en 16 redes y 117 de Aave V4. En Optimism, WBTC se congeló a las 23:03 UTC y se descongeló a las 12:44 UTC del día siguiente. Su LTV pasó a 0 con la congelación, pero siguió a 0 hasta las 13:57, porque en el código actual de Aave V3 descongelar una reserva no restaura su LTV: el emergency admin lo restaura con llamadas aparte, fuera de e-mode y dentro de cada e-mode (el modo de Aave con LTV más alto para activos correlacionados) en el que el activo es colateral. Así que durante 73 minutos se podía volver a depositar WBTC, pero no contaba nada como colateral. Un histórico construido solo con los eventos de congelación no ve esa ventana.
Una foto diaria no ve nada de esto, y además las reglas cambiaron: según la publicación de LlamaRisk, otro gestor de riesgo de Aave, se podía devolver deuda y retirar fondos y las liquidaciones seguían funcionando, pero nadie podía añadir colateral. Entre las 23:03 y las 12:44 UTC, devolver deuda era la única forma de subir un health factor.
4. Trata el modelo de tipos como un parámetro
A las 02:01 UTC del 30 de octubre, unas tres horas después de congelarse WBTC, se cambió la curva de tipos de USDC en Aave V3 Optimism: el Slope2, el tramo empinado por encima del 90 % de utilización, pasó del 10 % al 6 %. LlamaRisk había recomendado el recorte porque USDC en Optimism estaba al 94,9 % de utilización y, con los nuevos depósitos bloqueados, un tipo más alto sobre todo aumentaba la deuda de los prestatarios. Volvió al 10 % el 1 de noviembre a las 18:02 UTC, 64 horas después. Un looping que tomó USDC prestado esos días pagó un tipo que ninguna foto diaria ni ninguna propuesta mostraría.
Las estrategias con vaults tienen el mismo problema con las comisiones. En Morpho, un cambio de comisión en una vault V1 es inmediato. En V2 espera a un timelock que el curator fija por función y que puede ser cero. Lee el histórico de comisiones y timelocks de cada vault en lugar de suponer un plazo.
El método, paso a paso
- Enumera cada parámetro que toca la estrategia. Para un looping en Aave: LTV, umbral de liquidación, penalización y comisión de liquidación del protocolo de cada colateral; reserve factor; límites, techos de deuda y modo de aislamiento; el modelo de tipos de cada activo prestado; la configuración de e-mode; los estados de congelación y pausa; las reglas de close factor; y el oráculo que lee cada reserva, incluidos sus topes de precio. Para una vault: comisiones, timelocks, límites de asignación y los mercados que puede usar.
- Obtén cada uno de los eventos. En Aave V3, la mayoría de los cambios salen del contrato de
configuración:
CollateralConfigurationChanged,ReserveFrozen,ReservePaused,AssetLtvzeroInEModeChangedy los demás eventos de e-mode,ReserveInterestRateDataChangedy los cambios de límites. Los cambios de fuente del oráculo salen del contrato del oráculo (AssetSourceUpdated). Guarda bloque, marca de tiempo, transacción y valor de cada uno. - Indexa por número de bloque. Para cada acción simulada, toma el último valor fijado en ese bloque o antes. Es un cruce as-of, el mismo que se usa con los datos por añadas.
- Fecha por ejecución. Conserva la publicación del foro, la votación y la propuesta como metadatos que explican un cambio. En despliegues en L2, la ejecución en L1 tampoco es la fecha efectiva.
- Usa los precios tal como los vio el protocolo. Las liquidaciones se disparan con el precio del oráculo leído en ese bloque, no con un cierre de exchange. Toma el valor del oráculo del mismo bloque que los parámetros.
- Concilia con el estado. Comprueba el histórico reconstruido con lecturas directas del contrato en
bloques elegidos (en Aave,
getConfigurationcontra un nodo de archivo). Si no coinciden, te falta un tipo de evento.
Límites
- Un histórico limpio no garantiza un backtesting limpio. Los datos tal como se conocían en cada momento eliminan el sesgo de anticipación de los datos. No evitan el sobreajuste por probar muchas variantes de una estrategia sobre el mismo histórico, un problema que describen Bailey, Borwein, López de Prado y Zhu (2017).
- Repetir una posición con otras reglas supone que los demás actúan igual que entonces. Liquidadores, arbitrajistas y otros prestatarios podrían no hacerlo.
- El significado de los eventos cambia con las actualizaciones. Antes de Aave 3.1, congelar una reserva no tocaba su LTV; en el código actual, descongelarla no lo restaura. Lee cada evento en el contexto de la versión del contrato que lo emitió.
- Un backtesting no es una previsión. Muestra cómo le fue a una estrategia con las reglas vigentes. No dice nada seguro sobre el próximo cambio.
Hacerlo para toda una cartera
Un solo activo en un solo mercado ya ha necesitado varios tipos de evento, el rastro de ejecución de L1 a L2 y una comprobación de la versión del contrato. Una cartera real abarca muchas reservas, vaults y blockchains. Datablocks indexa todas las blockchains EVM desde el génesis y se actualiza en cada bloque, así que un backtesting puede usar lo que se sabía entonces, fracasos incluidos. Si estás montando uno, reserva una llamada aquí abajo y cuéntanos qué protocolos y estrategias necesitas cubrir.