🛡️ sandbox-labs GitHub ↗

CM-18 · Margen, garantías y riesgo#

En una frase, para cualquiera: si te dejan operar con dinero prestado, alguien tiene que asegurarse de que puedes responder cuando las cosas van en tu contra. Ese cálculo se hace todos los días, y cuando falla, falla para todos a la vez.

Estado real: 🟠 prototype — hay código y escenarios que se ejecutan, sin verificación en un entorno real · Módulo: crates/sandbox-markets/src/cases/margin.rs

Exposiciones, garantías y liquidaciones simuladas. No es una autorización regulatoria ni una recomendación de inversión.

Por qué se realiza este caso#

El margen es lo que permite que alguien opere por más de lo que tiene, y lo que impide que su pérdida se convierta en pérdida de otro.

ConceptoQué es, en llano
ExposiciónCuánto se puede perder si el precio va en contra
HaircutCuánto se descuenta del valor de una garantía. Una acción vale menos como garantía que efectivo, porque puede caer justo cuando haga falta
Margen inicialLo que hay que depositar para abrir la posición
Margen de variaciónLo que hay que añadir cada día según cómo se mueva el precio
Llamada de margenEl aviso de que hay que poner más, y el plazo para hacerlo
Liquidación forzadaCerrar la posición cuando no se atiende la llamada

Y el problema que hace este caso difícil: las garantías caen cuando más se necesitan. En un mal día, el precio del activo baja y el de la garantía también, así que la llamada de margen crece justo cuando cuesta más atenderla. Si además todos deben liquidar a la vez, la venta forzada hunde el precio y genera más llamadas.

La idea que enseña, y que ningún otro caso enseña#

El riesgo es dinámico, y liquidar tiene efecto sobre el mercado. Es el único caso de la familia donde la acción del sistema cambia las condiciones que la provocaron. Simularlo sin ese efecto es simular otra cosa.

Casos de uso reales#

Cómo funcionará#

flowchart LR
  P["📊 Posiciones"] --> E["📐 Exposición"]
  G["🏦 Garantías"] --> H["✂️ Haircut por tipo"]
  E & H --> M{"⚖️ ¿Garantía ajustada ≥<br/>margen requerido?"}
  M -- sí --> OK["✅ Suficiente"]
  M -- no --> C["📞 Llamada de margen<br/>con plazo"]
  C --> R{"¿Se atiende<br/>a tiempo?"}
  R -- sí --> OK
  R -- no --> L["🔨 Liquidación forzada"]
  L --> I["📉 Impacto en el precio"]
  I --> E

El bucle final —de Impacto a Exposición— es el punto del caso. Sin él, la simulación es optimista.

flowchart TB
  A["Cierre del día"] --> B["Revalorizar posiciones"]
  B --> C["Revalorizar garantías"]
  C --> D["Aplicar haircut por tipo de garantía"]
  D --> E{"¿Déficit?"}
  E -- no --> F["✅"]
  E -- sí --> G["Llamada por el déficit"]
  G --> H{"¿Supera el límite<br/>de concentración?"}
  H -- sí --> I["🚨 Riesgo concentrado en un participante"]

Esquemas#

{
  "participant": "P1",
  "positions": [{ "instrument": "ACME-SIM", "quantity": 10000, "price": { "minorUnits": 10000, "currency": "CLP" } }],
  "collateral": [
    { "kind": "cash", "value": { "minorUnits": 5000000, "currency": "CLP" }, "haircut": 0.0 },
    { "kind": "equity", "value": { "minorUnits": 8000000, "currency": "CLP" }, "haircut": 0.25 }
  ]
}
{
  "margin": {
    "initialRequired": { "minorUnits": 12000000, "currency": "CLP" },
    "variationToday": { "minorUnits": 900000, "currency": "CLP" },
    "collateralAfterHaircut": { "minorUnits": 11000000, "currency": "CLP" },
    "shortfall": { "minorUnits": 1900000, "currency": "CLP" },
    "marginCall": { "deadline": "2026-08-08T12:00:00Z" },
    "forcedLiquidation": null
  }
}

Software necesario#

ComponentePara qué
Rust 1.75+Cálculo de margen, haircuts y simulación del impacto
Node.js 20+ / pnpm 9+Panel de exposiciones y llamadas (recomendado)

Sin jaula ni Linux. Aritmética con enteros en unidades mínimas: un error de redondeo en un cálculo de margen se convierte en una llamada equivocada.

Instalación#

cargo build --release

Procesos que se crearán#

sandboxctl markets margin --scenario caida-de-garantias --seed 3
  │
  └─ un proceso determinista, sin red
      ├─ revalorización diaria con reloj simulado
      ├─ liquidación forzada con impacto en el precio
      └─ conciliación CM-03 y liquidación CM-10

Tiempo de carga estimado#

OperaciónCoste esperado
Calcular márgenes de 1 000 participantes< 100 ms
Simular 250 días de mercadosegundos
Una liquidación forzada con impactomilisegundos

Qué hace falta para construirlo#

  1. Exposición por posición e instrumento.
  2. Haircuts por tipo de garantía, configurables y versionados.
  3. Margen inicial y de variación, con revalorización diaria.
  4. Llamadas con plazo y liquidación forzada al vencer.
  5. Impacto de la liquidación sobre el precio, realimentado.
  6. Límites de concentración por participante e instrumento.

Si algo falla#

El caso ya tiene código y escenarios que se ejecutan. Lo que sigue son sus fallos con la causa y la salida:

SituaciónCausaCómo se resuelve
Las llamadas de margen se disparan todas a la vezLas garantías cayeron junto con las posicionesEs el escenario que este caso existe para simular. Se resuelve con haircuts realistas y límites de concentración, no bajando el margen requerido
La liquidación forzada hunde el precio y genera más llamadasEspiralEl modelo realimenta el impacto de la liquidación. Sin ese bucle la simulación es optimista y no sirve para prepararse
Un participante concentra casi toda la exposiciónRiesgo de concentraciónLímite por participante e instrumento, comprobado en cada cierre
El margen sale distinto por céntimos entre dos cálculosComa flotanteEnteros en unidades mínimas. Un redondeo en un cálculo de margen es una llamada equivocada a alguien
Se acepta como garantía algo que no vale lo que diceFalta el haircut o está malLos haircuts van por tipo de garantía, configurables y versionados: efectivo no descuenta, una acción sí

Los fallos que afectan a cualquier caso —la compilación, el catálogo, la evidencia— están resueltos uno a uno en Cuando algo falla.

Esta familia no necesita aislamiento del sistema: no ejecuta código ajeno, sino reglas de negocio deterministas. Por eso casi ningún fallo suyo viene del entorno, y casi todos vienen de los datos.

Cómo se comprueba#

cargo run -p sandboxctl -- markets check --case CM-18

Ejecuta los escenarios de este caso y compara cada uno con lo que declara de antemano que debe salir. Corre en cada commit: si el caso deja de detectar lo que dice detectar, la integración continua se pone roja.

cargo test -p sandbox-markets margin

Los invariantes del módulo, incluidos los que ningún escenario de arriba cubre.

Sigue en prototype, no en functional. Los escenarios se ejecutan y pasan, pero el caso no emite evidencia firmada por ejecución ni se ha usado contra datos que no sean los suyos. La regla completa está en el ROADMAP.

Ver también: Catálogo completo · CM-10 · liquidación · CM-14 · resiliencia