Lebenszyklus von Abonnements
Abonnements in StockSharp durchlaufen bestimmte Lebenszyklusphasen. Die Schnittstelle ISubscriptionProvider stellt Ereignisse bereit, mit denen jede Phase verfolgt werden kann.
Lebenszyklus-Ereignisse
SubscriptionStarted
event Action<Subscription> SubscriptionStarted;
Wird aufgerufen, wenn ein Abonnement erfolgreich gestartet wurde: Der Adapter hat die Anfrage akzeptiert und mit der Datenübertragung begonnen. Bei historischen Abonnements bedeutet dies, dass das Laden der Daten begonnen hat. Bei Live-Abonnements bedeutet es, dass der Server die Anfrage akzeptiert hat.
SubscriptionOnline
event Action<Subscription> SubscriptionOnline;
Wird aufgerufen, wenn das Abonnement in den Echtzeitmodus gewechselt ist. Bei Live-Abonnements bedeutet dies, dass das historische Aufholen, sofern vorhanden, abgeschlossen ist und die Daten nun in Echtzeit eintreffen. Dieses Signal ist für Strategien wichtig, damit sie erkennen, dass Indikatoren "aufgewärmt" sind und der Handel beginnen kann.
SubscriptionStopped
event Action<Subscription, Exception> SubscriptionStopped;
Wird aufgerufen, wenn das Abonnement beendet wurde. Der Parameter Exception enthält den Grund für das Beenden:
null- normale Beendigung (Benutzer hat abbestellt oder historische Daten sind abgeschlossen).- Ein Exception-Objekt - ein Fehler (Verbindungsverlust, serverseitiger Fehler usw.).
SubscriptionFailed
event Action<Subscription, Exception, bool> SubscriptionFailed;
Wird bei einem Abonnementfehler aufgerufen. Der dritte Parameter bool gibt an, ob es sich um eine Subscribe-Operation (true) oder eine Unsubscribe-Operation (false) handelte.
Ereignisreihenfolge
Typische Sequenz für ein Live-Abonnement:
Subscribe(subscription)aufrufenSubscriptionStarted- Abonnement akzeptiert- Daten treffen ein (Kerzen, Orderbücher, Trades usw.)
SubscriptionOnline- Wechsel in den Echtzeitmodus- Weitere Daten treffen in Echtzeit ein
UnSubscribe(subscription)aufrufen oder VerbindungsverlustSubscriptionStopped- Abonnement beendet
Bei einem historischen Abonnement (mit angegebenem Datumsbereich):
Subscribe(subscription)aufrufenSubscriptionStarted- Abonnement akzeptiert- Historische Daten treffen ein
SubscriptionStoppedmitnull- alle Daten wurden empfangen
SubscriptionsOnConnect
Die Eigenschaft Connector.SubscriptionsOnConnect definiert die Menge der Abonnements, die bei der Verbindung automatisch gesendet werden:
ISet<Subscription> SubscriptionsOnConnect { get; }
Standardmäßig sind Abonnements für die Suche nach Instrumenten, Portfolios und Orders enthalten:
SubscriptionsOnConnect.Add(SecurityLookup);
SubscriptionsOnConnect.Add(PortfolioLookup);
SubscriptionsOnConnect.Add(OrderLookup);
Sie können eigene Abonnements hinzufügen, die bei jeder Verbindung automatisch gestartet werden:
// Automatisches Level1-Datenabonnement hinzufügen
var l1Sub = new Subscription(DataType.Level1, security);
connector.SubscriptionsOnConnect.Add(l1Sub);
// Automatische Ordersuche bei Verbindung entfernen
connector.SubscriptionsOnConnect.Remove(connector.OrderLookup);
Verbindungsereignisse pro Adapter
Bei der Arbeit mit mehreren Verbindungen (mehreren Adaptern) sind Ereignisse hilfreich, die anzeigen, welcher konkrete Adapter verbunden oder getrennt wurde:
ConnectedEx
event Action<IMessageAdapter> ConnectedEx;
Wird bei erfolgreicher Verbindung eines bestimmten Adapters aufgerufen. Der Parameter ist der Adapter, der das Ereignis ausgelöst hat.
DisconnectedEx
event Action<IMessageAdapter> DisconnectedEx;
Wird beim Trennen eines bestimmten Adapters aufgerufen.
ConnectionErrorEx
event Action<IMessageAdapter, Exception> ConnectionErrorEx;
Wird bei einem Verbindungsfehler eines bestimmten Adapters aufgerufen.
Zusätzlich sind die aggregierten Ereignisse Connected, Disconnected und ConnectionError verfügbar, die ohne Angabe eines bestimmten Adapters ausgelöst werden.
Beispiel
private readonly Connector _connector = new();
public void SetupSubscriptionTracking()
{
// Lebenszyklus des Abonnements verfolgen
_connector.SubscriptionStarted += subscription =>
{
Console.WriteLine($"Abonnement gestartet: {subscription.DataType}, " +
$"Instrument: {subscription.SecurityId}");
};
_connector.SubscriptionOnline += subscription =>
{
Console.WriteLine($"Abonnement online: {subscription.DataType}");
};
_connector.SubscriptionStopped += (subscription, error) =>
{
if (error == null)
Console.WriteLine($"Abonnement abgeschlossen: {subscription.DataType}");
else
Console.WriteLine($"Abonnement unterbrochen: {subscription.DataType}, " +
$"Fehler: {error.Message}");
};
// Einzelne Adapterverbindungen verfolgen
_connector.ConnectedEx += adapter =>
{
Console.WriteLine($"Adapter verbunden: {adapter.Name}");
};
_connector.DisconnectedEx += adapter =>
{
Console.WriteLine($"Adapter getrennt: {adapter.Name}");
};
_connector.ConnectionErrorEx += (adapter, error) =>
{
Console.WriteLine($"Adapter-Verbindungsfehler {adapter.Name}: {error.Message}");
};
// Verbinden
_connector.Connect();
// Nach der Verbindung ein Abonnement erstellen
_connector.Connected += () =>
{
var subscription = new Subscription(DataType.Ticks, security);
_connector.Subscribe(subscription);
};
}