Gewinn- und Verlustverwaltung

S# implementiert die Gewinn- und Verlustberechnung (PnL) über den PnLManager. Der Manager verarbeitet einen Nachrichtenstrom (Trades, Marktdaten) und berechnet realisierten und unrealisierten Gewinn.

IPnLManager-Interface

Das Interface IPnLManager definiert den Basisvertrag:

  • RealizedPnL - realisierter Gewinn/Verlust (decimal). Wird angesammelt, wenn Positionen geschlossen werden.
  • UnrealizedPnL - unrealisierter Gewinn/Verlust (decimal). Wird anhand aktueller Marktpreise neu berechnet.
  • Reset() - setzt den Zustand des Managers zurück.
  • UpdateSecurity(Level1ChangeMessage) - aktualisiert Instrumentparameter (Preisschritt, Schrittpreis, Lot-Multiplikator).
  • ProcessMessage(Message, ICollection<PortfolioPnLManager>) - verarbeitet eine Nachricht; gibt PnLInfo zurück, wenn eine Position geschlossen wird, andernfalls null.

Architektur

Das PnL-System besitzt eine dreistufige Hierarchie:

PnLManager
  └── PortfolioPnLManager (nach Portfolioname)
        └── PnLQueue (nach SecurityId)
  • PnLManager - oberste Ebene, verwaltet ein Dictionary von Portfolio-Managern.
  • PortfolioPnLManager - PnL-Manager für ein bestimmtes Portfolio, verwaltet Queues nach Instrument.
  • PnLQueue - FIFO-Queue zum Abgleichen von Trades für ein einzelnes Instrument.

PnLQueue - Berechnungsqueue

PnLQueue ist für das Abgleichen eröffnender und schließender Trades verantwortlich:

  • PriceStep - Preisschritt des Instruments.
  • StepPrice - Wert eines Preisschritts (für Futures).
  • Leverage - Hebel.
  • LotMultiplier - Lot-Multiplikator.

Der Gewinnmultiplikator wird mit folgender Formel berechnet:

Multiplier = (StepPrice / PriceStep) * Leverage * LotMultiplier

Für reguläre Aktien (bei denen StepPrice nicht gesetzt ist) entspricht der Multiplikator 1 * Leverage * LotMultiplier.

PnLInfo - Ergebnis der Trade-Verarbeitung

Die Klasse PnLInfo enthält das Ergebnis des Schließens einer Position:

  • ServerTime - Trade-Zeit.
  • ClosedVolume - Volumen der geschlossenen Position.
  • PnL - realisierter Gewinn aus diesem Trade.

Wenn die Position beispielsweise +2 war und ein Trade über -5 Kontrakte eingetroffen ist, dann gilt ClosedVolume = 2 (2 Kontrakte aus der Position wurden geschlossen).

Konfigurieren von Datenquellen

PnLManager ermöglicht die Auswahl von Marktdatenquellen für die Berechnung des unrealisierten Gewinns:

Eigenschaft Standard Beschreibung
UseTick true Tick-Trades verwenden.
UseOrderBook false Orderbuch verwenden (bestes Bid/Ask).
UseLevel1 false Level1-Daten verwenden.
UseOrderLog false Order-Log verwenden.
UseCandles true Candles verwenden (Schlusskurs).

Integration über Adapter

Die Klasse PnLMessageAdapter kapselt einen inneren Adapter und verarbeitet automatisch alle Nachrichten für die PnL-Berechnung.

Integration mit Strategy

Die Strategie (Strategy) stellt Folgendes bereit:

  • Eigenschaft PnLManager - die Manager-Instanz.
  • Eigenschaft PnL - Gesamtgewinn (RealizedPnL + UnrealizedPnL).
  • Ereignis PnLChanged - Benachrichtigung über Gewinnänderungen.
  • Ereignis PnLReceived2 - Benachrichtigung, wenn neue PnL-Daten empfangen werden.

Verwendungsbeispiel

var pnlManager = new PnLManager
{
    UseTick = true,
    UseOrderBook = true,
    UseCandles = true
};

// Nachrichten verarbeiten
var info = pnlManager.ProcessMessage(executionMsg);
if (info != null)
{
    Console.WriteLine($"Closed: {info.ClosedVolume}, PnL: {info.PnL}");
}

// Gesamtgewinn/-verlust
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}");

Zustand zurücksetzen

Die Methode Reset() löscht alle Portfolio-Manager und Berechnungsqueues und setzt den realisierten PnL auf null zurück:

pnlManager.Reset();