15 de noviembre de 2026 · investigación

¿Cómo haces backtest del volumen cripto cuando el wash trading infla la cinta?

¿Cómo haces backtest del volumen cripto cuando el wash trading infla la cinta?

El lunes hicimos lo responsable. El agente tenía una estrategia de momentum sobre un perpetuo USDT-M mid-cap, con clips de 25,000 USDT por operación, y el primer backtest sin filtro de volumen ejecutó cada señal como si el libro fuera BTC. Así que añadimos la barrera de manual: veinte barras de un minuto de volumen en dólares tenían que superar veinte veces el clip antes de que pudiera salir una orden. Veinte minutos, medio millón de dólares de cinta. La moneda imprimía unos $40 million en un día ajetreado. El filtro conservó la mayoría de las señales. La curva de equity se volvió menos dentada. Lo mandamos a paper.

Once horas después, una compra de 25,000 USDT se comió 8,400 de bid y se detuvo. El volumen de veinte barras en ese minuto era $1.14 million. El filtro había dicho que sí.

34%de la cinta reportada nunca movió un nivel del libro
11 hrsde paper antes del primer clip atascado
20×regla clip-a-volumen que aun así dijo que sí

Lunes: el filtro que nos hizo sentir honestos

La nota del agente en el pull request era "chequeo de capacidad añadido, 20× nocional." Lo aprobé. Ya he aprobado esa frase antes. Es el tipo de regla que escribes después de que alguien te enseña un backtest que operó una moneda de $4,000-OI en clips de $50,000, y todo el mundo en la sala pone cara, y añades un múltiplo de volumen para que no vuelva a pasar.

El lunes la regla hizo lo que siempre hace en un backtest. Descartó las horas muertas. Conservó las horas en las que el propio número de volumen del exchange se veía ruidoso. El turnover cayó alrededor de un tercio. El tamaño medio de operación se quedó en 25,000 porque el modelo de fill es un cobarde: se lleva el clip entero al last más unos cuantos bps siempre que la barrera está abierta. Nadie le preguntó al libro si 25,000 estaba realmente sentado ahí.

Todavía me da un respingo cuando el volumen 24h de una moneda es un número redondo junto a un interés abierto flaco. Eso es residuo de 2021, cuando los bots de "market making" de Discord eran dos subcuentas operando entre sí y pegando la captura de volumen en #brag. La cinta parece una fiesta. El libro es cartón. Me dije que un filtro 20× sobre barras de un minuto era cómo se crece y se deja eso atrás. No lo es. Es cómo se promedia el cartón hasta un número más suave.

Martes: paper, y luego un resto

El paper empezó amable. Los primeros cinco clips se ejecutaron en 2–4 saltos bajando el ask. Feo, pero hecho. Luego, 14:07 UTC, una señal long, 25,000 USDT, top of book 1,100, siguiente nivel 2,400, y después aire. Conseguimos 8,400 ejecutados como taker y 16,600 en resting. Cuarenta segundos después el resto se canceló por nuestro propio time-in-force. La estrategia creía que estaba long un clip entero. La cuenta estaba long un tercio de uno.

Pero el filtro había dicho que sí. Saqué la barra. El volumen en dólares en los veinte minutos hasta las 14:07 era $1.14 million, holgadamente por encima de $500k. Unos $380k de esos $1.14 million eran pares de prints: mismo precio, mismo tamaño, flags de aggressor opuestos, a 2–8 milisegundos de distancia, y el tamaño de bid/ask en ese precio no se inmutó. Esas operaciones se pagaron las comisiones entre sí. No nos ofrecieron un agujero de 25,000 USDT.

Miércoles: emparejar la cinta con el libro

El miércoles fue el día lento, el que la próxima vez presupuestaría el doble de largo. Tomamos cinco días laborables de trades y snapshots L2 del mismo perp, fotos del libro a 100ms, y clasificamos cada print contra el libro un snapshot antes y un snapshot después.

  1. Si el tamaño al precio del trade bajó aproximadamente el tamaño del trade, tocó el libro. Cuéntalo.
  2. Si una compra y una venta de igual tamaño cruzaron a un precio sin cambio en el libro, llámalo wash y sácalo de cualquier cifra de capacidad.
  3. Si un trade recorrió varios niveles y esos niveles desaparecieron, eso es un taker de verdad. Cuéntalo, y no finjas que tú también puedes tomar esa liquidez; alguien ya lo hizo.
  4. Si el trade está etiquetado como liquidación, es tamaño real, y es el último tamaño que quieres usar como prueba de que tú puedes clipar 25,000. La orden forzada te está adelantando.

Los snapshots mienten un poco. Cualquier cosa que se ejecuta y se repone dentro de 100ms parece un fantasma, y algunos market-makers genuinos hacen cancel-replace así de rápido. Más tarde muestreamos unos minutos de libros a 10ms y la proporción de wash se movió un par de puntos, no por un factor de dos. Puedo vivir con un par de puntos. No puedo vivir tratando el ticker de volumen del exchange como un censo de liquidez.

AggTrades ya colapsan un taker golpeando a varios makers a un precio. No colapsan dos subcuentas haciendo wash. Si tu feed "limpio" son trades agregados, sigues teniendo este problema. Solo que lo tienes con menos filas.

Y el volumen 24h en la API del ticker es la misma suma sucia, retrasada, y por eso los agentes de research la adoran. Un campo. Siempre presente. Parece una feature. Es una estadística de marketing que resulta estar en el protobuf de market-data.

Si un número de volumen no se puede conciliar con un cambio en el libro, no pertenece a un chequeo de capacidad, a un modelo de impacto ni a un filtro de universo. El ticker 24h es la peor copia de ese número, porque ya ha sido sumado, redondeado y despojado de tiempo.

Jueves: la semana en una tabla

Cinco sesiones, el mismo clip, la misma regla 20×, el mismo modelo de fill en el backtest. El paper fill ratio es el nocional ejecutado sobre el nocional pretendido de las órdenes que realmente enviamos esa sesión. El paper del lunes está en blanco porque todavía estábamos en el backtest.

SesiónCinta del exchangeQue mueve el libroTipo washPrints de liq.El filtro dijo adelanteFill de paper
Lun$38.4m$22.6m$13.5m$2.3m41 / 48 señalesn/a
Mar$41.1m$24.2m$15.2m$1.7m36 / 400.61
Mié$29.6m$20.1m$8.1m$1.4m22 / 310.77
Jue$44.8m$25.6m$17.4m$1.8m39 / 440.54
Vie$33.2m$22.3m$9.4m$1.5m28 / 350.71

Los prints tipo wash fueron el 34% de la cinta de la semana. No estaban repartidos de forma uniforme. El jueves, la sesión que más le gustaba al filtro original, fue la más sucia. Ese es el modo de fallo que me importa. La barrera no solo sobreestima la liquidez en promedio. Se abre más los días en que los bots de wash están trabajando, porque esos días son cuando el número crudo se ve más sano.

Volvimos a correr el backtest solo con el volumen que mueve el libro, el mismo múltiplo 20×. Las señales cayeron de 198 en la semana a 121. Muchas de las descartadas estaban en esas horas estilo jueves en las que la cinta era ruidosa y el top of book era 1,100 USDT. El Sharpe original usaba 198 fills completos. No voy a citar el nuevo como si fuera un hallazgo sobre la estrategia. Es un hallazgo sobre el modelo de fill: en cuanto dejas de conceder 25,000 USDT a un precio que el libro no tenía, un trozo del "edge" son solo órdenes completadas que habrían sido restos.

Viernes: lo que realmente enviamos, y lo que yo me saltaría

La barrera que nos quedamos es aburrida. El nocional rodante que mueve el libro, contado solo a partir de prints que quitaron tamaño de un nivel, tiene que superar 20× el clip, y lo medimos en las barras antes de la barra de decisión para que el wash del minuto actual no pueda votar. Los prints de liquidación tienen un tope aparte: si más de un cuarto del volumen reciente que mueve el libro son liquidaciones, la estrategia se queda quieta. El flujo forzado es tamaño real que te adelanta.

El impacto recibió la misma dieta. El modelo viejo infería un lambda de Kyle a partir del volumen del exchange y nuestro clip. Aliméntalo con wash y lambda baja, porque el mercado parece profundo. Aliméntalo con volumen que mueve el libro y el mismo clip es una parte mucho mayor de lo que realmente cambió el libro. El slippage de paper en las siguientes sesiones se situó más cerca de esa cifra más fea. Más cerca, no idéntico. Seguimos sin ver la cola, y una foto de 100ms todavía se pierde algo de tamaño genuino.

Lo que me saltaría la próxima vez es todo el primer lunes. No empieces por el ticker, no empieces por el volumen 24h, no dejes que el agente meta el volumen crudo en dólares en el feature store y en la barrera como si fueran dos ideas. Son una sola serie sucia, usada dos veces. Construye primero la cinta consistente con el libro, aunque eso signifique investigar dos días un solo mid-cap antes de tener un universo. Un universo filtrado por wash es una lista de monedas que se dan maña para parecer ocupadas.

El otro salto: cualquier modelo de fill que trate un chequeo de volumen aprobado como un fill. El resto del martes era la estrategia. El filtro solo puede responder "¿ha estado alguien operando?". No puede responder "¿tus 25,000 van a quedar en resting o a desaparecer?". Esa segunda pregunta necesita el libro, un resto y un time-in-force, que es otro diario, y el que deberíamos haber escrito antes que este.

wash tradingvolumencriptobacktestingmicroestructura de mercado
← Todos los artículos