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();