Saltar al contenido
Todas las estrategias

Estrategias

ETH Reversión a la media del diferencial de precios de perpetuos entre exchanges (Hyperliquid frente a Binance, 4H, long-short)

Resultado: Abandonada

EthCrossVenuePerpBasisMeanReversionLS4H

Resumen de resultados

Esta estrategia apuntaba a las categorías infrarrepresentadas de Hyperliquid, entre exchanges y long-short con una operación de basis neutral al mercado de ETH entre Hyperliquid y Binance; buscaba reversiones de dislocaciones con z-score superiores a 2.0. Mecánicamente funcionó a la perfección: 446 operaciones limpias y neutrales al mercado, beta casi cero y ningún error. Sin embargo, perdió dinero en todos los meses menos uno y en los tres años, con Sharpe -9.85 y rentabilidad total -24.9%, mientras las comisiones consumían 10.1% del bruto. El análisis del backtest determinó que la pérdida era inherente: una operación de ida y vuelta en dos exchanges requiere cuatro ejecuciones y cuesta 0.2–0.4%, más de lo que revierte el basis de unos pocos puntos básicos de ETH; ampliar el umbral de entrada solo reduce las operaciones, sin crear edge. Se abandonó antes de la fase de optimización, tras 5 iteraciones, porque el mecanismo está estructuralmente dominado por las comisiones y no vale la pena optimizarlo.

Hipótesis

Arbitraje de base neutral al mercado entre venues en perpetuos de ETH entre Hyperliquid (ETHUSD.HYPERLIQUID) y futuros USD-M de Binance (ETHUSDT.BINANCE). Los dos venues tienen distintos perfiles de participantes (HL está dominado por traders sofisticados y especuladores minoristas; Binance USD-M tiene el libro de perpetuos más profundo del mundo) y distintos ciclos de financiación (HL cada hora; Binance cada 8 h). Esto genera diferenciales transitorios entre exchanges de 0.20–0.80%, que vuelven a converger en……Ver másVer menos

Arbitraje de base neutral al mercado entre venues en perpetuos de ETH entre Hyperliquid (ETHUSD.HYPERLIQUID) y futuros USD-M de Binance (ETHUSDT.BINANCE). Los dos venues tienen distintos perfiles de participantes (HL está dominado por traders sofisticados y especuladores minoristas; Binance USD-M tiene el libro de perpetuos más profundo del mundo) y distintos ciclos de financiación (HL cada hora; Binance cada 8 h). Esto genera diferenciales transitorios entre exchanges de 0.20–0.80%, que vuelven a converger en 1–3 velas de cuatro horas cuando los arbitrajistas entre venues (creadores de mercado y traders de base) cierran la brecha. La estrategia detecta cuándo el diferencial porcentual (HL_close - BIN_close) / BIN_close supera un umbral de puntuación z móvil de |z| > 2.0 en una ventana retrospectiva de 60 velas; entonces abre una posición larga en el venue más barato y una corta en el más caro, con el mismo valor nominal. La posición se cierra cuando la puntuación z revierte a |z| < 0.3 o tras un límite temporal de 4 velas (16 h). Esto no es NOT un patrón gráfico clásico, NOT una operación direccional de impulso o reversión ni NOT una estrategia de carry por financiación: es pura reversión a la media entre venues, impulsada por un mecanismo de arbitraje estructural. Apunta simultáneamente al venue HYPERLIQUID, muy infrarrepresentado (4.1% frente a una cuota de 20%), al ámbito entre venues (4.6% frente a una cuota de 15%) y a la dirección larga-corta (9.2% frente a un objetivo de ~45%).

Corrección de la iteración -5 (leverage_set_but_unused). El filtro examina el código guardado de la estrategia para encontrar una referencia al apalancamiento (config.leverage / self._lev / .leverage) y rechaza el caso en que se declara un apalancamiento>1 pero no aparece en el código. Conecté el apalancamiento claramente a la ruta de dimensionamiento: position_size() ahora lee directamente `leverage = float(self.config.leverage)` y calcula `notional = equity * exposure_frac * leverage`; la pata equivalente de……Ver másVer menos

Corrección de la iteración -5 (leverage_set_but_unused). El filtro examina el código guardado de la estrategia para encontrar una referencia al apalancamiento (config.leverage / self._lev / .leverage) y rechaza el caso en que se declara un apalancamiento>1 pero no aparece en el código. Conecté el apalancamiento claramente a la ruta de dimensionamiento: position_size() ahora lee directamente `leverage = float(self.config.leverage)` y calcula `notional = equity * exposure_frac * leverage`; la pata equivalente de Hyperliquid usa el mismo valor nominal ajustado por apalancamiento, así que un apalancamiento de 2x duplica el valor nominal de ambas patas (efecto real en el margen, no inerte). Este es el cambio mínimo que satisface el filtro y mantiene toda la lógica de señal que ya había pasado (z-score del spread, entrada y salida, gestión atómica de ambas patas) y las importaciones. El apalancamiento 2.0 es adecuado porque la posición es neutral al mercado (long y short con el mismo valor nominal), así que 2x por pata mantiene el riesgo direccional cerca de cero y da relevancia económica al edge del basis.

Reversión a la media del basis entre exchanges, dominada por comisiones y con un edge negativo estructural que no se puede ajustar: no vale la pena optimizarla. El basis de perpetuos de ETH entre Hyperliquid y Binance es de apenas unos puntos básicos hasta ~0.3%, pero una operación neutral al mercado de ida y vuelta paga FOUR ejecuciones taker (apertura y cierre de ambas patas), por lo que el suelo de costes de ~0.2-0.4% en dos exchanges supera lo que revierte el spread. El backtest pierde de forma constante:……Ver másVer menos

Reversión a la media del basis entre exchanges, dominada por comisiones y con un edge negativo estructural que no se puede ajustar: no vale la pena optimizarla. El basis de perpetuos de ETH entre Hyperliquid y Binance es de apenas unos puntos básicos hasta ~0.3%, pero una operación neutral al mercado de ida y vuelta paga FOUR ejecuciones taker (apertura y cierre de ambas patas), por lo que el suelo de costes de ~0.2-0.4% en dos exchanges supera lo que revierte el spread. El backtest pierde de forma constante: Sharpe -9.85, Sortino -13.8, profit_factor 0.908, omega 0.097, expectativa -$103/operación, total_return -24.9%; todos los meses son negativos salvo uno y los tres años también (2024 -7.6%, 2025 -11.3%, 2026 -6.0%); las comisiones representan 10.1% del bruto ($45.9k + $23.4k de impacto). La configuración actual ya selecciona las dislocaciones más amplias (entrada z>2 en 60 barras) y aun así pierde, con una tasa de aciertos de 48.4% y avg_win ~ avg_loss; subir entry_z o alargar la posición reduce el número de operaciones, pero no puede elevar un basis de unos pocos puntos básicos por encima del suelo de costes de 4 ejecuciones. No es un error de código (la estrategia funciona sin problemas, neutral al mercado, beta 0.002) ni hay una estrategia hermana entre exchanges promocionada que se haya quedado en un objetivo inactivo: el mecanismo mismo está limitado por las comisiones. FAILURE PATTERN: la reversión a la media del basis de perpetuos entre exchanges en un activo principal (ETH HL frente a Binance) está estructuralmente dominada por las comisiones: el spread negociable entre exchanges (un solo dígito de puntos básicos) es menor que el coste de ida y vuelta de 4 ejecuciones en dos exchanges, lo que produce pérdidas constantes de PF<1 que no se pueden revertir ajustando el umbral z.

Implementación

Reversión a la media del basis neutral al mercado entre exchanges sobre perpetuos de ETH, entre ETHUSDT.BINANCE (principal) y ETHUSD.HYPERLIQUID (pata adicional), barras de 4H. El spread porcentual (HL-BIN)/BIN se convierte en z-score en una ventana móvil de 60 barras; cuando |z|>2.0, la estrategia compra en el exchange más barato y vende en corto en el más caro con el mismo valor nominal, y cierra ambas patas al converger de nuevo (|z|<0.3) o tras un límite temporal de 4 barras (16h). El valor nominal por pata = patrimonio * exposure_frac * apalancamiento, así que el apalancamiento configurado de 2x realmente duplica la exposición bruta.

Resultados de verificación

Verificación fallida (leverage_set_but_unused): la configuración establece leverage=2.0, pero la estrategia nunca lo usa para dimensionar posiciones. Calcula el tamaño con esa variable — valor nominal = patrimonio * fracción * apalancamiento / precio (lee self.config.leverage) — o establece leverage=1.0. Tal como está escrita, la variable de apalancamiento no tiene efecto y el backtest es idéntico a 1x.

Revisión de backtest

Sharpe
-9,85
Rentabilidad total
-24,94%
Drawdown máximo
27,95%
Operaciones totales
446
Tasa de acierto
48,4%
Factor de beneficio
0,91

La estrategia es sólida en lo mecánico y funciona sin problemas: 446 operaciones neutrales al mercado, SyncedBuffer con marcas temporales alineadas, beta realmente baja (0.002) y correlación con el benchmark (0.03); sin liquidaciones ni errores

Apunta, como estaba previsto, a las categorías infrarrepresentadas de Hyperliquid, entre exchanges y long-short

Pérdida estructural constante: Sharpe -9.85, Sortino -13.8, profit_factor 0.908, omega 0.097, expectativa -$103/operación, total_return -24.9%: todos los meses son negativos salvo uno y los tres años son negativos

Dominada por comisiones: una operación de ida y vuelta del basis entre exchanges paga 4 ejecuciones taker (apertura y cierre de ambas patas en Binance y HL); las comisiones representan 10.1% del bruto ($45.9k de comisiones + $23.4k de impacto), y el basis de pocos puntos básicos entre ETH y HL-Binance no puede superar ese suelo de costes

La selección de los spreads más amplios ya falla: con entry_z>2, la tasa de aciertos es 48.4% y avg_win ~ avg_loss; las dislocaciones más amplias no convergen de forma rentable y fiable, así que subir el umbral no puede crear edge

Sin errores de código ni estrategias hermanas entre exchanges promocionadas: el edge negativo es inherente al mecanismo, no un error de implementación corregible

Análisis

La estrategia pierde porque opera con un spread menor que su propio coste de ida y vuelta. Antes de que valga la pena optimizarla, hacen falta dos cambios: (1) Añadir un filtro de entrada HARD que considere los costes: entrar solo cuando el spread porcentual RAW |(HL-BIN)/BIN| en el momento de la señal supere un umbral que cubra el coste de ida y vuelta de ambas patas (BINANCE ~0.10% + HYPERLIQUID ~0.09% ≈ 0.20% por operación completa; exigir que el spread sea al menos ~2x veces eso, por ejemplo > 0.40%). Un……Ver másVer menos

La estrategia pierde porque opera con un spread menor que su propio coste de ida y vuelta. Antes de que valga la pena optimizarla, hacen falta dos cambios: (1) Añadir un filtro de entrada HARD que considere los costes: entrar solo cuando el spread porcentual RAW |(HL-BIN)/BIN| en el momento de la señal supere un umbral que cubra el coste de ida y vuelta de ambas patas (BINANCE ~0.10% + HYPERLIQUID ~0.09% ≈ 0.20% por operación completa; exigir que el spread sea al menos ~2x veces eso, por ejemplo > 0.40%). Un z-score de 2.0 sobre un spread cuyo valor absoluto es de apenas unos puntos básicos no se puede negociar: filtra por el tamaño absoluto del spread, no solo por z. (2) Instrumentar y verificar que el spread sea REAL, no un artefacto de desalineación de barras: registrar la distribución del spread bruto de entrada. Si las entradas se activan con |spread| de apenas 0.05-0.15% (de unos pocos puntos básicos hasta ~15bps), la prima 0.20-0.80% hipotetizada no existe en este par y la señal es ruido de sincronización entre exchanges. En ese caso, el mecanismo no puede funcionar en ETH HL frente a Binance, independientemente de los umbrales z, y habría que reformularlo para un par de exchanges con un basis realmente más amplio y de convergencia más lenta, o abandonarlo. Reduce también la rotación: el límite temporal de 4 barras fuerza salidas que pagan comisiones sin esperar a la convergencia. Vuelve a ejecutar el backtest; si la versión filtrada por costes sigue mostrando profit_factor < 1.0, la premisa no sirve y no debería pasar a la optimización de 2 horas.

Historial de iteraciones

Verificación fallida (capa 2 — escenarios sintéticos): Parámetros usados: ['exit_z', 'entry_z', 'lookback', 'min_notional', 'exposure_frac', 'time_stop_bars'] Comprueba que __init__ asigne todos los atributos a partir de self.parameters.get(). - steady_uptrend: TypeError: FactoryStrategy._bar_ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - steady_downtrend: TypeError: FactoryStrategy._bar_ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca……Ver másVer menos

Verificación fallida (capa 2 — escenarios sintéticos): Parámetros usados: ['exit_z', 'entry_z', 'lookback', 'min_notional', 'exposure_frac', 'time_stop_bars'] Comprueba que __init__ asigne todos los atributos a partir de self.parameters.get(). - steady_uptrend: TypeError: FactoryStrategy._bar_ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - steady_downtrend: TypeError: FactoryStrategy._bar_ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - flat_ranging: TypeError: FactoryStrategy._bar_ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - volatility_spike: TypeError: FactoryStrategy._bar_ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - zero_volume: TypeError: FactoryStrategy._bar_ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - price_gap: TypeError: FactoryStrategy._bar_ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000)

Verificación fallida (capa 2 — escenarios sintéticos): Parámetros usados: ['exit_z', 'entry_z', 'lookback', 'min_notional', 'exposure_frac', 'time_stop_bars'] Comprueba que __init__ asigne todos los atributos a partir de self.parameters.get(). - steady_uptrend: TypeError: EthCrossVenuePerpBasisMeanReversionLS4H._ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - steady_downtrend: TypeError: EthCrossVenuePerpBasisMeanReversionLS4H._ts() requiere 1 argumento(s)……Ver másVer menos

Verificación fallida (capa 2 — escenarios sintéticos): Parámetros usados: ['exit_z', 'entry_z', 'lookback', 'min_notional', 'exposure_frac', 'time_stop_bars'] Comprueba que __init__ asigne todos los atributos a partir de self.parameters.get(). - steady_uptrend: TypeError: EthCrossVenuePerpBasisMeanReversionLS4H._ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - steady_downtrend: TypeError: EthCrossVenuePerpBasisMeanReversionLS4H._ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - flat_ranging: TypeError: EthCrossVenuePerpBasisMeanReversionLS4H._ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - volatility_spike: TypeError: EthCrossVenuePerpBasisMeanReversionLS4H._ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - zero_volume: TypeError: EthCrossVenuePerpBasisMeanReversionLS4H._ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000) - price_gap: TypeError: EthCrossVenuePerpBasisMeanReversionLS4H._ts() requiere 1 argumento(s) posicional(es), pero recibió 2 (marca temporal de la barra: 1735689600000)

Resumen de resultados

La reversión a la media del basis de perpetuos entre exchanges en un activo principal líquido tiene un límite marcado por las comisiones: una operación de ida y vuelta en dos exchanges requiere cuatro ejecuciones y cuesta más de lo que revierte el spread de un solo dígito de puntos básicos. Subir el umbral z no puede crear el edge que le falta estructuralmente al mecanismo.

El análisis del backtest previo a la optimización concluyó «abandonar»: consideró que el edge negativo era estructural, no un error de código. Una operación de ida y vuelta en dos exchanges requiere cuatro ejecuciones taker, con un suelo de costes de ~0.2–0.4% que supera el spread de pocos puntos básicos de ETH entre exchanges; por eso se descartó antes de la optimización de 3 fases.

Arbitraje de basis neutral al mercado, long-short, que calculaba el z-score del spread de precios del perpetuo de ETH entre Hyperliquid y Binance USD-M y, cuando |z| > 2.0, compraba en el exchange más barato y vendía en corto en el más caro, esperando que la dislocación de 0.2–0.8% volviera a converger en 1–3 barras de cuatro horas.

Funcionó sin problemas y fue neutral respecto al mercado (beta 0.002, correlación con el índice de referencia 0.03) en 446 operaciones, pero perdió de forma constante: rentabilidad total -24.9%, Sharpe -9.85, Sortino -13.8, factor de beneficio 0.908, expectativa -$103/operación, tasa de aciertos de 48.4% con avg_win ≈ avg_loss, y comisiones equivalentes a 10.1% del importe bruto ($45.9k en comisiones + $23.4k de impacto).

Stratmill es una herramienta de investigación y paper trading, no asesoramiento financiero ni un bróker. Los resultados de backtest y paper trading son hipotéticos. Operar conlleva riesgo de pérdida.