Testeinstellungen

Dieser Abschnitt beschreibt die wichtigsten Einstellungen des HistoryEmulationConnector zum Testen von Handelsstrategien.

Grundeinstellungen des Emulators

Marktdatenabonnements

Für korrektes Strategietesting müssen Abonnements für die erforderlichen Marktdatentypen eingerichtet werden. Selbst wenn die Strategie anhand von Kerzen getestet wird, ist für eine korrekte Trade-Emulation ein Abonnement für Tick-Trades erforderlich:

// Abonnement für Tick-Trades erstellen
var tickSubscription = new Subscription(DataType.Ticks, security);
_connector.Subscribe(tickSubscription);

Wenn die Strategie Orderbuchdaten benötigt:

// Abonnement für Orderbücher erstellen
var depthSubscription = new Subscription(DataType.MarketDepth, security);
_connector.Subscribe(depthSubscription);

Orderbuchgenerierung für Tests

Wenn keine historischen Orderbücher vorhanden sind, diese aber für das Strategietesting benötigt werden, können Sie die Orderbuchgenerierung aktivieren:

// Orderbuchgenerator mit Trendverhalten erstellen
var mdGenerator = new TrendMarketDepthGenerator(security.ToSecurityId());

// Abonnementnachricht an den Generator senden
_connector.MarketDataAdapter.SendInMessage(new GeneratorMessage
{
	IsSubscribe = true,
	Generator = mdGenerator
});

Einstellungen des Orderbuchgenerators

  • Aktualisierungsintervall des Orderbuchs (MarketDataGenerator.Interval) - Aktualisierungen können nicht häufiger erfolgen als das Eintreffen von Tick-Trades, da Orderbücher vor jedem Trade generiert werden:
mdGenerator.Interval = TimeSpan.FromSeconds(1);
mdGenerator.MaxAsksDepth = 1;
mdGenerator.MaxBidsDepth = 1;
  • Um ein realistisches Level-Volumen im Orderbuch zu erhalten, können Sie die Option MarketDepthGenerator.UseTradeVolume verwenden. Sie übernimmt die Volumina für die besten Quotes aus dem generierten Trade-Volumen:
mdGenerator.UseTradeVolume = true;
mdGenerator.MinVolume = 1;
mdGenerator.MaxVolume = 1;
  • Spread-Einstellungen - der minimal erzeugte Spread entspricht Security.PriceStep. Es wird empfohlen, keinen Spread zwischen den besten Quotes zu erzeugen, der größer als 5 Preisschritte ist, damit der Spread beim Generieren aus Kerzen nicht zu breit wird:
mdGenerator.MinSpreadStepCount = 1;
mdGenerator.MaxSpreadStepCount = 5;

Beispiel für eine vollständige Testkonfiguration

// Historische Verbindung erstellen
var connector = new HistoryEmulationConnector();

// Basisparameter konfigurieren
connector.MarketTimeChangedInterval = TimeSpan.FromSeconds(10);
connector.EmulationAdapter.Emulator.Settings.Latency = TimeSpan.FromMilliseconds(100);
connector.EmulationAdapter.Emulator.Settings.MatchOnTouch = false;

// Historische Daten laden
var storage = new StorageRegistry();
var security = new Security { Id = "AAPL", PriceStep = 0.01m };

// Abonnement für Kerzen erstellen
var candleSubscription = new Subscription(
	TimeSpan.FromMinutes(5).TimeFrame(),
	security)
{
	MarketData =
	{
		From = DateTime.Today.Subtract(TimeSpan.FromDays(30)),
		To = DateTime.Today,
		BuildMode = MarketDataBuildModes.Load
	}
};
connector.Subscribe(candleSubscription);

// Abonnement für Ticks zur korrekten Emulation erstellen
var tickSubscription = new Subscription(DataType.Ticks, security);
connector.Subscribe(tickSubscription);

// Orderbuchgenerierung konfigurieren
var mdGenerator = new TrendMarketDepthGenerator(security.ToSecurityId())
{
	Interval = TimeSpan.FromSeconds(1),
	MaxAsksDepth = 5,
	MaxBidsDepth = 5,
	UseTradeVolume = true,
	MinVolume = 1,
	MaxVolume = 100,
	MinSpreadStepCount = 1,
	MaxSpreadStepCount = 5
};

connector.MarketDataAdapter.SendInMessage(new GeneratorMessage
{
	IsSubscribe = true,
	Generator = mdGenerator
});

// Empfang von Daten abonnieren
connector.CandleReceived += OnCandleReceived;
connector.TickTradeReceived += OnTickReceived;
connector.OrderBookReceived += OnOrderBookReceived;

// Test starten
connector.Connect();

Ereignisverarbeitung

private void OnCandleReceived(Subscription subscription, ICandleMessage candle)
{
	// Empfangene Kerzen verarbeiten
	Console.WriteLine($"Kerze: {candle.OpenTime}, O:{candle.OpenPrice}, H:{candle.HighPrice}, L:{candle.LowPrice}, C:{candle.ClosePrice}");
}

private void OnTickReceived(Subscription subscription, ITickTradeMessage tick)
{
	// Empfangene Ticks verarbeiten
	Console.WriteLine($"Tick: {tick.ServerTime}, Preis: {tick.Price}, Volumen: {tick.Volume}");
}

private void OnOrderBookReceived(Subscription subscription, IOrderBookMessage orderBook)
{
	// Erweiterungsmethoden für IOrderBookMessage verwenden
	var bestBid = orderBook.GetBestBid();
	var bestAsk = orderBook.GetBestAsk();
	var spreadMiddle = orderBook.GetSpreadMiddle(Security.PriceStep);

	// Empfangene Orderbücher verarbeiten
	Console.WriteLine($"Orderbuch: {orderBook.ServerTime}, bestes Gebot: {bestBid?.Price}, bestes Angebot: {bestAsk?.Price}, Spread-Mitte: {spreadMiddle}");

	// Preis nach Order-Seite abrufen
	var bidPrice = orderBook.GetPrice(Sides.Buy);
	var askPrice = orderBook.GetPrice(Sides.Sell);

	Console.WriteLine($"Gebotspreis: {bidPrice}, Angebotspreis: {askPrice}");
}

Arbeiten mit Orderbuchdaten

Wenn Sie mit Orderbüchern als IOrderBookMessage arbeiten, können Sie die folgenden Erweiterungsmethoden verwenden:

// Best Bid abrufen
var bestBid = orderBook.GetBestBid();

// Best Ask abrufen
var bestAsk = orderBook.GetBestAsk();

// Mitte des Spreads abrufen
var spreadMiddle = orderBook.GetSpreadMiddle(Security.PriceStep);

// Preis nach Order-Seite abrufen
var price = orderBook.GetPrice(Sides.Buy); // oder Sides.Sell, oder null für die Mitte des Spreads

Bei der Arbeit mit Level1-Daten können Sie ebenfalls die Mitte des Spreads abrufen:

// Mitte des Spreads aus einer Level1-Nachricht abrufen
var spreadMiddle = level1.GetSpreadMiddle(Security.PriceStep);

Diese Erweiterungsmethoden vereinfachen den Zugriff auf Orderbuchdaten und ermöglichen es, saubereren und verständlicheren Code für die Arbeit mit Börsenquotes zu schreiben.