---
title: "7.4.2 ESMA y CFD: apalancamiento y protección"
description: "Las medidas de ESMA y de la CNMV sobre CFD para minoristas: garantía inicial, cierre al 50 % por cuenta, saldo negativo y advertencia, simuladas con datos."
url: "https://pythonparatrading.com/curso-python-trading/nivel-7/esma-y-cfds-apalancamiento-y-proteccion/"
lang: "es"
image: "https://pythonparatrading.com/og/curso-python-trading/nivel-7/esma-y-cfds-apalancamiento-y-proteccion.png"
---

# 7.4.2 · ESMA y CFD: apalancamiento, cierre y saldo negativo

> Desde 2018 un minorista de la UE no puede abrir un CFD con más apalancamiento que el que fija ESMA, y en España rige desde 2019 una resolución de la CNMV con las mismas reglas. Esta lección las convierte en una calculadora de garantías y un simulador de cuenta, y las prueba con las series de los niveles 2 y 3.

- Curso: [Nivel 7: Producción, MLOps, regulación, carrera y capstone](https://pythonparatrading.com/curso-python-trading/nivel-7/)
- Módulo: 7.4 · Regulación, ética y fiscalidad
- Duración: 60 min
- Requisitos: [1.2.4 · Forex: pares, pips, lotes, rollover y CFD](https://pythonparatrading.com/curso-python-trading/nivel-1/forex-pares-pips-lotes-y-rollover/), [4.2.6 · Riesgo de derivados: griegas de cartera, margen y liquidaciones](https://pythonparatrading.com/curso-python-trading/nivel-4/riesgo-de-derivados-griegas-margen-y-liquidaciones/), [7.4.1 · MiFID II: clientes, idoneidad y trading algorítmico](https://pythonparatrading.com/curso-python-trading/nivel-7/mifid-ii-clientes-idoneidad-y-trading-algoritmico/)

## Al terminar esta lección

- Situar la Decisión (UE) 2018/796 de ESMA y las resoluciones de la CNMV de 2019 y 2023: qué productos cubren, a quién y desde cuándo.
- Calcular la garantía inicial mínima de una cartera de CFD por tipo de subyacente según el anexo I de la resolución.
- Simular la protección del cierre al 50 % por cuenta y compararla con un cierre por posición, y medir la probabilidad de cierre con el apalancamiento máximo.
- Explicar la protección de saldo negativo con un salto de precio real de los datos y calcular el porcentaje de cuentas que pierden de la advertencia de riesgo.

## De la decisión de ESMA a la resolución de la CNMV

La lección 1.2.4 presentó los límites de los CFD para minoristas y calculó cuánto movimiento cierra una posición en
EURUSD. Esta lección va a las fuentes y al detalle que decide el resultado de una cuenta: qué subyacente cae en qué
tramo, cómo se mide el cierre al 50 %, qué pasa con un salto de precio y de dónde sale la cifra de la advertencia.

El poder de intervención de productos llegó con el Reglamento (UE) 600/2014 (MiFIR), aplicable desde el 3 de enero de
2018: su artículo 40 permite a ESMA restringir temporalmente un producto en toda la UE y el 42, a cada autoridad
nacional en su país. El 22 de mayo de 2018 ESMA adoptó dos decisiones: prohibir las opciones binarias a minoristas
desde el 2 de julio y restringir los CFD desde el 1 de agosto (Decisión (UE) 2018/796), por tres meses renovables.
Según la propia CNMV, ESMA las renovó tres veces. Para darles estabilidad, cada autoridad adoptó medidas nacionales
equivalentes; en España, la **Resolución de la CNMV de 27 de junio de 2019**, cuyo capítulo de CFD entró en vigor el 1
de agosto de 2019 y sigue aplicándose «mientras no se aprecie por la CNMV que se han producido cambios en las
condiciones de mercado que permitan su derogación».

```mermaid
flowchart TB
  A[MiFIR art. 40 y 42] --> B[ESMA 2018/796]
  B --> C[CNMV junio 2019]
  C --> D[CNMV julio 2023]
```

La resolución de 2019 se aplica a toda la comercialización, distribución y venta de CFD a **clientes minoristas
residentes en España**, sea cual sea el país de la entidad y tenga o no sucursal aquí; si otra autoridad impone algo
distinto, se aplica lo más estricto. Considera CFD, entre otros, el *rolling spot forex* y las apuestas sobre
diferenciales, y deja fuera los warrants y los turbos. No se aplica a los clientes profesionales: por eso la lección
7.4.1 insiste en lo que se pierde al pedir ese trato.

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

**No es asesoramiento.** Resumen de normas vigentes a 23 de octubre de 2026 con enlace al texto del BOE. Las series
son sintéticas (datos de los niveles 2 y 3, que imitan mercados reales sin serlo) y las simulaciones cierran solo con
precios de cierre diarios; un proveedor vigila la cuenta de forma continua. Las probabilidades no describen ningún
producto ni proveedor real.

</aside>

## Las cinco condiciones del artículo 4

El artículo 4 de la resolución permite vender un CFD a un minorista solo si se cumplen **todas** estas condiciones:

| Condición | Qué exige | Definición |
|---|---|---|
| a) Garantía inicial | Cobrar al cliente, como mínimo, la garantía del anexo I | Art. 3.c y anexo I |
| b) Cierre de posición | Liquidar CFD cuando fondos más ganancias netas no realizadas bajen de la mitad de la garantía inicial total | Art. 3.e |
| c) Saldo negativo | La responsabilidad del cliente se limita a los fondos de la cuenta de CFD | Art. 3.f |
| d) Sin incentivos | Ni pagos ni beneficios monetarios o no monetarios por operar, salvo información y herramientas de análisis | Art. 3.b |
| e) Advertencia | Toda comunicación lleva la advertencia del anexo II con el porcentaje de cuentas que pierden | Anexo II |

El anexo I fija la garantía por tipo de subyacente. El detalle está en las listas: «divisas principales» son seis
(dólar estadounidense, euro, yen, libra, dólar canadiense y franco suizo), y los índices del 5 % son diez nombrados, con
la denominación de 2019 («DAX30»). El IBEX 35 no está entre ellos. Una calculadora que lo aplica tal cual:

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

PRINCIPALES = {"USD", "EUR", "JPY", "GBP", "CAD", "CHF"}
INDICES_5 = {"FTSE 100", "CAC 40", "DAX30", "DJIA", "S&P 500",
             "NASDAQ", "NASDAQ 100", "Nikkei 225", "ASX 200",
             "EURO STOXX 50"}

def garantia_inicial(tipo, nombre=""):
    """Fracción del nominal (anexo I de la Resolución de 2019)."""
    if tipo == "divisa":
        a, b = nombre[:3], nombre[3:]
        return 0.0333 if {a, b} <= PRINCIPALES else 0.05
    if tipo == "indice":
        return 0.05 if nombre in INDICES_5 else 0.10
    if tipo == "materia_prima":
        return 0.05 if nombre == "oro" else 0.10
    if tipo == "cripto":
        return 0.50
    return 0.20                 # acciones y cualquier otro subyacente

cartera = pd.DataFrame([
    ("divisa", "EURUSD", 100_000), ("divisa", "EURTRY", 20_000),
    ("indice", "DAX30", 40_000), ("indice", "IBEX 35", 40_000),
    ("materia_prima", "oro", 20_000),
    ("materia_prima", "brent", 20_000),
    ("accion", "una acción", 10_000), ("cripto", "BTC", 4_000),
], columns=["tipo", "subyacente", "nominal_eur"])
pares = zip(cartera["tipo"], cartera["subyacente"])
cartera["garantia_pct"] = [100 * garantia_inicial(t, s)
                           for t, s in pares]
cartera["garantia_eur"] = (cartera["nominal_eur"]
                           * cartera["garantia_pct"] / 100)
print(cartera.to_string(index=False))
total = cartera["garantia_eur"].sum()
nominal = cartera["nominal_eur"].sum()
print(f"garantía total {total:,.0f} EUR para {nominal:,.0f} EUR de "
      f"nominal (apalancamiento medio {nominal / total:.1f}:1)")
```
```output
         tipo subyacente  nominal_eur  garantia_pct  garantia_eur
       divisa     EURUSD       100000          3.33        3330.0
       divisa     EURTRY        20000          5.00        1000.0
       indice      DAX30        40000          5.00        2000.0
       indice    IBEX 35        40000         10.00        4000.0
materia_prima        oro        20000          5.00        1000.0
materia_prima      brent        20000         10.00        2000.0
       accion una acción        10000         20.00        2000.0
       cripto        BTC         4000         50.00        2000.0
garantía total 17,330 EUR para 254,000 EUR de nominal (apalancamiento medio 14.7:1)
```

El mismo nominal en el DAX30 y en el IBEX 35 cuesta el doble de garantía en el segundo, y el par EURTRY, con una
divisa que no está en la lista, va al 5 %. El apalancamiento medio de la cartera, que mezcla tramos, no es ninguno de
los del anexo: es lo que pasa en una cuenta real.

## Lo que significa el apalancamiento máximo con datos

ESMA no eligió las cifras a ojo. En su decisión explica que calibró la garantía de cada subyacente según su volatilidad,
simulando con unos diez años de precios diarios la probabilidad de que un cliente pierda el 50 % de su inversión inicial
en un plazo de tenencia adecuado, con el objetivo de que esa probabilidad fuera coherente entre subyacentes. El mismo
ejercicio se puede hacer con los datos del curso. Las series imitan mercados reales; el tramo que se les asigna es el
del mercado al que imitan, y es un supuesto de la lección:

| Serie (datos) | Imita | Tramo del anexo I | Garantía |
|---|---|---|---|
| QEVUSD (`fx3_diario`) | EURUSD | Dos divisas principales | 3,33 % |
| USDQMP (`fx3_diario`) | USDMXN | Otra divisa | 5 % |
| RVE (`futuros3_indices_contado`) | EURO STOXX 50 | Índice principal | 5 % |
| MEA (`futuros2_continuos`) | Oro | Oro | 5 % |
| RVH (`futuros3_indices_contado`) | IBEX 35 | Otro índice | 10 % |
| ENA (`futuros2_continuos`) | Crudo ligero | Otra materia prima | 10 % |
| 120 acciones (`universo2_ajustados`) | Acciones | Acciones | 20 % |
| XBQ en boreal (`cripto3_diario`) | Bitcoin | Criptomoneda | 50 % |

El experimento: todo el saldo de la cuenta como garantía (el apalancamiento máximo permitido), una posición abierta
cada sesión, larga o corta, mantenida 20 sesiones. Se cierra si en algún cierre diario la pérdida llega a la mitad de
la garantía, es decir, a un movimiento en contra de la mitad del porcentaje del anexo:

```python
from numpy.lib.stride_tricks import sliding_window_view

fx = pd.read_parquet("fx3_diario.parquet")
ind = pd.read_csv("futuros3_indices_contado.csv", parse_dates=["fecha"])
fut = pd.read_parquet("futuros2_continuos.parquet")
acc = pd.read_parquet("universo2_ajustados.parquet")
cri = pd.read_parquet("cripto3_diario.parquet")

def serie(df, col_id, valor, col_precio):
    s = df[df[col_id] == valor].set_index("fecha")[col_precio]
    return s.sort_index().dropna()

series = {
    "QEVUSD": (serie(fx, "par", "QEVUSD", "spot"), 0.0333),
    "USDQMP": (serie(fx, "par", "USDQMP", "spot"), 0.05),
    "RVE": (serie(ind, "indice", "RVE", "contado"), 0.05),
    "MEA": (serie(fut, "mercado", "MEA", "cierre_ajustado"), 0.05),
    "RVH": (serie(ind, "indice", "RVH", "contado"), 0.10),
    "ENA": (serie(fut, "mercado", "ENA", "cierre_ajustado"), 0.10),
    "XBQ": (serie(cri[cri["exchange"] == "boreal"], "activo", "XBQ",
                  "cierre_spot"), 0.50),
}

def prob_cierre(precios, garantia, h=20):
    """Fracción de ventanas de h sesiones con cierre (media L/C)."""
    v = sliding_window_view(np.asarray(precios, float), h + 1)
    r = v[:, 1:] / v[:, :1] - 1
    largo = (r <= -0.5 * garantia).any(axis=1).mean()
    corto = (r >= 0.5 * garantia).any(axis=1).mean()
    return (largo + corto) / 2

res = {k: prob_cierre(s, g) for k, (s, g) in series.items()}
por_accion = [prob_cierre(g["cierre_ajustado"], 0.20)
              for _, g in acc.sort_values("fecha").groupby("ticker")
              if len(g) > 21]
res["acciones"] = float(np.mean(por_accion))
prob = pd.Series(res).sort_values(ascending=False)
(100 * prob).round(1)
```
```output
RVE         52.7
ENA         51.6
MEA         49.8
QEVUSD      39.8
USDQMP      36.7
RVH         30.0
acciones    19.3
XBQ          7.4
dtype: float64
```

La figura de la cabecera ordena el resultado. Con el apalancamiento máximo y todo el saldo comprometido, un CFD se
cierra por la regla del 50 % en una proporción grande de las ventanas de cuatro semanas, y la proporción no es igual
entre subyacentes. El tramo único del 5 % para índices principales, oro y divisas secundarias trata igual a series con
volatilidades distintas, y lo mismo pasa entre el IBEX 35 y el crudo al 10 %. La criptomoneda, con la garantía del 50
%, es la que menos se cierra: el tramo es conservador para su volatilidad. Las cifras dependen de los datos sintéticos;
lo que se puede generalizar es el método y el orden de magnitud.

La forma de reducir esa probabilidad no la decide la norma sino el cliente: no comprometer todo el saldo. La misma
cuenta con menos apalancamiento efectivo en el par principal:

```python
qev = series["QEVUSD"][0]
for apal in (30, 20, 10, 5, 2):
    # con apalancamiento efectivo L, el cierre llega con una caída
    # del 50 % del saldo: un movimiento de 0,5 / L
    p = prob_cierre(qev, 1 / apal)
    print(f"{apal:>2}:1  movimiento que cierra {50 / apal:5.2f} %  "
          f"prob. en 20 sesiones {100 * p:5.1f} %")
```
```output
30:1  movimiento que cierra  1.67 %  prob. en 20 sesiones  39.8 %
20:1  movimiento que cierra  2.50 %  prob. en 20 sesiones  23.0 %
10:1  movimiento que cierra  5.00 %  prob. en 20 sesiones   4.3 %
 5:1  movimiento que cierra 10.00 %  prob. en 20 sesiones   0.4 %
 2:1  movimiento que cierra 25.00 %  prob. en 20 sesiones   0.0 %
```

*Fig. — Probabilidad de que la regla del 50 % cierre un CFD en 20 sesiones según el apalancamiento efectivo; cada línea acaba en el máximo de su tramo.* Tres líneas de probabilidad de cierre en 20 sesiones frente al apalancamiento efectivo, de 1:1 al máximo permitido. QEVUSD llega al 39,8 % en 30:1, destacado; RVE al 52,7 % en 20:1; RVH al 30,0 % en 10:1. Con 3:1 o menos, las tres quedan en el 2 % o por debajo.

La simplificación es honesta en un sentido: con la garantía mínima y todo el saldo comprometido, garantía y saldo
coinciden, y el cierre llega con la pérdida de la mitad del saldo. Con menos apalancamiento, el proveedor no cerraría
por la regla del 50 % (el saldo sobra), pero la pérdida del 50 % del saldo sigue siendo el umbral que interesa al
cliente.

## El cierre al 50 %: por cuenta, no por posición

El artículo 3.e define la protección como la liquidación de uno o más CFD «cuando la suma de los fondos en la cuenta de
operativa en CFD y las ganancias netas no realizadas de todos los CFD abiertos asociados a esa cuenta desciendan a
menos de la mitad de la totalidad de la garantía inicial aportada para todos esos CFD abiertos». Es una regla **por
cuenta**. ESMA explica en su decisión que la consulta pública proponía una regla por posición y que la cambió: una
regla por cuenta permite que las ganancias de una posición compensen las pérdidas de otra, y un proveedor que cierre
por posición también cumple, porque es más estricto.

La diferencia importa en cuanto hay dos posiciones que se cubren. Un par largo-corto: CFD largo sobre RVE (índice
principal, 5 %) y corto sobre RVH (10 %), con el mismo nominal, y la cuenta con exactamente la garantía de los dos. Las
dos series tienen una correlación diaria de 0,73:

```python
p = ind.pivot(index="fecha", columns="indice", values="contado")
par = p[["RVE", "RVH"]].to_numpy()

def ventana(i, regla, h=20):
    nominal, signo = 1.0, np.array([1, -1])     # largo RVE, corto RVH
    garantia = nominal * np.array([0.05, 0.10])
    fondos = garantia.sum()
    abierta = np.array([True, True])
    cerrada_pnl = np.zeros(2)
    cerro = False
    for t in range(1, h + 1):
        vivo = signo * nominal * (par[i + t] / par[i] - 1)
        pnl = np.where(abierta, vivo, cerrada_pnl)
        if regla == "posicion":
            corta = abierta & (pnl < -0.5 * garantia)
            cerrada_pnl[corta], abierta[corta] = pnl[corta], False
            cerro |= corta.any()
        if abierta.any() and (fondos + pnl.sum()
                              < 0.5 * garantia[abierta].sum()):
            cerrada_pnl[abierta], abierta[:] = pnl[abierta], False
            cerro = True
    return cerro, pnl.sum() / fondos

for regla in ("cuenta", "posicion"):
    r = [ventana(i, regla) for i in range(len(par) - 20)]
    cerradas = np.mean([c for c, _ in r])
    final = np.array([x for _, x in r])
    print(f"{regla:9} cierres {100 * cerradas:5.1f} %   resultado "
          f"medio {100 * final.mean():5.1f} %   percentil 5 "
          f"{100 * np.percentile(final, 5):6.1f} %")
```
```output
cuenta    cierres   6.6 %   resultado medio   0.9 %   percentil 5  -51.2 %
posicion  cierres  71.8 %   resultado medio   2.0 %   percentil 5  -58.7 %
```

Con el cierre por posición, alguna pata se liquida en la mayoría de las ventanas: la pata del 5 % aguanta un 2,5 % en
contra antes de cerrarse, y en un par cubierto cada pata se mueve mucho más que el conjunto. Lo peor no es la
frecuencia, es lo que queda: una pata abierta sin su cobertura, una exposición que el cliente no había elegido.
Es el argumento que ESMA recoge de la consulta pública. La regla por cuenta mira lo que el cliente puede perder, el
neto, y casi no actúa. En una cuenta con una sola posición, como dice ESMA, las dos reglas son la misma.

La CNMV añade una buena práctica en el preámbulo de la resolución de 2019: avisar al cliente **antes** del 50 %, para
que pueda aportar garantías o cerrar por su cuenta. Y la de 2023 precisa que el cierre «no debe tener lugar antes de
alcanzar dicho umbral y de informar al cliente».

```mermaid
stateDiagram-v2
  [*] --> Normal
  Normal --> Aviso: fondos bajo umbral
  Aviso --> Normal: aporta o cierra
  Aviso --> Cierre: bajo el 50 %
  Cierre --> Normal: queda saldo
  Cierre --> Protegido: saldo negativo
  Protegido --> [*]
```

## Protección de saldo negativo

El cierre al 50 % deja la otra mitad de la garantía como colchón para ejecutar el cierre. Ese colchón no sirve si el
precio salta entre dos observaciones: un fin de semana, una decisión de un banco central, un hueco en la apertura. En
los datos de divisas hay uno así. El viernes 2 de octubre de 2015 QEVUSD cerró en 1,58226 y el lunes 5, en 1,45688:

```python
q = series["QEVUSD"][0]
salto = q.pct_change().abs().idxmax()
antes, despues = q.shift(1)[salto], q[salto]
mov = despues / antes - 1
fondos = 10_000                       # EUR en la cuenta de CFD
nominal = fondos / 0.0333             # todo el saldo como garantía
saldo = fondos + nominal * mov        # CFD largo
print(f"{salto.date()}: {antes:.5f} -> {despues:.5f} "
      f"({100 * mov:.2f} %)")
print(f"nominal {nominal:,.0f}; saldo tras el salto {saldo:,.0f} EUR")
print(f"pérdida del cliente con protección: {fondos:,.0f} EUR; "
      f"la asume el proveedor: {-min(saldo, 0):,.0f} EUR")
```
```output
2015-10-05: 1.58226 -> 1.45688 (-7.92 %)
nominal 300,300; saldo tras el salto -13,796 EUR
pérdida del cliente con protección: 10,000 EUR; la asume el proveedor: 13,796 EUR
```

Por simplicidad la cuenta está en euros y el nominal se expresa en euros. Una caída del 7,9 % con apalancamiento 30:1
es una pérdida del 238 % de la garantía: cuando el proveedor puede cerrar, ya no queda saldo. La protección de saldo
negativo (artículo 3.f) limita la responsabilidad del cliente, por todos los CFD de esa cuenta, a los fondos
depositados en ella. Cuántas veces pasa en el experimento de la sección anterior se puede contar: la primera señal de
cierre llega con la pérdida ya por encima del 100 % de la garantía.

```python
def saldo_negativo(precios, garantia, h=20):
    v = sliding_window_view(np.asarray(precios, float), h + 1)
    r = v[:, 1:] / v[:, :1] - 1
    out = 0
    for x in (r, -r):                          # largo y corto
        toca = x <= -0.5 * garantia
        hay = toca.any(axis=1)
        primero = toca.argmax(axis=1)
        perdida = -x[np.arange(len(x)), primero] / garantia
        out += int((hay & (perdida > 1)).sum())
    return out

pd.Series({k: saldo_negativo(s, g) for k, (s, g) in series.items()})
```
```output
QEVUSD     88
USDQMP      4
RVE       167
MEA       116
RVH        16
ENA       232
XBQ         0
dtype: int64
```

Son ventanas (largas y cortas) cuya primera señal de cierre llega con la pérdida ya por encima de la garantía: 232 en
el crudo, 167 en el índice principal, 88 en el par principal y ninguna en la criptomoneda, cuya garantía del 50 % deja
un colchón del 25 % de movimiento. Los saltos se concentran en pocas fechas y afectan a todas las ventanas que las
atraviesan, por eso los recuentos son grandes en unas series y pequeños en otras. Con datos intradía y vigilancia continua los casos serían menos, no ninguno: el hueco entre
dos precios existe en cualquier frecuencia.

## La advertencia de riesgo y su porcentaje

Toda comunicación de un proveedor de CFD a minoristas lleva una advertencia con un formato fijo (anexo II). En una web o
un soporte duradero:

> Los CFD son instrumentos complejos y están asociados a un riesgo elevado de perder dinero rápidamente debido al
> apalancamiento. [porcentaje del proveedor] % de las cuentas de inversores minoristas pierden dinero en la negociación
> de CFD con este proveedor. Debe considerar si comprende el funcionamiento de los CFD y si puede permitirse asumir un
> riesgo elevado de perder su dinero.

El porcentaje no es libre. La sección A.6 lo define: cada tres meses, sobre los 12 meses anteriores, la proporción de
cuentas de CFD de minoristas cuyo resultado neto realizado y no realizado en CFD fue negativo, **con** todos los costes
(cargos, tasas, comisiones) y **sin** las cuentas que no tuvieron ningún CFD abierto, sin el resultado de otros
productos y sin ingresos ni retiradas. El proveedor sin CFD abiertos en el periodo usa la advertencia estándar: «Entre un
74 y un 89 % de los inversores minoristas pierden dinero cuando negocian con CFD», el rango de los estudios de los
supervisores que cita la propia resolución.

Un validador sobre 5.000 cuentas sintéticas, comparado con dos cálculos tentadores y erróneos:

```python
rng = np.random.default_rng(2019)
n = 5_000
cuentas = pd.DataFrame({
    "con_cfd_abierto": rng.random(n) < 0.85,
    "realizado": rng.normal(-150, 900, n).round(2),
    "no_realizado": rng.normal(0, 200, n).round(2),
    "costes": rng.gamma(2.0, 180, n).round(2),
    "otros_productos": rng.normal(300, 1500, n).round(2),
    "ingresos": rng.gamma(1.5, 2000, n).round(2),
    "retiradas": rng.gamma(1.2, 900, n).round(2),
})
cuentas.loc[~cuentas["con_cfd_abierto"],
            ["realizado", "no_realizado", "costes"]] = 0.0

def pct_pierden(c):
    """Anexo II, sección A.6 de la Resolución de 2019."""
    c = c[c["con_cfd_abierto"]]
    neto = c["realizado"] + c["no_realizado"] - c["costes"]
    return 100 * (neto < 0).mean()

c = cuentas
sin_costes = c[c["con_cfd_abierto"]]
mal_1 = 100 * ((sin_costes["realizado"] + sin_costes["no_realizado"])
               < 0).mean()
saldo = (c["realizado"] + c["no_realizado"] - c["costes"]
         + c["otros_productos"] + c["ingresos"] - c["retiradas"])
mal_2 = 100 * (saldo < 0).mean()
print(f"anexo II A.6:                       {pct_pierden(c):5.1f} %")
print(f"sin costes:                         {mal_1:5.1f} %")
print(f"variación del saldo, todas cuentas: {mal_2:5.1f} %")
```
```output
anexo II A.6:                        70.3 %
sin costes:                          56.0 %
variación del saldo, todas cuentas:  29.7 %
```

Los dos errores rebajan la cifra. Olvidar los costes cambia el signo de las cuentas que ganan poco antes de comisiones
y financiación. Usar la variación del saldo de todas las cuentas mezcla ingresos, otros productos y cuentas sin CFD, y
convierte en «ganadoras» cuentas que solo recibieron una transferencia. El método del anexo existe para que la cifra
sea comparable entre proveedores.

## Lo que añadió la CNMV en 2023 y lo que no cubre nada de esto

La Resolución de la CNMV de 11 de julio de 2023, aplicable desde el 3 de agosto de 2023, hace dos cosas. Para los CFD
prohíbe las comunicaciones publicitarias dirigidas a minoristas en España, incluidas las que redirigen a una web o a
un formulario del proveedor y las ofertas al público de cursos, seminarios o cuentas demo gratuitas o a precio
simbólico; el patrocinio y la publicidad de marca con ese efecto; y prácticas como pagar a clientes por traer
clientes, remunerar a la red comercial por captaciones o pérdidas de clientes, los centros de llamadas que promocionan
estos productos y los ingresos con tarjeta de crédito. Y para **otros instrumentos apalancados** (aquellos cuyo riesgo
máximo no se conoce al suscribirlos o puede superar la aportación inicial, como futuros u opciones vendidas) exige a
los minoristas una garantía inicial y el cierre al 50 %. La garantía es el **menor** de dos importes: el del anexo I de
2019 según el subyacente o el que exija el centro de negociación; si el subyacente es un criptoactivo que no es
instrumento financiero MiFID, el del anexo sin rebaja.

```python
esp = pd.read_csv("futuros2_especificaciones.csv")
ultimo = fut[fut["fecha"] == fut["fecha"].max()].set_index("mercado")
esp = esp.set_index("mercado").loc[["IDA", "MEA", "ENA", "DIB", "BOC"]]
esp["nominal"] = ultimo["cierre"] * esp["multiplicador"]
esp["centro_pct"] = 100 * esp["margen_inicial"] / esp["nominal"]
# supuestos: IDA como índice principal; DIB, divisa no principal;
# un futuro sobre bonos es «otro subyacente»
esp["anexo_pct"] = [5.0, 5.0, 10.0, 5.0, 20.0]
esp["exigible_pct"] = esp[["centro_pct", "anexo_pct"]].min(axis=1)
esp[["nombre", "nominal", "centro_pct", "anexo_pct",
     "exigible_pct"]].round(2)
```
```output
                       nombre   nominal  centro_pct  anexo_pct  exigible_pct
mercado
IDA      Índice Aldebarán 500  389500.0        7.01        5.0          5.00
MEA                       Oro   41300.0        5.81        5.0          5.00
ENA              Crudo ligero   42670.0       12.89       10.0         10.00
DIB         Divisa Kestra/USD   60390.0        3.31        5.0          3.31
BOC            Bono a 10 años   95937.5        3.86       20.0          3.86
```

En tres de los cinco futuros del nivel 2 (índice, oro y crudo) la cifra del anexo es menor que el margen del mercado
y es la exigible; en la divisa y en el bono manda el margen del mercado, más bajo que el 5 % y el 20 % del anexo. La
resolución fija el mínimo que el proveedor debe pedir al cliente minorista. Su efecto práctico más claro está en el
cierre al 50 %, que el margen de un mercado no exige al cliente final.

Lo que ninguna de estas medidas cubre: a los clientes profesionales; a los minoristas que operan con entidades que no
están autorizadas (lección 4.4.1), y el riesgo de mercado en sí. Limitan cuánto se puede perder por apalancamiento, no
si la estrategia gana.

## Ejercicios

1. Repite el experimento de la cabecera con ventanas de 5 y de 60 sesiones. ¿Cómo cambia el orden de los
   subyacentes? ¿Qué te dice sobre el «plazo de tenencia adecuado» que usó ESMA?

**Solución.**

```python
tabla = pd.DataFrame({
    h: {k: 100 * prob_cierre(s, g, h=h)
        for k, (s, g) in series.items()}
    for h in (5, 20, 60)
}).round(1)
tabla.columns = [f"{h} sesiones" for h in tabla.columns]
tabla.sort_values("20 sesiones", ascending=False)
```
```output
        5 sesiones  20 sesiones  60 sesiones
RVE           22.3         52.7         70.0
ENA           21.0         51.6         70.7
MEA           18.7         49.8         69.3
QEVUSD        10.8         39.8         62.5
USDQMP         8.1         36.7         59.8
RVH            6.1         30.0         54.9
XBQ            0.3          7.4         36.2
```

Todas las probabilidades suben con el plazo, porque un camino más largo tiene más ocasiones de tocar el umbral, pero
no en la misma proporción: las que ya se cierran a menudo en 5 sesiones (RVE, ENA, MEA, alrededor del 20 %) se acercan
a un techo del 70 % a 60 sesiones, y la criptomoneda pasa de casi nunca (0,3 %) a algo más de un tercio (36,2 %). El
orden apenas cambia, pero las distancias sí. Por eso una calibración «coherente entre subyacentes» depende del
plazo elegido, y una garantía que parece holgada para una semana no lo es para un trimestre.

2. Modifica `ventana` para que la cuenta tenga el doble de fondos que la garantía exigida. ¿Cuántos cierres hay ahora
   con cada regla?

**Solución.**

```python
def ventana_holgada(i, regla, h=20, colchon=2.0):
    nominal, signo = 1.0, np.array([1, -1])
    garantia = nominal * np.array([0.05, 0.10])
    fondos = colchon * garantia.sum()
    abierta = np.array([True, True])
    cerrada_pnl, cerro = np.zeros(2), False
    for t in range(1, h + 1):
        vivo = signo * nominal * (par[i + t] / par[i] - 1)
        pnl = np.where(abierta, vivo, cerrada_pnl)
        if regla == "posicion":
            corta = abierta & (pnl < -0.5 * garantia)
            cerrada_pnl[corta], abierta[corta] = pnl[corta], False
            cerro |= corta.any()
        if abierta.any() and (fondos + pnl.sum()
                              < 0.5 * garantia[abierta].sum()):
            cerrada_pnl[abierta], abierta[:] = pnl[abierta], False
            cerro = True
    return cerro

for regla in ("cuenta", "posicion"):
    c = np.mean([ventana_holgada(i, regla)
                 for i in range(len(par) - 20)])
    print(f"{regla:9} cierres {100 * c:5.1f} %")
```
```output
cuenta    cierres   0.0 %
posicion  cierres  71.8 %
```

Con el doble de fondos, el cierre por cuenta desaparece (0,0 %): la cuenta tiene que perder una vez y media la
garantía antes de llegar al umbral. El cierre por posición no cambia nada, porque mira cada posición contra su propia
garantía y no ve los fondos de la cuenta. Aportar más saldo protege del cierre solo si la regla es por cuenta, que es
la mínima que exige la norma; conviene saber cuál aplica tu proveedor.

3. Un proveedor anuncia en una red social: «Opera el IBEX con apalancamiento 20:1 y llévate un bono de 100 EUR». Señala
   qué partes de las resoluciones de 2019 y 2023 incumple ese anuncio si va dirigido a minoristas en España.

**Solución.**

Tres. El IBEX 35 no está en la lista de índices del 5 %: su garantía mínima es del 10 %, apalancamiento 10:1 (anexo I),
así que 20:1 incumple el artículo 4.a. El bono es un beneficio monetario ligado a operar con CFD, prohibido por el
artículo 4.d. Y desde la resolución de 2023 está prohibida cualquier comunicación publicitaria de CFD dirigida a
minoristas en España, incluidas las de redes sociales; aunque no lo estuviera, el anuncio necesitaría la advertencia de
riesgo del anexo II con el porcentaje del proveedor.

## Autoevaluación

1. Un minorista residente en España tiene 10.000 EUR en su cuenta de CFD y abre un CFD sobre el IBEX 35. ¿Cuál es el nominal máximo?

   - A. 200.000 EUR: los índices tienen apalancamiento 20:1
   - B. 100.000 EUR: el IBEX 35 no está en la lista de índices principales, así que la garantía es del 10 % (10:1)
   - C. 300.000 EUR: 30:1
   - D. 50.000 EUR: 5:1, como las acciones

   *Respuesta B: 100.000 EUR: el IBEX 35 no está en la lista de índices principales, así que la garantía es del 10 % (10:1).* El anexo I da el 5 % solo a diez índices nombrados (FTSE 100, CAC 40, DAX30, DJIA, S&P 500, NASDAQ, NASDAQ 100, Nikkei 225, ASX 200 y EURO STOXX 50). El resto de índices de acciones va al 10 %.

2. Una cuenta tiene un CFD largo sobre un índice y uno corto sobre otro índice correlacionado. ¿Cuándo debe cerrar posiciones el proveedor según la resolución de la CNMV?

   - A. Cuando la suma de los fondos de la cuenta y las ganancias netas no realizadas de todos los CFD baje de la mitad de la garantía inicial total
   - B. Cuando cualquiera de las dos pierda la mitad de su garantía
   - C. Al final de cada sesión, si hay pérdidas
   - D. Nunca: el cliente decide

   *Respuesta A: Cuando la suma de los fondos de la cuenta y las ganancias netas no realizadas de todos los CFD baje de la mitad de la garantía inicial total.* La protección del cierre se mide por cuenta. ESMA explica en su decisión que un cierre por posición también cumple (es más estricto), pero el mínimo exigido es por cuenta. En la lección, con el par largo-corto, el cierre por posición salta en el 72 % de las ventanas de 20 sesiones y el de cuenta en el 7 %.

3. La cuenta del ejemplo tiene 10.000 EUR y un CFD largo de unos 300.000 EUR de nominal en el par principal (todo el saldo como garantía) cuando el precio cae un 7,9 % entre dos cierres. ¿Qué cubre la protección de saldo negativo?

   - A. Nada: el cliente debe al proveedor la diferencia
   - B. Devuelve al cliente la mitad de lo perdido
   - C. Solo se aplica si el cliente lo pide por escrito
   - D. Limita la pérdida del cliente a los fondos de su cuenta de CFD: el saldo queda en cero y el resto lo asume el proveedor

   *Respuesta D: Limita la pérdida del cliente a los fondos de su cuenta de CFD: el saldo queda en cero y el resto lo asume el proveedor.* La protección del saldo negativo limita la responsabilidad agregada del minorista por todos los CFD de la cuenta a los fondos de esa cuenta (artículo 3.f). En la lección, el salto deja la cuenta en −13.796 EUR; con la protección, el cliente pierde 10.000 y el proveedor asume el resto.

4. Para calcular el porcentaje de cuentas que pierden de la advertencia de riesgo, ¿qué cuentas y qué importes se usan?

   - A. Todas las cuentas abiertas, con la variación del saldo, incluidos ingresos y retiradas
   - B. Solo las cuentas cerradas en el año
   - C. Las cuentas con algún CFD abierto en los 12 meses, con el resultado neto realizado y no realizado de sus CFD, costes incluidos y sin ingresos, retiradas ni otros productos; se recalcula cada tres meses
   - D. Una cifra fija del 74 % al 89 %

   *Respuesta C: Las cuentas con algún CFD abierto en los 12 meses, con el resultado neto realizado y no realizado de sus CFD, costes incluidos y sin ingresos, retiradas ni otros productos; se recalcula cada tres meses.* Es el método de la sección A.6 del anexo II. El rango del 74 % al 89 % es la advertencia estándar, para el proveedor que no ha tenido CFD abiertos en el último periodo de cálculo.

5. ¿Qué añadió la resolución de la CNMV de 11 de julio de 2023?

   - A. Prohibió la publicidad de CFD dirigida a minoristas en España y extendió la garantía inicial y el cierre al 50 % a otros instrumentos apalancados, como futuros y opciones
   - B. Subió el apalancamiento máximo de los CFD sobre divisas
   - C. Eliminó la protección de saldo negativo
   - D. Dejó sin efecto la resolución de 2019

   *Respuesta A: Prohibió la publicidad de CFD dirigida a minoristas en España y extendió la garantía inicial y el cierre al 50 % a otros instrumentos apalancados, como futuros y opciones.* La parte primera prohíbe las comunicaciones publicitarias, el patrocinio y prácticas como pagar por captar clientes o aceptar ingresos con tarjeta de crédito; la segunda aplica a otros instrumentos cuyo riesgo máximo no se conoce o puede superar la aportación inicial la garantía mínima y el cierre al 50 %.

## Ideas clave

- ESMA restringió los CFD para minoristas con la Decisión (UE) 2018/796 (desde el 1 de agosto de 2018, renovada tres veces); en España la Resolución de la CNMV de 27 de junio de 2019 aplica las mismas reglas desde el 1 de agosto de 2019, sin plazo.
- Garantía inicial mínima: 3,33 % en pares de dos divisas principales; 5 % en diez índices principales, oro y otros pares; 10 % en otras materias primas e índices; 20 % en acciones y demás; 50 % en criptomonedas.
- El cierre al 50 % se mide por cuenta: fondos más ganancias netas no realizadas frente a la mitad de la garantía inicial total. Con el apalancamiento máximo y todo el saldo comprometido, en los datos del curso salta en el 7 % (criptomoneda) al 53 % (índice principal) de las ventanas de 20 sesiones.
- La protección de saldo negativo limita la pérdida a los fondos de la cuenta de CFD; un salto entre dos cierres puede llevar el saldo por debajo de cero antes de que el cierre actúe.
- La advertencia lleva el porcentaje de cuentas minoristas del proveedor que pierden, calculado cada tres meses sobre 12 meses con costes y sin ingresos ni retiradas; desde 2023 la CNMV prohíbe además la publicidad de CFD a minoristas.

## Recursos

### Research

- [Usos de la volatilidad](https://pythonparatrading.com/usos-de-la-volatilidad/) · Research-0003 · 6 min

### Documentación

- [Resolución de 27 de junio de 2019 de la CNMV sobre opciones binarias y CFD (BOE-A-2019-9737)](https://www.boe.es/diario_boe/txt.php?id=BOE-A-2019-9737) · boe.es
- [Resolución de 11 de julio de 2023 de la CNMV sobre CFD y otros productos apalancados (BOE-A-2023-16394)](https://www.boe.es/diario_boe/txt.php?id=BOE-A-2023-16394) · boe.es
- [Decisión (UE) 2018/796 de ESMA que restringe provisionalmente los CFD para minoristas, en el BOE](https://www.boe.es/buscar/doc.php?id=DOUE-L-2018-80955) · boe.es
- [Reglamento (UE) 600/2014 (MiFIR), artículos 40 a 42: intervención de productos, en el BOE](https://www.boe.es/buscar/doc.php?id=DOUE-L-2014-81281) · boe.es

### Datos

- [Datos del nivel 3: divisas diarias (Parquet)](https://pythonparatrading.com/curso/datos/nivel-3/fx3_diario.parquet) · Descarga · fx3_diario.parquet

Lección anterior: [7.4.1 · MiFID II: clientes, idoneidad y trading algorítmico](https://pythonparatrading.com/curso-python-trading/nivel-7/mifid-ii-clientes-idoneidad-y-trading-algoritmico/)

Lección siguiente: [7.4.3 · PRIIPs, KID y ETFs estadounidenses](https://pythonparatrading.com/curso-python-trading/nivel-7/priips-kid-y-etfs-estadounidenses/)
