Lección 4.2.2 · 70 min
Criterio de Kelly y volatility targeting: cuánto arriesgar
Kelly dice qué fracción del capital maximiza el crecimiento a largo plazo; el volatility targeting mantiene constante el riesgo de la posición. Esta lección deriva los dos, los aplica a las estrategias y al universo del nivel y los mide con lo que cuestan: el crecimiento que se pierde por estimar mal la media, las caídas de Kelly completo y el día en que el control de volatilidad tenía la exposición más alta justo antes del golpe.
- Módulo
- 4.2 · Gestión del riesgo y tamaño de posición
- Duración
- 70 min
- Requisitos
- 2.1.4 · Modelos de volatilidad: ARCH, GARCH, EGARCH y GJR con la librería arch, 2.2.2 · Universo, señal, filtro, entrada, salida, sizing y gestión del riesgo, 2.5.4 · Deflated Sharpe Ratio y Probability of Backtest Overfitting (PBO), 2.6.1 · CAGR, Sharpe, Sortino, Calmar, Omega, drawdown y Ulcer Index, 4.2.1 · Riesgo por operación, stops y riesgo de ruina
Lecciones del nivel 4
4.1 · Teoría y optimización de carteras
- 4.1.1 Markowitz: frontera eficiente y restricciones reales
- 4.1.2 Estimación de covarianzas: shrinkage, modelos factoriales y denoising
- 4.1.3 Black-Litterman: del equilibrio del mercado a las visiones
- 4.1.4 Risk parity, mínima varianza, HRP y HERC
- 4.1.5 Optimización con CVaR, drawdown, rotación y costes
- 4.1.6 Modelos factoriales: CAPM, Fama-French, PCA y atribución
- 4.1.7 Rebalanceo y carteras de estrategias
- 4.1.8 Herramientas de carteras: Riskfolio-Lib, PyPortfolioOpt, skfolio y bt
4.2 · Gestión del riesgo y tamaño de posición
- 4.2.1 Riesgo por operación, stops y riesgo de ruina
- 4.2.2 Criterio de Kelly y volatility targeting: cuánto arriesgar
- 4.2.3 VaR, Expected Shortfall y backtesting del VaR
- 4.2.4 Stress testing y riesgos de correlación, liquidez, gap y contraparte
- 4.2.5 Control del drawdown y kill switch
- 4.2.6 Riesgo de derivados: griegas de cartera, margen y liquidaciones
4.3 · Microestructura y ejecución
4.4 · Brokers y APIs
- 4.4.1 Elegir bróker desde España o la UE: regulación, activos, costes y API
- 4.4.2 Interactive Brokers: TWS e IB Gateway, ib_async, contratos, datos y órdenes
- 4.4.3 Alpaca, Tradier, MetaTrader 5 con Python y OANDA v20
- 4.4.4 APIs de exchanges cripto: ccxt, Binance, Bybit, Kraken y Coinbase
- 4.4.5 Credenciales seguras: variables de entorno, gestores de secretos y permisos mínimos
4.5 · Sistema de trading en vivo
- 4.5.1 Arquitectura de un sistema en vivo: de los datos a la reconciliación
- 4.5.2 Gestión de órdenes: estados, fills parciales, cancelaciones y reconexiones
- 4.5.3 Paper trading, shadow trading y seguimiento del slippage
- 4.5.4 Programación de tareas y alertas: cron, APScheduler, Prefect, Telegram, Slack y email
- 4.5.5 Tolerancia a fallos: idempotencia, estado persistente y reconciliación al arrancar
- 4.5.6 NautilusTrader o LEAN en real: del backtest a producción con el mismo código
Kelly: cuánto apostar cuando se tiene ventaja
La lección 2.2.2 repartía el riesgo entre mercados con un objetivo de volatilidad fijado a mano, y la 4.2.1 limita lo que se arriesga en cada operación. Falta la pregunta de arriba: cuánto riesgo total conviene tomar con una ventaja dada. John L. Kelly la contestó en 1956 para un jugador que apuesta repetidamente una fracción de su capital: la que maximiza el crecimiento logarítmico esperado, que es la tasa a la que crece el capital a largo plazo. Para una apuesta que gana por unidad con probabilidad y pierde la unidad con :
Una moneda con un 55 % de acierto y pago 1 a 1 da : apostar el 10 % del capital en cada tirada.
import numpy as np
import pandas as pd
p, b = 0.55, 1.0 # probabilidad de ganar y pago por unidad
f_kelly = p - (1 - p) / b
print(f"Fracción de Kelly: {f_kelly:.2f}")
def g(f):
"""Crecimiento logarítmico esperado por apuesta."""
return p * np.log1p(f * b) + (1 - p) * np.log1p(-f)
fracciones = [0.025, 0.05, 0.10, 0.15, 0.20, 0.30]
pd.Series({f: g(f) for f in fracciones}, name="g").round(5)Fracción de Kelly: 0.10
0.025 0.00219
0.050 0.00375
0.100 0.00501
0.150 0.00374
0.200 -0.00014
0.300 -0.01620
Name: g, dtype: float64El crecimiento por apuesta es máximo en (0,00501 en logaritmo) y casi simétrico alrededor: con 0,05 y con 0,15 se obtiene lo mismo (0,00375 y 0,00374). Con 0,20, el doble de Kelly, el crecimiento es ya negativo (−0,00014): se juega con ventaja y, aun así, el capital tiende a menguar. Con 0,30 el capital se desvanece. Una media no lo muestra; mil apuestas repetidas por 4.000 jugadores, sí:
rng = np.random.default_rng(7)
gana = rng.random((4000, 1000)) < p # 4.000 caminos de 1.000
filas = {}
for f in (0.05, 0.10, 0.20, 0.30):
paso = np.where(gana, np.log1p(f * b), np.log1p(-f))
lw = np.cumsum(paso, axis=1) # log de la riqueza
pico = np.maximum.accumulate(np.maximum(lw, 0), axis=1)
caida = np.exp(lw - pico) - 1
filas[f] = {"mediana_final": np.exp(np.median(lw[:, -1])),
"p_pierde": (lw[:, -1] < 0).mean(),
"p_mitad_inicial": (lw.min(axis=1)
<= np.log(0.5)).mean(),
"p_caida_50": (caida.min(axis=1) <= -0.5).mean(),
"p_caida_80": (caida.min(axis=1) <= -0.8).mean()}
pd.DataFrame(filas).T.round(3) mediana_final p_pierde p_mitad_inicial p_caida_50 p_caida_80
0.05 42.632 0.009 0.116 0.854 0.064
0.10 149.660 0.061 0.483 1.000 0.850
0.20 0.871 0.514 0.911 1.000 1.000
0.30 0.000 0.954 0.997 1.000 1.000Con Kelly (0,10) la mediana de los jugadores multiplica su capital por 150, pero el 6,1 % termina perdiendo, el 48,3 % toca alguna vez la mitad del capital inicial y todos sufren una caída del 50 % desde un máximo. Con medio Kelly (0,05) la mediana multiplica por 43, solo pierde el 0,9 %, el 11,6 % toca la mitad del capital inicial y el 6,4 % sufre una caída del 80 %, frente al 85 % con Kelly. Con el doble de Kelly (0,20) la mitad de los jugadores pierde dinero con una moneda a su favor.
En continuo: la volatilidad óptima es el Sharpe
Para una estrategia con exceso esperado y volatilidad (anuales), apalancada veces y rebalanceada a menudo, el crecimiento logarítmico del exceso es , una parábola. Su máximo:
La tercera igualdad es la más útil: a Kelly, la volatilidad de la cuenta es igual al Sharpe. Una estrategia de Sharpe 0,5 pide un 50 % de volatilidad anual, sea cual sea su volatilidad propia. Con una fracción de Kelly, el crecimiento es y la volatilidad . El logaritmo del capital es entonces un movimiento browniano con deriva y varianza , y la probabilidad de que caiga alguna vez hasta una fracción del capital inicial es (la de tocar una barrera inferior, con parámetros conocidos y horizonte infinito):
c = np.array([0.25, 0.5, 0.75, 1.0, 1.5, 2.0])
expo = 2 / c - 1 # P(caer alguna vez a x) = x ** expo
pd.DataFrame({"crecimiento_vs_max": 2 * c - c**2,
"vol_en_sharpes": c,
"p_caer_a_la_mitad": 0.5 ** expo,
"p_caer_al_20": 0.2 ** expo},
index=pd.Index(c, name="fraccion")).round(3) crecimiento_vs_max vol_en_sharpes p_caer_a_la_mitad p_caer_al_20
fraccion
0.25 0.438 0.25 0.008 0.000
0.50 0.750 0.50 0.125 0.008
0.75 0.938 0.75 0.315 0.068
1.00 1.000 1.00 0.500 0.200
1.50 0.750 1.50 0.794 0.585
2.00 0.000 2.00 1.000 1.000La figura de la cabecera dibuja esas dos curvas. El crecimiento es plano cerca del máximo y la probabilidad de caída no: pasar de Kelly a medio Kelly cuesta un 25 % del crecimiento y divide por cuatro la probabilidad de perder la mitad (del 50 % al 12,5 %); un cuarto de Kelly conserva el 44 % del crecimiento con un 0,8 %. Por encima de Kelly todo empeora a la vez: con 1,5 veces Kelly el crecimiento es el mismo que con medio Kelly (0,75) y la probabilidad de perder la mitad, del 79 %. La simulación de la moneda coincide con la fórmula (0,116 y 0,483 frente a 0,125 y 0,5). El error no es simétrico: apostar de menos cuesta poco; apostar de más, mucho.
Kelly en las estrategias del nivel
Las diez estrategias de estrategias4_diarias.parquet son rendimientos diarios simples en exceso del tipo libre,
2006-2025, con una media verdadera conocida (exceso_anual_esperado en estrategias4_verdad.csv). La lección deja
fuera degradada, que deja de funcionar en 2019 y es el caso de la lección 4.2.5. Además de , la celda
calcula la Kelly «exacta» de los datos (la que maximiza la media de con los rendimientos diarios
reales, colas incluidas) y el apalancamiento que arruina la cuenta en el peor día de la muestra:
from scipy.optimize import minimize_scalar
est = pd.read_parquet("estrategias4_diarias.parquet")
est = est.set_index("fecha").drop(columns="degradada")
verdad = pd.read_csv("estrategias4_verdad.csv",
index_col="estrategia").reindex(est.columns)
def kelly_log(r):
"""f que maximiza la media de log(1 + f·r) de los datos."""
tope = 0.999 / abs(r.min()) # más allá, ruina
res = minimize_scalar(lambda f: -np.log1p(f * r).mean(),
bounds=(0, tope), method="bounded")
return res.x
mu, var = est.mean() * 252, est.var() * 252
tabla = pd.DataFrame({
"mu": mu, "vol": np.sqrt(var),
"kelly": mu / var,
"kelly_verdad": verdad["exceso_anual_esperado"] / var,
"kelly_log": est.apply(kelly_log),
"ruina": 1 / est.min().abs()})
tabla.round(2) mu vol kelly kelly_verdad kelly_log ruina
tendencia_futuros 0.06 0.11 4.97 4.30 4.94 20.25
carry_futuros 0.03 0.08 5.06 5.63 5.02 31.35
carry_divisas 0.05 0.09 5.81 3.81 5.73 21.78
venta_puts 0.04 0.12 2.56 2.82 2.54 15.25
pares 0.02 0.06 6.72 8.43 6.61 25.65
momentum_acciones 0.05 0.12 3.19 2.83 3.12 12.44
valor_acciones 0.02 0.09 3.01 3.06 3.01 31.49
venta_volatilidad 0.04 0.16 1.55 2.61 1.47 5.19
reversion_corto 0.03 0.07 6.41 5.61 6.36 24.95Tres lecturas:
- Las Kelly son grandes: de 1,5 a 6,7 veces el capital para estrategias sueltas con volatilidades del 6 al 16 %. Es la consecuencia de : con un Sharpe de 0,4, Kelly pide un 40 % de volatilidad.
- La media muestral se aleja de la verdadera aunque haya 20 años: en
carry_divisasla Kelly muestral es 5,81 y la verdadera 3,81; enventa_volatilidad, 1,55 frente a 2,61. Con la media de la muestra se apuesta un 50 % de más en la primera y un 40 % de menos en la segunda. - Las colas mandan en la venta de volatilidad. Su Kelly exacta (1,47) es menor que la de la fórmula, y el apalancamiento de ruina, 5,19 veces, está a solo dos veces de la Kelly verdadera: el peor día de la muestra pierde un 19,3 %. En las demás, la ruina queda a 12-31 veces el capital y la fórmula y la Kelly exacta casi coinciden.
Con nueve estrategias poco correlacionadas, la cartera equiponderada tiene un Sharpe mayor y una volatilidad mucho menor, y Kelly se dispara:
cartera = est.mean(axis=1) # equiponderada, rend. simples
k_cartera = cartera.mean() / cartera.var()
print(f"Kelly de la cartera: {k_cartera:.1f} veces el capital")
print(f"Volatilidad a Kelly: {k_cartera * cartera.std() * 252**.5:.0%}")
def resultado(r):
w = (1 + r).cumprod()
años = len(r) / 252
return {"cagr": w.iloc[-1] ** (1 / años) - 1
if w.iloc[-1] > 0 else -1.0,
"max_caida": (w / w.cummax() - 1).min(),
"peor_dia": r.min(),
"ruina": bool((w <= 0).any())}
fr = {c: resultado(c * k_cartera * cartera)
for c in (0.125, 0.25, 0.5, 1.0, 2.0)}
print("Peor día:", cartera.idxmin().date())
pd.DataFrame(fr).T.astype(float).round(3)Kelly de la cartera: 18.8 veces el capital
Volatilidad a Kelly: 84%
Peor día: 2018-02-05
cagr max_caida peor_dia ruina
0.125 0.086 -0.315 -0.053 0.0
0.250 0.167 -0.544 -0.106 0.0
0.500 0.303 -0.816 -0.213 0.0
1.000 0.417 -0.979 -0.426 0.0
2.000 -0.081 -1.000 -0.851 0.0Kelly pide 18,8 veces el capital y un 84 % de volatilidad. Con la Kelly de toda la muestra (que usa la media de 20 años desde el primer día: anticipación) el resultado es el de la teoría con un matiz: Kelly completo da el mayor CAGR (41,7 %), pero con una caída máxima del −97,9 % y un día, el 5 de febrero de 2018, en que pierde el 42,6 % del capital. Un octavo de Kelly (2,3 veces) da un 8,6 % con una caída del −31,5 %. El doble de Kelly pierde un 8,1 % al año y se queda con una caída del 100 % (redondeada). Ninguna fracción llega a la ruina estricta (la cuenta no pasa de cero porque el peor día de la cartera pierde un 2,3 %), pero una caída del 98 % es una ruina a efectos prácticos.
Con lo que se sabía cada día (media y varianza desde el inicio, con tres años de arranque y sin posiciones cortas), la Kelly de la cartera empieza en cero en 2009, porque la crisis de 2008 dejó la media de la muestra en negativo, y sube a 5,9 en 2013, 14,6 en 2017 y 18,7 en 2025:
mu_t = cartera.expanding(756).mean().shift(1)
var_t = cartera.expanding(756).var().shift(1)
k_t = (mu_t / var_t).clip(lower=0) # sin posiciones cortas
print(k_t.resample("YE").last().loc["2009":"2025":4].round(1))
pd.DataFrame({c: resultado((c * k_t * cartera).dropna())
for c in (0.25, 0.5, 1.0)}).T.astype(float).round(3)fecha
2009-12-31 0.0
2013-12-31 5.9
2017-12-31 14.6
2021-12-31 16.2
2025-12-31 18.7
Freq: 4YE-DEC, dtype: float64
cagr max_caida peor_dia ruina
0.25 0.129 -0.346 -0.084 0.0
0.50 0.251 -0.581 -0.168 0.0
1.00 0.450 -0.839 -0.337 0.0El CAGR de Kelly completo sale incluso mayor (45,0 %) porque llegó tarde a la estrategia y con poco apalancamiento a las caídas de 2009-2012; la caída máxima, del −83,9 %, y el peor día, del −33,7 %, siguen siendo los de una cuenta que nadie mantendría. La suerte del calendario decide aquí más que la regla.
El error de estimación
Kelly supone que y se conocen. La volatilidad se estima bien con pocos datos; la media, no. Con años de datos, la media muestral tiene un error típico de , así que la Kelly estimada es con . Apostar una fracción de la Kelly estimada da un crecimiento esperado, relativo al de la Kelly verdadera, de
undefinedRespuesta plegada en cada pregunta
Autoevaluación
Una estrategia tiene un exceso esperado del 6 % anual y una volatilidad del 12 %. ¿Qué apalancamiento da Kelly y qué volatilidad tendría la cuenta?
- A4,2 veces el capital y un 50 % de volatilidad, que es el Sharpe (0,5)
- B0,5 veces el capital y un 6 % de volatilidad
- C1 vez el capital: Kelly nunca apalanca
- D12 veces el capital
Ver respuesta
Respuesta A. 4,2 veces el capital y un 50 % de volatilidad, que es el Sharpe (0,5)
f* = μ/σ² = 0,06/0,0144 ≈ 4,2. La volatilidad de la cuenta es f*·σ = μ/σ = Sharpe = 50 %. Con colas gruesas y una media estimada, nadie opera eso: de ahí las fracciones.
Con medio Kelly, ¿qué parte del crecimiento máximo se conserva y cuál es la probabilidad de caer alguna vez a la mitad del capital inicial (caso continuo, parámetros conocidos)?
- AEl 50 % del crecimiento y un 50 % de probabilidad
- BEl 75 % del crecimiento y un 12,5 % de probabilidad, frente al 50 % de Kelly completo
- CEl 100 % del crecimiento y ninguna probabilidad
- DEl 25 % del crecimiento y un 1 % de probabilidad
Ver respuesta
Respuesta B. El 75 % del crecimiento y un 12,5 % de probabilidad, frente al 50 % de Kelly completo
El crecimiento relativo es 2c − c² = 0,75 y la probabilidad de tocar x es x elevado a 2/c − 1: 0,5³ = 0,125. La simulación de la moneda da 0,116 con mil apuestas.
Una estrategia de Sharpe 0,4 se ha medido con 5 años de datos. Si se apuesta la Kelly estimada completa, ¿qué crecimiento se espera respecto al de la Kelly verdadera?
- AEl 100 %: la estimación es insesgada
- BEl 75 %
- CEl 50 %
- DNegativo (−24 %): el error de la media hace que la Kelly estimada supere a menudo el doble de la verdadera
Ver respuesta
Respuesta D. Negativo (−24 %): el error de la media hace que la Kelly estimada supere a menudo el doble de la verdadera
Con 5 años, f estimada / f verdadera tiene una desviación típica de 1/(0,4·√5) ≈ 1,1. El crecimiento esperado es 2c − c²(1 + 1/(SR²T)) = 2 − 2,25 < 0. La fracción que lo maximiza es 0,44.
En los datos, el volatility targeting sube el Sharpe de
RV_EEUUde 0,43 a 0,84. ¿Por qué no hay que esperar lo mismo en un mercado real?- APorque los datos tienen errores
- BPorque el control usa información futura
- CPorque en el generador los tramos de volatilidad alta tienen deriva negativa y la calma una prima alta (≈ 20 % anual): el control gana sobre todo por esa relación plantada; en la literatura la mejora es pequeña o no sobrevive fuera de muestra
- DPorque la renta variable real no tiene volatilidad variable
Ver respuesta
Respuesta C. Porque en el generador los tramos de volatilidad alta tienen deriva negativa y la calma una prima alta (≈ 20 % anual): el control gana sobre todo por esa relación plantada; en la literatura la mejora es pequeña o no sobrevive fuera de muestra
El control mejora el Sharpe cuando la rentabilidad esperada no sube en proporción a la volatilidad. En
RV_EEUUel tercil de volatilidad alta rinde un −13 % anual por construcción. Harvey et al. (2018) encuentran mejora en activos de riesgo y casi ninguna en bonos, divisas y materias primas; Cederburg et al. (2020), que fuera de muestra no supera de forma sistemática a la cartera sin gestionar.El 5 de febrero de 2018 la venta de volatilidad pierde un 19,3 % sin control y un 27,9 % con volatility targeting. ¿Qué pasó?
- AUn error de datos
- BEl control vendió en el peor momento
- CLa volatilidad prevista era baja tras meses de calma, así que la exposición era de 1,45 veces; un salto de −27 desviaciones previstas no da tiempo a reducirla
- DEl tope de exposición no funcionó
Ver respuesta
Respuesta C. La volatilidad prevista era baja tras meses de calma, así que la exposición era de 1,45 veces; un salto de −27 desviaciones previstas no da tiempo a reducirla
El control reacciona a la volatilidad pasada. Un salto sin aviso llega con la exposición en su máximo y el control lo amplifica. Al día siguiente la exposición baja a 0,28, cuando la pérdida ya está hecha.
Ideas clave
- Kelly maximiza el crecimiento a largo plazo con
f* = μ/σ²; a Kelly, la volatilidad de la cuenta es el Sharpe. Para la cartera de las nueve estrategias eso son 18,8 veces el capital y un 84 % de volatilidad. - Apostar por encima de Kelly es un mal negocio: a 2 veces Kelly el crecimiento es cero con todo el riesgo. Por debajo, se pierde poco crecimiento y mucha caída: medio Kelly conserva el 75 % del crecimiento con la mitad de volatilidad.
- La media se estima mal: con una muestra de T años, la fracción que maximiza el crecimiento esperado es SR²T/(1 + SR²T) de la Kelly estimada (0,44 con 5 años y Sharpe 0,4), y menos si el Sharpe del backtest está inflado.
- El volatility targeting mantiene el riesgo estable y reduce la máxima caída, pero solo sube el Sharpe si la rentabilidad no crece con la volatilidad; en los datos esa relación está plantada y en la literatura es frágil.
- Su peor episodio es el salto tras la calma: exposición alta y pérdida mayor que sin control (−27,9 % frente a −19,3 % en la venta de volatilidad).
- Una regla de tamaño se calcula con lo que se sabía cada día: un
shift(-2)en la volatilidad sube el Sharpe del método 1 − P de 0,94 a 1,18 sin que la regla sea mejor.
Recursos
Research
Libros
- Kelly, J. L. (1956): A New Interpretation of Information Rate. Bell System Technical Journal 35(4), 917-926
- Thorp, E. O. (2006): The Kelly Criterion in Blackjack, Sports Betting, and the Stock Market. Handbook of Asset and Liability Management, cap. 9
- Moreira, A. y Muir, T. (2017): Volatility-Managed Portfolios. The Journal of Finance 72(4), 1611-1644
- Harvey, C. R. et al. (2018): The Impact of Volatility Targeting. The Journal of Portfolio Management 45(1), 14-33
- Cederburg, S. et al. (2020): On the performance of volatility-managed portfolios. Journal of Financial Economics 138(1), 95-117