Lección 0.1.2 · 35 min

Expectativas realistas: costes, tiempo y riesgo de pérdida

Antes de buscar una ventaja hay que saber cuánto cuesta tenerla. Cuatro cálculos sencillos —costes, pérdidas, años malos y años de datos— que explican por qué la mayoría de las estrategias no llegan a funcionar en real.

Fig. — Subida necesaria para recuperar una pérdida
02/03
Módulo
0.1 · Bienvenida y expectativas
Duración
35 min
Lecciones del nivel 0
  1. 0.1 · Bienvenida y expectativas

    1. 0.1.1 Trading sistemático, algorítmico y cuantitativo frente al discrecional
    2. 0.1.2 Expectativas realistas: costes, tiempo y riesgo de pérdida
    3. 0.1.3 Estructura del curso, tests de entrada, repositorio personal y aprendizaje con IA
  2. 0.2 · Entorno de trabajo moderno

    1. 0.2.1 Instalación de Python con uv: versiones y ciclo de soporte
    2. 0.2.2 Entornos virtuales y dependencias: uv init, uv add, pyproject.toml y lockfiles
    3. 0.2.3 Editores (VS Code, Cursor, PyCharm) y notebooks (Jupyter, JupyterLab, marimo)
    4. 0.2.4 Terminal básica, rutas, variables de entorno y ficheros .env
    5. 0.2.5 Git y GitHub: commits, ramas, pull requests y .gitignore
    6. 0.2.6 Introducción a los asistentes de código con IA: prompts, revisión y tests
  3. 0.3 · Fundamentos del lenguaje

    1. 0.3.1 Variables, tipos y operadores; coma flotante y decimal para precios y ticks
    2. 0.3.2 Cadenas, f-strings y formato de números y fechas
    3. 0.3.3 Listas, tuplas, diccionarios, conjuntos y comprensiones
    4. 0.3.4 Control de flujo: if, elif, else, for, while y match-case
    5. 0.3.5 Funciones: argumentos, *args y **kwargs, lambdas y ámbito
    6. 0.3.6 Excepciones; módulos y paquetes, con los imports perezosos de Python 3.15
  4. 0.4 · Python intermedio

    1. 0.4.1 Programación orientada a objetos: clases, herencia, composición y dataclasses
    2. 0.4.2 Tipado: type hints, mypy o ty y Pydantic para configuraciones
    3. 0.4.3 Iteradores, generadores, decoradores y context managers
    4. 0.4.4 Ficheros (CSV, JSON, YAML, TOML) y fechas con zonas horarias
    5. 0.4.5 Logging profesional y testing con pytest
    6. 0.4.6 Concurrencia: threading, multiprocessing, asyncio y free-threading
  5. 0.5 · Computación numérica y datos

    1. 0.5.1 NumPy 2: arrays, broadcasting, vectorización, álgebra lineal y generadores aleatorios
    2. 0.5.2 pandas 3.0: Series, DataFrame, índices temporales, Copy-on-Write, tipo str y pd.col()
    3. 0.5.3 Selección, filtrado, groupby, merge, pivot, resample y ventanas móviles
    4. 0.5.4 Polars: API lazy frente a eager, expresiones, rendimiento y cuándo elegirlo frente a pandas
    5. 0.5.5 DuckDB y SQL esencial: SELECT, JOIN, GROUP BY y funciones de ventana sobre Parquet
  6. 0.6 · Visualización

    1. 0.6.1 Matplotlib orientado a objetos, Seaborn y Plotly: gráficos de precios, drawdown y velas
    2. 0.6.2 Dashboards rápidos con Streamlit: un panel de seguimiento en un solo script
  7. 0.7 · Matemáticas y estadística mínimas

    1. 0.7.1 Rentabilidades simples y logarítmicas, interés compuesto y estadística descriptiva
    2. 0.7.2 Probabilidad y distribuciones, correlación frente a causalidad y regresión simple
    3. 0.7.3 Álgebra lineal intuitiva: vectores y matrices como preparación para carteras

Lo que cuesta operar

Una estrategia no gana lo que dice su backtest, sino lo que queda después de pagar por operarla. Los costes tienen cinco fuentes, y solo la primera aparece en la tarifa del bróker:

  • Comisiones: lo que cobra el bróker por cada orden. Es el coste más visible y, en acciones líquidas, el menor.
  • Horquilla (spread): la diferencia entre el precio al que se puede comprar y el precio al que se puede vender. Cada operación completa la paga una vez.
  • Deslizamiento (slippage): la diferencia entre el precio de la señal y el precio realmente ejecutado. Crece con el tamaño de la orden y con la volatilidad del momento.
  • Financiación: intereses de las posiciones apalancadas, préstamo de títulos en los cortos, rollover en forex y funding en los perpetuos de cripto.
  • Impuestos: en España, las ganancias tributan en la base del ahorro (nivel 7). No cambian la estrategia, pero sí lo que queda al final.
Rentabilidad bruta− comisiones− horquilla y deslizamiento− financiación− impuestosRentabilidad neta
Fuente Mermaid
flowchart TB
  B[Rentabilidad bruta] --> C1[− comisiones] --> C2[− horquilla y deslizamiento] --> C3[− financiación] --> C4[− impuestos] --> N[Rentabilidad neta]

Si se agrupan los cuatro primeros en un coste por operación completa (comprar y vender) cc, y la estrategia hace nn operaciones completas al año, la rentabilidad neta es aproximadamente:

rneta≈rbruta−n⋅cr_{\text{neta}} \approx r_{\text{bruta}} - n \cdot c

La fórmula es sencilla y su consecuencia, dura: el coste de cada operación se multiplica por la rotación. En Python:

IN [01]python
import pandas as pd

def rentabilidad_neta(bruta: float, operaciones: int,
                      coste: float) -> float:
    """Rentabilidad anual neta.

    `coste`: coste de una operación completa, en tanto por uno.
    """
    return bruta - operaciones * coste

operaciones = [1, 5, 10, 25, 50, 100]
costes = [0.001, 0.002, 0.005]
tabla = pd.DataFrame(
    {f"coste {c:.1%}": [rentabilidad_neta(0.08, n, c) for n in operaciones]
     for c in costes},
    index=pd.Index(operaciones, name="operaciones/año"),
)
tabla.round(3)
OUT [01]Rentabilidad neta según rotación y coste
                 coste 0.1%  coste 0.2%  coste 0.5%
operaciones/año
1                     0.079       0.078       0.075
5                     0.075       0.070       0.055
10                    0.070       0.060       0.030
25                    0.055       0.030      -0.045
50                    0.030      -0.020      -0.170
100                  -0.020      -0.120      -0.420

Con un 8 % bruto y un 0,2 % por operación, la estrategia sigue siendo buena con 10 operaciones al año y pierde dinero a partir de 40:

Fig. — Rentabilidad neta de una estrategia con un 8 % bruto según su rotación (0,2 % de coste por operación completa)

Por eso las estrategias de alta rotación necesitan una ventaja bruta mucho mayor, y por eso un backtest sin costes no dice nada. A partir del nivel 2, todo backtest del curso lleva costes.

Las pérdidas no son simétricas

Si una cuenta de 10.000 € pierde un 50 %, quedan 5.000 €. Para volver a 10.000 € no basta con ganar un 50 %: hay que duplicar lo que queda, un 100 %. En general, tras una pérdida pp la subida necesaria es:

g=11−p−1g = \frac{1}{1 - p} - 1
IN [02]python
for perdida in (0.10, 0.20, 0.50, 0.75):
    subida = 1 / (1 - perdida) - 1
    print(f"Tras perder un {perdida:.0%}, hay que subir un {subida:.1%}")
OUT [02]Subida necesaria tras una pérdida
Tras perder un 10%, hay que subir un 11.1%
Tras perder un 20%, hay que subir un 25.0%
Tras perder un 50%, hay que subir un 100.0%
Tras perder un 75%, hay que subir un 300.0%

La figura de la cabecera muestra la curva completa. Hasta un 20 % la asimetría es pequeña; a partir de un 40 %, la recuperación exige rentabilidades que pocas estrategias dan en años. Esta es la razón de que la gestión del riesgo (nivel 4) importe más que buscar la regla que más gana: una caída del 60 % no se arregla con una buena racha.

Años malos con una estrategia buena

El ratio de Sharpe mide la rentabilidad media por unidad de volatilidad: un Sharpe anual de 1 significa que la rentabilidad media de un año es igual a su desviación típica. Si las rentabilidades anuales fueran normales, la probabilidad de cerrar un año en pérdidas sería Φ(−SR)\Phi(-\text{SR}), donde Φ\Phi es la función de distribución de la normal estándar:

IN [03]python
from statistics import NormalDist

for sharpe in (0.5, 1.0, 1.5):
    p = NormalDist().cdf(-sharpe)
    print(f"Sharpe {sharpe}: {p:.1%} de años en pérdidas")
OUT [03]Años en pérdidas según el Sharpe
Sharpe 0.5: 30.9% de años en pérdidas
Sharpe 1.0: 15.9% de años en pérdidas
Sharpe 1.5: 6.7% de años en pérdidas
Fig. — Probabilidad de cerrar un año en pérdidas según el ratio de Sharpe

Un Sharpe de 1 sostenido durante años es un resultado excelente para una estrategia sistemática, y aun así uno de cada seis años cierra en negativo. Las rentabilidades reales tienen colas más gruesas que la normal (nivel 1), así que la cifra real suele ser algo peor.

Una simulación lo hace más concreto. Diez mil trayectorias de diez años de una estrategia con Sharpe 0,5 —un 5 % de rentabilidad media y un 10 % de volatilidad—, con años independientes y normales:

IN [04]python
import numpy as np

rng = np.random.default_rng(42)
anos = rng.normal(loc=0.05, scale=0.10, size=(10_000, 10))
en_perdidas = anos < 0
tres_seguidos = (
    en_perdidas[:, :-2] & en_perdidas[:, 1:-1] & en_perdidas[:, 2:]
).any(axis=1)
capital_final = np.prod(1 + anos, axis=1)

print(f"Algún año en pérdidas: {en_perdidas.any(axis=1).mean():.1%}")
print(f"Tres años seguidos en pérdidas: {tres_seguidos.mean():.1%}")
print(f"Pierden dinero en diez años: {(capital_final < 1).mean():.1%}")
OUT [04]Diez mil trayectorias de diez años
Algún año en pérdidas: 97.5%
Tres años seguidos en pérdidas: 16.8%
Pierden dinero en diez años: 7.8%

La estrategia tiene una ventaja real por construcción, y aun así en casi todas las trayectorias hay años en pérdidas y en una parte no despreciable hay rachas de tres años seguidos. Quien abandona una estrategia tras un año malo abandona, la mayoría de las veces, una estrategia que funciona.

El tiempo: cuántos datos hacen falta

La otra cara del problema: si los años malos son normales, ¿cuántos años buenos hacen falta para creerse un backtest? Una aproximación útil relaciona el Sharpe anual con el estadístico t de la rentabilidad media tras TT años de datos:

t≈SR⋅Tt \approx \text{SR} \cdot \sqrt{T}

Un estadístico t de 2 es el umbral habitual para decir que una media es distinta de cero con un 95 % de confianza. Despejando TT:

IN [05]python
for sharpe in (0.5, 0.75, 1.0):
    anos_necesarios = (2 / sharpe) ** 2
    print(f"Sharpe {sharpe}: {anos_necesarios:.0f} años de datos")
OUT [05]Años de datos para un estadístico t de 2
Sharpe 0.5: 16 años de datos
Sharpe 0.75: 7 años de datos
Sharpe 1.0: 4 años de datos

Con un Sharpe de 0,5 —una estrategia buena en baja frecuencia— hacen falta unos 16 años de datos para que el resultado no sea compatible con el azar. Y eso para una estrategia: si se prueban cien variantes y se elige la mejor, el umbral sube (nivel 2, pruebas múltiples). Esta cuenta explica dos ideas del curso: los backtests de dos o tres años no prueban nada, y los parámetros se eligen con hipótesis, no buscando el máximo.

El tiempo de aprendizaje también cuenta. El temario completo son unas 750–850 horas: a 10–15 horas por semana, entre 12 y 18 meses. Saltarse los niveles 0 a 2 no acorta ese camino, solo lo hace más caro.

Riesgo de pérdida y apalancamiento

El apalancamiento multiplica la exposición y, con ella, las pérdidas. Con un apalancamiento de 10 a 1, una caída del 10 % del activo se lleva el 100 % del capital. Los productos apalancados para minoristas —CFD, opciones, futuros, perpetuos de cripto— permiten perder todo el depósito en muy poco tiempo.

El curso no recomienda operar con dinero real hasta el nivel 4, y siempre después de semanas de paper trading (operativa simulada con precios reales) y con límites de riesgo automáticos.

Ejercicios

  1. Una estrategia gana un 12 % bruto al año, hace 40 operaciones completas y cada una cuesta un 0,3 %. ¿Cuál es su rentabilidad neta? ¿Cuántas operaciones al año podría hacer, como máximo, sin perder dinero?
Solución

Neta: 12 % − 40 × 0,3 % = 12 % − 12 % = 0 %. El punto de equilibrio es justo 40 operaciones: 0,12 / 0,003 = 40. Con cualquier rotación mayor, la estrategia pierde dinero aunque su señal sea buena.

  1. Un fondo cae un 35 % en una crisis. ¿Qué subida necesita para recuperarse? Si después gana un 8 % al año, ¿cuántos años tarda?
Solución
IN [06]python
import math

subida = 1 / (1 - 0.35) - 1
anos_recuperacion = math.log(1 / (1 - 0.35)) / math.log(1.08)
print(f"Subida necesaria: {subida:.1%}")
print(f"Años al 8 % anual: {anos_recuperacion:.1f}")
OUT [06]Recuperación tras un 35 %
Subida necesaria: 53.8%
Años al 8 % anual: 5.6

Necesita algo más de un 50 % y, al 8 % anual compuesto, más de cinco años y medio solo para volver al punto de partida.

  1. Una estrategia tiene un Sharpe anual de 0,8. ¿Qué fracción de años cierra en pérdidas, si las rentabilidades anuales son normales? ¿Cuántos años de datos hacen falta para un estadístico t de 2?
Solución
IN [07]python
from statistics import NormalDist

sharpe = 0.8
print(f"Años en pérdidas: {NormalDist().cdf(-sharpe):.1%}")
print(f"Años de datos: {(2 / sharpe) ** 2:.2f}")
OUT [07]Sharpe 0,8
Años en pérdidas: 21.2%
Años de datos: 6.25

Uno de cada cinco años, aproximadamente, cierra en pérdidas, y hacen falta algo más de seis años de datos para un estadístico t de 2: más que la mayoría de los backtests que se publican.

Respuesta plegada en cada pregunta

Autoevaluación

  1. Una estrategia gana un 10 % bruto al año con 30 operaciones completas y un coste de 0,25 % por operación. ¿Cuál es su rentabilidad neta aproximada?

    • A9,75 %
    • B7,5 %
    • C2,5 %
    • D0 %
    Ver respuesta

    Respuesta C. 2,5 %

    Los costes restan 30 × 0,25 % = 7,5 puntos: 10 % − 7,5 % = 2,5 %. La rotación multiplica el coste de cada operación.

  2. Una cuenta cae un 40 %. ¿Qué subida necesita para volver al punto de partida?

    • A40 %
    • B50 %
    • C66,7 %
    • D80 %
    Ver respuesta

    Respuesta C. 66,7 %

    1 / (1 − 0,40) − 1 = 0,667. Tras la caída queda el 60 % del capital, y ese 60 % tiene que crecer dos tercios para volver al 100 %.

  3. Con rentabilidades anuales normales, ¿qué fracción de años cierra en pérdidas una estrategia con Sharpe 1?

    • ACasi ninguno
    • BUno de cada seis, aproximadamente
    • CLa mitad
    • DDepende solo de la volatilidad
    Ver respuesta

    Respuesta B. Uno de cada seis, aproximadamente

    P(R < 0) = Φ(−1) ≈ 15,9 %: un año de cada seis. Una estrategia buena tiene años malos; abandonarla por uno de ellos es un error frecuente.

  4. ¿Cuántos años de datos hacen falta, más o menos, para que una estrategia con Sharpe 0,5 tenga un estadístico t de 2?

    • A2
    • B4
    • C8
    • D16
    Ver respuesta

    Respuesta D. 16

    t ≈ SR · √T, así que T = (2 / 0,5)² = 16 años. Con Sharpes modestos, unos pocos años de backtest no distinguen una ventaja del azar.

Ideas clave

  • La rentabilidad neta es la bruta menos la rotación por el coste de cada operación: cuanto más se opera, más ventaja hace falta.
  • Las pérdidas no son simétricas: tras perder un 50 % hace falta un 100 % para recuperarse. Limitar el drawdown importa más que maximizar la ganancia.
  • Con Sharpe 1, uno de cada seis años cierra en pérdidas. Los años malos no demuestran que una estrategia haya dejado de funcionar.
  • Para distinguir un Sharpe de 0,5 del azar hacen falta unos 16 años de datos: la mayoría de los backtests cortos no prueban nada.
  • El apalancamiento multiplica las pérdidas igual que las ganancias. En la UE, la mayoría de las cuentas minoristas de CFD pierden dinero.

Recursos