---
title: "2.3.7 Cripto: momentum, funding y basis"
description: "Momentum transversal semanal, el factor común que domina las cripto y el carry del funding y del basis, con costes, colapsos y riesgo de contraparte."
url: "https://pythonparatrading.com/curso-python-trading/nivel-2/estrategias-cripto-momentum-funding-y-basis/"
lang: "es"
image: "https://pythonparatrading.com/og/curso-python-trading/nivel-2/estrategias-cripto-momentum-funding-y-basis.png"
---

# 2.3.7 · Estrategias específicas de cripto: momentum, arbitraje de funding y basis

> Las cripto se negocian todos los días a todas horas, se mueven juntas y tienen dos fuentes de carry propias: el funding de los perpetuos y el basis de los futuros con vencimiento. Esta lección mide el factor común de quince monedas sintéticas, prueba un momentum transversal semanal plantado con ejecución al día siguiente y costes, y presenta la idea del cash-and-carry, que el nivel 3 desarrolla.

- Curso: [Nivel 2: Estrategias sistemáticas y backtesting riguroso](https://pythonparatrading.com/curso-python-trading/nivel-2/)
- Módulo: 2.3 · Familias de estrategias
- Duración: 65 min
- Requisitos: [1.2.6 · Cripto: spot, perpetuos, funding y custodia](https://pythonparatrading.com/curso-python-trading/nivel-1/cripto-spot-perpetuos-y-funding/), [1.3.5 · Datos de cripto y on-chain](https://pythonparatrading.com/curso-python-trading/nivel-1/datos-de-cripto-y-on-chain/), [1.4.4 · Universos sin sesgo de supervivencia: deslistados, fusiones y cambios de símbolo](https://pythonparatrading.com/curso-python-trading/nivel-1/sesgo-de-supervivencia-y-point-in-time/)

## Al terminar esta lección

- Medir cuánto del movimiento de cada moneda explica el factor común del mercado cripto.
- Contrastar un momentum transversal semanal con IC de rangos y una cartera long-short ejecutada en la sesión siguiente a la señal, con comisiones.
- Calcular el funding anualizado de un perpetuo, su relación con la rentabilidad reciente y lo que cobra un cash-and-carry.
- Relacionar el basis de un futuro trimestral con el funding y explicar por qué fija el carry hasta el vencimiento.
- Enumerar los riesgos que el backtest no ve: colapsos, liquidaciones del margen y quiebra del exchange.

## Un mercado que no cierra y se mueve en bloque

El mercado cripto tiene tres rasgos que cambian cómo se diseña una estrategia (lecciones 1.2.6 y 1.3.5). No cierra:
la «sesión» diaria es una convención (aquí, el cierre a las 00:00 UTC) y los fines de semana cuentan. Tiene derivados
propios: el **perpetuo**, un futuro sin vencimiento que se ancla al contado con pagos periódicos de **funding**, y
futuros con vencimiento cuyo precio se separa del contado en el **basis**. Y casi todas las monedas suben y bajan a la
vez.

```mermaid
flowchart TB
  C[Mercado cripto] --> F[Factor común]
  C --> M[Momentum transv.]
  C --> D[Derivados]
  D --> P[Perpetuo: funding]
  D --> T[Futuro: basis]
  P --> K[Cash-and-carry]
  T --> K
```

<aside class="callout" data-kind="aviso">

Los datos son **sintéticos**: quince monedas ficticias (`KAL`, `KBR`…) de 2018 a 2025 con un factor común fuerte,
dos colapsos documentados y un **momentum transversal semanal plantado** (cada lunes, un rendimiento extra diario de
0,10 % por unidad de puntuación de la rentabilidad de los 28 días anteriores). El funding y el basis de tres monedas
siguen fórmulas conocidas. Nada de esto es evidencia sobre las cripto reales; la literatura citada sí lo es, con sus
propias limitaciones.

</aside>

```python
import numpy as np
import pandas as pd

cd = pd.read_parquet("cripto2_diario.parquet")
P = cd.pivot(index="fecha", columns="moneda", values="cierre")
r = P.pct_change(fill_method=None)
resumen = pd.DataFrame({
    "desde": P.apply(lambda s: s.first_valid_index()).dt.date,
    "hasta": P.apply(lambda s: s.last_valid_index()).dt.date,
    "vol_anual_pct": 100 * np.log1p(r).std() * np.sqrt(365),
})
print(resumen.round(0).sort_values("vol_anual_pct").to_string())
print("peor día de KJT y KLU:",
      (100 * r[["KJT", "KLU"]].min()).round(1).to_dict())
```
```output
             desde       hasta  vol_anual_pct
moneda
KAL     2018-01-01  2025-12-31           67.0
KMV     2019-07-01  2025-12-31           73.0
KCX     2018-01-01  2025-12-31           74.0
KGN     2018-01-01  2025-12-31           75.0
KES     2018-01-01  2025-12-31           78.0
KFL     2018-01-01  2025-12-31           81.0
KNX     2020-09-15  2025-12-31           85.0
KRM     2018-01-01  2025-12-31           98.0
KHX     2018-01-01  2025-12-31           99.0
KBR     2018-01-01  2025-12-31          103.0
KIO     2018-01-01  2025-12-31          103.0
KLU     2018-01-01  2022-11-30          108.0
KDL     2018-01-01  2025-12-31          109.0
KOB     2021-03-01  2025-12-31          111.0
KJT     2018-01-01  2022-05-27          138.0
peor día de KJT y KLU: {'KJT': -61.7, 'KLU': -45.5}
```

Doce monedas cotizan los ocho años; `KMV`, `KNX` y `KOB` empiezan más tarde, y `KJT` y `KLU` dejan de cotizar en
2022 tras perder el 99 % y el 90 % en pocos días (su peor día, −61,7 % y −45,5 %). La volatilidad anual va del 67 %
de `KAL`, la mayor y más líquida, al 138 % de `KJT`: entre tres y siete veces la de un índice de acciones. Un universo
que se construyera hoy con las monedas que existen no tendría ni `KJT` ni `KLU`.

## El factor común

El mercado cripto se puede resumir en un índice equiponderado de las monedas que cotizan cada día. Una regresión de
cada moneda sobre ese índice da su beta y su $R^2$, la fracción de su varianza diaria que explica el factor común:

```python
mercado = r.mean(axis=1)
filas = {}
for mon in r:
    d = pd.concat([r[mon], mercado], axis=1).dropna()
    b, a = np.polyfit(d.iloc[:, 1], d.iloc[:, 0], 1)
    filas[mon] = {"beta": b, "r2": d.corr().iloc[0, 1] ** 2}
fc = pd.DataFrame(filas).T.sort_values("r2")

corr = r.corr().to_numpy()
media_corr = corr[np.triu_indices_from(corr, 1)].mean()
completas = r.dropna()
valores = np.linalg.eigvalsh(np.corrcoef(completas.T.to_numpy()))
print(f"correlación media: {media_corr:.2f}; primer componente: "
      f"{valores[-1] / valores.sum():.0%} de la varianza")
fc.round(2).T
```
```output
correlación media: 0.58; primer componente: 70% de la varianza
       KJT   KBR   KHX   KOB   KIO   KMV   KES   KFL   KRM   KCX   KLU   KDL   KGN   KNX   KAL
beta  0.91  0.94  0.91  1.31  1.08  0.86  0.85  0.91  1.12  0.86  1.06  1.37  0.94  1.15  0.89
r2    0.40  0.40  0.42  0.54  0.54  0.59  0.59  0.62  0.63  0.67  0.71  0.75  0.75  0.77  0.84
```

La correlación media entre pares es de 0,58 y el primer componente principal explica el 70 % de la varianza de las
quince. El $R^2$ frente al índice va del 0,40 de `KJT` y `KBR` al 0,84 de `KAL`: en la moneda grande, más de cuatro
quintas partes de lo que pasa cada día es el mercado entero; en las que tienen más volatilidad propia, menos de la
mitad. Las betas están entre 0,85 y 1,37. Para una estrategia, la consecuencia es directa: una cartera solo larga es,
sobre todo, una apuesta por el factor común, y la señal transversal solo se aísla con una cartera long-short.

*Fig. — Fracción de la varianza diaria de cada moneda que explica el índice equiponderado del mercado cripto (R²).* Quince barras horizontales ordenadas de mayor a menor: KAL 0,84, KNX 0,77, KGN 0,75, KDL 0,75, KLU 0,71, KCX 0,67, KRM 0,63, KFL 0,62, KES 0,59, KMV 0,59, KIO 0,54, KOB 0,54, KHX 0,42, KBR 0,40, KJT 0,40. KAL, la moneda grande, destacada, es la que más depende del factor común.

## Momentum transversal semanal

La hipótesis plantada es la de un momentum de corto plazo: las monedas que más han subido en las últimas cuatro
semanas siguen haciéndolo un poco mejor que las demás la semana siguiente. Liu, Tsyvinski y Wu (2022) encuentran en
datos reales que un modelo de tres factores (mercado, tamaño y momentum) explica la sección cruzada de rentabilidades
de las cripto; Liu y Tsyvinski (2021) documentan un momentum de series temporales fuerte.

El calendario de la señal importa. La señal se calcula con el cierre del domingo (rentabilidad de 28 días hasta ese
cierre) y la posición se toma al cierre del lunes, la sesión siguiente:

```mermaid
flowchart LR
  D[Cierre domingo] --> S[Señal 28 días]
  S --> L[Orden lunes]
  L --> H[7 días]
```

```python
from scipy import stats

lunes = [i for i, f in enumerate(P.index)
         if f.dayofweek == 0 and 29 <= i < len(P) - 8]
logp = np.log(P)
ic = {"al cierre del domingo": [], "al cierre del lunes": []}
for i in lunes:
    senal = logp.iloc[i - 1] - logp.iloc[i - 29]
    for clave, ent in [("al cierre del domingo", i - 1),
                       ("al cierre del lunes", i)]:
        fut = logp.iloc[ent + 7] - logp.iloc[ent]
        ok = senal.notna() & fut.notna()
        ic[clave].append(stats.spearmanr(senal[ok], fut[ok])[0])
ic = pd.DataFrame(ic)
pd.DataFrame({"ic_medio": ic.mean(),
              "t": ic.mean() / ic.std() * np.sqrt(len(ic)),
              "semanas_pos_pct": 100 * (ic > 0).mean()}).round(3)
```
```output
                       ic_medio      t  semanas_pos_pct
al cierre del domingo     0.068  4.820           59.223
al cierre del lunes       0.069  4.842           60.922
```

El IC de rangos semanal es de +0,068 ejecutando al cierre del domingo (el de la señal) y de +0,069 al del lunes, con t
de 4,8 en los dos casos: la señal plantada (IC esperado ≈ +0,05) se recupera con claridad, y es positiva en el 59 % al
61 % de las semanas. Que la ejecución al día siguiente no la empeore es una propiedad de esta señal concreta: el
rendimiento plantado se reparte por igual en toda la semana, y la ventana del lunes al lunes también lo recoge casi
entero. Una señal cuyo efecto se concentrara en las primeras horas no lo resistiría.

La cartera compra las cinco monedas de mayor señal y vende las cinco de menor, con el mismo peso, entra al cierre del
lunes y se rehace cada semana. El coste es un supuesto de la lección: 10 puntos básicos por lado sobre el nominal
negociado, entre comisión y deslizamiento, del orden de lo que paga un cliente minorista que toma liquidez en un
exchange grande con monedas líquidas. Las posiciones vendidas se suponen en perpetuos, así que además pagarían o
cobrarían funding, que aquí se ignora.

```python
COSTE = 10 / 1e4
pesos = pd.DataFrame(0.0, index=P.index, columns=P.columns)
for i in lunes:
    senal = (logp.iloc[i - 1] - logp.iloc[i - 29]).dropna()
    orden = senal.rank()
    w = (pd.Series(0.0, index=P.columns)
         .add((orden > len(orden) - 5) / 5, fill_value=0)
         .sub((orden <= 5) / 5, fill_value=0))
    pesos.iloc[i + 1:i + 8] = w.to_numpy()      # desde el martes
pesos = pesos.where(P.notna(), 0.0)

giro = pesos.diff().abs().sum(axis=1)
ls = (pesos * r.fillna(0)).sum(axis=1) - COSTE * giro
ls = ls[ls.index >= P.index[lunes[0] + 1]]
ew = mercado.reindex(ls.index)

def metricas(x):
    eq = (1 + x).cumprod()
    return pd.Series({
        "rent_anual_pct": 100 * x.mean() * 365,
        "vol_anual_pct": 100 * x.std() * np.sqrt(365),
        "sharpe": x.mean() / x.std() * np.sqrt(365),
        "max_dd_pct": 100 * (eq / eq.cummax() - 1).min(),
        "beta": np.polyfit(ew, x, 1)[0]})

coste_anual = 100 * COSTE * giro[ls.index].mean() * 365
print(f"coste anual de comisiones: {coste_anual:.2f} %")
pd.DataFrame({"long_short_neto": metricas(ls),
              "indice_equiponderado": metricas(ew)}).round(2)
```
```output
coste anual de comisiones: 5.80 %
                long_short_neto  indice_equiponderado
rent_anual_pct            46.89                 30.46
vol_anual_pct             39.94                 70.79
sharpe                     1.17                  0.43
max_dd_pct               -41.45                -84.27
beta                      -0.05                  1.00
```

Neta de comisiones, la cartera rinde un 46,9 % anual con una volatilidad del 39,9 %: un Sharpe de 1,17 y una beta de
−0,05 frente al índice, que es casi nula. Las comisiones, con un giro semanal alto, se llevan 5,8 puntos al año. El
índice equiponderado rinde un 30,5 % con un Sharpe de 0,43 y una caída máxima del 84 %: esa es la prima del factor
común de estos datos, no la de la señal.

El Sharpe de 1,17 no es una promesa para las cripto reales: es lo que da una señal plantada con un IC de 0,07 en
quince monedas sintéticas. Lo útil es compararlo con lo plantado. Con una diferencia media de 1,96 entre las
puntuaciones normales por rangos de las dos patas, el generador promete unos 70 puntos al año antes de costes, y la
cartera gana unos 53 (46,9 más 5,8 de comisiones). Con una volatilidad del 40 % en ocho años, el error típico de la
rentabilidad media anual es de unos 14 puntos: la diferencia es poco más de un error típico, compatible con el azar. Y
la **caída máxima del 41 %**, en una cartera neutral al mercado, pide mirar los peores días:

```python
peores = ls.nsmallest(3)
print((100 * peores).round(1).to_string())
d = peores.index[0]
aporte = (pesos.loc[d] * r.fillna(0).loc[d]).nsmallest(2)
print("peor día, por moneda (% del capital):",
      (100 * aporte).round(1).to_dict())
m = aporte.index[0]
print(f"{m} ese día: {100 * r.loc[d, m]:+.0f} %, "
      f"peso {pesos.loc[d, m]:.2f}")
eq = (1 + ls).cumprod()
dd = eq / eq.cummax() - 1
print("caída máxima:", eq[:dd.idxmin()].idxmax().date(), "a",
      dd.idxmin().date(), f"({100 * dd.min():.1f} %)")
```
```output
fecha
2022-05-03   -16.5
2023-08-22   -10.6
2022-06-21   -10.0
peor día, por moneda (% del capital): {'KOB': -15.6, 'KES': -1.2}
KOB ese día: +78 %, peso -0.20
caída máxima: 2021-03-08 a 2022-06-26 (-41.4 %)
```

El peor día es el 3 de mayo de 2022: `KOB`, que la cartera tenía vendida con un 20 % del capital, sube un 78 % y la
pata corta pierde un 15,6 % del capital en una sesión; el resto de las posiciones casi no cuenta. Los dos peores días
siguientes, de −10,6 % y −10,0 %, son de la misma magnitud, y la caída máxima, del 41,4 %, va del 8 de marzo de 2021 al
26 de junio de 2022. El generador recorta las innovaciones idiosincráticas a ±5 desviaciones típicas, y aun así, con
la volatilidad de estas monedas, quedan días de hasta el +84 % según el README de los datos. Es el riesgo propio de la
pata corta: una posición vendida en un activo pequeño y volátil puede perder en un día lo que la señal gana en meses.
Límites de peso por moneda, stops de la pata corta y ponderar por la inversa de la volatilidad son la respuesta
habitual, y todos cambian el resultado.

*Fig. — Momentum transversal semanal (cinco contra cinco, neto de 10 pb por lado) frente al índice equiponderado.* Dos curvas de capital diarias de 2018 a 2025 en escala logarítmica, base 100. El índice equiponderado cae hasta 16 en 2018-2020, sube con fuerza en 2020 y 2021, vuelve a caer en 2022 y termina en 161. El long-short, destacado, sube con fuerza en 2018 y 2019, se aplana en 2020 y 2021, cae en la primera mitad de 2022 (el 3 de mayo, KOB, vendida, sube un 78 % en un día) y vuelve a subir desde 2023 hasta terminar en 2.159.

La figura enseña la curva de la cartera frente a la del índice, en escala logarítmica. La cartera sube con fuerza en
2018 y 2019, se aplana en 2020 y 2021, cae en la primera mitad de 2022 y vuelve a subir desde 2023. El índice, en
cambio, pierde más de la mitad en 2018 y en 2022 y gana en los tramos alcistas: dos curvas casi independientes, como
dice la beta.

## El funding de los perpetuos

Un perpetuo no vence. Para que su precio no se aleje del contado, cada 8 horas los largos pagan a los cortos un
porcentaje del nominal, el **funding**, si el perpetuo cotiza por encima del índice, y al revés si cotiza por debajo
(lección 1.2.6). Cuando el mercado está eufórico y muchos quieren estar largos con apalancamiento, el funding sube.
`cripto2_funding.parquet` tiene la tasa de cada periodo de `KAL`, `KBR` y `KCX`:

```python
fu = pd.read_parquet("cripto2_funding.parquet")
fu["fecha"] = fu["ts"].dt.tz_convert(None).dt.normalize()
diario = fu.groupby(["fecha", "moneda"])["tasa_funding"].sum().unstack()
anual = 100 * diario * 365              # % anual, sin capitalizar

tabla = pd.DataFrame({
    "media_pct": anual.mean(),
    "dias_negativo_pct": 100 * (diario < 0).mean(),
    "peor_30d_pct": anual.rolling(30).mean().min(),
    "mejor_30d_pct": anual.rolling(30).mean().max(),
})
r7 = np.log(P[anual.columns]).diff(7)
tabla["corr_con_r7"] = [anual[c].corr(r7[c]) for c in anual]
print(tabla.round(2))
print((anual.groupby(anual.index.year).mean()).round(1).T)
```
```output
        media_pct  dias_negativo_pct  peor_30d_pct  mejor_30d_pct  corr_con_r7
moneda
KAL         11.52              35.63        -36.30          52.86         0.84
KBR         11.40              42.09        -36.93          63.70         0.89
KCX         14.04              34.60        -37.91          63.72         0.89
fecha   2018  2019  2020  2021  2022  2023  2024  2025
moneda
KAL      1.4  15.2  13.1  11.3   2.6  20.3  18.9   9.4
KBR      5.9   9.0   9.4  14.3  14.5  12.3   9.8  16.0
KCX      5.8  20.8  15.5  13.8   9.0  16.4  12.4  18.7
```

El funding medio, anualizado sin capitalizar, es de un 11,4 % a un 14,0 %: de media, los largos pagan a los cortos
algo más que el 0,01 % por periodo de base. Pero no es estable. Entre el 35 % y el 42 % de los días es negativo; la
peor media de 30 días es de −36 % a −38 % anual, y la mejor, de +53 % a +64 %. La correlación con la rentabilidad de
los 7 días anteriores es de 0,84 a 0,89: sube tras las subidas, que es la fórmula plantada
($0{,}0001 + 0{,}0006 \tanh(r_7 / 0{,}15)$ por periodo, más ruido). Por años, el de `KAL` va del 1,4 % de 2018 al 20,3 %
de 2023.

*Fig. — Funding diario anualizado frente a la rentabilidad de los 7 días anteriores en KAL, KBR y KCX.* Veinte puntos, medias de grupos por rentabilidad de 7 días, de -28 % a +26 %, frente al funding anualizado, de -48 % a 72 %. Los puntos siguen una curva en S destacada, la fórmula del generador con una tangente hiperbólica: el funding sube con la rentabilidad reciente y se satura en los extremos.

## Cash-and-carry: cobrar el funding sin apostar por el precio

El **cash-and-carry** compra la moneda al contado y vende la misma cantidad en el perpetuo. Las dos patas se
compensan: si el precio sube, gana el contado y pierde el perpetuo en la misma cuantía. Lo que queda es el funding que
cobra la pata corta cuando es positivo (y paga cuando es negativo), menos los costes de entrar y salir de las dos
patas.

```mermaid
flowchart TB
  K[Capital] --> S[Contado largo]
  K --> M[Margen del corto]
  M --> P[Perpetuo corto]
  P --> F[Cobra funding]
  S --> N[Precio neutro]
  P --> N
```

```python
f_kal = diario["KAL"]
cobrado = f_kal.groupby(f_kal.index.year).sum() * 100
print("funding cobrado por el corto, % del nominal por año:")
print(cobrado.round(1).to_string())

# capital: 1 en contado + margen del perpetuo corto
# (1/3 del nominal: apalancamiento 3x)
rend_capital = f_kal.sum() / (1 + 1 / 3) / (len(f_kal) / 365)
print(f"rendimiento anual sobre el capital: {100 * rend_capital:.1f} %"
      " (sin costes)")
subida_30d = (P["KAL"] / P["KAL"].rolling(30).min() - 1).max()
print(f"mayor subida de KAL en 30 días: {100 * subida_30d:.0f} %")
```
```output
funding cobrado por el corto, % del nominal por año:
fecha
2018     1.4
2019    15.2
2020    13.1
2021    11.3
2022     2.6
2023    20.3
2024    18.9
2025     9.4
rendimiento anual sobre el capital: 8.6 % (sin costes)
mayor subida de KAL en 30 días: 116 %
```

El corto del perpetuo de `KAL` cobra entre un 1,4 % (2018) y un 20,3 % (2023) del nominal cada año, y ningún año
negativo. Pero el capital necesario no es solo el nominal del contado: el perpetuo corto necesita margen. Con un
apalancamiento de 3x en esa pata (un tercio del nominal), el rendimiento sobre el capital baja al 8,6 % anual, sin
costes. Y la última línea es el riesgo: `KAL` llegó a subir un 116 % en 30 días. Con un margen de un tercio del
nominal, una subida así se lo come varias veces; hay que reponerlo a tiempo, vendiendo parte del contado o con
efectivo, o el exchange liquida la pata corta.

<aside class="callout" data-kind="riesgo">

El cash-and-carry no tiene riesgo de precio en el papel, pero tiene tres riesgos reales. La **liquidación**: la pata
corta del perpetuo pierde cuando el precio sube, y si el margen no se repone a tiempo el exchange la cierra a la fuerza
y la cobertura desaparece justo en el peor momento. El **funding negativo**: en las caídas el corto paga. Y el
**riesgo de contraparte**: el contado y el margen están en el exchange; si este quiebra o congela las retiradas, la
posición entera queda atrapada. El nivel 3 trata la gestión de estos riesgos.

</aside>

## El basis de los futuros con vencimiento

El futuro trimestral vence en una fecha fija y converge al contado al vencer. Su diferencia con el contado, anualizada,
es el **basis**: $b = \ln(F/S) \times 365 / \text{dias}$. Comprar el contado y vender el futuro fija ese basis al
abrir: al vencimiento las dos patas valen lo mismo y el resultado es la diferencia inicial, pase lo que pase con el
precio. En los datos, el basis se forma a partir del funding: alrededor de 0,8 veces el funding anualizado de 7 días
más un 2 %.

```python
ba = pd.read_parquet("cripto2_basis.parquet")
f7 = (diario.rolling(7).mean() * 365).stack().rename("funding_7d")
f7.index.names = ["fecha", "moneda"]
ba = ba.join(f7, on=["fecha", "moneda"]).dropna()

for mon, g in ba.groupby("moneda"):
    b, a = np.polyfit(g["funding_7d"], g["basis_anual"], 1)
    print(f"{mon}: basis = {a:.3f} + {b:.2f} × funding_7d,"
          f" corr {g['basis_anual'].corr(g['funding_7d']):.2f}")

# un cash-and-carry por contrato: se abre a 80-90 días del vencimiento
entrada = ba[ba["dias_al_vencimiento"].between(80, 90)]
entrada = entrada.groupby(["moneda", "contrato"]).first()
fijado = 100 * entrada["basis_anual"]
print("\nbasis fijado al abrir (% anual) por moneda:")
print(fijado.groupby("moneda").describe()[
    ["count", "mean", "min", "max"]].round(1))
```
```output
KAL: basis = 0.025 + 0.80 × funding_7d, corr 0.97
KBR: basis = 0.012 + 0.80 × funding_7d, corr 0.99
KCX: basis = 0.012 + 0.81 × funding_7d, corr 0.97

basis fijado al abrir (% anual) por moneda:
        count  mean   min   max
moneda
KAL      33.0  17.1 -25.9  58.6
KBR      33.0   8.1 -49.0  74.2
KCX      33.0  15.2 -30.0  84.4
```

La regresión recupera la relación plantada: una pendiente de 0,80 a 0,81 sobre el funding de 7 días y una
correlación de 0,97 a 0,99. La ordenada sale entre 1,2 % y 2,5 % (verdad 2 %). Para el cash-and-carry con futuro, lo
importante es la segunda tabla: abriendo a 80-90 días del vencimiento, el basis fijado medio es del 17,1 % anual en
`KAL`, del 8,1 % en `KBR` y del 15,2 % en `KCX`. El mínimo es negativo en las tres: en los trimestres de pánico el
futuro cotiza por debajo del contado, y el cash-and-carry habría que hacerlo al revés (vender contado y comprar
futuro), lo que exige tomar prestada la moneda. A diferencia del perpetuo, el basis se fija al abrir: si el contado y
el futuro se compran y venden a esos precios, el resultado al vencimiento es ese basis, haga lo que haga el funding
mientras tanto.

## Costes, comisiones y lo que el backtest no ve

- **Comisiones por lado.** Las comisiones de los exchanges dependen del volumen del cliente y de si pone o toma
  liquidez; un long-short semanal paga cuatro lados por moneda y semana. El supuesto de 10 puntos básicos de la lección
  se lleva varios puntos al año.
- **Fin de semana y horarios.** No hay cierre oficial: el precio de «cierre» es el que elige el proveedor (lección
  1.3.5). Dos fuentes con horas de corte distintas dan señales distintas.
- **Colapsos.** `KJT` y `KLU` pierden el 99 % y el 90 % en pocos días y dejan de cotizar. Un universo construido con
  las monedas de hoy los borra (lección 1.4.4); uno point-in-time los incluye, y una cartera larga en ellas los paga.
- **Liquidaciones y apalancamiento.** Los derivados cripto se negocian con margen y liquidación automática; una mecha
  de pocos minutos puede cerrar una posición que en datos diarios nunca estuvo en peligro.
- **Contraparte.** El dinero está en el exchange. La diversificación entre exchanges y la retirada periódica de
  beneficios son parte de la gestión del riesgo, no un detalle operativo.

## Ejercicios

1. Repite el IC de rangos semanal (ejecución al cierre del lunes) con ventanas de 7, 14, 28 y 56 días para la señal.
   ¿Cuál da el mejor IC? ¿Qué te dice el resultado sobre buscar la ventana óptima?

**Solución.**

```python
def ic_ventana(n):
    v = []
    for i in lunes:
        if i - 1 - n < 0:
            continue
        senal = logp.iloc[i - 1] - logp.iloc[i - 1 - n]
        fut = logp.iloc[i + 7] - logp.iloc[i]
        ok = senal.notna() & fut.notna()
        v.append(stats.spearmanr(senal[ok], fut[ok])[0])
    v = np.array(v)
    return v.mean(), v.mean() / v.std() * np.sqrt(len(v))

pd.DataFrame({n: ic_ventana(n) for n in [7, 14, 28, 56]},
             index=["ic_medio", "t"]).T.round(3)
```
```output
    ic_medio      t
7      0.034  2.414
14     0.057  3.893
28     0.069  4.847
56     0.069  4.597
```

La ventana de 28 días, la plantada, da el t más alto (4,85), pero la de 56 días empata con ella en IC medio
(+0,069, t = 4,60): se solapan, y la de 56 días contiene entera la ventana plantada. La de 14 días queda en +0,057 y
la de 7, en +0,034. Sin conocer la verdad, nadie sabría con estos números si la ventana buena es la de 28 o la de 56
días. En datos reales no hay una ventana «verdadera» conocida: probar varias y quedarse con la mejor es una prueba
múltiple (lección 2.1.8), y el IC de la ganadora estará inflado. Aquí la diferencia entre las dos mejores es ruido.

2. Un cash-and-carry condicional solo mantiene la posición cuando el funding medio de los últimos 7 días, anualizado,
   supera el 5 %, y paga 10 puntos básicos por lado en cada pata al entrar y al salir. Calcula su resultado anual en
   `KAL` frente al de mantenerla siempre.

**Solución.**

```python
f7_kal = diario["KAL"].rolling(7).mean() * 365
dentro = (f7_kal > 0.05).shift(1, fill_value=False)   # decide ayer
cambios = dentro.astype(int).diff().abs().fillna(0)
coste = cambios * 2 * 2 * 10 / 1e4      # 2 patas × entrar o salir
anos = len(f_kal) / 365
siempre = f_kal.sum() / anos
condicional = ((f_kal * dentro).sum() - coste.sum()) / anos
print(f"siempre dentro: {100 * siempre:.1f} % anual del nominal")
print(f"condicional:    {100 * condicional:.1f} % anual "
      f"({int(cambios.sum())} entradas y salidas, "
      f"{100 * dentro.mean():.0f} % del tiempo dentro)")
```
```output
siempre dentro: 11.5 % anual del nominal
condicional:    4.7 % anual (183 entradas y salidas, 60 % del tiempo dentro)
```

Mantener siempre el cash-and-carry rinde un 11,5 % anual del nominal; la versión condicional, solo un 4,7 %. Está
dentro el 60 % del tiempo, pero entra y sale 183 veces en ocho años, y cada cambio paga cuatro lados de 10 puntos
básicos: unos 9 puntos al año de costes. Además, el funding es persistente pero ruidoso, y una regla con un umbral fijo
entra justo después de las subidas y sale justo después de las caídas. Una regla con banda (entrar por encima de un
nivel y salir por debajo de otro más bajo) reduciría los cambios.

3. El backtest del cash-and-carry de `KAL` cobra funding neto todos los años. Enumera lo que tendría que pasar en un
   exchange real para que perdiera dinero, aunque el funding fuera el de los datos.

**Solución.**

Que una subida rápida del precio consumiera el margen del perpetuo corto y el exchange lo liquidara antes de reponerlo:
la cobertura desaparecería y el contado quedaría sin cubrir, o se vendería con pérdidas para pagar. Que los costes
reales (comisiones, horquilla al entrar y salir, deslizamiento en las liquidaciones) fueran mayores que los supuestos.
Que el perpetuo cotizara durante días con una prima o un descuento grande frente al índice, de forma que la pata corta
no compensara exactamente al contado. Que el exchange congelara las retiradas o quebrara con el contado y el margen
dentro. Y que el funding de los datos no fuera el que paga ese exchange: cada uno calcula el suyo con su propio índice
y su propia fórmula.

## Autoevaluación

1. La correlación media entre las quince monedas es de 0,58 y el primer componente principal explica el 70 % de la varianza. ¿Qué implica para una estrategia de momentum transversal?

   - A. Que no sirve para nada
   - B. Que basta con comprar las ganadoras
   - C. Que conviene apalancarla más
   - D. Que hay que construirla long-short: comprar unas y vender otras quita casi todo el factor común, que si no domina el resultado

   *Respuesta D: Que hay que construirla long-short: comprar unas y vender otras quita casi todo el factor común, que si no domina el resultado.* Una cartera solo larga de las ganadoras es, sobre todo, una apuesta por el mercado cripto. La versión long-short equiponderada, con betas parecidas en las dos patas, aísla la parte transversal, que es donde está la señal plantada.

2. La señal de momentum se calcula con el cierre del domingo. ¿Por qué la lección ejecuta al cierre del lunes y no al del domingo?

   - A. Porque los exchanges cierran el domingo
   - B. Porque la orden necesita el dato del cierre del domingo para calcularse; ejecutar a ese mismo precio supone operar en un instante que ya pasó
   - C. Porque el lunes hay más volumen
   - D. Por convención

   *Respuesta B: Porque la orden necesita el dato del cierre del domingo para calcularse; ejecutar a ese mismo precio supone operar en un instante que ya pasó.* Es el mismo principio de todo el nivel: el dato de un cierre sirve para actuar después de ese cierre. En cripto, que no tiene subasta ni cierre oficial, el «cierre» es una hora convenida (00:00 UTC aquí) y entre el cálculo y la orden siempre pasa algo de tiempo.

3. Un perpetuo paga un funding de 0,01 % cada 8 horas. ¿Cuál es su equivalente anual aproximado?

   - A. 0,01 %
   - B. 3,65 %
   - C. Unos 11 %
   - D. Unos 33 %

   *Respuesta C: Unos 11 %.* Tres pagos al día durante 365 días: 0,0001 × 3 × 365 ≈ 0,1095, un 11 % anual sin capitalizar. Es el orden de magnitud del funding medio de las tres monedas de la lección (del 11,4 % al 14,0 %).

4. ¿Qué diferencia un cash-and-carry con futuro trimestral de uno con perpetuo?

   - A. Con el futuro trimestral el carry queda fijado al abrir (el basis converge a cero al vencimiento); con el perpetuo se cobra el funding de cada periodo, que cambia y puede volverse negativo
   - B. Ninguna
   - C. El trimestral no tiene riesgo de contraparte
   - D. El perpetuo no necesita margen

   *Respuesta A: Con el futuro trimestral el carry queda fijado al abrir (el basis converge a cero al vencimiento); con el perpetuo se cobra el funding de cada periodo, que cambia y puede volverse negativo.* Comprar el contado y vender el futuro fija la diferencia de precio, que desaparece al vencimiento. El perpetuo no vence: el funding se recalcula cada 8 horas y en las caídas puede pasar a pagar el corto. En los dos casos hay margen, liquidaciones posibles y riesgo del exchange.

5. En los datos, `KJT` pierde el 99 % en cinco días y deja de cotizar. ¿Qué error cometería un backtest que solo usa las monedas que existen hoy?

   - A. Ninguno
   - B. Un error de zona horaria
   - C. Un error de costes
   - D. Sesgo de supervivencia: quitaría de la historia las monedas que se hundieron, y una estrategia larga en ellas parecería mejor de lo que fue

   *Respuesta D: Sesgo de supervivencia: quitaría de la historia las monedas que se hundieron, y una estrategia larga en ellas parecería mejor de lo que fue.* Es el sesgo de la lección 1.4.4 en su versión más extrema. En cripto, los colapsos de monedas y de exchanges no son raros, y un universo construido con la lista actual los borra.

## Ideas clave

- Las cripto comparten un factor común muy fuerte: correlación media de 0,58 y un primer componente que explica el 70 % de la varianza en los datos.
- El momentum transversal semanal plantado se recupera con un IC de rangos de +0,069 (t ≈ 4,8); el long-short neto de 10 pb por lado tiene un Sharpe de 1,17, pero una caída máxima del 41 % y un peor día de −16,5 % por una sola posición corta.
- El funding de un perpetuo, anualizado, está entre un 11 % y un 14 % de media en los datos, sube tras las subidas y puede ser negativo durante semanas.
- El cash-and-carry (contado largo, derivado corto) cobra el funding o el basis sin exposición neta al precio, pero exige margen en la pata corta y queda expuesto al exchange.
- El basis del futuro trimestral sigue al funding (≈ 0,8 × funding + 2 %) y fija el carry hasta el vencimiento.
- Colapsos de monedas, liquidaciones y quiebras de exchanges son riesgos que un backtest con precios limpios no ve.

## Recursos

### Research

- [Volatility Targeting en Python](https://pythonparatrading.com/volatility-targeting/) · Research-0004 · 8 min

### Documentación

- [Liu y Tsyvinski (2021): Risks and Returns of Cryptocurrency, Review of Financial Studies 34(6)](https://doi.org/10.1093/rfs/hhaa113) · doi.org
- [Liu, Tsyvinski y Wu (2022): Common Risk Factors in Cryptocurrency, Journal of Finance 77(2)](https://doi.org/10.1111/jofi.13119) · doi.org
- [pandas: ventanas móviles (rolling, ewm) y sus métodos, como corr](https://pandas.pydata.org/docs/reference/window.html) · pandas.pydata.org

### Datos

- [Datos del nivel 2: quince monedas sintéticas, diario (Parquet)](https://pythonparatrading.com/curso/datos/nivel-2/cripto2_diario.parquet) · Descarga · cripto2_diario.parquet
- [Datos del nivel 2: funding de los perpetuos cada 8 horas (Parquet)](https://pythonparatrading.com/curso/datos/nivel-2/cripto2_funding.parquet) · Descarga · cripto2_funding.parquet
- [Datos del nivel 2: basis de los futuros trimestrales (Parquet)](https://pythonparatrading.com/curso/datos/nivel-2/cripto2_basis.parquet) · Descarga · cripto2_basis.parquet

Lección anterior: [2.3.6 · Introducción al market making: inventario, spread y selección adversa (Avellaneda-Stoikov)](https://pythonparatrading.com/curso-python-trading/nivel-2/market-making-avellaneda-stoikov/)

Lección siguiente: [2.4.1 · Backtest vectorizado desde cero: matrices, desfase, costes y límites](https://pythonparatrading.com/curso-python-trading/nivel-2/backtest-vectorizado-desde-cero/)
