Gestión de pérdidas y ganancias
S# implementa el cálculo de pérdidas y ganancias (PnL) mediante PnLManager. El administrador procesa un flujo de mensajes (trades, datos de mercado) y calcula el beneficio realizado y no realizado.
Interfaz IPnLManager
La interfaz IPnLManager define el contrato base:
- RealizedPnL — beneficio/pérdida realizado (decimal). Se acumula cuando se cierran posiciones.
- UnrealizedPnL — beneficio/pérdida no realizado (decimal). Se recalcula basándose en precios de mercado actuales.
- Reset() — restablece el estado del administrador.
- UpdateSecurity(Level1ChangeMessage) — actualiza parámetros del instrumento (paso de precio, precio del paso, multiplicador de lote).
- ProcessMessage(Message, ICollection<PortfolioPnLManager>) — procesa un mensaje; devuelve PnLInfo cuando se cierra una posición, de lo contrario
null.
Arquitectura
El sistema PnL tiene una jerarquía de tres niveles:
PnLManager
└── PortfolioPnLManager (por nombre de cartera)
└── PnLQueue (por SecurityId)
- PnLManager — nivel superior, gestiona un diccionario de administradores de carteras.
- PortfolioPnLManager — administrador PnL para una cartera específica, gestiona colas por instrumento.
- PnLQueue — cola FIFO para emparejar trades en un único instrumento.
PnLQueue — Cola de cálculo
PnLQueue es responsable de emparejar trades de apertura y cierre:
- PriceStep — paso de precio del instrumento.
- StepPrice — coste del paso de precio (para futuros).
- Leverage — apalancamiento.
- LotMultiplier — multiplicador de lote.
El multiplicador de beneficio se calcula usando la fórmula:
Multiplier = (StepPrice / PriceStep) * Leverage * LotMultiplier
Para acciones normales (donde StepPrice no está establecido), el multiplicador es igual a 1 * Leverage * LotMultiplier.
PnLInfo — Resultado del procesamiento de trades
La clase PnLInfo contiene el resultado de cerrar una posición:
- ServerTime — hora del trade.
- ClosedVolume — volumen de la posición cerrada.
- PnL — beneficio realizado de este trade.
Por ejemplo, si la posición era +2 y llegó un trade de -5 contratos, entonces ClosedVolume = 2 (se cerraron 2 contratos de la posición).
Configuración de fuentes de datos
PnLManager permite seleccionar fuentes de datos de mercado para el cálculo de beneficio no realizado:
| Propiedad | Predeterminado | Descripción |
|---|---|---|
UseTick |
true |
Usar tick trades. |
UseOrderBook |
false |
Usar libro de órdenes (mejor bid/ask). |
UseLevel1 |
false |
Usar datos Level1. |
UseOrderLog |
false |
Usar order log. |
UseCandles |
true |
Usar velas (precio de cierre). |
Integración mediante adaptador
La clase PnLMessageAdapter envuelve un adaptador interno y procesa automáticamente todos los mensajes para el cálculo de PnL.
Integración con Strategy
La estrategia (Strategy) proporciona:
- Propiedad
PnLManager— la instancia del administrador. - Propiedad
PnL— beneficio total (RealizedPnL + UnrealizedPnL). - Evento
PnLChanged— notificación de cambios de beneficio. - Evento
PnLReceived2— notificación cuando se reciben nuevos datos PnL.
Ejemplo de uso
var pnlManager = new PnLManager
{
UseTick = true,
UseOrderBook = true,
UseCandles = true
};
// Procesamiento de mensajes
var info = pnlManager.ProcessMessage(executionMsg);
if (info != null)
{
Console.WriteLine($"Closed: {info.ClosedVolume}, PnL: {info.PnL}");
}
// Beneficio/pérdida total
var realizedPnL = pnlManager.RealizedPnL;
var unrealizedPnL = pnlManager.UnrealizedPnL;
var totalPnL = realizedPnL + unrealizedPnL;
Console.WriteLine($"Realized PnL: {realizedPnL}");
Console.WriteLine($"Unrealized PnL: {unrealizedPnL}");
Console.WriteLine($"Total PnL: {totalPnL}");
Restablecimiento del estado
El método Reset() borra todos los administradores de carteras, colas de cálculo y restablece el PnL realizado a cero:
pnlManager.Reset();