Gestão de Lucros e Perdas
S# implementa o cálculo de lucros e perdas (PnL) através do PnLManager. O gestor processa um fluxo de mensagens (negócios, dados de mercado) e calcula o lucro realizado e não realizado.
Interface IPnLManager
A interface IPnLManager define o contrato base:
- RealizedPnL - lucro/perda realizado (decimal). Acumulado quando posições são fechadas.
- UnrealizedPnL - lucro/perda não realizado (decimal). Recalculado com base nos preços de mercado atuais.
- Reset() - reinicia o estado do gestor.
- UpdateSecurity(Level1ChangeMessage) - atualiza parâmetros do instrumento (passo de preço, preço do passo, multiplicador de lote).
- ProcessMessage(Message, ICollection<PortfolioPnLManager>) - processa uma mensagem; devolve PnLInfo quando uma posição é fechada, caso contrário
null.
Arquitetura
O sistema de PnL tem uma hierarquia de três níveis:
PnLManager
└── PortfolioPnLManager (por nome de portefólio)
└── PnLQueue (por SecurityId)
- PnLManager - nível superior, gere um dicionário de gestores de portefólio.
- PortfolioPnLManager - gestor de PnL para um portefólio específico, gere filas por instrumento.
- PnLQueue - fila FIFO para correspondência de negócios num único instrumento.
PnLQueue - Fila de Cálculo
PnLQueue é responsável por fazer a correspondência entre negócios de abertura e de fecho:
- PriceStep - passo de preço do instrumento.
- StepPrice - custo do passo de preço (para futuros).
- Leverage - alavancagem.
- LotMultiplier - multiplicador de lote.
O multiplicador de lucro é calculado usando a fórmula:
Multiplier = (StepPrice / PriceStep) * Leverage * LotMultiplier
Para ações normais (em que StepPrice não está definido), o multiplicador é igual a 1 * Leverage * LotMultiplier.
PnLInfo - Resultado do Processamento de Negócios
A classe PnLInfo contém o resultado do fecho de uma posição:
- ServerTime - hora do negócio.
- ClosedVolume - volume da posição fechada.
- PnL - lucro realizado deste negócio.
Por exemplo, se a posição era +2 e chegou um negócio de -5 contratos, então ClosedVolume = 2 (foram fechados 2 contratos da posição).
Configurar Fontes de Dados
PnLManager permite selecionar fontes de dados de mercado para o cálculo do lucro não realizado:
| Propriedade | Predefinição | Descrição |
|---|---|---|
UseTick |
true |
Usar negócios tick. |
UseOrderBook |
false |
Usar livro de ordens (melhor bid/ask). |
UseLevel1 |
false |
Usar dados Level1. |
UseOrderLog |
false |
Usar log de ordens. |
UseCandles |
true |
Usar velas (preço de fecho). |
Integração via Adapter
A classe PnLMessageAdapter envolve um adapter interno e processa automaticamente todas as mensagens para o cálculo de PnL.
Integração com Estratégia
A estratégia (Strategy) fornece:
- Propriedade
PnLManager- a instância do gestor. - Propriedade
PnL- lucro total (RealizedPnL + UnrealizedPnL). - Evento
PnLChanged- notificação de alterações no lucro. - Evento
PnLReceived2- notificação quando são recebidos novos dados de PnL.
Exemplo de Utilização
var pnlManager = new PnLManager
{
UseTick = true,
UseOrderBook = true,
UseCandles = true
};
// Processamento de mensagens
var info = pnlManager.ProcessMessage(executionMsg);
if (info != null)
{
Console.WriteLine($"Closed: {info.ClosedVolume}, PnL: {info.PnL}");
}
// Lucro/prejuízo 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}");
Reiniciar o Estado
O método Reset() limpa todos os gestores de portefólio, filas de cálculo e reinicia o PnL realizado para zero:
pnlManager.Reset();