Indikator-Code-Beispiele
Diese Seite bietet mehrere Python- und C#-Code-Beispiele für die Erstellung technischer Indikatoren, die für den manuellen oder algorithmischen Handel verwendet werden.
Indikator-Beispiel-Repositorys
Umfassende Indikator-Code-Beispiele, einschließlich sofort ausführbarer Vorlagen für verschiedene Indikatortypen und technische Analysetools, sind in separaten Python- und C#-Repositorys in GitHub verfügbar.
Einfache Indikatoren
Der High-Minus-Low-Indikator berechnet die Differenz zwischen den Höchst- und Tiefstkursen des aktuellen Balkens und zeigt sie in einer Ausgabereihe an. Die Reihe wird auf dem Chart als Linie gezeichnet, die die resultierenden Werte in jedem Balken verbindet.
1 2 3 4 5 6 7 8 9 10 11 | |
Hinweis
Python-Indikatoren verwenden anpassbare Parameter, die in ihren .cs-Dateien deklariert werden.
1 2 3 4 5 6 7 | |
Die Deklaration [Indicator...] enthält mehrere Parameter, die wie folgt definiert sind:
IsOverlay– ein boolescher Wert, der festlegt, ob die Linie auf dem Chart überlagert oder in einem separaten UI-Panel angezeigt wird.TimeZone– ein Feld der KlasseTimeZones, das die Zeitzone der Indikatordaten und der Serverzeit angibt.AccessRights– ein Feld der KlasseAccessRights, das die Ihrem Indikator zugewiesenen Zugriffsrechte bestimmt.ScalePrecision– ein int-Wert, der die Skalenpräzision der Indikatorausgabe festlegt.
Wie Sie zuvor beim Bearbeiten des Indikatorcodes gelernt haben, wird das Attribut Output deklariert, um eine Eigenschaft als Indikatorausgabe zu kennzeichnen. Diese Eigenschaft sollte public sein, damit sie von anderen Klassen referenziert werden kann.
Die Indikatorausgabe sollte immer vom Datentyp IndicatorDataSeries sein, der eine Liste von Doubles ist, die wie ein Array indiziert werden kann. Daher kann der Wert bei jedem [index] in der Liste Result in der Methode Calculate wie folgt zugewiesen werden.
1 2 3 4 | |
1 2 | |
Indikatoren mit Parametern
In den meisten Fällen kann die Ausgabe von Indikatoren je nach Benutzereingabe variieren. Die Art und Weise, wie anpassbare Parameter für Indikatoren eingerichtet werden, ähnelt der Vorgehensweise bei cBots.
Der nachfolgende Simple Moving Average-Indikator ist so konzipiert, dass er eine Preisquelle und einen Zeitraum als anpassbare Parameter akzeptiert. Solchen Parametern (Source und Periods in diesem speziellen Beispiel) muss das Attribut Parameter vorangestellt werden.
Ähnlich wie die zuvor besprochenen Attribute [Indicator()] und [Output()] kann das Attribut [Parameter()] bestimmte Merkmale definieren, die auf die Benutzereingabe angewendet werden.
1 | |
Hinweis
Python-Indikatoren verwenden anpassbare Parameter, die in ihren .cs-Dateien deklariert werden.
Oben geben wir die folgenden Merkmale an:
- Den Namen, der zur Bezeichnung dieses Parameters in der cTrader-Benutzeroberfläche angezeigt wird (
"MA Periods). - Den Standardwert des Parameters; er kann vom Benutzer beim Anpassen einer Instanz geändert werden (
DefaultValue = 14) - Die minimalen und maximalen Parameterwerte (
MinValue = 1, MaxValue = 20)
Im folgenden Snippet zeigen wir, wie anpassbare Parameter in den Indikatorcode integriert werden können.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | |
Hinweis
Python-Indikatoren verwenden anpassbare Parameter, die in ihren .cs-Dateien deklariert werden.
1 2 3 4 5 6 7 8 | |
Verschachtelte Indikatoren
Verschachtelte Indikatoren sind als Indikatoren definiert, deren Wert von den Ergebnissen der von anderen Indikatoren durchgeführten Berechnungen abhängt. Sie sind nützlich beim Schreiben bestimmter Arten von Erweiterungen wie dem DeMark 9-Indikator. Betrachten Sie den folgenden Beispielcode:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | |
Hinweis
Python-Indikatoren verwenden anpassbare Parameter, die in ihren .cs-Dateien deklariert werden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
Im obigen Beispiel sind deMinMA und deMaxMA zwei Variablen, die zur Berechnung des Werts unseres DeMarker-Indikators verwendet werden.
Verschachtelte Indikatoren müssen in der Methode Initialize() definiert werden. Zum Beispiel ist deMinMA als der Simple Moving Average der Reihe deMin definiert.
1 | |
1 | |
deMin wiederum ist in der Methode Calculate() als das Maximum der letzten beiden Tiefstkurswerte definiert.
1 | |
1 | |
Um die Arbeit mit verschachtelten Indikatoren zu vereinfachen, füllt IntelliSense automatisch die Liste aller integrierten Indikatoren auf, wenn Sie Indicators gefolgt von einem Punkt in den Code-Editor eingeben. Es werden auch alle zugehörigen Eingabeparameter angezeigt, sobald Sie einen bestimmten Indikator aus dieser Liste auswählen.

Lazy Loading
cTrader Algo verwendet Lazy Loading, wenn Sie referenzierte Indikatoren verwenden. Die vom referenzierten Indikator gelieferten Werte werden erst berechnet, wenn Ihr Code beginnt, sie aktiv zu verwenden.
Wenn Sie auf die Outputs-Daten eines referenzierten Indikators zugreifen, beginnt cTrader mit dem Laden der Indikatordaten, indem es seine Methode Calculate() auf vergangenen und zukünftigen Balken aufruft. In jedem anderen Fall bleibt der referenzierte Indikator inaktiv und verbraucht daher keine Systemressourcen.
Dies bedeutet auch, dass Sie den Standardwert der betreffenden Eigenschaft erhalten, wenn Ihr Indikator keine Output hat oder wenn Sie versuchen, auf eine seiner öffentlichen Eigenschaften zuzugreifen. Um dieses Problem zu lösen, rufen Sie die Methode Calculate() Ihres benutzerdefinierten Indikators aus der Methode Calculate() des aktuellen Indikators auf.
Oszillatoren und das Levels-Attribut
Der Begriff „Oszillatoren" umfasst alle Indikatoren, die um eine bestimmte konstante Variable oszillieren.
Beim Erstellen von Oszillatoren ist es nützlich, zuerst eine horizontale oder „Level"-Linie bei diesem konstanten Wert zu zeichnen; der Indikator oszilliert dann um diese Linie. In vielen Fällen entspricht der konstante Wert Null.
Im folgenden Beispiel definieren wir einen Momentum Oscillator. Er oszilliert typischerweise um den Wert 100. Wir fügen eine Level-Linie bei diesem Wert hinzu, indem wir das Attribut Levels verwenden, das vor den Indikatorattributen deklariert wird.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
Hinweis
Python-Indikatoren verwenden anpassbare Parameter, die in ihren .cs-Dateien deklariert werden.
1 2 3 4 | |
Beachten Sie, dass das Attribut Levels nur verwendet werden kann, wenn der Indikator nicht auf dem Chart überlagert ist, was bedeutet, dass die Eigenschaft IsOverlay nicht auf true gesetzt ist. Standardmäßig ist der Wert von IsOverlay false. Wenn dieses Attribut in Ihrem Code weggelassen wird, sollte Levels ordnungsgemäß funktionieren.
Wenn Sie mehrere „Level"-Linien einrichten müssen, fügen Sie eine durch Kommas getrennte Liste von Werten innerhalb der Klammern hinzu, wie unten dargestellt.
1 | |
1 | |
1 | |
Levels in Python-Indikatoren
In Python deklarieren Sie Levels in Ihrer Indikator-C#-Datei genauso wie bei C#-Indikatoren.
Die IsLastBar-Eigenschaft
In einigen Fällen möchten Sie möglicherweise einen Indikator erstellen, der nur für den letzten Balken im Handels-Chart berechnet werden muss. Vereinfacht ausgedrückt kann die Eigenschaft IsLastBar verwendet werden, um zu überprüfen, ob der Indexparameter der Methode Calculate() der des letzten Balkens ist.
Der folgende Indikator basiert auf der UTC-Zeit; er kann jedoch die letzte Eröffnungszeit in New York und Tokio anzeigen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
Indikatoren kombinieren
cTrader ermöglicht es, mehrere Indikatoren im selben Bereich oder innerhalb desselben Charts zu kombinieren.
Der folgende Indikator kombiniert die Indikatoren Aroon, RSI und Directional Movement System in einem.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | |
Hinweis
Python-Indikatoren verwenden anpassbare Parameter, die in ihren .cs-Dateien deklariert werden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Mehrere Zeitrahmen
-
Verwendung mehrerer Zeitrahmen
Das folgende Beispiel zeigt einen Moving-Average-Indikator auf verschiedenen Zeitrahmen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)] public class MultiTF_MA : Indicator { [Parameter(DefaultValue = 50)] public int Period { get; set; } [Output("MA", LineColor = "Yellow")] public IndicatorDataSeries MA { get; set; } [Output("MA5", LineColor = "Orange")] public IndicatorDataSeries MA5 { get; set; } [Output("MA10", LineColor = "Red")] public IndicatorDataSeries MA10 { get; set; } private Bars bars5; private Bars bars10; private MovingAverage ma; private MovingAverage ma5; private MovingAverage ma10; protected override void Initialize() { bars5 = MarketData.GetBars(TimeFrame.Minute5); bars10 = MarketData.GetBars(TimeFrame.Minute10); ma = Indicators.MovingAverage(Bars.ClosePrices, Period, MovingAverageType.Triangular); ma5 = Indicators.MovingAverage(bars5.ClosePrices, Period, MovingAverageType.Triangular); ma10 = Indicators.MovingAverage(bars10.ClosePrices, Period, MovingAverageType.Triangular); } public override void Calculate(int index) { MA[index] = ma.Result[index]; var index5 = bars5.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]); if (index5 != -1) MA5[index] = ma5.Result[index5]; var index10 = bars10.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]); if (index10 != -1) MA10[index] = ma10.Result[index10]; } }Hinweis
Python-Indikatoren verwenden anpassbare Parameter, die in ihren
.cs-Dateien deklariert sind.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
class MultiTF_MA(): def initialize(self): self.bars5 = api.MarketData.GetBars(TimeFrame.Minute5) self.bars10 = api.MarketData.GetBars(TimeFrame.Minute10) # Period is declared as a parameter in the C# file # We use indicator time frame bars for this moving average self.ma = Indicators.MovingAverage(api.Bars.ClosePrices, api.Period, MovingAverageType.Triangular) # We use other two time frame bars that we created previously # for these two moving averages self.ma5 = Indicators.MovingAverage(self.bars5.ClosePrices, api.Period, MovingAverageType.Triangular) self.ma10 = Indicators.MovingAverage(self.bars10.ClosePrices, api.Period, MovingAverageType.Triangular) def calculate(self, index): # MA, MA5, and MA10 are outputs we declared in the C# file api.MA[index] = self.ma.Result[index] index5 = self.bars5.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index]) if index5 > -1: api.MA5[index] = self.ma5.Result[index5] index10 = self.bars10.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index]) if index10 > -1: api.MA10[index] = self.ma10.Result[index10] -
Verwendung mehrerer Zeitrahmen und Symbole
Das folgende Beispiel zeigt den Moving-Average-Indikator auf mehreren Zeitrahmen und Symbolen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)] public class MultiSymbolMA : Indicator { private MovingAverage ma1, ma2, ma3; private Bars bars2, bars3; private Symbol symbol2, symbol3; [Parameter(DefaultValue = "EURCHF")] public string Symbol2 { get; set; } [Parameter(DefaultValue = "EURCAD")] public string Symbol3 { get; set; } [Parameter(DefaultValue = 14)] public int Period { get; set; } [Parameter(DefaultValue = MovingAverageType.Simple)] public MovingAverageType MaType { get; set; } [Output("MA Symbol 1", LineColor = "Magenta")] public IndicatorDataSeries Result1 { get; set; } [Output("MA Symbol 2", LineColor = "Magenta")] public IndicatorDataSeries Result2 { get; set; } [Output("MA Symbol 3", LineColor = "Magenta")] public IndicatorDataSeries Result3 { get; set; } protected override void Initialize() { symbol2 = Symbols.GetSymbol(Symbol2); symbol3 = Symbols.GetSymbol(Symbol3); bars2 = MarketData.GetBars(TimeFrame, symbol2.Name); bars3 = MarketData.GetBars(TimeFrame, symbol3.Name); ma1 = Indicators.MovingAverage(Bars.ClosePrices, Period, MaType); ma2 = Indicators.MovingAverage(bars2.ClosePrices, Period, MaType); ma3 = Indicators.MovingAverage(bars3.ClosePrices, Period, MaType); } public override void Calculate(int index) { ShowOutput(Symbol, Result1, ma1, Bars, index); ShowOutput(symbol2, Result2, ma2, bars2, index); ShowOutput(symbol3, Result3, ma3, bars3, index); } private void ShowOutput(Symbol symbol, IndicatorDataSeries result, MovingAverage movingAverage, Bars bars, int index) { var index2 = bars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]); result[index] = movingAverage.Result[index2]; string text = string.Format("{0} {1}", symbol.Name, Math.Round(result[index], symbol.Digits)); Chart.DrawStaticText(symbol.Name, text, VerticalAlignment.Top, HorizontalAlignment.Right, Color.Yellow); } }Hinweis
Python-Indikatoren verwenden anpassbare Parameter, die in ihren
.cs-Dateien deklariert sind.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
class MultiSymbolMA(): def initialize(self): # Symbol2 and Symbol3 are declared as parameters in the C# file self.symbol2 = api.Symbols.GetSymbol(api.Symbol2) self.symbol3 = api.Symbols.GetSymbol(api.Symbol3) self.bars2 = api.MarketData.GetBars(api.TimeFrame, self.symbol2.Name) self.bars3 = api.MarketData.GetBars(api.TimeFrame, self.symbol3.Name) self.ma1 = api.Indicators.MovingAverage(api.Bars.ClosePrices, api.Period, api.MaType) self.ma2 = api.Indicators.MovingAverage(self.bars2.ClosePrices, api.Period, api.MaType) self.ma3 = api.Indicators.MovingAverage(self.bars3.ClosePrices, api.Period, api.MaType) def calculate(self, index): # Result1, Result2, and Result3 are declared as outputs in the C# file self.show_output(api.Symbol, api.Result1, self.ma1, api.Bars, index) self.show_output(self.symbol2, api.Result2, self.ma2, self.bars2, index) self.show_output(self.symbol3, api.Result3, self.ma3, self.bars3, index) def show_output(self, symbol, result, movingAverage, bars, index): index2 = bars.OpenTimes.GetIndexByTime(api.Bars.OpenTimes[index]) result[index] = movingAverage.Result[index2] text = f"{symbol.Name} {round(result[index], symbol.Digits)}" api.Chart.DrawStaticText(symbol.Name, text, VerticalAlignment.Top, HorizontalAlignment.Right, Color.Yellow)
