
Neudefinition der Indikatoren von MQL5 und dem MetaTrader 5
Einführung
MQL5 ist nicht mehr eine einfache Programmiersprache, wie sie früher für die Erstellung einfacher Handelsroboter verwendet wurde. Die Sprache ist heutzutage ausgereift, man kann ziemlich viele Handelsprogramme von großer Komplexität erstellen, einsetzen und auf eine viel robustere und bequemere Weise testen.
Jeder von uns hat entweder die „nativen“ oder die „nutzerdefinierten Indikatoren“ zu irgendeinem Zeitpunkt auf seiner Handelsreise verwendet. MetaTrader5 verfügt über eine einfache Schnittstelle zum Laden und Anhängen des Indikators an das Chart. Dies ermöglicht es Händlern (vor allem manuellen Händlern), die Märkte mit Hilfe von Indikatoren in gewisser Weise zu analysieren.
Beim manuellen Handel muss man beispielsweise die Linie des gleitenden Durchschnittsindikators betrachten, um einen Trend zu erkennen, wenn man danach sucht. Beim algorithmischen Handel hingegen kann man nach einem positiven Trend suchen, der darauf basiert, ob der Schlusskurs über oder unter dem gleitenden Durchschnittswert liegt, der über eine bestimmte Anzahl von Balken berechnet wurde.
Wenn Sie beim algorithmischen Handel einen bestimmten Indikator verwenden möchten, z. B. einen einfachen gleitenden Durchschnitt (SMA) der Periode 20, müssen Sie dies tun:
int sma_handle; //Declare an indicator handle //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { sma_handle = iMA(Symbol(), Period(), 20, 0, MODE_SMA, PRICE_CLOSE); //Initialize the indicator inside the OnInit function //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- double sma_buffer[]; CopyBuffer(sma_handle, 0, 0, 1, sma_buffer); //Copy the indicator buffers inside the Ontick function }
Dieser Ansatz ist praktisch und funktioniert gut, aber es fühlt sich grob an und gibt uns nicht die Flexibilität und Kontrolle darüber, welche Informationen an den Indikator für unmittelbare Berechnungen übergeben werden können.
Auf der Grundlage dieses Ansatzes wird festgestellt, dass der Indikator Gleitender Durchschnitt (MA) nur auf eine der in der Dokumentation angegebenen Preiskonstanten angewendet werden soll.
ID | Beschreibung |
---|---|
PRICE_CLOSE | Schlusskurs |
PRICE_OPEN | Eröffnungspreis |
PRICE_HIGH | Der Höchstpreis für den Zeitraum |
PRICE_LOW | Der Tiefstpreis für den Zeitraum |
PRICE_MEDIAN | Medianpreis, (Hoch + Tief)/2 |
PRICE_TYPICAL | Typischer Preis, (Hoch + Tief + Schlusskurs)/3 |
PRICE_WEIGHTED | Durchschnittspreis, (Hoch + Tief + Schlusskurs + Schlusskurs)/4 |
Ganz zu schweigen davon, dass Sie auf die in den Dokumenten beschriebenen Glättungsmethoden/-techniken beschränkt sind.
ID | Beschreibung |
---|---|
MODE_SMA | Einfache Mittelwertbildung |
MODE_EMA | Exponentielle Mittelwertbildung |
MODE_SMMA | Geglättete Mittelwertbildung |
MODE_LWMA | Linear gewichtete Mittelwertbildung |
Was passiert, wenn Sie etwas Neues ausprobieren wollen? Wenn wir zum Beispiel den gleitenden Durchschnitt der Differenz zwischen Höchst- und Tiefstkursen berechnen wollen, ist das mit dem derzeitigen Ansatz nicht möglich, da die Möglichkeiten der Indikatoren eingeschränkt sind.
Ich verstehe, dass die meisten Indikatoren so sind, wie sie sind, weil sie mathematisch definiert und abgeleitet wurden, aber wäre es nicht großartig, wenn wir den Indikatoren verschiedene Eingaben und Parameter übergeben könnten, um neue Muster auf dem Markt zu beobachten?
Inspiriert von der Technical Analysis (TA-Lib) Python-Bibliothek, zielt dieser innovative Ansatz darauf ab, Händlern und Entwicklern von algorithmischen Systemen mehr Kontrolle darüber zu geben, welche Informationen dem Indikator für unmittelbare Berechnungen zugeführt werden.
In diesem Artikel werden wir einige Indikatoren (die am häufigsten verwendeten) mit diesem Plug-and-Play-Ansatz implementieren.
In Kategorien gruppiert.
Trend-Indikatoren
- Einfacher gleitender Durchschnittsindikator
- Exponentieller gleitender Durchschnittsindikator
- Bollinger Bänder
- Der parabolische SAR
- Standard Deviation
Oszillatoren
- Der gleitende Durchschnitt Konvergenz Divergenz (MACD)
- Relativer Streng-Index (RSI)
- Stochastische Oszillatoren
- Average True Range (ATR)
- Momentum-Indikator
Bill Williams
- Accelerator Oszillator
- Der Awesome Oszillator
Einfacher gleitender Durchschnitt (SMA) Indikator
Dies ist einer der am häufigsten verwendeten technischen Indikatoren. Er berechnet den Durchschnitt einer Kursreihe über einen bestimmten Zeitraum.
Gegeben durch die Formel.
wobei:
sind Preise (z.B. Schlusskurse) über den Zeitraum
.
ist die Periodenlänge des SMA.
Wir können diese Formel leicht in eine vektorisierte Funktion umsetzen.
Datei: ta-lib.mqh
vector CTrendIndicators::SMA(const vector &price, uint period, uint shift = 0) { uint size = (uint)price.Size(); if(!CheckShiftPeriod(size, period, shift)) return price; //--- vector ma(size); ma.Fill(NaN); for(uint i = shift + period - 1; i < size; i++) //Loop through all the prices considering the period and shift { double sum = 0; for(uint j = i - period + 1; j <= i; j++) sum += price[j]; //sum of the prices ma[i] = sum / period; //divided by period to find the mean of that period } return ma; }
Dies ist, wie ein Indikator, der einfache, gleitende Durchschnitt, berechnet wird, ohne Puffer, ohne Überprüfung auf MQL5-Fehler beim Laden des Indikators für ein bestimmtes Symbol, etc., was lästig werden könnte.
Bei diesem minimalistischen Ansatz wird nur geprüft, ob die Werte shift (Verschiebung) und period (Periodenlänge) korrekt sind. Ist dies der Fall, fährt die Funktion mit der Berechnung der Indikatoren fort und gibt die berechneten Werte in Vektorform zurück. Ich habe mich für das Vektorformat entschieden, um mehr Kontrolle und Flexibilität über das Endergebnis zu erhalten.
Da alle Funktionen in unseren Indicators-Klassen statisch sind, können wir in unseren MQL5-Programmen leicht auf die Indikatorwerte zugreifen, zum Beispiel in einem einfachen Skript.
Datei: Testskript für nutzerdefinierte Indikatoren.mq5
#include <ta-lib.mqh> //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { vector prices = {1,2,3,4,5,6,7,8,9,10}; int period = 3; Print("SMA values: ", CTrendIndicators::SMA(prices, period)); }
Ausgabe:
2025.01.21 09:57:35.727 Custom Indicators test script (EURUSD,H1) SMA values: [nan,nan,2,3,4,5,6,7,8,9]
Auf diese Weise konnten wir den einfachen gleitenden Durchschnitt anhand eines Vektors einiger Werte berechnen. Wir werden später besprechen, wie diese Werte für einen visuellen Indikator dargestellt werden können.
Exponentieller gleitender Durchschnitt (EMA) Indikator
Der EMA wird wie der SMA als Durchschnitt einer Preisreihe über eine bestimmte Anzahl von Perioden berechnet, wobei jedoch die jüngsten Preise stärker berücksichtigt werden, sodass er im Vergleich zum einfachen gleitenden Durchschnitt (SMA) besser auf Preisänderungen reagiert.
Gegeben durch die Formel.
wobei:
der EMA zum Zeitpunkt t.
der Preis zum Zeitpunkt t.
der EMA der vorangegangenen Periode.
der Glättungsfaktor (wobei n die Periodenlänge ist)
Wir können es in MQL5 wie folgt implementieren;
Datei: ta-lib.mqh
vector CTrendIndicators::EMA(const vector &price, uint period, uint shift = 0) { uint size = (uint)price.Size(); if(!CheckShiftPeriod(size, period, shift)) return price; //--- double alpha = 2.0 / (period + 1.0); // Smoothing factor vector res(size); res.Fill(NaN); // Initialize the EMA with the SMA of the first period vector sma = SMA(price, period, shift); res[period - 1 + shift] = sma[period - 1 + shift]; // Calculate EMA for the rest of the prices for(ulong i = period + shift; i < size; i++) res[i] = alpha * price[i] + (1 - alpha) * res[i - 1]; return res; }
Wir können die berechneten Indikatorwerte ähnlich wie beim SMA erhalten.
Datei: Testskript für nutzerdefinierte Indikatoren.mq5
void OnStart() { vector prices = {1,2,3,4,5,6,7,8,9,10}; int period = 3; Print("EMA values: ", CTrendIndicators::EMA(prices, period)); }
Ausgabe:
2025.01.21 10:19:54.291 Custom Indicators test script (EURUSD,H1) EMA values: [nan,nan,2,3,4,5,6,7,8,9]
Wir haben den einfachen gleitenden Durchschnitt (SMA) und den exponentiellen gleitenden Durchschnitt (EMA) separat berechnet, im Gegensatz zur Berechnung im integrierten IMA-Indikator, der eine Option für die von Ihnen bevorzugte Glättungsmethode bietet.
Dieser getrennte Ansatz erfordert das Schreiben zusätzlicher Codezeilen, um alle Glättungsmethoden der Indikatoren des gleitenden Durchschnitts zu implementieren.
Funktionen für Glättungsmethoden wie MODE_SMMA (geglättete Mittelwertbildung) und (MODE_LWMA) linear gewichtete Mittelwertbildung müssen noch in die Bibliothek aufgenommen werden, da sie meiner Meinung nach nicht so häufig verwendet werden wie ihre Gegenstücke (die Glättungsmethoden SMA und EMA).
Der Bollinger-Bänder-Indikator
Dies ist ein Volatilitätsindikator, der aus drei Bändern besteht.
- Das mittlere Band ist ein einfacher gleitender Durchschnitt (SMA) der Schlusskurse über einen bestimmten Zeitraum.
- Das obere Band ist das mittlere Band plus ein Vielfaches der Standardabweichung der Schlusskurse im gleichen Zeitraum.
- Das untere Band ist das mittlere Band abzüglich eines Vielfachen der Standardabweichung der Schlusskurse im gleichen Zeitraum.
wobei:
typischerweise 2 (die Standardeinstellung für Bollinger Bänder)
Die Periodenlänge für die Berechnung von SMA und Standardabweichung.
Da dieser Indikator drei (3) eindimensionale (1D) Werte zurückgeben muss, die als Puffer bekannt sind, wenn Sie den integrierten Bollinger-Bänder-Indikator verwenden, lassen Sie diese Funktion eine Struktur von 3 Vektoren zurückgeben.
Datei: ta-lib.mqh
struct BB_res_struct { vector upper_band; vector lower_band; vector middle_band; };
BB_res_struct CTrendIndicators::BollingerBands(const vector &price, uint period, uint shift = 0, double k = 2.0) { uint size = (uint)price.Size(); BB_res_struct res; //--- Check for valid parameters if(!CheckShiftPeriod(size, period, shift)) return res; //--- Initialize vectors res.upper_band.Resize(size); res.lower_band.Resize(size); res.upper_band.Fill(NaN); res.lower_band.Fill(NaN); //--- Calculate the middle band (SMA) res.middle_band = SMA(price, period, shift); //--- Calculate the upper and lower bands for(uint i = shift + period - 1; i < size; i++) { double sum_squared_diff = 0; for(uint j = i - period + 1; j <= i; j++) { sum_squared_diff += MathPow(price[j] - res.middle_band[i], 2); } double std_dev = MathSqrt(sum_squared_diff / period); res.upper_band[i] = res.middle_band[i] + (k * std_dev); res.lower_band[i] = res.middle_band[i] - (k * std_dev); } return res; }
Im Folgenden erfahren Sie, wie Sie den Bollinger-Bänder-Indikator einfach implementieren und seine Werte erhalten.
Datei: Testskript für nutzerdefinierte Indikatoren.mq5
void OnStart() { vector prices = {1,2,3,4,5,6,7,8,9,10}; int period = 3; BB_res_struct bb; bb = CTrendIndicators::BollingerBands(prices,period,0,2); Print("BB upper: ",bb.upper_band); Print("BB middle: ",bb.middle_band); Print("BB lower: ",bb.lower_band); }
Ausgabe:
RL 0 11:39:21.000 Custom Indicators test script (EURUSD,H1) BB upper: [nan,nan,3.632993161855452,4.632993161855453,5.632993161855453,6.632993161855453,7.632993161855453,8.632993161855453,9.632993161855453,10.63299316185545] RO 0 11:39:21.000 Custom Indicators test script (EURUSD,H1) BB middle: [nan,nan,2,3,4,5,6,7,8,9] FF 0 11:39:21.000 Custom Indicators test script (EURUSD,H1) BB lower: [nan,nan,0.3670068381445479,1.367006838144548,2.367006838144548,3.367006838144548,4.367006838144547,5.367006838144547,6.367006838144547,7.367006838144547]
Der parabolische SAR (Stop and Reverse)
Es handelt sich dabei um einen Trendfolgeindikator, der dazu dient, potenzielle Umschwünge auf dem Markt zu erkennen. Er platziert die Punkte je nach Trendrichtung über oder unter dem Preis.
Gegeben durch die Formel.
Bei einem Aufwärtstrend
Bei einem Abwärtstrend
wobei:
= der SAR-Wert für den nächsten Zeitraum
= Beschleunigungsfaktor (beginnt mit einem Standardwert, z. B. 0,02, und erhöht sich bei jedem neuen Höchst-/Tiefstwert um 0,02. Bis zu einem Höchstwert von 0,2)
= Extrempunkt (höchstes Hoch in einem Aufwärtstrend, tiefstes Tief in einem Abwärtstrend)
Dieser Indikator kann wie folgt in MQL5 implementiert werden.
Datei: ta-lib.mqh
vector CTrendIndicators::ParabolicSAR(const vector &high, const vector &low, const vector &close, double step = 0.02, double max = 0.2) { uint size = (uint)close.Size(); vector psar(size); psar.Fill(NaN); // Initialize variables double AF = step; // Acceleration Factor double EP = high[0]; // Extreme Point double SAR = low[0]; // Initial SAR bool isUptrend = true; // Assume uptrend at the start // Calculate Parabolic SAR for(uint i = 0; i < size; i++) { // Update SAR if(isUptrend) SAR = SAR + AF * (EP - SAR); else SAR = SAR + AF * (SAR - EP); // Determine if trend changes if(isUptrend && SAR > low[i]) { // Switch to downtrend isUptrend = false; SAR = EP; // Reset SAR to the most recent EP EP = low[i]; // Reset EP AF = step; // Reset AF } else if(!isUptrend && SAR < high[i]) { // Switch to uptrend isUptrend = true; SAR = EP; // Reset SAR to the most recent EP EP = high[i]; // Reset EP AF = step; // Reset AF } // Update EP and AF if(isUptrend) { if(high[i] > EP) { EP = high[i]; AF = MathMin(AF + step, max); } } else { if(low[i] < EP) { EP = low[i]; AF = MathMin(AF + step, max); } } // Store the SAR value psar[i] = SAR; } return psar; }
Im Gegensatz zu den beiden vorangegangenen Trendfolgeindikatoren, die einen einzigen Vektor als Preisinput erhalten können, berücksichtigt der parabolische SAR drei (3) Preiswerte (Hoch-, Tief- und Schlusskurs).
Datei: Testskript für nutzerdefinierte Indikatoren.mq5
void OnStart() { vector close = {1,2,3,4,5,6,7,8,9,10}; vector high = {1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5}; vector low = {0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5}; Print("Parabolic SAR values: ", CTrendIndicators::ParabolicSAR(high,low,close,0.02,0.2)); }
Ausgabe:
2025.01.21 11:11:03.525 Custom Indicators test script (EURUSD,H1) Parabolic SAR values: [1.5,0.5,0.54,0.6584000000000001,0.8888960000000001,1.25778432,1.782005888,2.46816518144,3.3126220560384,4.302602527072256]
Der Indikator für die Standardabweichung
Dieser Indikator misst die Schwankung oder Streuung des Preises von seinem Mittelwert. Dieser Indikator wird häufig zur Bewertung der Marktvolatilität verwendet.
Ein hoher Wert der Standardabweichung weist auf eine hohe Volatilität hin, während ein niedriger Wert der Standardabweichung auf eine geringe Volatilität hindeutet.
Gegeben durch die Formel.
wobei:
= Standardabweichung
n = Zeitraum
= Preispunkt
= Mittelwert der Datenpunkte
Wir können diesen Indikator in MQL5 wie folgt implementieren;
Datei: ta-lib.mqh
vector CTrendIndicators::StandardDeviation(const vector &price, uint period, uint shift = 0) { uint size = (uint)price.Size(); // Check if the period and shift are valid if(!CheckShiftPeriod(size, period, shift)) return price; // Initialize standard deviation vector vector std_dev(size); std_dev.Fill(NaN); // Loop through the price data for(uint i = shift + period - 1; i < size; i++) { double sum = 0.0; double sum_sq_diff = 0.0; // Calculate mean for(uint j = i - period + 1; j <= i; j++) sum += price[j]; double mean = sum / period; // Calculate squared differences for(uint j = i - period + 1; j <= i; j++) sum_sq_diff += MathPow(price[j] - mean, 2); // Calculate standard deviation std_dev[i] = MathSqrt(sum_sq_diff / period); } return std_dev; }
Dies ist ein weiterer einfacher Indikator, der wie folgt aufgerufen werden kann.
Datei: Testskript für nutzerdefinierte Indikatoren.mq5
void OnStart() { vector prices = {1,2,3,4,5,6,7,8,9,10}; int period = 3; Print("Stddev values: ", CTrendIndicators::StandardDeviation(prices, period)); }
Ausgabe:
2025.01.21 11:55:11.657 Custom Indicators test script (EURUSD,H1) Stddev values: [nan,nan,0.816496580927726,0.816496580927726,0.816496580927726,0.816496580927726,0.816496580927726,0.816496580927726,0.816496580927726,0.816496580927726]
Der gleitende Durchschnitt Konvergenz Divergenz (MACD)
Dieser Oszillator zeigt die Beziehungen zwischen zwei gleitenden Durchschnitten des Kurses eines Wertpapiers an. Sie wird häufig als Instrument der technischen Analyse verwendet.
Gegeben durch die Formel.
MACD Hauptlinie
wobei:
= Exponentieller gleitender Durchschnitt mit einer kürzeren Periode (z. B. 12)
= Exponentieller gleitender Durchschnitt mit einer längeren Periode (z. B. 26)
Signallinie
Dies ist ein geglätteter EMA der MACD-Linie, normalerweise mit einem Periodenwert von 9
Macd-Histogramm
Dies ist der Unterschied zwischen der MACD-Linie und der Signallinie.
Ähnlich wie wir mehrere berechnete Bollinger-Bänder zurückgegeben haben, definieren wir eine Struktur für die Rückgabe der MACD-Histogramm-, Haupt- und Signallinienwerte.
Datei: ta-lib.mqh
struct MACD_res_struct { vector main; // The MACD Line vector signal; // The Signal Line vector histogram; // The MACD Histogram };
MACD_res_struct COscillatorIndicators::MACD(const vector &price, uint fast_ema = 12, uint slow_ema = 26, uint macd_sma = 9, uint shift = 0) { uint size = (uint)price.Size(); MACD_res_struct res; if(!CheckShiftPeriod(size, slow_ema, shift)) return res; //--- Calculate EMA(short), EMA(long), and MACD Line vector fast_ema_vector = CTrendIndicators::EMA(price, fast_ema, shift); vector slow_ema_vector = CTrendIndicators::EMA(price, slow_ema, shift); res.main.Resize(size); res.main.Fill(NaN); for(uint i = 0; i < size; i++) res.main[i] = fast_ema_vector[i] - slow_ema_vector[i]; //--- Calculate Signal Line (SMA of MACD Line) res.signal = CTrendIndicators::SMA(price, macd_sma, shift); //--- Calculate MACD Histogram res.histogram.Resize(size); res.histogram.Fill(NaN); for(uint i = 0; i < size; i++) res.histogram[i] = res.main[i] - res.signal[i]; return res; }
Wir können die vom MACD-Oszillator berechneten Werte ganz einfach in einem Testskript wie folgt erhalten.
Datei: Testskript für nutzerdefinierte Indikatoren.mq5
void OnStart() { vector prices = {1,2,3,4,5,6,7,8,9,10}; MACD_res_struct macd; macd = COscillatorIndicators::MACD(prices,2,3,4); Print("MACD main: ", macd.main); Print("MACD signal: ", macd.signal); }
Ausgabe:
RD 0 12:28:51.368 Custom Indicators test script (EURUSD,H1) MACD main: [nan,nan,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5] HO 0 12:28:51.368 Custom Indicators test script (EURUSD,H1) MACD signal: [nan,nan,nan,2.5,3.5,4.5,5.5,6.5,7.5,8.5]
Der Relative-Stärke-Indikator (RSI)
Es handelt sich um einen Momentum-Oszillator, der die Geschwindigkeit und das Ausmaß von Kursbewegungen misst. Er schwankt zwischen 0 und 100. Händler nutzen ihn, um überkaufte und überverkaufte Marktbedingungen zu erkennen.
Die Berechnung des RSI-Indikators erfolgt in folgenden Schritten;
01: Ermittlung der durchschnittlichen Gewinne und der durchschnittlichen Verluste über einen bestimmten Zeitraum
02: Berechnung der relativen Stärke (RS)
03: Berechnung des RSI
MQL5-Implementierung
vector COscillatorIndicators::RSI(const vector &price, uint period, uint shift = 0) { uint size = (uint)price.Size(); //--- Check for valid parameters if(!CheckShiftPeriod(size, period, shift)) return price; //--- Initialize vectors vector rsi(size), gains(size), losses(size); rsi.Fill(NaN); gains.Fill(0.0); losses.Fill(0.0); //--- Calculate gains and losses for(uint i = shift + 1; i < size; i++) { double change = price[i] - price[i - 1]; gains[i] = (change > 0) ? change : 0; losses[i] = (change < 0) ? -change : 0; } //--- Initialize first average gain and loss (simple average for the first period) double avg_gain = 0, avg_loss = 0; for(uint i = shift + 1; i < shift + 1 + period; i++) { avg_gain += gains[i]; avg_loss += losses[i]; } avg_gain /= period; avg_loss /= period; //--- Compute RSI for the rest of the periods for(uint i = shift + period; i < size; i++) { // Apply smoothing for average gain and loss avg_gain = ((avg_gain * (period - 1)) + gains[i]) / period; avg_loss = ((avg_loss * (period - 1)) + losses[i]) / period; // Calculate RSI double rs = (avg_loss == 0) ? 0 : avg_gain / avg_loss; rsi[i] = (avg_loss == 0) ? 100 : (100 - (100 / (1 + rs))); } return rsi; }
Nachfolgend erfahren Sie, wie Sie die Werte des RSI-Indikators erhalten können.
void OnStart() { vector prices = {1,2,3,4,5,6,7,8,9,10}; int period = 3; Print("RSI values: ", COscillatorIndicators::RSI(prices,period)); }
Ausgabe:
2025.01.21 12:51:29.640 Custom Indicators test script (EURUSD,H1) RSI values: [nan,nan,nan,100,100,100,100,100,100,100]
Der Stochastik Oszillator Indikator
Dies ist ein Momentum-Indikator, der den Schlusskurs eines Wertpapiers mit seiner Preisspanne über einen bestimmten Zeitraum vergleicht.
Die Formel zur Berechnung dieses Indikators lautet wie folgt;
%K-Linie
Wobei
ist der aktuelle Schlusskurs
ist der niedrigste Preis im Rückblickszeitraum
ist der höchste Preis im Rückblickszeitraum
%D-Linie
Dies ist der gleitende Durchschnitt der %K-Linie, wobei in der Regel ein einfacher gleitender 3-Perioden-Durchschnitt (SMA) verwendet wird.
Im Folgenden wird beschrieben, wie Sie diesen Indikator in MQL5 implementieren.
Stochastic_struct COscillatorIndicators::StochasticOscillator(const vector &high, const vector &low, const vector &close, uint k_period = 5, uint d_period = 3, uint period = 3, uint shift = 0) { uint size = (uint)close.Size(); Stochastic_struct res; // Check for valid parameters if(!CheckShiftPeriod(size, period, shift)) return res; // Initialize vectors for %K and %D vector K(size), D(size); K.Fill(NaN); D.Fill(NaN); // Calculate %K for(uint i = shift + period - 1; i < size; i++) { double H_max = -DBL_MAX, L_min = DBL_MAX; // Find the highest high and the lowest low over the lookback period for(uint j = i - period + 1; j <= i; j++) { H_max = MathMax(H_max, high[j]); L_min = MathMin(L_min, low[j]); } // Calculate %K double K_value = (H_max - L_min != 0) ? ((close[i] - L_min) / (H_max - L_min)) * 100 : 0; K[i] = K_value; } // Smooth %K with a simple moving average (k_period) vector smoothedK(size); smoothedK.Fill(NaN); for(uint i = shift + k_period - 1; i < size; i++) { double sum = 0; for(uint j = i - k_period + 1; j <= i; j++) { sum += K[j]; } smoothedK[i] = sum / k_period; } // Calculate %D (3-period moving average of %K) D = CTrendIndicators::SMA(smoothedK, period, shift); res.main = K; res.signal = D; return res; }
Wir geben das Signal und die Hauptleitung in einer Struktur zurück.
void OnStart() { vector close = {1,2,3,4,5,6,7,8,9,10}; vector high = {1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5}; vector low = {0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5}; Stochastic_struct stoch; stoch = COscillatorIndicators::StochasticOscillator(high,low,close,5,3,3); Print("Stoch main: ", stoch.main); Print("Stoch signal: ", stoch.signal); }
Der Indikator Average True Range (ATR)
Dies ist ein nützlicher Indikator für das Verständnis der Marktvolatilität. Er misst die durchschnittliche Spanne zwischen Höchst- und Tiefstpreisen über einen bestimmten Zeitraum.
Gegeben durch die Formel.
01: Berechnen des True Range (TR)
Wobei
H ist das aktuelle Hoch.
ist das aktuelle Tief.
ist der vorherige Schlusskurs.
02: Berechnung der Average True Range (ATR)
ATR ist der gleitende Durchschnitt der tatsächlichen Spanne über einen bestimmten Zeitraum.
SMA ist der einfache gleitende Durchschnitt.
Wir können diesen Indikator in MQL5 wie folgt implementieren.
vector COscillatorIndicators::ATR(const vector &high, const vector &low, const vector &close, uint period = 14, uint shift = 0) { uint size = (uint)close.Size(); // Check for valid parameters if(!CheckShiftPeriod(size, period, shift)) return close; // Initialize the True Range (TR) and ATR vectors vector TR(size); TR.Fill(NaN); // Calculate the True Range for each period for(uint i = shift + 1; i < size; i++) { double H = high[i]; double L = low[i]; double C_prev = close[i - 1]; // Calculate the three possible True Range values double TR1 = H - L; double TR2 = MathAbs(H - C_prev); double TR3 = MathAbs(L - C_prev); // True Range is the maximum of the three TR[i] = MathMax(TR1, MathMax(TR2, TR3)); } //--- Smooth the True Range using a simple moving average (SMA) over the specified period return CTrendIndicators::SMA(TR, period, shift); }
Im Folgenden erfahren Sie, wie Sie die Werte für diesen Indikator erhalten können.
void OnStart() { vector close = {1,2,3,4,5,6,7,8,9,10}; vector high = {1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5}; vector low = {0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5}; Print("ATR values: ", COscillatorIndicators::ATR(high,low,close,3)); }
Ausgabe:
2025.01.21 13:57:59.943 Custom Indicators test script (EURUSD,H1) ATR values: [nan,nan,nan,1.5,1.5,1.5,1.5,1.5,1.5,1.5]
Der Momentum-Indikator
Dies ist ein einfacher Indikator zur Messung der Geschwindigkeit, mit der sich der Preis eines Vermögenswerts in einem bestimmten Zeitraum bewegt. Er hilft, Trends und eine potenzielle Trendumkehr zu erkennen.
Er ist gegeben durch eine einfache Formel.
Wobei
Momentum(t) = Momentumwert zum Zeitpunkt t
Preis(t) = der aktuelle Preis
Preis(t - n) = Preis von vor n Perioden
n = die Periode, über die das Momentum berechnet wird
Einige Varianten zur Berechnung des Momentums verwenden ein Verhältnis.
Wir werden den Momentum-Indikator in dieser Variante implementieren.
MQL5-Implementierung
vector COscillatorIndicators::MomentumIndicator(const vector &price, uint period, uint shift = 0) { uint size = (uint)price.Size(); // Check for valid input if(!CheckShiftPeriod(size, period, shift)) return price; // Initialize the momentum vector vector momentum(size); momentum.Fill(NaN); // Calculate Momentum for(uint i = shift + period; i < size; i++) { //momentum[i] = price[i] - price[i - period]; // Momentum difference formula // using the ratio formula: momentum[i] = (price[i] / price[i - period]) * 100; } return momentum; }
Fantastischer Oszillator-Indikator
Es handelt sich um einen Momentum-Indikator, der die Differenz zwischen zwei einfachen gleitenden Durchschnitten (SMAs) des Medianpreises berechnet.
Er ist gegeben durch die Formel:
Wobei
= SMA mit der kürzerer Periodenlänge (üblicherweise 5)
= SMA mit der längeren Periodenlänge (üblicherweise 34)
Im Folgenden wird die MQL5-Implementierung dargestellt.
vector CBillWilliamsIndicators::AwesomeOscillator(const vector &high, const vector &low, uint fast_period = 5, uint slow_period = 34, uint shift = 0) { uint size = (uint)high.Size(); if(size != low.Size()) return vector::Zeros(0); // Ensure high and low vectors are of the same size if(!CheckShiftPeriod(size, slow_period, shift)) return vector::Zeros(0); // Validate shift and slow period // Initialize vectors vector ao(size), median_price(size); ao.Fill(NaN); median_price.Fill(NaN); // Calculate Median Price for(uint i = 0; i < size; i++) median_price[i] = (high[i] + low[i]) / 2; // Calculate Fast and Slow SMAs of the Median Price vector sma_fast = CTrendIndicators::SMA(median_price, fast_period, shift); vector sma_slow = CTrendIndicators::SMA(median_price, slow_period, shift); // Calculate AO for(uint i = 0; i < size; i++) ao[i] = sma_fast[i] - sma_slow[i]; return ao; }
Da wir sehr einfache Vektoren für die Hochs und Tiefs haben, können wir die kurze Periodenlänge auf 3 und die lange Periode auf 5 setzen.
void OnStart() { vector close = {1,2,3,4,5,6,7,8,9,10}; vector high = {1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5}; vector low = {0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5}; Print("AO values: ", CBillWilliamsIndicators::AwesomeOscillator(high,low,3,5)); }
Ausgabe.
2025.01.21 14:25:50.590 Custom Indicators test script (EURUSD,H1) AO values: [nan,nan,nan,nan,1,1,1,1,1,1]
Der Indikator Accelerator Oscillator
Der Accelerator Oscillator (AC) ist ein technisches Analysewerkzeug, das die Geschwindigkeit der Veränderungen des Kursmomentums verfolgt. Er zeigt an, ob sich die treibende Kraft des Marktes beschleunigt oder verlangsamt und hilft Händlern, potenzielle Umschwünge zu antizipieren.
Er wird als Differenz zwischen dem Awesome Oscillator und dem einfachen gleitenden 5-Perioden-Durchschnitt (SMA) des AO berechnet.
Gegeben durch die folgende Formel.

Wir können diesen Indikator in MQL5 wie folgt implementieren.
vector CBillWilliamsIndicators::AcceleratorOscillator(const vector &high, const vector &low, uint ao_period_fast = 5, // Fast period for AO uint ao_period_slow = 34, // Slow period for AO uint ac_period = 5 // Period for AC SMA ) { uint size = (uint)high.Size(); if(size != low.Size()) return vector::Zeros(0); // Ensure high and low vectors are of the same size // Validate shift and period if(!CheckShiftPeriod(size, ao_period_slow, 0)) return vector::Zeros(0); // Calculate AO (Awesome Oscillator) vector ao = AwesomeOscillator(high, low, ao_period_fast, ao_period_slow); // Calculate AC (Accelerator Oscillator) vector ac(size); ac.Fill(NaN); vector ao_sma_ac = CTrendIndicators::SMA(ao, ac_period); for(uint i = 0; i < size; i++) ac[i] = ao[i] - ao_sma_ac[i]; return ac; }
Da der Accelerator Oscillator dem Awesome Oscillator sehr ähnlich ist, können wir seine Funktion mit ähnlichen Argumenten aufrufen.
void OnStart() { vector close = {1,2,3,4,5,6,7,8,9,10}; vector high = {1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5,10.5}; vector low = {0.5,1.5,2.5,3.5,4.5,5.5,6.5,7.5,8.5,9.5}; //--- Bill williams indicator Print("AO values: ", CBillWilliamsIndicators::AwesomeOscillator(high,low,3,5)); Print("AC values: ", CBillWilliamsIndicators::AcceleratorOscillator(high,low,3,5)); }
Ausgabe:
MQ 0 14:40:36.296 Custom Indicators test script (EURUSD,H1) AO values: [nan,nan,nan,nan,1,1,1,1,1,1] EL 0 14:40:36.296 Custom Indicators test script (EURUSD,H1) AC values: [nan,nan,nan,nan,nan,nan,nan,nan,0,0]
Vereinfachte Datenerhebung der Indikatoren
Nachdem wir nun gesehen haben, wie einige der Indikatoren in der Bibliothek implementiert wurden, können wir versuchen, alle Informationen, die wir vom Markt erhalten möchten, zu sammeln und darauf einen Indikator aufzubauen. Ich werde zum Beispiel den gleitenden Durchschnitt für Eröffnungs-, Höchst-, Tiefst- und Schlusskurs berechnen.
Wir beginnen mit der Ermittlung der OHLC-Werte.
int size = 1000; vector open, high, low, close; open.CopyRates(Symbol(), Period(), COPY_RATES_OPEN, 1, size); high.CopyRates(Symbol(), Period(), COPY_RATES_HIGH, 1, size); low.CopyRates(Symbol(), Period(), COPY_RATES_LOW, 1, size); close.CopyRates(Symbol(), Period(), COPY_RATES_CLOSE, 1, size);
Beginnend mit dem einfachen gleitenden Durchschnitt der Periode 20, angewandt auf die Eröffnungskurse.
vector sma_open = CTrendIndicators::SMA(open, 20);
Wir können mühelos verschiedene SMA-Indikatoren für einen anderen Zeitraum und einen anderen Preis sammeln.
vector sma_open = CTrendIndicators::SMA(open, 20); vector sma_high = CTrendIndicators::SMA(high, 50); vector sma_low = CTrendIndicators::SMA(low, 100); vector sma_close = CTrendIndicators::SMA(close, 20);
Wir sollten sie stattdessen in eine Matrix einfügen und sie gemeinsam betrachten.
matrix Indicators(size, 4); Indicators.Col(CTrendIndicators::SMA(open, 20), 0); Indicators.Col(CTrendIndicators::SMA(high, 50), 1); Indicators.Col(CTrendIndicators::SMA(low, 100), 2); Indicators.Col(CTrendIndicators::SMA(close, 20), 3); Print("Indicators matrix\n",Indicators);
Ausgabe:
NK 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0485715,1.0484514,nan,1.048488] LL 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0484425,1.0485544,nan,1.0484265] RP 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.048381,1.0486754,nan,1.048299] QG 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0483055,1.0488004,nan,1.048152] KK 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0481585,1.0489198,nan,1.048296] HL 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.048303,1.049033,nan,1.0485255] DS 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.048533,1.0491756,nan,1.0487015] OK 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.048658,1.0493158,1.0475226,1.0488295] KD 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0487895,1.0494628,1.047473,1.0488985] JR 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0488575,1.0494916,1.0474256,1.0489465] FR 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0489055,1.049475,1.0473723,1.0490045] LL 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.048964,1.0494814,1.0473137,1.049052] HK 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0490075,1.0494728,1.0472494,1.0491065] CF 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.049062,1.0494618,1.0471845,1.049044] RE 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0489995,1.0494452,1.047114,1.048892] FQ 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.048848,1.0494558,1.047044,1.0487065] CL 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0486625,1.0495002,1.0469762,1.0486305] DK 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.048586,1.0496014,1.0469234,1.048582] EE 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0485375,1.0496714,1.0468866,1.048646] RE 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0486015,1.0497982,1.046857200000001,1.04877] IP 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0487245,1.0498646,1.0468378,1.0490025] DO 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0489565,1.0499466,1.046833500000001,1.0492415] GN 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0491975,1.050113,1.046846700000001,1.0497525] CK 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0497085,1.0502838,1.046881000000001,1.0502025] IJ 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.050159,1.0503826,1.046898100000001,1.0506915] PF 0 18:30:25.100 Custom Indicators test script (EURUSD,H1) [1.0506475,1.0504916,1.046935200000001,1.051158…]
Nehmen wir an, ich möchte die Dynamik dieser Variablen messen, indem ich einen Momentum-Indikator auf der Grundlage dieser Variablen erstelle.
Indicators.Col(COscillatorIndicators::MomentumIndicator(open, 20), 4); Indicators.Col(COscillatorIndicators::MomentumIndicator(high, 50), 5); Indicators.Col(COscillatorIndicators::MomentumIndicator(low, 100), 6); Indicators.Col(COscillatorIndicators::MomentumIndicator(close, 20), 7);
Ausgabe:
IN 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.0441885,nan,nan,1.0438975,99.43679181343492,nan,nan,99.44502817843157] LN 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.0438975,1.0495116,nan,1.043593,99.44407828753189,nan,nan,99.41864350150351] QS 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.0435925,1.0492638,nan,1.0433225,99.4176888931316,98.82473464044848,nan,99.4833645288208] HG 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.0436275,1.049148199999999,nan,1.043363,100.0668474731655,99.45161810609009,nan,100.0773424743863] EH 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.0436685,1.0490618,nan,1.043385,100.0782973197491,99.59030385797199,nan,100.0420047732697] KO 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.0436925,1.0489454,nan,1.0434175,100.0458251389074,99.4479854313681,nan,100.0620536907626] JQ 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.0437225,1.048834,nan,1.043484,100.0572803299347,99.47183265534476,nan,100.1270939444036] JE 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.043788,1.048718,nan,1.0435725,100.1251839535195,99.45010144680205,nan,100.1690625149243] LE 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.043877,1.048595199999999,nan,1.0435315,100.1700192943244,99.41799844546816,nan,99.92180198737388] MI 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.0438365,1.048457,nan,1.0437085,99.92275488503829,99.34503611305946,nan,100.3389538390831] HN 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.044013,1.0483164,nan,1.044095,100.3379931060896,99.33386396801032,nan,100.7431263218612] KS 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.0443985,1.048186,nan,1.044364,100.7411964891704,99.38227742565063,nan,100.5158345877638] EE 0 18:39:34.172 Custom Indicators test script (EURUSD,H1) [1.0446665,1.0480502,nan,1.044532,100.5139219145509,99.35649569733499,nan,100.3225558712848…]
Mit nutzerdefinierten Funktionen die erstellte Indikatoren darstellen
Wir wollen nun versuchen, die aus dieser Bibliothek gewonnenen Indikatorberechnungen für das menschliche Auge sichtbar zu machen.
Obwohl dieser Ansatz eher auf die Datenerfassung als auf die Visualisierung abzielt, wollen wir die Berechnungen des Indikators in einem nutzerdefinierten MetaTrader 5 Indikator visualisieren.
Visualisierung des SMA (20) Indikators.
#property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_color1 clrDodgerBlue #property indicator_type1 DRAW_LINE #property indicator_style1 STYLE_SOLID #include <ta-lib.mqh> input int period_ = 20; //SMA period double buffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0, buffer, INDICATOR_DATA); PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0); PlotIndexSetString(0,PLOT_LABEL,"SMA("+string(period_)+")"); PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,period_+1); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- if (prev_calculated==0) //Initial indicator calculation, For Plotting the entire past { vector buffer_vector = CTrendIndicators::SMA(close, period_); VectorToArray(buffer_vector, buffer); //We assign the calculations into an array format } else //For plotting the current value { for (int i=prev_calculated-1; i<rates_total; i++) //Loop from the prev_calculated bars -1 to the total bars present { double temp_close[]; //For storing temporary close values int size = period_*2; //We are going to copy an equivalent of period x 2 to leave a room for NaN values if (ArrayCopy(temp_close, close, 0, i - size, size) < 0) { printf("Failed to copy closing price values to a temporary array, err = %d",GetLastError()); continue; } vector indicator_values = CTrendIndicators::SMA(temp_close, period_); ulong last_index = indicator_values.Size() - 1; //The last value in the vector is the recent calculated indicator value buffer[i] = indicator_values[last_index]; //Assing the last indicator value to the last value in the buffer } } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| A crude way to convert a vector into Array | //+------------------------------------------------------------------+ template <typename T> void VectorToArray(const vector<T> &v, T &arr[]) { ArrayResize(arr, (uint)v.Size()); for (uint i=0; i<(uint)v.Size(); i++) arr[i] = v[i]; }
Ausgabe
Abschließende Überlegungen
Dieser Ansatz der nutzerdefinierten Erfassung von Indikatorwerten ist bei der Datenerfassung praktischer als bei jeder anderen Aufgabe. Er eignet sich gut für Datenanalytiker und Enthusiasten, die nach innovativen Wegen zur Erfassung von Indikatordaten zu Analysezwecken suchen.
Ich habe oft festgestellt, dass ich einen schnellen Weg brauche, um mehrere Indikatorwerte zu erhalten, ohne den Indikator zu initialisieren und den ganzen langweiligen Kram zu machen, der oft zu MetaTrader5 Fehlern führt. Mit der steigenden Nachfrage nach Daten in MQL5, die auf die neu eingeführte Fähigkeit zurückzuführen ist, anspruchsvolle KI- und ML-Modelle zu handhaben, benötigen wir verschiedene und effektive Methoden zur Extraktion und Visualisierung von Indikatordaten für Analyse- und ML-Trainingszwecke.
Peace out.
Tabelle der Anhänge
Dateiname | Beschreibung/Verwendung |
---|---|
Include\ta-lib.mqh | MQL5-Bibliothek mit allen in diesem Artikel besprochenen Indikatorencodes. |
Indicators\Trend Indicators Redefined.mq5 | Ein Indikator mit einem einfachen gleitenden Durchschnittsindikator, der zu Demonstrationszwecken implementiert wurde. |
Scripts\Custom Indicators test script.mq5 | Ein einfaches Skript zum Testen und Debuggen von Indikatorcode. |
Quellen und Referenzen
- Relative Strength Index (RSI) Indicator Explained With Formula
- Moving Average (MA): Purpose, Uses, Formula, and Examples
- How to Use Bollinger Bands to Gauge Trends
- Parabolic SAR Indicator: Definition, Formula, Trading Strategies
- Standard Deviation Formula and Uses vs. Variance
- What is MACD?
- Stochastic Oscillator: What It Is, How It Works, How To Calculate
- Average True Range (ATR) Formula, What It Means, and How to Use It
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/16931






- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.