Saltar a contenido

⚙️ Motor de Cartera — Modelo Matemático

💡 Resumen

Esta página define formalmente el modelo matemático que subyace al motor de cálculo de carteras de LibreFolio. Todas las demás páginas de métricas (NAV, Valor contable, P&L período, Rendimiento sobre coste, PMC, Capital depositado) hacen referencia a esta página para sus reglas de cálculo precisas.


📐 1. Notación y conjuntos

Símbolo Significado
\(V(u)\) Todos los brókeres visibles para el usuario \(u\)
\(S \subseteq V(u)\) Ámbito de brókeres seleccionado (filtrado)
\(A\) Conjunto de activos con posiciones
\(C^*\) Moneda objetivo
\([t_0, t_1]\) Marco de evaluación solicitado
\(q(a,b,t)\) Cantidad del activo \(a\) en el bróker \(b\) en la fecha \(t\)
\(p(a,t)\) Precio de valoración del activo \(a\) en la fecha \(t\)
\(\mathrm{fx}(c_1, c_2, t)\) Tipo de cambio de la moneda \(c_1\) a \(c_2\) en la fecha \(t\)

📐 2. Precio de valoración

\[ \operatorname{mark}(a,t)= \begin{cases} \text{MARKET}(a,t) & \text{cotización del sistema de activos del mismo día}\\ \operatorname{avg}(\text{TRADE}(a,t)) & \text{observaciones de COMPRA/VENTA/AJUSTE con precio del mismo día}\\ \text{última observación antes de }t & \text{arrastrado (LOCF)}\\ \varnothing & \text{sin observación en }t\text{ o antes} \end{cases} \]
  • El resolutor unificado es el único cerebro de valoración: MARKET → TRADE_AVG → CARRIED → MISSING.
  • CARRIED es la última observación arrastrada (LOCF). Transporta metadatos de antigüedad days_back.
  • estimated=True significa origen TRADE. Una cotización MARKET arrastrada obsoleta está obsoleta, no estimada.
  • Las valoraciones permanecen en moneda nativa; cada consumidor convierte a \(C^*\) en la fecha de valoración \(t\).
  • La conversión FX del coste base permanece fijada a la fecha de la transacción.
  • El efectivo permanece en la divisa en que se registró, bróker a bróker, y se valora al tipo de cambio de \(t\) (§5); cada movimiento de efectivo sigue registrándose, y cada flujo de caja externo entra en el capital, al tipo de cambio de su propia fecha.
  • El PMC nunca se usa como precio de valoración.

Consulta Resolución de precios para conocer el contrato del resolutor y la semántica de calidad de datos.


📐 3. Estado de la posición

Para cada posición \((a, b)\) con \(q(a,b,t) > 0\):

\[ \mathrm{MV}(a,b,t) = \frac{q(a,b,t)}{qbq(a)}\cdot \operatorname{mark}(a,t)\cdot \mathrm{fx}\bigl(\mathrm{ccy}_{mark}, C^*, t\bigr) \]
\[ \mathrm{CB}(a,b,t) = q(a,b,t) \cdot w(a,b,t) \]
\[ \mathrm{UGL}(a,b,t) = \mathrm{MV}(a,b,t) - \mathrm{CB}(a,b,t) \]

Donde \(w(a,b,t)\) es el precio medio de compra (PMC) para la posición \((a,b)\) en la fecha \(t\), mantenido en \(C^*\) a tipos de cambio históricos (§4): el coste base no toma tipo de cambio en \(t\), por lo que para un activo extranjero el efecto del tipo de cambio es parte de \(\mathrm{UGL}\).


📐 4. Actualización iterativa del PMC

Mantenido por posición \((a,b)\) con estado de fondo \((\hat{q}, \hat{c})\), el coste \(\hat{c}\) mantenido en \(C^*\):

Adquisición (cantidad \(> 0\), importe \(P\) pagado en la moneda \(c\) en la fecha \(d\)):

\[ \hat{q}_{\text{new}} = \hat{q} + q_{\text{tx}}, \quad \hat{c}_{\text{new}} = \hat{c} + P \cdot \mathrm{fx}(c, C^*, d), \quad w = \frac{\hat{c}_{\text{new}}}{\hat{q}_{\text{new}}} \]

\(P\) es el efectivo pagado por una COMPRA, o la sobrescritura del coste base por unidad multiplicada por \(q_{\text{tx}}\) para una TRANSFERENCIA o AJUSTE; \(\mathrm{fx}(C^*, C^*, d) = 1\). Cuando no existe un tipo de cambio en \(d\) o antes, o la adquisición no tiene coste base, la cantidad entra y el coste no: el coste de la posición se marca como incompleto en lugar de contar como cero.

Reducción (cantidad \(< 0\)):

\[ w_{\text{pre}} = \frac{\hat{c}}{\hat{q}}, \quad \hat{q}_{\text{new}} = \hat{q} - |q_{\text{tx}}|, \quad \hat{c}_{\text{new}} = \hat{q}_{\text{new}} \cdot w_{\text{pre}} \]

Desdoblamiento (vinculado a un evento de desdoblamiento): \(\hat{q}\) cambia, \(\hat{c}\) no.

Orden

Dentro de la misma fecha: las adiciones se procesan antes que las reducciones. Garantiza que la VENTA lea el PMC correcto, incluidas las COMPRAS del mismo día.


📐 5. Agregación de cartera

\[ \mathrm{MV}(t) = \sum_{(a,b) \in S} \mathrm{MV}(a,b,t) \]
\[ \mathrm{NAV}(t) = \mathrm{MV}(t) + \mathrm{Cash}(t) + \mathrm{InTransit}(t) \]
\[ \mathrm{Book}(t) = \mathrm{OCB}(t) + \mathrm{Cash}(t) + \mathrm{InTransitBook}(t) \]
\[ \mathrm{UGL}(t) = \mathrm{NAV}(t) - \mathrm{Book}(t) \]

\(\mathrm{Cash}(t)\) es el efectivo de cada bróker, mantenido en las divisas en que se registró y valorado al tipo de cambio de \(t\):

\[ \mathrm{Cash}(t) = \sum_{b \in S} \sum_{c} N_{b,c}(t) \cdot \mathrm{fx}(c, C^*, t) \]

donde \(N_{b,c}(t)\) es el saldo del bróker \(b\) en la divisa \(c\) tras sus movimientos con fecha igual o anterior a \(t\), en proporción a la cuota de propiedad del bróker, y \(\mathrm{fx}(c, C^*, t)\) es el último tipo de cambio en la fecha \(t\) o anterior (\(1\) para \(c = C^*\)). El mismo término está en el NAV y en el Book, por lo que el efecto cambiario sobre el efectivo se anula en el UGL: se registra como resultado de cambio (§6) y pertenece al P&L total.


📐 6. Modelo de efectivo de tres fondos — Por bróker \((K_b, R_b, W)\)

Tres fondos acumuladores rastrean la procedencia del efectivo. \(K\) y \(R\) se mantienen por bróker \(b\); \(W\) es global (sale del sistema por completo).

Fondo Ámbito Significado
\(K_b\) Por bróker Capital externo aún en el bróker \(b\) como efectivo
\(R_b\) Por bróker Rendimientos generados aún en el bróker \(b\) como efectivo
\(W\) Global Rendimientos que salieron del sistema (ocultos, restaurables al volver a depositar)

Propiedad clave

Una COMPRA en el bróker \(b_1\) solo puede consumir \(R_{b_1}\), nunca \(R_{b_2}\). El efectivo no se teletransporta entre brókeres — solo las transferencias explícitas mueven los saldos de los fondos.

🔁 Reglas de actualización (por transacción en el bróker \(b\), cronológicas)

Icono y tipo Fórmulas de actualización Lógica y descripción

DEPÓSITO
\(D > 0\)
\(r = \min(D,\, W)\)
\(R_b \mathrel{+}= r\)
\(W \mathrel{-}= r\)
\(K_b \mathrel{+}= D - r\)
Restaura primero los rendimientos retirados previamente desde el rastreador global \(W\), luego agrega el resto al capital \(K_b\).

RETIRO
\(X > 0\)
\(k = \min(X,\, K_b)\)
\(K_b \mathrel{-}= k\)
\(\rho = \min(X - k,\, R_b)\)
\(R_b \mathrel{-}= \rho\)
\(W \mathrel{+}= \rho\)
Consume primero el capital \(K_b\), luego mueve los rendimientos restantes \(\rho\) al rastreador global \(W\).

DIVIDENDO / INTERÉS
\(I > 0\)
\(R_b \mathrel{+}= I\) Los rendimientos incrementan directamente el fondo de rendimientos \(R_b\).

COMISIÓN / IMPUESTO
\(F > 0\)
\(R_b \mathrel{-}= F\)
\(\text{si } R_b < 0\text{: } K_b \mathrel{+}= R_b,\; R_b = 0\)
Consume primero los rendimientos \(R_b\); si \(R_b\) se vuelve negativo, se drena desde el capital \(K_b\).

COMPRA
\(B > 0\)
\(\rho = \min(B,\, R_b)\)
\(R_b \mathrel{-}= \rho\)
\(K_b \mathrel{-}= (B - \rho)\)
Consume primero los rendimientos \(R_b\), luego drena el resto desde el capital \(K_b\).

VENTA
\(G = P - C\)
\(K_b \mathrel{+}= C\)
\(R_b \mathrel{+}= G\)
\(\text{si } R_b < 0\text{: } K_b \mathrel{+}= R_b, \quad R_b = 0\)
El coste base $C =

TRANSFERENCIA DE FONDOS
(Interna, \(s \to d\), \(X > 0\))
Tramo de salida (\(s\)):
\(\rho = \min(X,\, R_s)\)
\(R_s \mathrel{-}= \rho\)
\(\kappa = X - \rho\)
\(K_s \mathrel{-}= \kappa\)

Tramo de llegada (\(d\)):
\(K_d \mathrel{+}= \kappa\)
\(R_d \mathrel{+}= \rho\)
Las transferencias internas de fondos mueven las asignaciones de fondos (\(R_s \to R_d\), \(K_s \to K_d\)) proporcionalmente al saldo de salida.
El rastreador global \(W\) nunca se toca (el capital permanece dentro del sistema).

Si las fechas de salida y llegada difieren, la transferencia está en tránsito: se resta de \(s\) el día de salida y se suma a \(d\) el día de llegada. Entre esas fechas, \(\sum K_b + \sum R_b < \mathrm{Cash}_{\text{like}}\) por el monto en tránsito — gestionado mediante conciliación proporcional.

💱 Resultado de cambio sobre el efectivo en divisas

Cada movimiento de efectivo entra en el efectivo del bróker, y en sus fondos, al tipo de cambio de su propia fecha; el saldo mantenido después sigue el tipo de cambio (§5). Cada día \(t\) en que cambia el tipo de una divisa extranjera mantenida como efectivo en \(S\) — incluido su primer tipo conocido —, después de los movimientos de efectivo de ese día y antes de que las transacciones de ese día actualicen los fondos, cada bróker \(b\) que mantiene efectivo en divisas se revaloriza:

\[ \varepsilon_b(t) = \sum_{c} N_{b,c}(t) \cdot \mathrm{fx}(c, C^*, t) - \mathrm{Cash}^{\text{replay}}_b(t) \]
\[ \mathrm{Cash}^{\text{replay}}_b \mathrel{+}= \varepsilon_b, \qquad R_b \mathrel{+}= \varepsilon_b, \qquad \text{si } R_b < 0\text{: } K_b \mathrel{+}= R_b,\; R_b = 0 \]

\(\mathrm{Cash}^{\text{replay}}_b(t)\) es el efectivo que la reproducción lleva para \(b\): su valor en la revalorización anterior más cada movimiento posterior al tipo de cambio de su propia fecha. Una ganancia va a los rendimientos; una pérdida consume primero los rendimientos y luego el capital, exactamente como una COMISIÓN. La base de capital no se mueve: un resultado de cambio es un resultado, no una aportación, así que está en el NAV, el P&L total, el ROI, el TWRR y el MWRR, nunca en el capital depositado.

🧮 Agregación para la salida

\[ \mathrm{CashFromCapital}(t) = \sum_{b \in S} K_b(t) \]
\[ \mathrm{CashFromReturns}(t) = \sum_{b \in S} R_b(t) \]

⚖️ Invariante de conciliación

\[ \mathrm{Cash}_{\text{like}}(t) \approx \sum_{b \in S} K_b(t) + \sum_{b \in S} R_b(t) \]

Primero ambos fondos se acotan a cero por bróker. Si los fondos no están vacíos y la desviación sigue superando \(0.01\), los fondos sumados se escalan a \(\mathrm{Cash}_{\text{like}}\), el efectivo más el efectivo en tránsito — un escalado agregado, no por bróker, con cada resultado acotado a cero:

\[ \mathrm{CashFromCapital}(t) = \sum_{b \in S} K_b(t) \]

En caso contrario, \(\mathrm{CashFromCapital}(t) = \min\bigl(\sum_b K_b(t),\, \mathrm{Cash}_{\text{like}}(t)\bigr)\) y \(\mathrm{CashFromReturns}\) es el resto, acotado a cero. Los resultados de cambio sobre el efectivo en reposo se registran en los fondos (arriba), así que la desviación que queda viene de la temporización en tránsito: el efectivo en tránsito — y el movimiento de su tipo de cambio mientras viaja — no está en los fondos de ningún bróker.


📐 7. Contribución del período

Para el período \([t_0, t_1]\), por posición \((a,b)\):

\[ \Delta\mathrm{UGL}(a,b) = \mathrm{UGL}(a,b,t_1) - \mathrm{UGL}(a,b,t_0) \]
\[ \mathrm{PnL}(a,b) = \Delta\mathrm{UGL}(a,b) + \mathrm{Realized}(a,b) + \mathrm{Income}(a,b) - \mathrm{FeesTaxes}(a,b) \]

Conjunto de posiciones de contribución:

\[ \mathcal{P} = \text{posiciones con actividad de COMPRA/VENTA/AJUSTE/TRANSFERENCIA o cantidad límite} \]

El P&L período a nivel de cartera también expone un residuo:

\[ \mathrm{Other} = \mathrm{PnL}_{period} - \Delta\mathrm{UGL} - \mathrm{Realized} - \mathrm{Income} + \mathrm{FeesTaxes} \]

Como el UGL no puede contener el resultado de cambio sobre el efectivo (§5), Other se divide en el resultado de cambio de cada bróker durante el período y lo que queda:

\[ \mathrm{Other} = \sum_{b \in S} \mathrm{FXonCash}_b + \mathrm{Residual} \]

Las comisiones/ingresos no asignados sin asset_id se agrupan por bróker como otros efectos del período, y también \(\mathrm{FXonCash}_b\): una fila por cada bróker que mantiene efectivo en divisas, que se muestra cuando su resultado no es cero. Ver P&L período — Efecto del tipo de cambio sobre el efectivo.


📐 8. P&L realizado

En una VENTA de \(|q_s|\) unidades de la posición \((a,b)\) en la fecha \(t\):

\[ C = |q_s| \cdot w_{\text{pre}}(a,b) \]
\[ \mathrm{Realized} = P_{\text{sell}} \cdot \mathrm{fx}(\mathrm{ccy}_{\text{sell}}, C^*, t) - C \]

Donde \(w_{\text{pre}}\) es el PMC en \(C^*\) antes de la reducción del fondo (el mismo valor usado por la regla de VENTA de 3 fondos anterior): las unidades vendidas salen a su coste histórico, sin conversión en la fecha de venta. Una venta cuyos ingresos no puedan convertirse, o que se extraiga de una posición cuyo coste esté incompleto, se deja fuera del P&L realizado.


📐 9. Arquitectura de pre-marco / marco

Fase Rango de fechas Calcula
Pre-marco \([t_{\mathrm{first}},\ t_0)\) Efectivo, cantidad, PMC, fondos — sin evaluación de mercado
Marco \([t_0,\ t_1]\) Diario completo: precios, FX, estados de posición, estados de cartera

Las transacciones de pre-marco actualizan los acumuladores (libro mayor de efectivo, fondos PMC, K/R/W de 3 fondos) sin ninguna evaluación de mercado: no se lee ningún precio ni se valora ninguna posición. Cada movimiento se convierte al tipo de cambio de su propia fecha, como en el marco, y cada día en que cambia el tipo de una divisa extranjera mantenida, el efectivo se revaloriza al tipo de ese día y el resultado de cambio entra en los fondos (§6), de modo que los fondos son correctos en \(t_0\). Esto permite un almacenamiento en caché eficiente basado en rangos.


📐 10. Métricas de rendimiento (Capa 2)

Calculadas después de los estados diarios, como una pasada separada:

Métrica Fórmula Referencia
P&L total \(\mathrm{NAV}(t) - \text{CapitalBaseline}(t)\) Capital depositado
P&L período \(\mathrm{NAV}(t_1) - \mathrm{NAV}(t_0) - \text{ECF}_{[t_0,t_1]}\) P&L período
TWRR \(\prod_i (1 + r_i) - 1\) (cadena de subperíodos) TWRR
MWRR XIRR resolviendo \(\sum \frac{CF_i}{(1+r)^{d_i/365}} = 0\) MWRR
ROI simple \((\mathrm{NAV} - \text{NetInvested}) / \text{NetInvested}\) ROI
Rendimiento anualizado neto \((1+r_{\mathrm{net}})^{365/d}-1\), suprimido por debajo de 30 días Rendimiento anualizado neto
Rendimiento sobre coste Ingreso bruto por transacción de los últimos 365 días por unidad histórica elegible, dividido por el PMC unitario residual en \(t_1\) Rendimiento sobre coste
Efecto timing \(\text{MWRR}_{\text{cum}} - \text{TWRR}_{\text{cum}}\) Efecto timing

🔗 Relacionado