Arbeiten mit Charts in Strategien
In StockSharp stellt die Klasse Strategy eine komfortable Schnittstelle bereit, um Handelsaktivitäten in einem Chart zu visualisieren. In diesem Artikel sehen wir uns an, wie Sie aus einer Strategie auf einen Chart zugreifen, Bereiche (ChartArea) erstellen, verschiedene Elemente hinzufügen (Kerzen, Indikatoren, Trades) und Daten zeichnen.
Zugriff auf den Chart
GetChart-Methode
Um aus einer Strategie auf den Chart zuzugreifen, verwenden Sie die Methode Strategy.GetChart():
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
// Chart abrufen
_chart = GetChart();
// Chart-Verfügbarkeit prüfen
if (_chart != null)
{
// Chart initialisieren
InitializeChart();
}
else
{
// Chart ist nicht verfügbar, z. B. beim Start im Konsolenmodus
LogInfo("Diagramm ist nicht verfügbar. Visualisierung deaktiviert.");
}
}
Die Methode GetChart() gibt eine IChart-Schnittstelle zurück, die Zugriff auf Chart-Funktionen bietet. Es ist wichtig, das Ergebnis auf null zu prüfen, da der Chart beispielsweise beim Ausführen einer Strategie im Konsolenmodus oder beim Cloud-Testing nicht verfügbar sein kann.
SetChart-Methode
In manchen Fällen kann der Chart von außen gesetzt werden. Verwenden Sie dafür die Methode Strategy.SetChart:
// Chart aus einer externen Quelle setzen
public void ConfigureVisualization(IChart chart)
{
SetChart(chart);
if (chart != null)
{
InitializeChart();
}
}
Chart-Bereiche erstellen
Nachdem Sie Zugriff auf den Chart erhalten haben, können Sie einen oder mehrere Bereiche erstellen, um verschiedene Daten anzuzeigen. Verwenden Sie dazu die Methode CreateChartArea:
private void InitializeChart()
{
// Hauptbereich für Kerzen und Indikatoren erstellen
_mainArea = CreateChartArea();
// Zusätzlichen Bereich für Volumen erstellen
_volumeArea = CreateChartArea();
// Bereiche konfigurieren und Elemente hinzufügen
ConfigureChartElements();
}
Sie können auch direkt die Methode IChart.AddArea verwenden:
private void InitializeChart()
{
// Vorhandene Bereiche bei Bedarf löschen
foreach (var area in _chart.Areas.ToArray())
_chart.RemoveArea(area);
// Hauptbereich für Kerzen und Indikatoren erstellen
_mainArea = _chart.AddArea();
// Zusätzlichen Bereich für Volumen erstellen
_volumeArea = _chart.AddArea();
// Bereiche konfigurieren und Elemente hinzufügen
ConfigureChartElements();
}
Elemente zum Chart hinzufügen
Nach dem Erstellen der Chart-Bereiche können Sie verschiedene Elemente hinzufügen, um Daten anzuzeigen. StockSharp unterstützt unterschiedliche Elementtypen wie Kerzen, Indikatoren, Trades und Orders.
Kerzen hinzufügen
Um Kerzen anzuzeigen, verwenden Sie die Methode AddCandles des Chart-Bereichs:
private void ConfigureChartElements()
{
// Kerzenelement zum Hauptbereich hinzufügen
_candleElement = _mainArea.AddCandles();
// Kerzendarstellung konfigurieren
_candleElement.DrawStyle = ChartCandleDrawStyles.CandleStick; // japanische Kerzen
_candleElement.AntiAliasing = true; // Glättung
_candleElement.UpFillColor = Color.Green; // Körperfarbe steigender Kerzen
_candleElement.DownFillColor = Color.Red; // Körperfarbe fallender Kerzen
_candleElement.UpBorderColor = Color.DarkGreen; // Rahmenfarbe steigender Kerzen
_candleElement.DownBorderColor = Color.DarkRed; // Rahmenfarbe fallender Kerzen
_candleElement.StrokeThickness = 1; // Linienstärke
_candleElement.ShowAxisMarker = true; // Y-Achsenmarker anzeigen
}
Die Schnittstelle IChartCandleElement bietet viele Eigenschaften zum Konfigurieren der Kerzendarstellung:
DrawStyle - Darstellungsstil der Kerzen:
- CandleStick - japanische Kerzen
- Ohlc - Balken
- LineOpen/LineHigh/LineLow/LineClose - Linien für die jeweiligen Preise
- BoxVolume - Volumenboxen
- ClusterProfile - Clusterprofil
- Area - Fläche
- PnF - Point-and-Figure-Chart
Farbeinstellungen:
- UpFillColor/DownFillColor - Körperfarbe steigender/fallender Kerzen
- UpBorderColor/DownBorderColor - Rahmenfarbe steigender/fallender Kerzen
- LineColor - Linienfarbe für linienbasierte Charts
- AreaColor - Flächenfarbe für den Typ Area
Weitere Einstellungen:
- StrokeThickness - Linienstärke
- AntiAliasing - Glättung
- ShowAxisMarker - Y-Achsenmarker anzeigen
Indikatoren hinzufügen
Um Indikatoren anzuzeigen, verwenden Sie die Methode DrawIndicator:
// Indikatoren erstellen
_sma = new SimpleMovingAverage { Length = SmaLength };
_bollinger = new BollingerBands
{
Length = BollingerLength,
Deviation = BollingerDeviation
};
// Indikatoren zur Strategiesammlung hinzufügen
Indicators.Add(_sma);
Indicators.Add(_bollinger);
// Indikatoren visualisieren
_smaElement = DrawIndicator(_mainArea, _sma, Color.Blue);
_bollingerUpperElement = DrawIndicator(_mainArea, _bollinger, Color.Purple);
_bollingerLowerElement = DrawIndicator(_mainArea, _bollinger, Color.Purple);
_bollingerMiddleElement = DrawIndicator(_mainArea, _bollinger, Color.Gray);
Die Methode DrawIndicator erstellt automatisch ein Indikatorelement und fügt es dem angegebenen Chart-Bereich hinzu. Sie können eine Farbe und eine zusätzliche Farbe für die Darstellung angeben.
Sie können ein Indikatorelement auch direkt über die Methode AddIndicator des Chart-Bereichs hinzufügen:
// SMA direkt über den Chart-Bereich hinzufügen
var smaElement = _mainArea.AddIndicator(_sma);
smaElement.Color = Color.Blue;
smaElement.StrokeThickness = 2;
smaElement.DrawStyle = DrawStyles.Line;
smaElement.AntiAliasing = true;
smaElement.ShowAxisMarker = true;
smaElement.AutoAssignYAxis = true; // Y-Achse automatisch zuweisen
Die Schnittstelle IChartIndicatorElement stellt die folgenden Eigenschaften zur Konfiguration bereit:
- Color - Hauptfarbe des Indikators
- AdditionalColor - zusätzliche Farbe (für Indikatoren mit zwei Linien)
- StrokeThickness - Linienstärke
- AntiAliasing - Glättung
- DrawStyle - Zeichenstil (Linie, Punkte, Histogramm usw.)
- ShowAxisMarker - Y-Achsenmarker anzeigen
- AutoAssignYAxis - Y-Achse automatisch zuweisen
Trades hinzufügen
Um Trades anzuzeigen, verwenden Sie die Methode DrawOwnTrades:
// Element zur Anzeige von Trades hinzufügen
_tradesElement = DrawOwnTrades(_mainArea);
// Trade-Darstellung konfigurieren
_tradesElement.BuyBrush = Color.Green; // Kauffarbe
_tradesElement.SellBrush = Color.Red; // Verkaufsfarbe
_tradesElement.PointSize = 10; // Punktgröße
Orders hinzufügen
Um Orders anzuzeigen, verwenden Sie die Methode DrawOrders:
// Element zur Anzeige von Orders hinzufügen
_ordersElement = DrawOrders(_mainArea);
// Order-Darstellung konfigurieren
_ordersElement.ActiveBrush = Color.Blue; // Farbe aktiver Orders
_ordersElement.CanceledBrush = Color.Gray; // Farbe stornierter Orders
_ordersElement.DoneBrush = Color.Green; // Farbe ausgeführter Orders
_ordersElement.ErrorColor = Color.Red; // Fehlerfarbe
_ordersElement.PointSize = 8; // Punktgröße
Die Schnittstelle IChartOrderElement stellt die folgenden Eigenschaften zur Konfiguration bereit:
- ActiveBrush - Farbe aktiver Orders
- CanceledBrush - Farbe stornierter Orders
- DoneBrush - Farbe ausgeführter Orders
- ErrorColor - Fehlerfarbe
- ErrorStrokeColor - Fehler-Rahmenfarbe
- Filter - Filter für die Order-Anzeige
Daten im Chart zeichnen
Nachdem alle Chart-Elemente konfiguriert sind, können Sie mit dem Zeichnen von Daten fortfahren. Je nach Datentyp werden unterschiedliche Methoden verwendet.
Kerzen und Indikatoren zeichnen
Die effizienteste Möglichkeit, Daten zu zeichnen, ist die Verwendung der Methode IChart.Draw mit einem IChartDrawData-Objekt:
private void ProcessCandle(ICandleMessage candle)
{
// Kerze in Indikatoren verarbeiten
var smaValue = _sma.Process(candle);
var bollingerValue = _bollinger.Process(candle);
// Wenn der Chart nicht verfügbar ist, Zeichnen überspringen
if (_chart == null)
return;
// Daten zum Zeichnen erstellen
var drawData = _chart.CreateData();
// Daten nach Kerzenzeit gruppieren
var group = drawData.Group(candle.OpenTime);
// Kerze hinzufügen
group.Add(_candleElement,
candle.DataType,
candle.SecurityId,
candle.OpenPrice,
candle.HighPrice,
candle.LowPrice,
candle.ClosePrice,
candle.PriceLevels,
candle.State);
// Indikatorwerte hinzufügen
group.Add(_smaElement, smaValue);
if (bollingerValue != null)
{
group.Add(_bollingerUpperElement, bollingerValue);
group.Add(_bollingerMiddleElement, bollingerValue);
group.Add(_bollingerLowerElement, bollingerValue);
}
// Daten im Chart zeichnen
_chart.Draw(drawData);
}
Die Methode IChart.CreateData erstellt ein IChartDrawData-Objekt, das zum Gruppieren und Hinzufügen von Daten für verschiedene Chart-Elemente verwendet wird. Die Gruppierung der Daten erfolgt nach Zeitstempel über die Methode Group.
Zum Hinzufügen von Daten unterschiedlicher Typen werden verschiedene Überladungen der Methode Add des Objekts IChartDrawDataItem verwendet.
Trades und Orders zeichnen
Zum Zeichnen von Trades und Orders wird normalerweise ein automatischer Mechanismus verwendet, der ausgelöst wird, wenn neue Trades eingehen oder Orders geändert werden. Wenn manuelles Zeichnen erforderlich ist, können Sie jedoch den folgenden Code verwenden:
// Trade zeichnen
var tradeDrawData = _chart.CreateData();
var tradeGroup = tradeDrawData.Group(trade.Time);
tradeGroup.Add(_tradesElement, trade.Id, trade.StringId, trade.Side, trade.Price, trade.Volume);
_chart.Draw(tradeDrawData);
// Order zeichnen
var orderDrawData = _chart.CreateData();
var orderGroup = orderDrawData.Group(order.Time);
orderGroup.Add(_ordersElement, order.Id, order.StringId, order.Side, order.Price, order.Volume);
_chart.Draw(orderDrawData);
Vollständiges Beispiel für Chart-Rendering in einer Strategie
Unten sehen Sie ein vollständiges Beispiel einer Strategie mit Chart-Einrichtung und Rendering:
public class SmaStrategy : Strategy
{
private readonly StrategyParam<int> _smaLength;
private readonly StrategyParam<int> _bollingerLength;
private readonly StrategyParam<decimal> _bollingerDeviation;
private SimpleMovingAverage _sma;
private BollingerBands _bollinger;
private IChart _chart;
private IChartArea _mainArea;
private IChartArea _volumeArea;
private IChartCandleElement _candleElement;
private IChartIndicatorElement _smaElement;
private IChartIndicatorElement _bollingerUpperElement;
private IChartIndicatorElement _bollingerMiddleElement;
private IChartIndicatorElement _bollingerLowerElement;
private IChartOrderElement _ordersElement;
private IChartTradeElement _tradesElement;
public SmaStrategy()
{
_smaLength = Param(nameof(SmaLength), 20);
_bollingerLength = Param(nameof(BollingerLength), 20);
_bollingerDeviation = Param(nameof(BollingerDeviation), 2m);
}
public int SmaLength
{
get => _smaLength.Value;
set => _smaLength.Value = value;
}
public int BollingerLength
{
get => _bollingerLength.Value;
set => _bollingerLength.Value = value;
}
public decimal BollingerDeviation
{
get => _bollingerDeviation.Value;
set => _bollingerDeviation.Value = value;
}
protected override void OnStarted2(DateTime time)
{
base.OnStarted2(time);
// Indikatoren erstellen
_sma = new SimpleMovingAverage { Length = SmaLength };
_bollinger = new BollingerBands
{
Length = BollingerLength,
Deviation = BollingerDeviation
};
// Indikatoren zur Strategiesammlung hinzufügen
Indicators.Add(_sma);
Indicators.Add(_bollinger);
// Chart abrufen
_chart = GetChart();
// Chart initialisieren, wenn verfügbar
if (_chart != null)
{
InitializeChart();
}
// Kerzen abonnieren
var subscription = new Subscription(
DataType.TimeFrame(TimeSpan.FromMinutes(5)),
Security);
subscription
.WhenCandlesFinished(this)
.Do(ProcessCandle)
.Apply(this);
Subscribe(subscription);
}
private void InitializeChart()
{
// Vorhandene Bereiche löschen
foreach (var area in _chart.Areas.ToArray())
_chart.RemoveArea(area);
// Hauptbereich für Kerzen und Indikatoren erstellen
_mainArea = _chart.AddArea();
// Zusätzlichen Bereich für Volumen erstellen
_volumeArea = _chart.AddArea();
// Chart-Elemente konfigurieren
ConfigureChartElements();
}
private void ConfigureChartElements()
{
// Element zur Anzeige von Kerzen hinzufügen
_candleElement = _mainArea.AddCandles();
_candleElement.DrawStyle = ChartCandleDrawStyles.CandleStick;
_candleElement.AntiAliasing = true;
_candleElement.UpFillColor = Color.Green;
_candleElement.DownFillColor = Color.Red;
_candleElement.UpBorderColor = Color.DarkGreen;
_candleElement.DownBorderColor = Color.DarkRed;
_candleElement.StrokeThickness = 1;
_candleElement.ShowAxisMarker = true;
// Elemente für Indikatoren hinzufügen
_smaElement = _mainArea.AddIndicator(_sma);
_smaElement.Color = Color.Blue;
_smaElement.StrokeThickness = 2;
_bollingerUpperElement = _mainArea.AddIndicator(_bollinger);
_bollingerUpperElement.Color = Color.Purple;
_bollingerUpperElement.StrokeThickness = 1;
_bollingerMiddleElement = _mainArea.AddIndicator(_bollinger);
_bollingerMiddleElement.Color = Color.Gray;
_bollingerMiddleElement.StrokeThickness = 1;
_bollingerLowerElement = _mainArea.AddIndicator(_bollinger);
_bollingerLowerElement.Color = Color.Purple;
_bollingerLowerElement.StrokeThickness = 1;
// Elemente für Orders und Trades hinzufügen
_ordersElement = DrawOrders(_mainArea);
_tradesElement = DrawOwnTrades(_mainArea);
}
private void ProcessCandle(ICandleMessage candle)
{
// Kerze mit Indikatoren verarbeiten
var smaValue = _sma.Process(candle);
var bollingerValue = _bollinger.Process(candle);
// Wenn der Chart nicht verfügbar ist, Zeichnen überspringen
if (_chart == null)
return;
// Daten im Chart zeichnen
var drawData = _chart.CreateData();
var group = drawData.Group(candle.OpenTime);
// Kerze hinzufügen
group.Add(_candleElement,
candle.DataType,
candle.SecurityId,
candle.OpenPrice,
candle.HighPrice,
candle.LowPrice,
candle.ClosePrice,
candle.PriceLevels,
candle.State);
// Indikatorwerte hinzufügen
group.Add(_smaElement, smaValue);
if (bollingerValue != null)
{
group.Add(_bollingerUpperElement, bollingerValue);
group.Add(_bollingerMiddleElement, bollingerValue);
group.Add(_bollingerLowerElement, bollingerValue);
}
// Daten im Chart zeichnen
_chart.Draw(drawData);
// Handelslogik
if (!IsFormed)
return;
// ... Implementierung der Handelslogik ...
}
}
Fazit
Charts in StockSharp-Strategien ermöglichen die Visualisierung von Handelsaktivitäten. Das vereinfacht die Entwicklung, das Debugging und die Überwachung von Handelsstrategien erheblich. Die Klasse Strategy stellt viele Methoden für die Arbeit mit Charts bereit, mit denen sich verschiedene Elemente einfach hinzufügen und Daten rendern lassen.
Wenn Sie eine Strategie mit grafischer Oberfläche entwickeln, berücksichtigen Sie immer, dass der Chart beispielsweise beim Start im Konsolenmodus oder beim Cloud-Testing nicht verfügbar sein kann. Deshalb ist es wichtig, das Ergebnis der Methode GetChart() auf null zu prüfen und ein alternatives Szenario vorzusehen, damit die Strategie ohne Visualisierung arbeiten kann.