Sound-Signale in Indikatoren

Andrey Khatimlianskii | 31 März, 2016


Einleitung


Obwohl der automatisierte Trade immer beliebter wird, handeln viele Händler immer noch manuell. Also, wo ein Expert Advisor einige Millisekunden benötigt, die aktuelle Marktsituation einzuschätzen, muss ein Mensch für die gleiche Einschätzung viel Zeit, Energie und - was am wichtigsten ist - Aufmerksamkeit geben.

Als auch ein paar Jahre zuvor, verwenden viele Trader für die Analyse Technische Indikatoren - einen oder mehrere gleichzeitig. Einige Strategien berechnen Indikatorswerte auf mehreren Zeiträumen gleichzeitig.

Wie soll man ein wichtiges Signal nicht verpassen? Es gibt mehrere Variante:
  • Einen Expert Advisor schreiben, der den Markt analysieren würde und über wichtige Ereignisse berichten;
  • Vor dem Bildschirm setzen bleiben und zehn Charts inzwischen umschalten, und dabei versuchen, die Informationen aus allen Charts zu vergleichen;
  • Das Alarm-System über Handelssignale zu allen verwendeten Indikatoren hinzufügen.
Die erste Variante ist, meiner Meinung nach, die richtigste. Aber es erfordert entweder Programmierungkenntnisse oder Geld für ihre Realisierung. Die zweite Variante ist sehr zeitaufwendig, mühsam und ineffizient. Die dritte Wahl ist sowas, zwischen den beiden erstgenannten Varianten. Man braucht viel weniger Fähigkeiten und weniger Zeit, sie zu realisieren. Aber sie kann wirklich das Leben (die Arbeit) des Traders, der manuell handelt, zu erleichtern.

Eben  der Realisierung der dritten Variante  widmet sich der Artikel. Jeder Trader, der den Artikel durchliest, kann danach zu seinen Indikatoren passenden Signalen hinzufügen.

Arten von Alarmen


Es gibt viele Möglichkeiten, die Indikatoren zu interpretieren. Menschen können sogar unterschiedlich die Bedeutung der Terminal-Indikatoren MetaTrader 4 Client verstehen. Ganz geschweige den möglichen Benutzer-Indikatoren...

Jemand kauft, wenn die MACD-Linie der Signal-Linie kreuzt, jemand wartet lieber auf die Kreuzung mit der nullwertigen Linie, und irgendjemand öffnet eine Long-Position, wenn MACD weniger als 0 ist und geht nach oben. Ich bin nicht in der Lage, alle möglichen Interpetationsvariante voraussichtlich festzustellen, deshalb erzähle ich lieber über das Prinzip, mit dem man den Signal-Block hinzuzufügen kann, und sie können abgesehen davon ein Signal zu meisten Indikatoren hinzufügen.

Also, welche Arten des Signals haben wir:
  • Die Kreuzung von zwei Linien eines Indikators (wie im obigen Beispiel - die Hauptlinie MACD mit der Signallinie);
  • Die Kreuzung einer bestimmten Ebene von Indikatorlinien (zum Beispiel die Hauptlinie MACD und die Null-Linie, Stoсhastic und Ebenen 70 und 30, CCI und Ebenen -100 und 100);
  • Die Richtungsänderung der Bewegung (beispielsweise AC und AO, normal MA);
  • Die Änderung des Standortes bezüglich des Preises (Parabolic SAR);
  • Eine Erscheinung des Pfeils über oder unter dem Preis (Fractals).
Wahrscheinlich gibt es noch andere Intrepetationsweisen, und ich habe sie einfach vergessen oder wusste über sie gar nicht. Deshalb lassen Sie uns erstmal diese 5 Weisen betrachten.

Alarmierungsarten


MetaTrader 4 und MQL4 ermöglicht ein Paar Arten zu realisieren, sowohl der optischen, auch der akustischen Alarmen:
  • eine normale Meldung im Bildschirm (die Funktion Comment);
  • Der Text im Protokoll (die Funktion Print);
  • Ein Fenster mit einer Meldung und ein Sound-Signal(die Funktion Alert);
  • ein spezielles Sound-Signal, in dem die verwendete Datei ausgewählt werden kann (die Funktion PlaySound).
Außerdem gibt es Funktionen für die Sendung einer Datei an den FTP-Server (die Funktion SendFTP ()), für die Erscheinung des Dialogfensters (MessageBox ()) und für die Sendung des Mails (Sendmail ()). Die Funktion SendFTP () wird kaum von einem normalen Benutzer gefordert, die Funktion MessageBox () passt nicht zur Verwendung im Indikator, denn sie stoppt seine Funktionalität, bevor das Meldungsfenster geschlossen wird, und obwohl die Funktion Sendmail () gut ist, SMS zu senden ist sie eher "gefährlich" bei der Verwendung - Sie bekommen eine unendliche und unregelbare Reihe von Nachrichten, wenn Sie ein Paar Indikatoren im Chart lassen. Die Funktion kann verwendet werden, aber es wäre besser mit dem EA, zum Beispiel eine Nachricht zu senden, wenn ein Signal gleichzeitig auf mehreren Indikatoren auftritt, sein Sie aber dabei aufmerksam.

In diesem Artikel werden wir nur akustische und visuelle Alarmierungsarten des MetaTrader 4 Client-Terminals betrachten.

Einer der bequemsten und einfachsten von ihnen ist die Funktion Alert, denn sie enthält sowohl einen Text und auch einen Ton. Außerdem speichert der Terminal die History der Alerte, so dass es möglich ist, zu sehen, welches Signal vor einer Stunde kam.

Aber wie allgemein bekannt ist, über Geschmack lässt sich nicht streiten. Deshalb mache ich eine Vorlage für alle erwähnten Arten (mit Ausnahme für SendFTP, MessageBox, und Sendmail) und sie können für sich die bequemsten aussuchen.

Alert-Frequenzfilter


Wenn Sie schon irgendwann Signalen in Indikatoren verwendet haben, hatten Sie sicherlich auch mit ihren Überfrequenz zu tun, vor allem, wenn es um kleineren Zeitrahmen geht. Das Problem kann mit einigen Arten gelöst werden:
  • Signalen auf Basis der gebildeten Bars zu definieren. Das ist die richtigste Lösung;
  • Signalen abwechseln - nach dem Kauf ist nur verkaufen und umgekehrt (es ist ein sehr logischer Schritt, den man auch zusammen mit den anderen verwenden kann);
  • Eine Pause zwischen den Signalen machen (keine gute Idee);
  • Geben Sie nur ein Signal pro bar (diese Einschränkung ist eher absichtlich).
Ob man das Signal von einem Null-Bar beim Handeln verwenden soll, der noch nicht gebildet ist, ist die persönliche Sache. Ich halte es zum Beispiel für eine falsche Entscheidung. Aber es gibt Indikatoren, die eine sofortige Reaktion brauchen - für Sie ist ein Bar zu viel. So, lassen wir dem Benutzer auswählen. Mehrere Signale zu kaufen, hätte kaum einen Sinn, deshalb werden wir alle Signale abwechseln. Und absichtliche Pausen machen wir lieber nicht. Wenn sie wirklich gefordert werden, dann schreibt man darüber in Kommentaren zu diesem Artikel.

Also, fangen wir an, zu realisieren.

Das erste Signal - die Kreuzung der zwei Indikator-Linien


Lassen Sie uns mit der MACD beginnen, die oben in den Beispielen gegeben wurde.

Unsere Hauptaufgabe ist, zu definieren, in welchen Arrays die Indikatorlinien gespeichert sind. Deswegen schauen wir auf den Code:
//---- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 2
#property  indicator_color1  Silver
#property  indicator_color2  Red
#property  indicator_width1  2
//---- indicator parameters
extern int FastEMA = 12;
extern int SlowEMA = 26;
extern int SignalSMA = 9;
//---- indicator buffers
double MacdBuffer[];
double SignalBuffer[];

Geben Sie bitte Acht auf den Kommentar "indicator buffers" - das ist eben das, was wir gesucht haben. Solche Arrays haben meistens einen intuitiv klaren Namen (MacdBuffer - der Werte-Buffer der Hauplinie  MACD, SignalBuffer - der Buffer der Signallinie) und sie sind immer außer den Funktionen init, deinit und start.

Wenn es viele Arrays gibt und es ist schwierig, zu verstehen, wer von ihnen notwendig ist, schauen Sie auf die Funktion init - alle Arrays, die im Chart angezeigt sind, sie werden durch die Funktion SetIndexBuffer mit einer Nummer verankert:
int init()
  {
//---- drawing settings
   SetIndexStyle(0, DRAW_HISTOGRAM);
   SetIndexStyle(1, DRAW_LINE);
   SetIndexDrawBegin(1, SignalSMA);
   IndicatorDigits(Digits + 1);
//---- indicator buffers mapping
   SetIndexBuffer(0, MacdBuffer);
   SetIndexBuffer(1, SignalBuffer);
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName("sMACD(" + FastEMA + "," + SlowEMA + "," + SignalSMA + ")");
   SetIndexLabel(0, "sMACD");
   SetIndexLabel(1, "sSignal");
//---- initialization done
   return(0);
  }
In dieser Reihenfolge (von 0 bis 7) wird der Wert der Indikator-Linie im Fenster DataWindow angezeigt. Die Namen, die Sie dort sehen können, werden durch die Funktion SetIndexLabel gegeben - das ist die dritte Identifizierungsmethode.

Nun, wenn wir wissen, wo die notwendigen Daten gespeichert sind, können wir den Signal-Block realisieren. Dazu lassen Sie uns bis zum Ende der Funktion Start gehen - über dem letzten Operator return:

   for(i = 0; i < limit; i++)
       SignalBuffer[i] = iMAOnArray(MacdBuffer, Bars,S ignalSMA, 0, MODE_SMA, i);
//---- done
 
// Und hier fügen wir unseren Code hinzu
 
   return(0);
  }
//+------------------------------------------------------------------+
In keinem Fall sollte der Signal-Block zur Loop der Indikator-Berechnung hinzugefügt werden - diese Ausführung verlangsamt die Arbeit und bringt nichts.

Also, beginnen zu schreiben:
    //---- Statistische Variablen, wo die Zeit
    //---- des letzten Bars und die Richtung des letzten Signals gespeichert sind
    static int PrevSignal = 0, PrevTime = 0;
 
    //---- Wenn kein Null-Bar zur Analyse ausgewählt wurde, dann hat es keinen Sinn, das Signal mehrmals
    //---- zu überprüfen. Wenn es keinen neuen Bar begonnen hat, dann verlassen wir es.
    if(SIGNAL_BAR > 0 && Time[0] <= PrevTime ) 
        return(0);
    //---- Merken wir an, dass dieser Bar überprüft wurde
    PrevTime = Time[0];
Jedes Mal, wenn die Funktion start ausgeführt wird, wird auch unser Code ausgeführt. Normale Variable werden nach jeder Ausführung der Funktion auf 0 zurückgesetzt. Zwecks der Speicherung des letzten Signals und der Nummer des berechneten Bars haben wir zwei statistischen Variablen angezeigt.
Weiter wird eine  einfache Überprüfung durchgeführt, ob ein Bar begonnen hat(es funktioniert nur dann, wenn SIGNAL_BAR mehr als 0 ist).

Übrigens, haben wie die Variable SIGNAL_BAR viel früher angezeigt, vor der Funktion init:
double     SignalBuffer[];
 
//---- Die Nummer des Bars, unter dieser Nummer wird das Signal gesucht
#define SIGNAL_BAR 1
 
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
Geben Sie Acht auf das Verzeichnis #define - Der Kompilator wird im ganzen Code die Variable SIGNAL_BAR mit dem gegebenen Wert (1) auswechseln.

Nun ist eigentlich der Code des Signals:
    //---- Wenn das vorherige Signal Sell war oder das ist der erste Start(PrevSignal=0)
    if(PrevSignal <= 0)
      {
        //---- Überprüfen Wir, ob die Linien im letzten Bar einander nicht gekreuzt haben:
        if(MacdBuffer[SIGNAL_BAR] - SignalBuffer[SIGNAL_BAR] > 0 && 
           SignalBuffer[SIGNAL_BAR+1] - MacdBuffer[SIGNAL_BAR+1] >= 0)
          {
            //---- Wenn Sie einander gekreuzt haben, dann markieren wir, dass es das letzte Signal war
            PrevSignal = 1;
            //---- und wir liefern die Information:
            Alert("sMACD (", Symbol(), ", ", Period(), ")  -  BUY!!!");
//            Print("sMACD (", Symbol(), ", ", Period(), ")  -  BUY!!!");
//            Comment("sMACD (", Symbol(), ", ", Period(), ")  -  BUY!!!");
//            PlaySound("Alert.wav");
          }
      }

Es ist hier auch alles einfach. Wenn das vorherige Signal auch Sell war, überprüfen Wir, ob die Linien im letzten Bar einander nicht gekreuzt haben:
wenn  der Wert  der Hauptlinie MACD im Bar №1 mehr ist, als der Wert der Signallinie im Bar №1
    und
der Wert der Signallinie im Bar №2 mehr ist, als der Wert der Linie MACD im Bar №2
    Dann heißt es,
dass die Linie einander gekreuzt haben.

Weiter markieren wir, dass das letzte Signal für Buy war, und liefern die Meldung. Beachten Sie  die drei kommentierten Zeilen - das sind  drei Alarm Variationen. Sie können einige oder alle von ihnen decomment oder löschen. Ich lass nur Alert standardmäßig als das bequemste.
In der Funktion Playsound kann gegeben werden, welche Audio-Datei abgespielt werden soll. Diese Datei müssen im Verzeichnis MetaTrader 4\sounds\ sein und muss die Erweiterung wav haben. Zum Beispiel kann ein spezielles Alarmsignal für Buy zugeordnet werden, ein anderes - für die SELL-Benachrichtigung, oder es können verschiedene Töne für verschiedene Indikatoren sein, usw..

Das Signal für Buy ist ähnlich:
    //---- Genauso ähnlich ist es für das Signal des Sells
    if(PrevSignal >= 0)
      {
        if(SignalBuffer[SIGNAL_BAR] - MacdBuffer[SIGNAL_BAR] > 0 && 
           MacdBuffer[SIGNAL_BAR+1] - SignalBuffer[SIGNAL_BAR+1] >= 0)
          {
            PrevSignal = -1;
            Alert("sMACD (", Symbol(), ", ", Period(), ")  -  SELL!!!");
//            Print("sMACD (", Symbol(), ", ", Period(), ")  -  SELL!!!");
//            Comment("sMACD (", Symbol(), ", ", Period(), ")  -  SELL!!!");
//            PlaySound("Alert.wav");
          }
      }

Weitere Signale


Nun, wenn wir den Indikator-Code bekannt haben, wird es viel einfacher für uns, andere Alarmierungsblöcke zu schreiben. Nur die "Formel" wird geändert, der Rest des Codes wird nur kopiert.

Das Alarmsignal über die Kreuzung einer bestimmten Ebene ist sehr ähnlich mit dem Signal der Linien-Kreuzung. Ich habe es zu Stochastic hinzugefügt, aber Sie können sowas mit einem anderen Indikator machen:
    if(PrevSignal <= 0)
      {
        if(MainBuffer[SIGNAL_BAR] - 30.0 > 0 && 
           30.0 - MainBuffer[SIGNAL_BAR+1] >= 0)
          {
            PrevSignal = 1;
            Alert("sStochastic (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(70.0 - MainBuffer[SIGNAL_BAR] > 0 && 
           MainBuffer[SIGNAL_BAR+1] - 70.0 >= 0)
          {
            PrevSignal = -1;
            Alert("sStochastic (", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }
Wie Sie sehen können, der Indikator wird Buy ausführen, wenn die Linie %K (MainBuffer) der Ebene 30 von hinten nach oben gekreuzt hat, und führt bei der Kreuzung der Ebene 70 von oben nach unten Sell aus.

Die dritte Art von Alarmen ist die Alarm-Informierung über die veränderte Bewegungsrichtung. Wir werden sie im Beispiel mit dem AC-Indikator erwähnen. Beachten Sie, dass  fünf Puffer in diesem Indikator verwendet werden:
//---- indicator buffers
double     ExtBuffer0[];
double     ExtBuffer1[];
double     ExtBuffer2[];
double     ExtBuffer3[];
double     ExtBuffer4[];

ExtBuffer3 und ExtBuffer4 werden für Zwischenberechnungen verwendet, ExtBuffer0 speichert immer die Indikatorwerte, ExtBuffer2 und ExtBuffer3 "Farbe" färben Spalte in 2 Farben. Da wir nur den Indikatorwert benötigen, werden wir ExtBuffer0 verwenden:
    if(PrevSignal <= 0)
      {
        if(ExtBuffer0[SIGNAL_BAR] - ExtBuffer0[SIGNAL_BAR+1] > 0 &&
           ExtBuffer0[SIGNAL_BAR+2] - ExtBuffer0[SIGNAL_BAR+1] > 0)
          {
            PrevSignal = 1;
            Alert("sAC (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(ExtBuffer0[SIGNAL_BAR+1] - ExtBuffer0[SIGNAL_BAR] > 0 &&
           ExtBuffer0[SIGNAL_BAR+1] - ExtBuffer0[SIGNAL_BAR+2] > 0)
          {
            PrevSignal = -1;
            Alert("sAC (", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }

Wenn der Indikatorwert mal sinkt und später begann, zu erhöhen, geben wir ein Signal für Buy, wenn umgekehrt ist - für SELL.

Die vierte Art vom Alarm - Benachrichtigung über geänderte Lage im Preis - ist eher selten.
Aber es kommt manchmal vor, beispielsweise in parabolisch. Wir werden die "Formel" von diesem Beispiel schreiben:
    if(PrevSignal <= 0)
      {
        if(Close[SIGNAL_BAR] - SarBuffer[SIGNAL_BAR] > 0)
          {
            PrevSignal = 1;
            Alert("sParabolic Sub (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(SarBuffer[SIGNAL_BAR] - Close[SIGNAL_BAR] > 0)
          {
            PrevSignal = -1;
            Alert("sParabolic Sub(", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }

Es ist hier alles einfach - wir vergleichen den Indikatorwert mit dem Exit-Price des Bars. Beachten Sie, dass jede Preis-Berührung des Parabolics mit einer Warnung begleitet wird, wenn SIGNAL_BAR für 0 gesetzt ist.

Das letzte Alarm informiert über die Erscheinung eines Pfeils im Chart. Es scheint eher selten in Standard-Indikatoren, aber es kommt sehr oft in Benutzer "Pivot-Finder" vor. Ich werde diese Art von Signalen im Indikator Fractals betrachten ( der Quellcode in MQL 4 ist in Code Base: Fractals).

Solche Indikatoren haben ein gemeinsames Merkmal: sie sind nicht gleich 0 (oder EMPTY_VALUE) in den Orten, wo sie in einem Chart gezeichnet wurden. Auf allen anderen Bars sind ihre Puffer leer. Das heißt, das Signal zu definieren, ist es genug, nur den Pufferwert mit 0 zu vergleichen:
    if(PrevSignal <= 0 )
      {
        if(ExtDownFractalsBuffer[SIGNAL_BAR] > 0)
          {
            PrevSignal = 1;
            Alert("sFractals (", Symbol(), ", ", Period(), ")  -  BUY!!!");
          }
      }
    if(PrevSignal >= 0)
      {
        if(ExtUpFractalsBuffer[SIGNAL_BAR] > 0)
          {
            PrevSignal = -1;
            Alert("sFractals (", Symbol(), ", ", Period(), ")  -  SELL!!!");
          }
      }

Aber, wenn Sie einen Indikator mit einem solchen Code zum Chart hinzufügen, werden Sie  nie Warnungen erhalten. Fraktale haben eine Besonderheit - sie verwenden zwei zukünftigen Bars für Analysen, so dass die Pfeile nur auf Bar №2 erscheinen(oder im dritten vom Anfang, - 0-ste, 1-te, 2-te ). Also, um Signale im Betrieb zu haben, ist es notwendig, SIGNAL_BAR als 2 einzustellen:
//---- Die Nummer des Bars, unter dieser Nummer wird das Signal gesucht
#define SIGNAL_BAR 2

Das ist alles, Warnungen werden funktionieren!

Abschluss


Der Artikel enthält  eine Beschreibung von den verschiedenen Methoden, um akustische Signale zu Indikatoren hinzuzufügen. Es wurden auch nebenbei solche Begriffe definiert, wie Die Interpretationsmethode des Signals (Art der Warnung), Art und Weise der Alarmierung und Alarmfrequenzfilter.

Die folgenden Arten von Warnungen wurden definiert und realisiert:
  • Die Kreuzung der zwei Linien eines Indikators;
  • Die Kreuzung der Indikatorslinien einer bestimmten Ebene;
  • Die Alarm-Informierung über die veränderte Bewegungsrichtung;
  • Die Änderung des Standortes bezüglich des Preises;
  • Eine Erscheinung des Pfeils über oder unter dem Preis.
Für die Benachrichtigungen wurden folgenden Funktionen ausgesucht:
  • Comment() - eine normale Meldung im Bildschirm;
  • Print() - für eine Meldungsdarstellung im Chronik;
  • Alert() - für eine Meldungsdarstellung im speziellen Fenster und für das Soundssignal;
  • PlaySound() - für das Abspiele eine Soundsdatei.
Um die Alert-Frequenze zu verringern:
  • Bei der Definition eines Signals sollte ein gebildeter Bar verwendet werden;
  • Alle Signalen abwechseln - nach dem Kauf ist nur verkaufen und umgekehrt.
Im Beispiel von 5 Indikatoren, die 5 Signalarten entsprechen, wurden ihre Signal-Blocken betrachtet. Die erhaltenden Indikatoren können runtergeladen werden - die Links sind am Ende.

Ich hoffe, sie haben jetzt geglaubt, dass es beim Hinzufügen eines Signal-Blocks zu Indikatoren kein Problem gibt - das ist für jeden machbar. Wahrscheinlich wird es ab jetzt weniger Posten in Foren um dieses Problem und wir könnten uns weiter entwickeln.