Universeller Trend mit grafischem Interface
Inhalt
- Einführung
- Indikatortypen
- Trendanzeige
- Verwendete Indikatoren
- Externe Parameter
- Erstellen eines Indikators
- Erstellen eines grafischen Interfaces
- Zusammenführen von GUI und Indikator
- Schlussfolgerung
- Anlagen
Einführung
Zwei frühere Artikel beschreiben wie man einen universellen Oszillator mit einem grafischen Interface erstellt, und wie man auf dieser Basis einen universellen Kanal entwickelt.
Ein universeller Trendindikator kann auch auf Basis des universellen Oszillators erstellt werden. Um aber Wiederholungen zu vermeiden, verwenden wir einen etwas anderen Weg. Einige finden vielleicht Gefallen an diesem, neuen Weg.
Für den universellen Oszillator und den universellen Kanal wurden alle Elemente als Klassen über automatische Pointer erstellt, und die Sichtbarkeit und Positionierung durch weitere Klassen gehandhabt. Jetzt erstellen wir ein universelles, mehrteiliges Bedienelement nach den Prinzipien, wie sie in der Serie "Benutzerdefinierte grafische Bedienelemente" (Artikel 1, Artikel 2, Artikel 3) beschrieben werden. Es werden jedoch nur die Methoden entwickelt, die für diesen Artikel benötigt werden.
Indikatortypen
Wir werden uns nicht nur auf die Indikatoren beschränken, die traditionell als Trendindikatoren erachtet werden. Jeder Indikator, der auf der Preisrichtung beruht (gleitende Durchschnitte, der RSI und andere) kann für die Bestimmung sowohl der Positionseröffnung wie der Trendrichtung verwendet werden. Ist der Preis zum Beispiel über dem gleitenden Durchschnitt, können wir einen Aufwärtstrend annehmen und umgekehrt (Fig. 1).
Fig. 1. Preis und gleitender Durchschnitt zur Trendbestimmung. Blaue Aufwärtspfeile deuten auf Kaufgelegenheiten
(der Preis ist über dem MA), rote Abwärtspfeile auf Verkaufsgelegenheiten (der Preis ist unter dem MA).
Die Steigung eines MA kann auf ähnliche Weise verwendet werden: steigend — Aufwärtstrend, fallend — Abwärtstrend (Fig. 2).
Fig. 2. Die Steigung als Trendindikator. Blaue Aufwärtspfeile deuten auf Kaufgelegenheiten
(der MA steigt), rote Abwärtspfeile auf Verkaufsgelegenheiten (der MA fällt)
Wurde eine Bar ermittelt, die den MA kreuzt (Der Schlusskurs einer Bar ist unter dem MA, der der nächsten über ihm), entsteht so durch den gleitende Durchschnitt eine Eröffungsgelegenheit. In diesem Fall existiert das Handelssignal für die Dauer der Bar (Fig. 3).
Fig. 3. Der gleitenden Durchschnitt zur Bestimmung der Positionseröffnung. Blaue Aufwärtspfeile zeigen Kaufgelegenheiten
(der Preis einer Bar ist unter dem MA, der der nächsten darüber), rote Abwärtspfeile zeigen
Verkaufsgelegenheiten (der Preis der einen Bar ist über dem MA, der der nächsten darunter)
Die Steigung des MA kann ähnlich genutzt werden: Bars mit einer Umkehr der Steigung sind Einstiegspunkte (Fig. 4).
Fig. 4. Die Steigung eines gleitenden Durchschnitts zur Bestimmung der Positionseröffnung. Blaue Aufwärtspfeile zeigen Kaufgelegenheiten
(lokales Minimum des MA), rote Abwärtspfeile ´zeigen Verkaufsgelegenheiten (lokales Maximum des MA)
In diesem Artikel befassen wir uns mit den Möglichkeiten, einen Trend zu bestimmen (siehe Fig. 1 und Fig. 2). Das Ermitteln von Einstigsgelegenheiten sind hier nur zum besseren Verständnis und der Vollständigkeit halber aufgeführt.
Auch Oszillatoren werden zum Bestimmen von Einstiegspunkten verwendet, meistens durch das Kreuzen bestimmter Level, z.B. RSI (Fig. 5). Es gibt mindesten zwei Möglichkeiten, den Stochastik Oszillator für Einstiegspunkte zu verwenden: Das Kreuzen eines Levels oder das Kreuzen der Hauptlinie mit einer Signallinie.
Fig. 5. Einstiegspunkte auf Basis des RSI Indikators. Blaue Pfeile zeigen Kaufsignale (Kreuzen des Levels von
70 aufwärts), rote Pfeile zeigen Verkaufssignale (Kreuzen des Levels von 30 nach unten)
Fragen wir uns, wie Oszillatoren einen Trend identifizieren können. Die Antwort ist für die Stochastik eindeutig: Auf Basis der Lage von Haupt- und Signallinie, und zwar ist die Hauptlinie über der Signallinie, kann man kaufen, ist sie darunter — verkaufen (Fig. 6).
Fig. 6. Die Lage von Haupt- und Signallinie des Stochastik Oszillators zur Trendbestimmung. Die blauen Pfeile zeigen
einen Aufwärtstrend (Hauptlinie über der Signallinie), rote Pfeile einen Abwärtstrend (Hauptlinie unter der Signallinie)
Ähnlich die Verwendung von Level: Ist der Oszillator über einem bestimmten Level, kaufen, ist sie darunter — verkaufen (Fig. 7).
Fig. 7. Die Verwendung des RSI-Oszillators mittels Levels zur Trendbestimmung. Blaue Pfeile zeigen den Aufwärtstrend
(RSI über 60), rote Pfeile einen Abwärtstrend (RSI unter 40)
Trendanzeige
Finden wir den bequemsten Weg, einen Trend anzuzeigen. Die allererste Idee ist einfach eine Linie zu zeichnen, deren Farbe mit dem Trend wechselt. Betrachten wir die Trendbestimmung durch RSI und die Level von 60 und 40. Ist die Linie des RSI über 60, können wir kaufen, ist sie unter 40, verkaufen (Fig. 7). Im Falle, dass der der RSI zwischen 40 und 60 ist, können wir weder kaufen noch verkaufen. Vertauschen wir nun beide Level: Der Level für Kaufen ist nun 40 (wir können kaufen, wenn die Werte größer 40 sind), und der Verkaufslevel ist nun 60 (verkaufen, wenn unter 60). In diesem Fall könnten wir, wenn die Werte zwischen 40 und 60 liegen, sowohl kaufen wie verkaufen (Fig. 8).
Fig. 8. Trendbestimmung mittels des RSI-Oszillators. Der Kauflevel steht auf 40, der für Verkauf auf 60.
Jetzt gibt es eine Zone, in der ge- und verkauft werden kann (es existieren blaue und rote Pfeile).
Daraus folgt, dass der Trend in zwei unabhängigen Datengruppen angezeigt werden müssten. Wir verwenden zwei Indikatorpuffer: einer ist etwas nach oben geschoben worden, der andere etwas nach unten (so können beide Puffer zugleich angezeigt werden). Da die Puffer nicht ständig Daten anzeigen, ist es besser Icons oder eine Histogramm zu verwenden. Wählen wir zunächst die Icons. In diesem Fall können wir, zusätzlich zu den unterschiedlichen Farben für die Puffer, verschiedene Icons verwenden. Fig. 9 zeigt wie der Indikator jetzt aussieht.
Fig. 9. Ein bequemer Weg, einen Trend anzuzeigen
Diese Methode zur Trenddarstellung erhöht die Anzahl der darstellbaren Indikatoren. So können zum Beispiel Indikatoren angezeigt werden, die nicht von der Trendrichtung abhängen, sondern nur in bestimmtem Zeitspannen das Handeln erlauben oder verbieten. So können wir zum Beispiel den ATRoder STD verwenden. Sind ihre Werte über einem jeweiligen Schwellwert, werden beide Pfeile (auf- und abwärts) angezeigt. So wird der universelle Indikator noch universeller.
Verwendete Indikatoren
Bevor wir aber mit dem Erstellen des universellen Trendindikators beginnen, definieren wir die Liste der Indikatoren für die Bestimmung des Trends. Damit ergeben sich auch die die externen Parameter (Werte und Typen der Variablen). Natürlich können nicht alle Möglichkeiten durch einen Indikator erfasst werden — es wären einfach zu viele. Selbst ein gleitender Durchschnitt kann auf zwei Arten verwendet werden. Mehr noch, es könnten zwei gleitenden Durchschnitte verwendet werden. Es muss daher eine einfache Möglichkeit angeboten werden, die Daten der Initialisierung anzupassen.
Einige Indikatoren verwenden identische Optionen, obwohl das auf den ersten Blick nicht immer so aussieht. Wenn Sie zum Beispiel zur Trendbestimmung zwei MAs verwenden (schnell und langsam), wird eine Trendbestimmung auf Basis von MA und Preis überflüssig. Setzen wir die Periodenlänge des schnellen MA auf 1, dann entspricht der MA dem Preis. Daher sollte jeder Indikator individuell behandelt werden. Darüber hinaus ist es notwendig, jede Variante von jedem Indikator zu berücksichtigen.
Der Indikator hat keine eigenen Parameter, er ist identisch mit dem OsMA mit bestimmten Parametern, wir werden ihn daher übergehen.
iAD (Accumulation/Distribution)
Ein sehr spezifischer Indikator. Die Breite der Indikatorwerte ist nicht festgelegt, seine Linie ist nicht kontinuierlich und er eignet sich ohne zusätzliche Maßnahmen (z.B. Glättung) nicht zur Trendbestimmung. Er wird nicht verwendet.
iADX (Average Directional Index)
Variante 1. Die Lage der Linien von PDI und MDI. PDI über MDI — Abwärtstrend, PDI unter MDI — Abwärtstrend.
Parameter:
- int adx_period.
Variante 2. Ist Richtungsunabhängig. Die Linie des ADX relativ zur Lage einen bestimmten Levels. ADX über dem Level — Kauf und Verkauf ist erlaubt. Zusätzlich zu den Parametern des Indikators, benötigen wir einen weiteren zur Angabe des Levels.
Parameter:
- int adx_period — Periodenlänge;
- double level — Wert des Levels.
iADXWilder (Average Directional Index by Welles Wilder)
Ähnlich dem ADX.
Der Indikator besteht aus drei gleitenden Durchschnitten mit unterschiedlichen Periodenlängen und Versatz. Es gibt viele Möglichkeiten, diesem Indikator zu verwenden. Wir verwenden allerdings nur eine.
Variante 1. Die schnelle Linie (Lippen) ist über der mittleren (Zähne), die mittlere über der langsamen (Kinn) — Aufwärtstrend, liegen die Linien in einer umgekehrten Reihenfolge vor, — Abwärtstrend.
Parameter:
- int jaw_period — Periodenlänge der Linie des Kinns;
- int jaw_shift — Versatz der Linie des Kinns;
- int teeth_period — Periodenlänge der Linie der Zähne;
- int teeth_shift — Versatz der Linie der Zähne;
- int lips_period — Periodenlänge der Linie der Lippen;
- int lips_shift — Versatz der Linie der Lippen;
- ENUM_MA_METHOD ma_method — Typ der Glättung;
- ENUM_APPLIED_PRICE applied_price — Preistyp.
iAMA (Adaptive Moving Average)
Der Indikator ist ein gleitender Durchschnitt. Wir werden zwei Varianten der Anwendung für alle MAs.
Variante 1. Steigung der Linie. Zusätzlich zu den Standardparametern der Indikatoren, benötigen wir einen weiteren Parameter, der einen zweiten Bezugspunkt des Indikators zur Bestimmung der Steigung festlegt.
Parameter:
- int ama_period — AMA Periodenlänge;
- int fast_ma_period — Periodenlänge des schnellen, gleitenden Durchschnitts;
- int slow_ma_period — Periodenlänge des langsamen, gleitenden Durchschnitts;
- int ama_shift — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price — Preistyp;
- int shift2 — Abstand des Punktes zur Bestimmung der Steigung.
Variante 2. Zwei Linien: schnell und langsam. Ist die erste Linie über der langsamen — Aufwärtstrend, die schnell unter der langsamen — Abwärtstrend. Zwei identische Sätze von Parametern werden benötigt.
Parameter:
- int ama_period1 — AMA Periodenlänge;
- int fast_ma_period1 — Periodenlänge des schnellen, gleitenden Durchschnitts;
- int slow_ma_period1 — Periodenlänge des langsamen, gleitenden Durchschnitts;
- int ama_shift1 — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price1 — Preistyp;
- int ama_period2 — AMA Periodenlänge;
- int fast_ma_period2 — Periodenlänge des schnellen, gleitenden Durchschnitts;
- int slow_ma_period2 — Periodenlänge des langsamen, gleitenden Durchschnitts;
- int ama_shift2 — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price2 — Preistyp.
Hinweis: Variablen der schnellen Linie enden mit 1, die der langsamen mit 2.
Der Indikator hat keine Parameter, er ist identisch mit dem MACD-Indikator mit bestimmten Parametern, er wird nicht verwendet.
Dieser Indikator hängt nicht von einer Richtung ab, wir verwenden eine Variante.
Variante 1: Richtungsunabhängig. Die Lage der Linie des ATR relativ zu einem Level. ATR über dem Level — kaufen und verkaufen sind erlaubt. Zusätzlich zu den Parametern des Indikators, benötigen wir einen weiteren zur Angabe des Levels.
Parameter:
- int ma_period — Periodenlänge;
- double level — Wert des Levels.
iBearsPower (Bears Power) und iBullsPower (Bulls Power)
Die Indikatoren BearsPower und BullsPower sind nicht symmetrisch, d.h. sie müssen beide verwendet werden: einer für die Kaufsignale, der andere für die zum Verkaufen. Wir verwenden BullsPower für den Aufwärtstrend und BearsPower für den Abwärtstrend. Wir verwenden zwei Varianten: die relative Lage des Indikators zu einem Level und die Steigung.
Variante 1. Ist BullsPower über dem Level — ist Kaufen erlaubt, ist BearsPower unter demselben Level — ist Verkaufen erlaubt. Zusätzlich zu den Standardparametern benötigen wir den Wert des Levels.
Parameter:
- int ma_period — Periodenlänge;
- double level — Wert des Levels.
Variante 2. Die Richtung des Indikators. Für diese Variante benötigen wir einen weiteren Parameter, der einen zweiten Bezugspunkt des Indikators zur Bestimmung der Steigung festlegt.
Parameter:
- int ma_period — Periodenlänge;
- int shift2 — Abstand des zweiten Punktes.
Dieser bildet einen Kanal.
Variante 1. Kreuzt der Preis die obere Linie nach oben, beginnt ein Aufwärtstrend; kreuzt der Preis die Mittellinie nach unten ist der Aufwärtstrend beendet. Der Indikator funktioniert ähnlich in die andere Richtung mit der unteren Linie und dem Abwärtstrend.
Parameter:
- int bands_period — Periodenlänge der Mittellinie;
- int bands_shift — horizontaler Versatz des Indikators;
- double — Zahl der Standardabweichungen;
- ENUM_APPLIED_PRICE applied_price — Preistyp.
iCCI (Commodity Channel Index)
Der Indikator ist ein Oszillator in einem eigenen Fenster. Die Linie des Indikators ist stark unterbrochen, selbst bei längeren Periodenlängen, wir verwenden ihn daher ohne seine Steigung.
Variante 1. Position relativ zum Level. Ist der Indikatorwert über dem Level — Aufwärtstrend, ist er kleiner als der negative Werte des Levels — Abwärtstrend.
Parameter:
- int ma_period — Glättungslänge;
- ENUM_APPLIED_PRICE applied_price — Preistyp oder handle;
- double level — Wert des Levels.
Der Indikator ist ähnlich dem CCI.
Variante 1. Position relativ zum Level. Ist der Indikatorwert über dem Level — Aufwärtstrend, ist er kleiner als der negative Werte des Levels — Abwärtstrend.
Parameter:
- int fast_ma_period — schnelle Periodenlänge;
- int ow_ma_period — langsame Periodenlänge;
- ENUM_MA_METHOD ma_method — Typ der Glättung;
- ENUM_APPLIED_VOLUME applied_volume — verwendetes Volumen;
- double level — Wert des Levels.
iDEMA (Double Exponential Moving Average)
Der Indikator ist ein gleitender Durchschnitt und wird ähnlich dem oben beschriebenen AMA verwendet.
Variante 1. Steigung der Linie.
Parameter:
- int ma_period — Glättungslänge;
- ENUM_APPLIED_PRICE applied_price — Preistyp;
- int ma_shift — horizontaler Versatz des Indikators;
- int shift2 — Abstand des Punktes zur Bestimmung der Steigung.
Variante 2. Zwei Linien: schnell und langsam.
Parameter:
- int ma_period1 — Glättungslänge;
- ENUM_APPLIED_PRICE applied_price1 — Preistyp;
- int ma_shift1 — horizontaler Versatz des Indikators;
- int ma_period2 — Glättungslänge;
- ENUM_APPLIED_PRICE applied_price2 — Preistyp;
- int ma_shift2 — horizontaler Versatz des Indikators.
Hinweis: Variablen der schnellen Linie enden mit 1, die der langsamen mit 2.
Der Indikator ist ein Oszillator in einem eigenen Fenster mit einem Bereich zwischen 0 und 1. Der Neutralwert des Indikators liegt bei 0,5. Die Linie des Indikators ist sehr unruhig, so dass dessen Steigung nicht verwendbar ist.
Variante 1. Position relativ zum Level. Das Verkaufslevel wird über die Parameter gesetzt, das Kauflevel wird dazu symmetrisch zum Wert von 0,5 berechnet.
Parameter:
- int ma_period — Glättungslänge;
- double level — Verkaufslevel.
Der Indikator bildet einen Kanal ähnlich den Bollinger Bänder, nur ist seine Verwendung einfacher.
Variante 1. Ist der Preis höher als die Obergrenze des Kanals, ist Kaufen erlaubt. Ist er unter der Untergrenze, ist Verkaufen erlaubt.
Parameter:
- int ma_period — Periodenlänge der Mittellinie;
- int ma_shift — horizontaler Versatz des Indikators;
- ENUM_MA_METHOD ma_method — Typ der Glättung;
- ENUM_APPLIED_PRICE applied_price — Preistyp;
- double deviation — Abweichung der Kanalgrenzen von der Mittellinie.
Der Indikator ist ein Oszillator in einem eigenen Fenster mit einem Bereich um 0. Der Indikator ist ähnlich dem CCI.
Variante 1. Position relativ zum Level.
Parameter:
- int ma_period — Glättungslänge;
- ENUM_MA_METHOD ma_method — Typ der Glättung;
- ENUM_APPLIED_VOLUME applied_volume — Volumenstyp für die Berechnung;
- double level — Wert des Levels.
Der Indikator hat keine Parameter.
Variante 1. Verwendung erfolgt auf Grund des letzten Fraktals. War das letzte Fraktal ein Maximum, ist Verkaufen erlaubt. Ist es ein Minimum — Kaufen ist erlaubt.
iFrAMA (Fractal Adaptive Moving Average)
Der Indikator ist ein gleitender Durchschnitt. Seine Verwendung ist ähnlich der des AMA.
Variante 1. Steigung der Linie.
Parameter:
- int ma_period — Glättungslänge;
- int ma_shift — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price — Preistyp;
- int shift2 — Abstand des Punktes zur Bestimmung der Steigung.
Variante 2. Zwei Linien: schnell und langsam.
Parameter:
- int ma_period1 — Glättungslänge;
- int ma_shift1 — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price1 — Preistyp;
- int ma_period2 — Glättungslänge;
- int ma_shift2 — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price2 — Preistyp.
Hinweis: Variablen der schnellen Linie enden mit 1, die der langsamen mit 2.
Der Indikator berechnet sich auf Basis des Alligator-Indikators. Die Information dieses Indikators kann auch über den Alligator erhalten werden, wir werden ihn daher nicht einbeziehen.
iIchimoku (Ichimoku Kinko Hyo)
Die folgenden Linien des Indikators könnten interessant sein: Tenkan — Kijun und die Wolke. In der Wolke können wir zwei Linie mit wechselnden Positionen definieren (mal ist die eine oben, mal die andere). Es gibt zwei Varianten des Indikators.
Variante 1. Die Position der Linien von Tenkan und Kijun. Ist die Linie des Tenkan (rot) über der Linie des Kijun (blau), haben wir einen Aufwärtstrend. Ist der Tenkan unter dem Kijun — gibt es einen Abwärtstrend.
Parameter:
- int tenkan_sen — Periodenlänge der Tenkan-sen-Linie;
- int kijun_sen — Periodenlänge der Kijun-sen-Linie;
- int senkou_span_b — Periodenlänge des Senkou Span B.
Variante 2. Auf Basis der Richtung der Wolke. Die Wolke wird duch zwei Linie definiert: SpanA und SpanB. Ist SpanA über SpanB — Aufwärtstrend, anders herum — Abwärtstrend.
Parameter:
- int tenkan_sen — Periodenlänge der Tenkan-sen-Linie;
- int kijun_sen — Periodenlänge der Kijun-sen-Linie;
- int senkou_span_b — Periodenlänge des Senkou Span B.
Wir werden diesen Indikator nicht verwenden, da er sehr spezifisch ist.
Der Indikator ist ein Oszillator in einem eigenen Fenster. Die Linie des Indikators ist sehr unruhig, so dass dessen Steigung nicht verwendbar ist. Es wird aber die Version mit Level verwendet.
Variante 1. Level. Neutraler Level: 100. Zusätzlich zu den Standardparametern benötigen wir den Wert eines Verkaufslevels. Der Kauflevel berechnet sich symmetrisch zum neutralen Level von 100.
Parameter:
- int mom_period — Glättungslänge;
- ENUM_APPLIED_PRICE applied_price — Preistyp oder handle;
- double level — Verkaufslevel.
Der Indikator ist ein Oszillator in einem eigenen Fenster mit einem Bereich zwischen 0 und 100. Neutraler Level: 50. Die Linie des Indikators ist sehr unruhig, so dass dessen Steigung nicht verwendbar ist.
Variante 1. Mit Level. Zusätzlich zu den Standardparametern benötigen wir den Wert eines Verkaufslevels. Der Kauflevel berechnet sich symmetrisch zum neutralen Level von 50. Ist die Indikatorlinie über dem Kauflevel — Aufwärtstrend, ist sie unter dem Verkaufslevel — Abwärtstrend.
Parameter:
- int ma_period — Glättungslänge;
- ENUM_APPLIED_VOLUME applied_volume — Volumenstyp für die Berechnung;
- double level — Verkaufslevel.
Das ist eine einfacher, gleitender Durchschnitt.
Variante 1. Steigung der Linie.
Parameter:
- int ma_period — Glättungslänge;
- int ma_shift — horizontaler Versatz des Indikators;
- ENUM_MA_METHOD ma_method — Typ der Glättung;
- ENUM_APPLIED_PRICE applied_price — Preistyp;
- int shift2 — Abstand des Punktes zur Bestimmung der Steigung.
Variante 2. Zwei Linien: schnell und langsam.
Parameter:
- int ma_period1 — Glättungslänge;
- int ma_shift1 — horizontaler Versatz des Indikators;
- ENUM_MA_METHOD ma_method1 — Typ der Glättung;
- ENUM_APPLIED_PRICE applied_price1 — Preistyp;
- int ma_period2 — Glättungslänge;
- int ma_shift2 — horizontaler Versatz des Indikators;
- ENUM_MA_METHOD ma_method2 — Typ der Glättung;
- ENUM_APPLIED_PRICE applied_price2 — Preistyp.
Hinweis: Variablen der schnellen Linie enden mit 1, die der langsamen mit 2.
iOsMA (Moving Average of Oscillator (MACD histogram)
Der OsMA Oszillator ist ein Histogramm in einem eigenen Fenster. Zwei Varianten sind möglich: Auf Basis von Level und Richtung.
Variante 1. Mit Level. Ist das Histogramm über dem Level, ist Kaufen erlaubt, ist es unter dem negativen Wert dieses Levels — ist Verkaufen erlaubt.
Parameter:
- int fast_ema_period — Periodenlänge des schnellen, gleitenden Durchschnitts;
- int slow_ema_period — Periodenlänge des langsamen, gleitenden Durchschnitts;
- int signal_period — Glättungslänge der Signallinie;
- ENUM_APPLIED_PRICE applied_price — Preistyp oder handle;
- double level — Wert des Levels.
Variante 2. Auf Basis der Richtung. Ist die Richtung des Histogramms aufwärts, ist Kaufen erlaubt; ist sie abwärts — ist Verkaufen erlaubt. Wir benötigen einen weiteren Parameter, der einen zweiten Bezugspunkt des Indikators zur Bestimmung der Steigung festlegt.
Parameter:
- int fast_ema_period — Periodenlänge des schnellen, gleitenden Durchschnitts;
- int slow_ema_period — Periodenlänge des langsamen, gleitenden Durchschnitts;
- int signal_period — Glättungslänge der Signallinie;
- ENUM_APPLIED_PRICE applied_price — Preistyp oder handle;
- int shift2 — Abstand des zweiten Punktes zur Bestimmung der Richtung.
iMACD (Moving Averages Convergence-Divergence)
Das Histogramm des MACD wird mit der Signallinie im eigenen Fester gezeichnet. Es gibt drei Wege diesen Indikator zu verwenden: Auf Basis des Verhältnisses des Histogramms zum Level, die Richtung des Histogramms und dessenb Position relativ zur Signallinie. Das Letzte ist jedoch ein Sonderfall der Wertung des OsMA gegen den Level (wenn dessen Level 0 beträgt), und er wird daher nicht verwendet.
Variante 1. Mit Level. Ist das Histogramm über dem Level, ist Kaufen erlaubt, ist es unter dem negativen Wert dieses Levels — ist Verkaufen erlaubt.
Parameter:
- int fast_ema_period — Periodenlänge des schnellen, gleitenden Durchschnitts;
- int slow_ema_period — Periodenlänge des langsamen, gleitenden Durchschnitts;
- int signal_period — Glättungslänge der Signallinie;
- ENUM_APPLIED_PRICE applied_price — Preistyp oder handle;
- double level — Wert des Levels.
Variante 2. Auf Basis der Richtung. Bewegt sich das Histogramm aufwärts — Kaufen; wenn abwärts — Verkaufen. Wir benötigen einen weiteren Parameter, der einen zweiten Bezugspunkt des Indikators zur Bestimmung der Steigung festlegt.
Parameter:
- int fast_ema_period — Periodenlänge des schnellen, gleitenden Durchschnitts;
- int slow_ema_period — Periodenlänge des langsamen, gleitenden Durchschnitts;
- int signal_period — Glättungslänge der Signallinie;
- ENUM_APPLIED_PRICE applied_price — Preistyp oder handle;
- int shift2 — Abstand des zweiten Punktes zur Bestimmung der Richtung.
So wie der AD hat dieser Indikator keinen bestimmten Wertebereich und ist sehr unruhig. Er wird nicht verwendet.
iSAR (Parabolic Stop And Reverse System)
Der Indikator wird auf dem Chart in Form von Punktelinien gezeichnet. Abhängig vom der Richtung der Preisbewegung liegt die Linie darüber oder darunter.
Variante 1. Position relativ zum Preis. Preis ist über dem Indikator — Aufwärtstrend, Preis liegt unter dem Indikator — Abwärtstrend.
Parameter:
- double step — Schrittweite der Preisänderungen — Beschleunigungsfaktor;
- Doppel-Maximum — maximale Schrittweite.
iRSI (Relative Strength Index)
Ein Oszillator im eigenen Fenster. Eine Anwendungsvariante ähnlich zum MFI.
Variante 1. Mit Level.
Parameter:
- int ma_period — Glättungslänge;
- ENUM_APPLIED_PRICE price — Preistyp;
- double level — Verkaufslevel.
Ein Oszillator im eigenen Fenster mit einer Signallinie. Die Werte schwanken um Null.
Variante 1. Mit Level. Über dem Level — kaufen, unter den Negativen des Levels — verkaufen.
Parameter:
- int ma_period — Glättungslänge;
- double level — Wert des Levels.
Variante 2. Die Haupt- und Signallinie.
Parameter:
- int ma_period — Glättungslänge.
Dieser Indikator hängt nicht von einer Richtung ab. Ähnlich den ATR.
Variante 1. Mit Level.
Parameter:
- int ma_period — Glättungslänge;
- int ma_shift — horizontaler Versatz des Indikators;
- ENUM_MA_METHOD ma_method — Typ der Glättung;
- ENUM_APPLIED_PRICE applied_price — Preistyp;
- double level — Wert des Levels.
iStochastic (Stochastic Oscillator)
Ein Oszillator im eigenen Fenster mit Haupt- und Signallinie.
Variante 1. Die Steigung der Hauptlinie.
Parameter:
- int Kperiod — K-Periodenlänge;
- int Dperiod — D-Periodenlänge;
- int slowing — abschließende Glättungslänge;
- ENUM_MA_METHOD ma_method — Typ der Glättung;
- ENUM_STO_PRICE price_field — Preistyp;
- int shift2 — Abstand des zweiten Punktes zur Bestimmung der Richtung der Steigung.
Variante 2. Mit Level. Die Indikatorwerte variieren im Bereich von 0 bis +100, der neutrale Level liegt bei 50. Ein zusätzlicher Parameter wird für den Verkaufslevel benötigt, der Kauflevel wird errechnet.
Parameter:
- int Kperiod — K-Periodenlänge;
- int Dperiod — D-Periodenlänge;
- int slowing — abschließende Glättungslänge;
- ENUM_MA_METHOD ma_method — Typ der Glättung;
- ENUM_STO_PRICE price_field — Preistyp;
- double level — Wert des Levels.
Variante 3. Die Position von Haupt- und Signallinie.
Parameter:
- int Kperiod — K-Periodenlänge;
- int Dperiod — D-Periodenlänge;
- int slowing — abschließende Glättungslänge;
- ENUM_MA_METHOD ma_method — Typ der Glättung;
- ENUM_STO_PRICE price_field — Preistyp.
iTEMA (Triple Exponential Moving Average)
Ein weiterer gleitenden Durchschnitt.
Variante 1. Steigung der Linie.
Parameter:
- int ma_period — Glättungslänge;
- int ma_shift — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price — Preistyp;
- int shift2 — Abstand des Punktes zur Bestimmung der Steigung.
Variante 2. Zwei Linien: schnell und langsam.
Parameter:
- int ma_period1 — Glättungslänge;
- int ma_shift1 — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price1 — Preistyp;
- int ma_period2 — Glättungslänge;
- int ma_shift2 — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price2 — Preistyp.
Anmerkung. Die Variablen für die schnelle Linie endend mit 1, die der langsamen mit 2.
iTriX (Triple Exponential Moving Averages Oscillator)
Ein Oszillator im eigenen Fenster. Eine Variante — Steigung der Linie. Wir versuchen eine zweite Variante mit zwei Linien: schnell und langsam
Variante 1. Steigung der Linie.
Parameter:
- int ma_period — Glättungslänge;
- int ma_shift — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price — Preistyp;
- int shift2 — Abstand des Punktes zur Bestimmung der Steigung.
Hinweis: Die iTriX-Funktion hat keinen Parameter ma_shift, dennoch kann der Indikator verschoben werden. Das Verschieben geschieht nicht über einen Versatz-Parameter (er ist für alle Indikatoren auf 0 gesetzt), sondern durch die Berechnung des Index der Bar.
Variante 2. Zwei Linien: schnell und langsam.
Parameter:
- int ma_period1 — Glättungslänge;
- int ma_shift1 — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price1 — Preistyp;
- int ma_period2 — Glättungslänge;
- int ma_shift2 — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price2 — Preistyp.
Anmerkung. Die Variablen für die schnelle Linie endend mit 1, die der langsamen mit 2.
iWPR (Williams' Percent Range)
Der Indikator ist identisch mit der Linie der Stochastik mit einer Verzögerung (slowing) von 1, nur in umgekehrter Darstellung. Er wird nicht verwendet.
iVIDyA (Variable Index Dynamic Average)
Ein weiterer gleitenden Durchschnitt.
Variante 1. Steigung der Linie.
Variante 2. Zwei Linien: schnell und langsam.Parameter:
- int cmo_period — CMO period
- ema_period — Glättungslänge
- ma_shift — horizontaler Versatz des Indikators
- ENUM_APPLIED_PRICE applied_price — Preistyp
- int shift2 — Abstand des Punktes zur Bestimmung der Steigung.
Parameter:
- int ma_period1 — Glättungslänge;
- int ma_shift1 — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price1 — Preistyp;
- int ma_period2 — Glättungslänge;
- int ma_shift2 — horizontaler Versatz des Indikators;
- ENUM_APPLIED_PRICE applied_price2 — Preistyp.
Hinweis: Variablen der schnellen Linie enden mit 1, die der langsamen mit 2.
Die Werte des Indikators hängen nicht von seiner Richtung ab. Der Indikator kann ähnlich wie ATR oder STD verwendet werden.
Variante 1. Level. Sind die Werte des Indikators über dem Level, sind Kaufen und Verkaufen erlaubt.
Parameter:
- ENUM_APPLIED_VOLUME applied_volume — Volumenstyp;
- double level — Wert des Levels.
Wir haben die Indikatoren mit ihren verwendeten Varianten definiert. Schreiben wir als nächsten eine Enumeration all dessen. Im Verzeichnis "Includes" erstellen wir das Verzeichnis "UniTrend" und erstellen dort die Datei UniTrendDefines.mqh mit folgender Enumeration:
enum EType{ Type_ADX_PDIMDI, // Positionen der Linien von PDI und MDI des Indikators ADX Type_ADX_Level, // Position der Linien des ADX relativ zu Level Type_ADXW_PDIMDI, // Positionen der Linien von PDI und MDI des Indikators Wilders ADX Type_ADXW_Level, // Postione der Linie des ADX relativ zum Level von Wilders ADX Type_Alligator, // Alligator Type_AMA_Dir, // Richtung des АМА Type_AMA_2MA, // zwei АМАs Type_ATR_Level, // ATR Type_BuBe_Level, // Bulls/Bears Power mit Level Type_BuBe_Dir, // Richtung von Bulls/Bears Power Type_Bands, // Bollinger Bänder Type_CCI_Level, // CCI, und mit Level Type_Chaikin_Level, // Chaikin Oszillator und mit Level Type_DEMA_Dir, // Richtung des DEMA Type_DEMA_2MA, // zwei DEMAs Type_DeMarker_Level, // DeMarker und mit Level Type_Envelopes, // Envelope Type_Force_Level, // Force Oszillator und mit Level Type_Fractals, // Fraktale Type_FrAMA_Dir, // Richtung des FrAMA Type_FrAMA_2MA, // zwei FrAMAs Type_Ichimoku_TK, // Ichimoku: Tenkan und Kijun Type_Ichimoku_SASB, // Ichimoku: Wolke Type_Momentum_Level, // Momentum und mit Level Type_MFI_Level, // MFI und mit Level Type_MA_Dir, // Richtung des MA Type_MA_2MA, // zwei MAs Type_OsMA_Dir, // Richtung des OsMA Type_OsMA_Level, // OsMA und mit Level Type_MACD_Dir, // Richtung des MACD Type_MACD_Level, // MACD und mit Level Type_SAR, // SAR Type_RSI_Level, // RSI und mit Level Type_RVI_Level, // RVI und mit Level Type_RVI_MS, // Haupt- und Signallinie des RVI Type_STD_Level, // standard deviation und mit Level Type_Sto_Dir, // Richtung der Stochastik Type_Sto_Level, // Stochastik und mit Level Type_Sto_MS, // Haupt- und Signallinie der Stochastik Type_TEMA_Dir, // Richtung des TEMA Type_TEMA_2MA, // zwei TEMAs Type_TriX_Dir, // Richtung des TriX Type_TriX_2MA, // zwei TriXs Type_VIDyA_Dir, // Richtung des VIDyA Type_VIDyA_2MA, // zwei VIDyAs Type_Volumes // Volumen
};
Externe Parameter
Durch die Analyse de oben beschrieben Indikatoren erkennen wir die benötigten, externen Parameter. Alle benötigten Parameter mit ihren Typen befinden sich in Tabelle 1. Alle Variablen beginnen zunächst mit "f_" (für schnell oder engl. "fast"). In den Varianten mit einem schnellen und einem langsamen gleitenden Durchschnitt erhält die zweite Gruppe der Parameter den Präfix "s_" (für "langsam" oder eng. "slow").
Tabelle 1. Externe Parameter mit ihren Typen
Typ | Name |
---|---|
int | f_period1 |
int | f_shift1 |
int | f_period2 |
int | f_shift2 |
int | f_period3 |
int | f_shift3 |
ENUM_MA_METHOD | f_method |
ENUM_APPLIED_PRICE | f_price |
ENUM_APPLIED_VOLUME | f_volume |
ENUM_STO_PRICE | f_sto_price |
double | f_level |
int | f_dot2shift |
double | f_step |
double | f_maximum |
int | s_period1 |
int | s_shift1 |
int | s_period2 |
int | s_shift2 |
int | s_period3 |
int |
s_shift3 |
ENUM_MA_METHOD | s_method |
ENUM_APPLIED_PRICE | s_price |
int | mult |
int | level_digits |
int | sar_step_digits |
int | sar_maximum_digits |
Zusätzlich zu den angegebenen Parameter aus den Beschreibungen der Indikatoren, gibt es weitere Parameter am Ende der Tabelle:
- mult — Ein Multiplikator der Parameter in Points, abhängig von der Anzahl der Dezimalstellen der Kurse. Die Werte einiger Indikatoren, wie MACD und OsMA, zeigen sich als Preise und da ist es bequemer, sie in Points festzulegen. Die Werte der Parameter müssen dann in Abhängigkeit der Dezimalstellen der Preise angepasst werden.
- level_digits — Die Anzahl der Dezimalstellen der Level-Parameter. Im grafischen Interface wird der Werte der Level mittels dem Bedienelement CSpinBox festgelegt (ein Eingabefeld mit "+" und "-"-Tasten), es wäre daher nahe liegend, die verschiedenen, minimalen Änderungen der verschiedenen Indikatoren auch so festzulegen (der Betrag, um den sich der Wert durch das Drücken von "+" oder "-" ändert).
- sar_step_digits — die Anzahl der Dezimalstellen der Parameter von Schrittweiten des Indikators SAR.
- sar_maximum_digits — Anzahl der Dezimalstellen des Maximalwertes des Indikators SAR.
#define ADX_LEVEL_DIGITS 0 // für den ADX-Indikator #define ADXW_LEVEL_DIGITS 0 // für den ADX Wilder-Indikator #define ATR_LEVEL_DIGITS 1 // für den ATR-Indikator #define BUBE_LEVELS_DIGITS 1 // für den Bulls/Bears-Power-Indikator #define CCI_LEVEL_DIGITS 0 // für den CCI-Indikator #define CHAIKIN_LEVEL_DIGITS 0 // für den Chaikin-Oszillator #define DEMARKER_LEVEL_DIGITS 2 // für den Demarker-Indikator #define FORCE_LEVEL_DIGITS 3 // für den Force-Indikator #define MOMENTUM_LEVEL_DIGITS 2 // für den Momentum-Indikator #define MFI_LEVEL_DIGITS 0 // für den MFI-Indikator #define OSMA_LEVBEL_DIGITS 2 // für den OsMA-Indikator #define MACD_LEVEL_DIGITS 2 // für den MACD-Indikator #define RSI_LEVEL_DIGITS 0 // für den RSI-Indikator #define RVI_LEVEL_DIGITS 2 // für den RVI-Indikator #define STD_LEVEL_DIGITS 1 // für den STD-Indikator #define STO_LEVEL_DIGITS 0 // für den Stochastic-Indikator #define BANDS_LEVEL_DIGITS 1 // für die Bollinger Bänder #define ENVELOPES_LEVEL_DIGITS 2 // für den Envelopes-Indikator #define SAR_STEP_DIGITS 3 // für den SAR-Indikator (Parameter der Schrittweite) #define SAR_MAXIMUM_DIGITS 2 // für den SAR-Indikator (Parameter für das Maximum)
Erstellen wir folgende Struktur aus der Tabelle 1:
struct SExtParams{ int f_period1; int f_shift1; int f_period2; int f_shift2; int f_period3; int f_shift3; long f_method; long f_price; long f_volume; long f_sto_price; double f_level; int f_dot2shift; double f_step; double f_maximum; int s_period1; int s_shift1; int s_period2; int s_shift2; int s_period3; int s_shift3; long s_method; long s_price; int mult; int level_digits; int sar_step_digits; int sar_maximum_digits; };
Die Kombinierbarkeit von Parametern in einer Struktur erlaubt uns, sie vom Rest des Codes zu trennen. Das erleichtert spätere Revisionen des Indikators, wenn die bestehenden Trendindikatoren nicht ausreichen und weitere hinzugefügt werden sollen. Darüber hinaus erleichtert das erheblich die Übergabe der Parameter an Funktionen und Klassenmethoden.
Da der Indikator dieses Artikels den Trend als eine Reihe von Zeichen (gleich für alle Indikatoren) darstellt, können wir sehr leicht eine Benachrichtigung über den Beginn eines neuen Trends ergänzen. Der eine oder andere bevorzugt vielleicht, erst von einem vollständig, gebildeten Trend (Anzeige auf einer vollständigen Bar) benachrichtigt zu werden, andere wieder wollen sofort über einen neuen Trend (auf der aktuellen Bar) informiert werden. Daher schreiben wir eine weitere Enumeration für die Art der Benachrichtigung:
enum EAlerts{ Alerts_off=0, // keine Benachrichtigung Alerts_Bar0=1, // Benachrichtigung während der aktuellen Bar Alerts_Bar1=2 // Benachrichtigung nach der letzten geschlossenen Bar };
Erstellen eines Indikators
Das Erstellen der Klassen für den universelle Indikator ist detailliert in den Artikeln "Der universell Oszillator mit dem graphischen Interface" und "Universeller Kanal mit grafischem Interface" beschrieben. betrachte wir die besonderen Merkmale ihrer Erzeugung bezüglich dieses Artikels.
Alle bereits erwähnten Methoden für Bestimmung des Trends sind in zwei Gruppen organisiert: mit einem oder zwei Indikatoren. In der ersten Gruppe muss nach dem Laden des Indikators ein Handle geprüft werden, in der zweiten zwei Handles. Das bedeutet die Basisklasse bekommt zwei Kindklassen, jeweils mit einer unterschiedlichen Überprüfung der Handles. Im Gegenzug haben diese Kindklassen wiederum ihre eigenen Kindklassen zur Trendbestimmung.
Die Basisklasse:
class CUniTrend{ protected: int m_handle1; int m_handle2; string m_name; string m_help; int m_ci; double m_b1[1]; double m_b2[1]; double m_b3[1]; double m_b4[1]; int m_shift; int m_shift1; int m_shift2; int m_shift3; int m_dot2shift; double m_level; public: void CUniTrend(){ m_handle1=INVALID_HANDLE; m_handle2=INVALID_HANDLE; } void ~CUniTrend(){ if(m_handle1!=INVALID_HANDLE){ IndicatorRelease(m_handle1); } if(m_handle2!=INVALID_HANDLE){ IndicatorRelease(m_handle2); } } virtual int Calculate( const int rates_total, const int prev_calculated, double & upBuffer[], double & dnBuffer[] ){ return(rates_total); } virtual bool Calculated(){ return(false); } virtual bool CheckHandles(){ return(true); } string Name(){ return(m_name); } string Help(){ return(m_help); } };
Der "protected" Bereich beinhaltet die Deklaration verschiedener Hilfsvariablen, die nützlich in den Kindklassen werden. Die Variable für die Handles der Indikatoren werden im Konstruktor initialisiert und werden vom Destruktor wieder freigegeben. Die weiteren Methoden sind virtuell.
Die Kindklasse einer Variante mit einem Indikator:
class CUniTrend1:public CUniTrend{ public: bool Calculated(){ if(BarsCalculated(m_handle1)>0){ return(true); } else{ return(false); } } bool CheckHandles(){ return(m_handle1!=INVALID_HANDLE); } };
Die Klasse hat zwei Methoden: CheckHandle() — sie erlaubt zu prüfen, ob der Indikator geladen werden kann, und Calculated() — sie stell fest, ob der Indikator vollständig berechnet worden ist, und, ob die Inhalte der Puffer, die den Trend zeigen, aktualisiert werden können.
Eine Kindklasse mit der Variante für zwei Indikatoren:
class CUniTrend2:public CUniTrend{ public: bool Calculated(){ if(BarsCalculated(m_handle1)>0 && BarsCalculated(m_handle2)>0){ return(true); } else{ return(false); } } bool CheckHandles(){ return(m_handle1!=INVALID_HANDLE && m_handle2!=INVALID_HANDLE); } };
Alle Klassen mit unterschiedlichen Varianten zur Trendbestimmung, sind Kindklassen von entweder CUniTrend1 oder CUniTrend2. Betrachten wir die folgende Kindklasse:
class CUniTrend_ADX_PDIMDI:public CUniTrend1{ private: public: void CUniTrend_ADX_PDIMDI( bool use_default, bool keep_previous, SExtParams & par){ // Einstellen der Standardparameter if(use_default){ if(keep_previous){ if(par.f_period1==PARAMETER_EMPTY)par.f_period1=14; } else{ par.f_period1=14; } } // Landen des Indikators m_handle1=iADX(Symbol(),Period(),par.f_period1); // Bilden des Namens des Indikators mit Hinweis über die Parameter m_name=StringFormat( "iADX_PDIMDI(%i)", par.f_period1 ); m_help=StringFormat( "adx_period - f_period1(%i)", par.f_period1 ); } int Calculate( const int rates_total, const int prev_calculated, double & upBuffer[], double & dnBuffer[] ){ int start; if(prev_calculated==0){ start=1; } else{ start=prev_calculated-1; } for(int i=start;i<rates_total;i++){ upBuffer[i]=EMPTY_VALUE; dnBuffer[i]=EMPTY_VALUE; m_ci=rates_total-i-1; if(CopyBuffer(m_handle1,PLUSDI_LINE,m_ci,1,m_b1)==-1){ return(0); } if(CopyBuffer(m_handle1,MINUSDI_LINE,m_ci,1,m_b2)==-1){ return(0); } if(m_b1[0]>m_b2[0]){ upBuffer[i]=1; } else if(m_b1[0]<m_b2[0]){ dnBuffer[i]=-1; } } return(rates_total); } };
Die wichtigsten Punkte im Konstruktor der Klasse sind kommentiert, und die Methode Calculate() ist analog zur Standardfunktion OnCalculate() der Indikatoren. Der Code dieser Methode in Anlehnung an den Code der Indikatoren geschrieben.
In der dem Artikel beigefügten Datei befinden sich all Indikatorklassen in Include/UniTrend/UniTrendIndicators.mqh.
Jetzt, da wir alle Klassen vorbereitet haben, können einen einfachen Indikator zur Trendbestimmung erstellen, genau so, wie wir das bereits in den Artikeln über den universellen Oszillator und universellen Kanal gemacht haben. Ein fertiger Indikator ohne grafisches Interface ist in der beigefügten Datei Indicators/iUniTrend.mq5 vorhanden.
Erstellen eines grafischen Interfaces
Alle Klassen des grafischen Interfaces befinden sich in den Dateien UniTrendForm.mqh und UniTrendControl.mqh. Die Formklasse befindet sich in der Datei UniTrendForm.mqh file, und die Datei UniTrendControl.mqh beinhaltet die Klassen des universellen Bedienelementes zur Eingabe der Indikatorparameter. Es ist nicht notwendig auf die Formklasse detailliert einzugehen, da sie bereits in den erwähnten Artikeln über den universellen Oszillator und den universellen Kanal beschrieben wurde. Außerdem wurde sie im Artikel "Benutzerdefinierte grafische Bedienelemente. Teil 3. Formen" erläutert. Wenden wir uns dem Erstellen des universellen Bedienelementes zu.
Die Basis des universellen Bedienelementes ist die Basisklasse CUniTrendControl. Der "public" Teil der Klasse enthält nur virtuelle Methoden, der "protected" Teil einige Hilfsmethoden zum Bearbeiten von Auswahllisten: Methoden zum Eintragen der Einstellungen der Varianten in die Liste und Methoden zur Auswahl aus der Liste. Hier ist der kommentierte Code der Basisklasse:
class CUniTrendControl{ protected: /* Funktion zur Berechnung der kleinsten Wertänderung durch die Anzahl der Dezimalstellen des Parameters des Levels */ double SolveChange(int d){ return(NormalizeDouble(1.0/pow(10,d),d)); } // Ausfüllen der Liste der Varianten aus ENUM_MA_METHOD void AddVariantsMethod(CComBox & cb){ for(int i=0;i<ArraySize(e_method);i++){ cb.AddItem(EnumToString((ENUM_MA_METHOD)e_method[i])); } } // Ausfüllen der Liste der Varianten aus ENUM_APPLIED_PRICE void AddVariantsPrice(CComBox & cb){ for(int i=0;i<ArraySize(e_price);i++){ cb.AddItem(EnumToString((ENUM_APPLIED_PRICE)e_price[i])); } } // Ausfüllen der Liste der Varianten aus ENUM_APPLIED_VOLUME void AddVariantsVolume(CComBox & cb){ for(int i=0;i<ArraySize(e_volume);i++){ cb.AddItem(EnumToString((ENUM_APPLIED_VOLUME)e_volume[i])); } } // Ausfüllen der Liste der Varianten aus ENUM_STO_PRICE void AddVariantsStoPrice(CComBox & cb){ for(int i=0;i<ArraySize(e_sto_price);i++){ cb.AddItem(EnumToString((ENUM_STO_PRICE)e_sto_price[i])); } } // Rückgabe des Index der ENUM_MA_METHOD int MethodIndex(long val){ for(int i=ArraySize(e_method)-1;i>=0;i--){ if(e_method[i]==val){ return(i); } } return(-1); } // Rückgabe des Index aus ENUM_APPLIED_PRICE int PriceIndex(long val){ for(int i=ArraySize(e_price)-1;i>=0;i--){ if(e_price[i]==val){ return(i); } } return(-1); } // Rückgabe des Index aus ENUM_APPLIED_VOLUME int VolumeIndex(long val){ for(int i=ArraySize(e_volume)-1;i>=0;i--){ if(e_volume[i]==val){ return(i); } } return(-1); } // Rückgabe des Index aus ENUM_STO_PRICE int StoPriceIndex(long val){ for(int i=ArraySize(e_sto_price)-1;i>=0;i--){ if(e_sto_price[i]==val){ return(i); } } return(-1); } public: // Initialisierung des Bedienelementes virtual void Init(SExtParams & par){} // Festlegen der Werte virtual void SetValues(SExtParams & par){} // Rückgabe der Werte virtual void GetValues(SExtParams & par){} // Anzeigen des Bedienelementes virtual void Show(int x,int y){} // Ausblenden des Bedienelementes virtual void Hide(){} // Anzahl der Bedienelemente zur Berechnung der Fensterhöhe virtual int ControlsCount(){ return(0); } // Handhabung von Ereignissen virtual int Event(int id,long lparam,double dparam,string sparam){ return(0); } };
Batrachten wir jetzt eine Kindklasse zur Trendbestimmung auf Basis von ADX mit Level (zwei Bedienelemente):
class CUniTrendControl_ADX_Level: public CUniTrendControl{ private: // Pointer auf die einfachen Bedienelemente CSpinInputBox m_f_period1; CSpinInputBox m_f_level; public: // Initialisierung des Bedienelementes void Init(SExtParams & par){ m_f_period1.Init("f_period1",SPIN_BOX_WIDTH,1," adx_period"); m_f_period1.SetMinValue(1); m_f_period1.SetReadOnly(false); m_f_level.Init("f_level",COMBO_BOX_WIDTH,this.SolveChange(par.level_digits)," level"); m_f_level.SetMinValue(0); m_f_level.SetReadOnly(false); } // Festlegen der Werte void SetValues(SExtParams & par){ m_f_period1.SetValue(par.f_period1); m_f_level.SetValue(par.f_level); } // Rückgabe der Werte void GetValues(SExtParams & par){ par.f_period1=(int)m_f_period1.Value(); par.f_level=m_f_level.Value(); } // Anzeigen des Bedienelementes void Show(int x,int y){ m_f_period1.Show(x,y); y+=20; m_f_level.Show(x,y); } // Ausblenden des Bedienelementes void Hide(){ m_f_period1.Hide(); m_f_level.Hide(); } // Anzahl der Bedienelemente zur Berechnung der Fensterhöhe int ControlsCount(){ return(2); } // Ausführen der Ereignisse der Bedienelemente int Event(int id,long lparam,double dparam,string sparam){ int e1=m_f_period1.Event(id,lparam,dparam,sparam); int e2=m_f_level.Event(id,lparam,dparam,sparam); if(e1!=0 || e2!=0){ return(1); } return(0); } };
Eine Variable des Typs SExtParam wird den Methoden SetValues() und GetValues() übergeben, die Struktur umfasst die benötigten Variablen, die von den Kindklassen verwendet werden. Wir müssen die Minimaländerung des Bedienelementes der Level festlegen; das kann währen der Initialisierung des Bedienelementes geschehen, es wird daher auch eine Struktur mit den Parametern der Methode init() übergeben. Im Allgemeinen korrespondiert das Erstellen einer Kindklasse mit allen Prinzipien für das Erstellen eines Bedienelementes im Artikel "Benutzerdefinierte grafische Bedienelemente. Teil 1: Erstellen eines einfachen Bedienelements", außer, dass hier nicht alle, sondern nur die notwendigen Methoden erstellt wurden.
Zusammenführen von GUI und Indikator
Dieses Stadium der Indikatorerstellung ist sehr ähnlich dem korrespondierenden Stadium der Erstellung des universellen Trendindikators und der des universellen Kanals. Betrachten wir die Unterschiede.
Früher, als der Indikator mit Standardwerten lief (UseDefault=true), wurden alle Parameter mit -1 initialisiert. Jetzt reicht das nicht mehr aus, da die Werte der Level manchmal negative sein können. Die Initialisierung wird daher jetzt mit dem Wert PARAMETER_EMPTY durchgeführt, der in der Datei UniTrendDefines.mqh deklariert ist. Die Konstante erhält den Wert INT_MAX (ein Wert, der die Grenzen der realen Werte der Level weit überschreitet).
Ein weiterer, kleiner Unterschied betrifft die Funktion OnTimer(). Die Methode Calculated() wird aufgerufen, um zu prüfen, ob der Indikator berechnet wurde, da einige Varianten für den Trend nur einen Indikator überprüfen müssen, andere aber zwei. Das lässt sich nur innerhalb der Indikatorklassen ermitteln.
Im Ergebnis erhalten einen weiteren, universellen und bequemen Indikator (Fig. 10).
Fig. 10. Ein universeller Trendindikator mit grafischem Interface
Hinweis: Zusätzlich zur Anzeige des Namens der aus der Liste gewählten Variante, wird auch der verwendete Indikatortyp im Fenster des Indikators angezeigt, oben links in der Ecke. Neben dem Typ werden auch die Werte aller Parameter (in Klammern) angezeigt. Sind die Werte der Level in Points angegeben, wird angezeigt, wie die Points in reale Werte umzurechnen sind(Fig. 11).
Fig. 11. Darstellung von Parametern in Points
Der dargestellte Indikator ist Teil des Attachments unten, sein Dateiname ist Indicators/iUniTrendGUI.mq5.
Schlussfolgerung
Insgesamt umfasst der Indikator 46 verschiedene Möglichkeiten zur Trendbestimmung. Das grafische Interface, das einen schnellen Wechsel der Parameter der Indikator und ihres Typs erlaubt, ermöglicht eine komfortable Analyse der Historie. Durch die Möglichkeit von Benachrichtigungen ist er geeignet für einen praktischen Einsatz.
Es ist ein neuer Weg, ein grafisches Interface zu erstellen, der Vor- aber auch Nachteile hat. Der Nachteil ist die große Menge an Code und daher eine Menge Arbeit. Anders als die Klassen, die die Sichtbarkeit von Bedienelemente handhabt (wie beim universellen Oszillator und dem universellen Kanal), wurde hier ein vollständiges Bedienelement für fast jede Variante zur Trendbestimmung erstellt. Aber eine klare Trennung und die Unabhängigkeit des Codes der kombinierten Bedienelementes konnte die Entwicklung stark vereinfachen, und das vereinfacht weitere Entwicklungen, falls das notwendig werden sollte.
Anlagen
Dem Artikel beigefügt ist das Archiv mit allen benötigten Dateien. Die Dateien liegen bereits an den korrekten Verzeichnissen. Sie sollten in den gleichen Verzeichnissen des Terminals kopiert werden.
Übersetzt aus dem Russischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/ru/articles/3018
- 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.