Implementierung der Automatischen Analyse der Elliott-Wellen in MQL5

MRoVas | 15 April, 2016


Einleitung

Eine der populärsten Methoden zur Analyse von Märkten ist das Prinzip der Elliott-Wellen. Diese Analyse ist jedoch ziemlich kompliziert, sodass wir hierfür zusätzliche Tools verwenden müssen. Eines dieser Instrumente ist der automatische Marker.

Dieser Beitrag beschreibt die Erzeugung eines automatischen Analyseinstruments der Elliott-Wellen in der MQL5-Sprache. Es wird davon ausgegangen, dass der Leser bereits mit der Wellentheorie vertraut ist. Falls nicht, wird empfohlen, sich vor dem Lesen dieses Artikels in den entsprechenden Quellen darüber zu informieren.


1. Das Prinzip der Elliott-Wellen

Elliott-Wellen - ist ein theoretisches Modell des Verhaltens von Märkten, das von Ralph Nelson Elliott entwickelt wurde. Laut Elliott unterliegen alle Kursbewegungen auf dem Markt der menschlichen Psychologie und stellen einen zyklischen Prozess an Änderungen der Impuls- zu Korrekturwellen, und umgekehrt, dar.

Impulswellen sind eine Abfolge von fünf Kursschwankungen; Korrekturwellen sind eine Abfolge von drei oder fünf Kursschwankungen . In ihrer Form, Struktur und den auf sie anwendbaren Regeln unterteilen sich Impulswellen in die folgenden fünf Arten:

1. Impulse:
Abb. 1 Impuls
Abb. 1 Impuls
  • Das Ende der zweiten Welle kommt nie über den Anfang der ersten Welle;
  • Die dritte Welle erstreckt sich immer jenseits der Spitze der ersten Welle;
  • Das Ende der vierten Welle kommt nie über nie die Spitze der ersten Welle;
  • Die dritte Welle ist niemals die kürzeste aller agierenden Wellen;
  • Die dritte Welle ist immer ein Impuls;
  • Die erste Welle ist entweder ein Impuls oder eine führende Diagonale;
  • Die fünfte Welle kann entweder ein Impuls oder eine Diagonale sein;
  • Die zweite Welle könnte die Form jeder Korrekturwelle annehmen, jedoch nie zu einem Dreieck werden;
  • Die vierte Welle könnte die Form jeder Korrekturwelle annehmen.
2. Führende Diagonale:
Abb. 2 Führende Diagonale
Abb. 2 Führende Diagonale
  • Das Ende der zweiten Welle kommt nie über den Anfang der ersten Welle;
  • Die dritte Welle erstreckt sich immer jenseits der Spitze der ersten Welle;
  • Das Ende der vierten Welle kommt immer über die Spitze der ersten Welle, reicht jedoch nie über den Anfang der dritten Welle hinaus;
  • Die dritte Welle ist niemals die kürzeste aller agierenden Wellen;
  • Die dritte Welle ist immer ein Impuls;
  • Die erste Welle ist entweder ein Impuls oder eine führende Diagonale;
  • Die fünfte Welle kann entweder ein Impuls oder eine Diagonale sein;
  • Die zweite Welle könnte die Form jeder Korrekturwelle annehmen, jedoch nie zu einem Dreieck werden;
  • Die vierte Welle könnte die Form jeder Korrekturwelle annehmen;
3. Diagonalen:
Abb. 3 Diagonale
Abb. 3 Diagonale
  • Das Ende der zweiten Welle kommt nie über den Anfang der ersten Welle;
  • Die dritte Welle erstreckt sich immer jenseits der Spitze der ersten Welle;
  • Das Ende der vierten Welle kommt meist über die Spitze der ersten Welle, reicht jedoch nie über die Spitze der dritten Welle hinaus;
  • Die dritte Welle ist niemals die kürzeste aller agierenden Wellen;
  • Die ersten, zweiten und dritten Wellen könnten die Form jeder Korrekturwelle annehmen, jedoch nie zu einem Dreieck werden;
  • Die vierten und fünften Welle könnten die Form jeder Korrekturwelle annehmen;
Korrekturwellen sind klassifiziert in:
4. Zigzag:
Abb. 4 Zigzag
Abb. 4 Zigzag
  • Welle A kann die Form eines Impuls oder einer führenden Diagonale annehmen;
  • Welle C kann die Form eines Impuls oder einer Diagonale annehmen;
  • Welle B kann die Form jeder Korrekturwelle annehmen;
  • Welle C erstreckt sich über die Spitze von Welle A hinaus;
  • Das Ende von Welle B geht nicht über den Anfang von Welle A;
5. Flats:
Abb. 5 Flat
Abb. 5 Flat
  • Welle A könnte die Form jeder Korrekturwelle annehmen, jedoch nie zu einem Dreieck werden;
  • Welle B kann die Form jeder Korrekturwelle annehmen;
  • Welle C könnte die Form eines Impuls oder einen Diagonale annehmen;
6. Doppel-Zigzags:
Abb. 6 Doppel-Zigzag
Abb. 6 Doppel-Zigzag
  • Welle W und Welle Y können die Form eines Zigzags annehmen;
  • Welle X kann die Form jeder Korrekturwelle annehmen;
  • Welle Y erstreckt sich über die Spitze von Welle W;
  • Das Ende von Welle X geht nicht über den Anfang von Welle W;
7. Dreifach-Zigzags:
Abb. 7 Dreifach-Zigzag
Abb. 7 Dreifach-Zigzag
  • Welle W, Welle Y und Welle Z nehmen die Form eines Zigzags an;
  • Welle X können die Form jeder Korrekturwelle annehmen, jedoch nie zu einem Dreieck werden;
  • Welle XX kann die Form jeder Korrekturwelle annehmen;
  • Welle Y erstreckt sich über die Spitze von Welle W;
  • Welle Z erstreckt sich über die Spitze von Welle Y;
  • Das Ende von Welle X geht nicht über den Anfang von Welle W;
  • Das Ende von Welle XX geht nicht über den Anfang von Welle Y;
8. Double Threes:
Abb. 8 Double Three
Abb. 8 Double Three
  • Welle W nimmt die Form jeder Korrekturwelle an, wird jedoch nie zu einem Dreieck;
  • Welle X und Welle Y nehmen die Form jeder Korrekturwelle an;
9. Triple Threes:
Abb. 9 Triple Three
Abb. 9 Triple Three
  • Welle W, Welle X und Welle Y können die Form jeder Korrekturwelle annehmen, jedoch nie zu einem Dreieck werden;
  • Welle XX und Welle Z könnten die Form jeder Korrekturwelle annehmen;
10. Zusammenziehendes Dreieck:
Abb. 10 Zusammenziehendes Dreieck
Abb. 10 Zusammenziehendes Dreieck
  • Welle C übersteigt niemals die Kurslimits von Welle B;
  • Welle D übersteigt niemals die Kurslimits von Welle C;
  • Welle E übersteigt niemals die Kurslimits von Welle D;
  • Welle A, Welle B und Welle C können die Form jeder Korrekturwelle annehmen, jedoch nie zu einem Dreieck werden;
  • Welle D und Welle E könnten die Form jeder Korrekturwelle annehmen;
11. Expandierendes Dreieck:
Abb. 11 Expandierendes Dreieck
Abb. 11 Expandierendes Dreieck
  • Welle C ist in ihrer Länge immer größer als Welle B;
  • Welle D ist in ihrer Länge immer größer als Welle C;
  • Welle A, Welle B und Welle C könnten die Form jeder Korrekturwelle annehmen, jedoch nie zu einem Dreieck werden;
  • Welle D und Welle E könnten die Form jeder Korrekturwelle annehmen;

Die oben präsentierten Wellenmodelle und Regeln entsprechen nur dem klassischen Verständnis der Wellenanalyse.

Es gibt auch noch eine moderne Vorstellung dieser Analyse, die sich bei der Betrachtung des Forex-Markts herausgebildet hat. So wird z.B. ein neues Modell des schiefwinkliges (gleitenden) Dreiecks gefunden, Impulse mit dem Dreieck in der zweiten Welle identifiziert, usw.

Wie man in Abb. 1-11 deutlich erkennen kann, besteht jeder Impuls oder Korrekturwelle aus demselben Impuls und Korrekturwellen (die gepunkteten Linien), doch in geringerem Ausmaß. Dies ist das sog. Fraktal (Verschachtelung) der Elliott-Wellen: Wellen großen Ausmaßes bestehen aus Wellen geringeren Ausmaßes, die ihrerseits wiederum aus Wellen noch geringeren Ausmaßes bestehen usw.

Mit dieser Bemerkung können wir die Kurzeinführung in das Prinzip der Elliott-Wellen abschließen und uns dem Thema der automatischen Kennzeichnung von Wellen zuwenden.


2. Algorithmus der automatischen Kennzeichnung von Elliott-Wellen

Wie sie wahrscheinlich bereits erkannt haben, ist die Analyse der Elliott-Wellen komplex und vielschichtig. Daher hat man bereits zu Beginn mit der Suche nach Instrumenten und ihre Anwendung begonnenen, um diesen Prozess zu erleichtern.

Ein solches Tool ist der Mechanismus der automatischen Kennzeichnung von Elliott-Wellen geworden.

Es lassen sich hier zwei Prinzipien der automatischen Kennzeichnung unterscheiden:

  1. In Übereinstimmung mit der Fraktalstruktur der Wellen, wird die Analyse von oben nach unten durchgeführt - also von den größeren zu den kleineren Wellen;
  2. Die Analyse wird durch eine direkte Aufzählung aller möglichen Optionen durchgeführt.

Abb. 12 zeigt ein Blockdiagramm der automatischen Analyse der Elliott-Wellen.

Abb. 12 Ein Blockdiagramm der automatischen Analyse der Elliott-Wellen
Abb. 12 Ein Blockdiagramm der automatischen Analyse der Elliott-Wellen

Sehen wir uns den Algorithmus auf Grundlage des Beispiels der automatischen Kennzeichnung des Impulses mal genauer an (vgl. Abb. 13).

Im ersten Stadium, am nötigen Zeitintervall des Kurscharts, mittels des "Zigzags", ist die Anzahl, der zur Ausführung der Kennzeichnung nötigen Punkte, hervorgehoben. Die Anzahl der Punkte hängt davon ab, welche Art von Welle wir analysieren möchten. Für die Analyse des Impulses braucht man z.B. sechs Punkte - 5 Scheitelpunkte und einen Startpunkt. Will man die Zigzag-Welle analysieren, braucht man dazu 4 Punkte - 3 Scheitelpunkte und einen Startpunkt.

Hat die Zigzag-Welle auf dem Kurschart sechs Punkte gefunden, kann man sofort eine Kennzeichnung des Impulses erzeugen: der erste Punkte = Startpunkt der ersten Welle; der zweite Punkte = Scheitelpunkt der ersten Welle; der dritte Punkte = Scheitelpunkt der zweiten Welle; der vierte Punkt = Scheitelpunkt der dritten Welle; der fünfte Punkte = Scheitelpunkt der vierten Welle und der sechste Punkte = Scheitelpunkt der fünften Welle.

In Abb. 13 hat der "Zigzag" 8 Punkte festgestellt. In diesem Fall ist es notwendig, alle möglichen Optionen und Kennzeichnungen der Welle nach diesen Punkten aufzuzählen. Es gibt davon fünf (jeweils in einer anderen Farbe markiert). Und jede Version der Kennzeichnung muss gemäß den Regeln überprüft werden.

Kennzeichnungs-Optionen
Abb. 13 Optionen der Markierung von Kennzeichnungen eines Impulses

Sollte, nach einer Prüfung vor dem Hintergrund der Regeln, die Kennzeichnung der Welle ein Impuls durch all seinen Parameter sein, werden all seine Sub-Wellen exakt auf die gleiche Art und Weise analysiert

Das gleiche gilt ganz genauso für die Analyse aller anderen Impuls- und Korrekturwellen.

 

3. Arten der Wellen für die automatische Kennzeichnung

Wie bereits erwähnt, wird die Analyse von oben nach unten durchgeführt, indem man dem Programm Anweisungen gibt, auf einem gegebenen Intervall eine Welle zu finden. Es ist jedoch auf dem größten Intervall unmöglich, den Status der Welle - ihren Anfang und Ende - festzustellen. So eine Welle nennen wir nicht begonnenen und nicht beendet.

Alle Wellen lassen sich in die folgenden Gruppen unterteilen:

  1. Nicht begonnene Wellen:
    1. Wellen mit einer nicht begonnenen ersten Welle - 1-2-3-4-5 (z.B. ein Impuls mit einer nicht begonnenen Welle 1, die nötige Zahl an Punkten - 5), und 1-2-3 (z.B. ein Zigzag mit einer nicht begonnenen Welle A; die nötige Zahl an Punkten - 3);
    2. Wellen mit einer nicht begonnenen zweiten Welle - 2-3-4-5 (z.B. eine Diagonale mit einer nicht begonnenen Welle 2, die nötige Zahl an Punkten - 4), und 2-3 (z.B. ein Flat mit einer nicht begonnenen Welle B; die nötige Zahl an Punkten - 2);
    3. Wellen mit einer nicht begonnenen dritten Welle - 3-4-5 (z.B. ein Dreifach-Zigzag mit einer nicht begonnenen Welle Y; die nötige Zahl an Punkten - 3);
    4. Wellen mit einer nicht begonnenen vierten Welle - 4-5 (z.B. ein Dreieck mit einer nicht begonnenen Welle D; die nötige Zahl an Punkten -2);
    5. Wellen mit einer nicht begonnenen fünften Welle - 5 (z.B. ein Impuls mit einer nicht begonnenen Welle 5, die nötige Zahl an Punkten - 1);
    6. Wellen mit einer nicht begonnenen dritten Welle - 3 (z.B. ein Double Three mit einer nicht begonnenen Welle Z; die nötige Zahl an Punkten - 1);
  2. Nicht beendete Wellen:
    1. Wellen mit einer nicht beendeten fünften Welle - 1-2-3-4-5 (z.B. ein Impuls mit einer nicht beendeten Welle 5, die nötige Zahl an Punkten - 5);
    2. Wellen mit einer nicht beendeten vierten Welle - 1-2-3-4> (z.B. ein Dreifach-Zigzag mit einer nicht beendeten Welle XX, die nötige Zahl an Punkten - 4);
    3. Wellen mit einer nicht beendeten dritten Welle - 1-2-3> (z.B. eine führende Diagonale von der nicht beendeten Welle 3, die nötige Zahl an Punkten -3);
    4. Wellen mit einer nicht beendeten zweiten Welle - 1-2> (z.B. ein Zigzag mit einer nicht beendeten Welle B; die nötige Zahl an Punkten -2);
    5. Wellen mit einer nicht beendeten ersten Welle - 1> (z.B. ein Flat mit einer nicht beendeten Welle A; die nötige Zahl an Punkten -1);
  3. Nicht begonnene und nicht beendete Wellen:
    1. Wellen mit einer nicht begonnenen ersten Welle und einer nicht beendeten zweiten Welle -1-2>(z.B. ein Zigzag mit einer nicht begonnenen Welle A und einer nicht beendeten Welle B; die nötige Zahl an Punkten - 1);
    2. Wellen mit einer nicht begonnenen zweiten Welle und einer nicht beendeten dritten Welle - 2-3>(z.B. a Zigzag mit einer nicht begonnenen Welle B und einer nicht beendeten Welle C; die nötige Zahl an Punkten - 1);
    3. Wellen mit einer nicht begonnenen dritten Welle und einer nicht beendeten vierten Welle - 3-4>< (z.B. ein Impuls mit einer nicht begonnenen Welle 3 und einer nicht beendeten Welle 4, die nötige Zahl an Punkten - 1);
    4. Wellen mit einer nicht begonnenen vierten Welle und einer nicht beendeten fünften Welle - 4-5> (z.B. ein Impuls mit einer nicht begonnenen Welle 4 und einer nicht beendeten Welle 5, die nötige Zahl an Punkten - 1);
    5. Wellen mit einer nicht begonnenen ersten und einer nicht beendeten dritten Welle - 1-2-3> (z.B. das Triple Three mit einer nicht begonnenen Welle W und einer nicht beendeten Welle Y; die nötige Zahl an Punkten - 2);
    6. Wellen mit einer nicht begonnenen zweiten Welle und einer nicht beendeten vierten Welle -2-3-4>(z.B. eine führende Diagonale mit einer nicht begonnenen Welle 2 und einer nicht beendeten Welle 4, die nötige Zahl an Punkten - 2);
    7. Wellen mit einer nicht begonnenen dritten Welle und einer nicht beendeten fünften Welle - 3-4-5>(z.B. eine Diagonale mit einer nicht begonnenen Welle 3 und einer nicht beendeten Welle 5, die nötige Zahl an Punkten - 2);
    8. Wellen mit einer nicht begonnenen ersten Welle und einer nicht beendeten vierten Welle -1-2-3-4>(z.B. ein Triple Three mit einer nicht begonnenen Welle W und einer nicht beendeten Welle XX; die nötige Zahl an Punkten - 3);
    9. Wellen mit einer nicht begonnenen zweiten Welle und einer nicht beendeten fünften Welle - 2-3-4-5 (z.B. ein Impuls mit einer nicht begonnenen Welle 2 und einer nicht beendeten Welle 5; die nötige Zahl an Punkten - 3);
    10. Wellen mit einer nicht begonnenen ersten Welle und einer nicht beendeten fünften Welle -1-2-3-4-5>(z.B. ein Dreifach-Zigzag mit einer nicht begonnenen Welle W und einer nicht beendeten Welle Z; die nötige Zahl an Punkten - 4);
  4. Abgeschlossene Wellen - 1-2-3-4-5 (die nötige Zahl an Punkten - 6) und 1-2-3 (die nötige Zahl an Punkten - 4).

Das Zeichen "<" nach der Nummer der Welle gibt an, dass sich nicht begonnen hat. Das Zeichen ">" nach der Nummer der Welle gibt an, dass sich nicht beendet ist.

Auf Abb. 14 erkennen wir folgende Wellen:

  1. Eine Welle mit einer ersten, nicht begonnenen Welle A -A -B-C;
  2. Eine Welle mit einer nicht begonnenen, ersten Welle W und einer nicht beendeten, zweiten Welle X -W<-X>;
  3. Abgeschlossene Wellen B and C;

Nicht begonnene und nicht beendete Wellen 
Abb. 14. Nicht begonnene und nicht beendete Wellen


4. Beschreibung der Datenstruktur des automatischen Analyseinstruments für Elliott-Wellen

Um ein automatisches Analyseinstrument für Elliott-Wellen zu schreiben, brauchen wir folgende Datenstrukturen:

4.1 Struktur der Beschreibung der analysierten Welle im Programm:

// The structure of the description of the analyzed waves in the program
struct TWaveDescription
  {
   string            NameWave;    // name of the wave
   int               NumWave;     // number of sub-waves in a wave
   string            Subwaves[6]; // the names of the possible sub-waves in the wave
  };

4.2 Eine Klasse zum Ablegen der Parameter für eine bestimmte Welle: 

// A class for storing the parameters of a wave
class TWave
  {
public:
   string            Name;            // name of the wave
   string            Formula;         // the formula of the wave (1-2-3-4-5, <1-2-3 etc.)
   int               Level;           // the level of the wave
   double            ValueVertex[6]; // the value of the top of the wave
   int               IndexVertex[6]; // the indexes of the top of the waves
  };

4.3 Eine Klasse zum Ablegen der Werte der Scheitelpunkte und der Indices des Scheitelpunkts des Zigzags:

// A class for storing the values of vertexes and indexes of the zigzag
class TZigzag:public CObject
  {
public:
   CArrayInt        *IndexVertex;    // indexes of the vertexes of the zigzag
   CArrayDouble     *ValueVertex;    // value of the vertexes of the zigzags
  };

4.4 Eine Klasse zur Abbildung des Wellen-Baums:

// A class for the presentation of the tree of the waves
class TNode:public CObject
  {
public:
   CArrayObj        *Child;    // the child of the given tree node
   TWave            *Wave;      // the wave, stored in the given tree node
   string            Text;       // text of the tree node
   TNode            *Add(string Text,TWave *Wave=NULL) // the function of adding the node to the tree
     {
      TNode *Node=new TNode;
      Node.Child=new CArrayObj;
      Node.Text =Text;
      Node.Wave=Wave;
      Child.Add(Node);
      return(Node);
     }
  };

4.5 Die Struktur zum Ablegen der, vom Zigzag gefundenen Punkte:

// The structure for storing the points, found by the zigzag
struct TPoints
  {
   double            ValuePoints[];  // the values of the found points
   int               IndexPoints[];  // the indexes of the found points
   int               NumPoints;       // the number of found points
  };

4.6 Eine Klasse zum Ablegen der Parameter des bereits analysierten Abschnitts des Charts:

// A class for storing the parameters of the already analyzed section, corresponding to the wave tree node
class TNodeInfo:CObject
  {
public:
   int               IndexStart,IndexFinish;  // the range of the already analyzed section
   double            ValueStart,ValueFinish;  // the edge value of the already analyzed section
   string            Subwaves;                  // the name of the wave and the group of the waves
   TNode            *Node;                      // the node, pointing to the already analyzed range of the chart
  };

4.7 Eine Klasse zum Ablegen der Markierung der Wellen vor ihrer Abbildung auf dem Chart:

// A class for storing the marking of waves before placing them on the chart
class TLabel:public CObject
  {
public:
   double            Value;  // the value of the vertex
   int               Level;  // the level of the wave
   string            Text;    // the marking of the wave
  };

 

5. Beschreibung der Funktion des automatischen Analyseinstruments für Elliott-Wellen

Um ein automatisches Analyseinstrument für Elliott-Wellen zu schreiben, brauchen wir folgende Funktionen:

5.1. Zigzag

Die Suchfunktion nach den Extremwerten des "Zigzags":

int Zigzag(intH,int Start,int Finish,CArrayInt *IndexVertex,CArrayDouble *ValueVertex)

Ein Schlüsselelement im automatischen Analyseinstrument der Elliott-Wellen ist der "Zigzag", nach dem die Wellen gebaut werden. Die Berechnung des "Zigzag" mit irgendeinem Parameter muss sehr rasch erfolgen.

In unserem Analyseinstrument verwenden wir den "Zigzag" aus dem Beitrag "Wie man schnelle Zigzags ohne Neuzeichnung schreibt".

Die Zigzag-Funktion berechnet den Zigzag mit dem Parameter H im Intervall von Start bis Ende und zeichnet dann die vier Indices der Scheitelpunkte bzw. die werte der Scheitelpunkte in die Arrays IndexScheitelpunkt und WertScheitelpunkt auf, deren Adressen in diese Funktion übertragen werden.

Die Zigzag-Funktion liefert die Anzahl der gefundenen Scheitelpunkte des "Zigzag". 

5.2. FillZigzagArray

Die Funktion des Füllens des "Zigzag" und Speicherung ihrer Parameter: 

void FillZigzagArray(int Start,int Finish)

Wie vorhin bereits dargestellt, müssen wir zunächst die notwendige Anzahl an Punkten auf dem Kurschart für die Kennzeichnung der Welle finden. Und dazu brauchen wir ein Array der Scheitelpunktes des "Zigzag" mit verschiedenen Parametern, die sich dann wiederholen, um diese Punkte zu finden. 

Die Funktion FillZigzagArray berechnet den "Zigzag" auf dem Intervall auf dem Chart von Start bis Ende mit allen möglichen Werten des Parameters H (bis die Anzahl der Scheitelpunkte des "Zigzag" weder "2" oder kleiner erreicht). Dann speichert sie die Information über die gefundenen Scheitelpunkte in den Objekten der Klasse TZigzag und zeichnet diese Objekte im globalen Array ZigzagArray auf, das sich wie folgt ankündigt:

CArrayObj *ZigzagArray;

5.3. FindPoints

Diese Suchfunktion auf einem gegebenen Intervall verlangt die Anzahl der Punkte auf einem Kurschart: 

bool FindPoints(int NumPoints,int IndexStart,int IndexFinish,double ValueStart,double ValueFinish,TPoints &Points)

Die Funktion FindPoints sucht nach den letzten drei NumPoints Punkten auf dem Kurschart im benötigten Bereich, von IndexStart bis IndexEnde und mit den benötigten Werten der ersten und letzten Punkte WertStart und WertEnde, speichert diese (die Punkte) in die Struktur der Points, deren Link in diese Funktion übertragen wird.

Wenn die benötigte Anzahl an Punkten gefunden ist, liefert die Funktion FindPoints 'true'; andernfalls liefert sie 'false'.

5.4. NotStartedAndNotFinishedWaves

Die Funktion der Analyse nicht begonnener und nicht beendeter Wellen:

void NotStartedAndNotFinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)

Die Funktion NichtBegonneneUndNichtBeendeteWellen analysiert alle Wellen der dritten Gruppe der Wellen - nicht begonnene und nicht beendete. Die Funktion analysiert die NumWave Welle (mit einem Wellenlevel Level), Wellen mit demselben übergeordneten Wellennamen (ParentWave.Name), die die Form von Sub-Wellen Wellen annehmen könnten (Form eines Zigzags, Flats, Doppel-Zigzag, und/oder, usw.). Die analysierte Welle NumWave wird im Knoten des Wellenbaums gespeichert - dem untergeordneten Knoten (child node).

Wenn z.B. ParentWave.Name = "Impuls", NumWave = 5, Sub-Wellen = "Impulse Diagonale und Level = 2, können wir sagen, dass die Funktion NichtBegonneneUndNichtBeendeteWellen die fünfte Welle des Impulses analysieren wird, mit ihrem Wellen-Level von zwei, und die die Form eines Impulses oder einer Diagonale annehmen kann.

Als Beispiel nehmen wir ein Block-Diagramm der Algorithmus-Analyse nicht begonnener und nicht beendeter Wellen 1<-2-3> in der Funktion NichtBegonneneUndNichtBeendeteWellen her:

  <img alt="Abb. 15 Das Block-Diagramm der Wellenanalyse mit der Formel "1"" Titel="Abb. 15 Das Block-Diagramm der Wellenanalyse mit der Formel "1"" src="http://p.mql5.com/data/2/260/fig15.gif" style="vertical-align:middle;" height="1746" width="750">
Abb. 15. Das Block-Diagramm der Wellenanalyse mit der Formel "1<-2-3>"

Wenn man die Funktion NichtBegonneneUndNichtBeendeteWellen benutzt, werden folgende Funktionen aufgerufen: NichtBegonneneWellen, NichtBeendeteWellen und BeendeteWellen.

5.5. NotStartedWaves

Die Funktion zur Analyse nicht begonnener Wellen: 

void NotStartedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)

Die Funktion NichtBegonneneWellen analysiert alle Wellen der ersten Gruppe an Wellen - die nicht begonnenen Wellen. Die Funktion analysiert die NumWave Welle (mit einem Wellenlevel Level) der Welle mit dem Namen ParentWave.Name, die die Form von Sub-Wellen Wellen annehmen könnte. Die analysierte NumWave Welle wird im Knoten des Wellenbaums gespeichert, dem untergeordneten Knoten (child node).

Wenn die Funktion Nicht BegonneneWellen arbeitet, werden die folgenden Funktionen aufgerufen: NichtBegonneneWellen und BeendeteWellen.

Alle Wellen werden, ähnlich wie im Block-Diagramm in Abb. 15 dargestellt, analysiert. 

5.6. NotFinishedWaves

Die Funktion zur Analyse nicht beendeter Wellen: 

void NotFinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)

Die Funktion NichtBeendeteWellen analysiert alle Wellen der zweiten Gruppe an Wellen - die nicht beendeten Wellen. Die Funktion analysiert die NumWave Welle (mit einem Wellenlevel Level) der Welle mit dem Namen ParentWave.Name, die die Form von Sub-Wellen Wellen annehmen könnte. Die analysierte NumWave Welle wird im Knoten des Wellenbaums gespeichert, dem untergeordneten Knoten (child node).

Wenn die Funktion Nicht BeendeteWellen arbeitet, werden die folgenden Funktionen aufgerufen: NichtBeendeteWellen und BeendeteWellen.   

Alle Wellen werden, ähnlich wie im Block-Diagramm in Abb. 15 dargestellt, analysiert.

5.7. FinishedWaves

Die Funktion zur Analyse abgeschlossener (beendeter) Wellen: 

void FinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)

Die Funktion BeendeteWellen analysiert alle Wellen der vierten Gruppe an Wellen - die beendeten Wellen. Die Funktion analysiert die NumWave Welle (mit einem Wellenlevel Level) der Welle mit dem Namen ParentWave.Name, die die Form von Sub-Wellen Wellen annehmen könnte. Die analysierte NumWave Welle wird im Knoten des Wellenbaums gespeichert, dem untergeordneten Knoten (child node).

Wenn die Funktion BeendeteWellen arbeitet, wird die Funktion BeendeteWellen aufgerufen.   

Alle Wellen werden, ähnlich wie im Block-Diagramm in Abb. 15 dargestellt, analysiert.

5.8. FindWaveInWaveDescription

Diese Funktion suicht nach Wellen in der Datenstruktur WaveBeschreibung:

int FindWaveInWaveDescription(string NameWave)

Die Funktion FindWaveInWaveDescription, sucht entsprechend im Array der Strukturen WellenBeschreibung per Namen der Welle NameWave, der als Parameter übertragen wurde, und liefert die Indexziffer der entsprechenden Welle.

Das Array der Strukturen WelleDescription sieht so aus:

TWaveDescription WaveDescription[]=
  {
     {
      "Impulse",5,
        {
         "",
         "Impulse,Leading Diagonal,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Impulse,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,",
         "Impulse,Diagonal,"
        }
     }
      ,
     {
      "Leading Diagonal",5,
        {
         "",
         "Impulse,Leading Diagonal,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Impulse,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,",
         "Impulse,Diagonal,"
        }
     }
      ,
     {
      "Diagonal",5,
        {
         "",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,"
        }
     }
      ,
     {
      "Zigzag",3,
        {
         "",
         "Impulse,Leading Diagonal,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,",
         "Impulse,Diagonal,",
         "",
         ""
        }
     }
      ,
     {
      "Flat",3,
        {
         "",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,",
         "Impulse,Diagonal,",
         "",
         ""
        }
     }
      ,
     {
      "Double Zigzag",3,
        {
         "",
         "Zigzag,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,",
         "Zigzag,",
         "",
         ""
        }
     }
      ,
     {
      "Triple Zigzag",5,
        {
         "",
         "Zigzag,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Triple Three,Contracting Triangle,Expanding Triangle,",
         "Zigzag,"
        }
     }
      ,
     {
      "Double Three",3,
        {
         "",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,",
         "",
         ""
        }
     }
      ,
     {
      "Triple Three",5,
        {
         "",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,"
        }
     }
      ,
     {
      "Contracting Triangle",5,
        {
         "",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,"
        }
     }
      ,
     {
      "Expanding Triangle",5,
        {
         "",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,",
         "Zigzag,Flat,Double Zigzag,Triple Zigzag,Double Three,Triple Three,Contracting Triangle,Expanding Triangle,"
        }
     }
  };

Die Funktion FindWaveInWaveDescription wird in der Funktionsanalyse folgender Wellen verwendet: NichtBegonneneUndNichtBeendeteWellen, NichtBegonneneWellen, NichtBeendeteWellen und BeendeteWellen. 

5.9. Already

Die Funktion überprüft, ob ein gegebener Bereich des Charts bereits analysiert worden ist: 

bool Already(TWave *Wave,int NumWave,TNode *Node,string Subwaves)

Da die automatische Analyse der Elliott-Wellen nach der Methode der Aufzählung abläuft, kann es durchaus zu einer Situation kommen, in der ein gegebener Bereich des Charts bereits auf Anwesenheit einer Welle oder einer Gruppe an Wellen analysiert worden. Um hier sicherzugehen, muss man den Link zum Knoten im Wellenbaum der bereits analysierten Welle speichern und dann nur noch den Link prüfen. All dies geschieht in der Funktion 'Already'.

Diese Funktion sucht nach einem globalen Array, NodeInfoArray, das die Objekte der TNodeInfo Klasse speichert und nach dem Intervall des Charts, entsprechend der Welle NumWave, der Welle namens Wave.Name, die die Form von Sub-Wellen Wellen hat, und zeichnet die Adresse des Knotens des Bereichs des Charts, in dem bereits eine Kennzeichnung erfolgt ist, im Knoten auf. Existiert dieser Bereich nicht, wird ein neues Objekt der TNodeInfo Klasse erzeugt und gefüllt, und im Array NodeInfoArray aufgezeichnet.

Die Funktion liefert 'true', wenn der Intervall des Charts bereits analysiert worden ist; ansonsten liefert sie 'false'. 

Das NodeInfoArray Array wird folgendermaßen deklariert: 

CArrayObj NodeInfoArray;

5.10. Die Funktionen der Prüfung der Wellen auf ihre Regeln

Sie umfassen die Funktionen VertexAAboveB, WaveAMoreWaveB und WaveRules, aus der die ersten zwei Funktionen aufgerufen werden. Beachten Sie beim Testen bitte, dass die Wellen nicht begonnen und/oder unbeendet sein können, und dass, z.B. für die Welle mit der Formel "1<-2-3>", nicht festgestellt werden kann, ob die vierte Welle sich außerhalb des Bereichs der ersten Welle erstreckt, da es ja noch keine vierte Welle gibt.

5.10.1. WaveRules

Funktion zum Prüfen der Wellen auf ihre Regeln:

bool WaveRules(TWave *Wave)

Die Funktion WaveRules liefert 'true', wenn eine Welle mit dem Namen Wave.Name "korrekt" ist, ansonsten liefert sie 'false'. Bei der Arbeit der Funktion WaveRules, wird diese Funktion von der Funktion VertexAAboveVertexB und WaveAMoreWaveB aufgerufen.

5.10.2. VertexAAboveVertexB

Diese Funktion überprüft das Überragen eines Scheitelpunktes über einen anderen: 

int VertexAAboveVertexB(int A,int B,bool InternalPoints)

Die Funktion VertexAAboveVertexB liefert die Zahl > = 0, wenn die Spitze der A-Welle die Spitze der B-Welle überragt; ansonsten liefert sie -1. Sind die InternalPoints = 'true', werden auch die internen Punkte von Wellen (Maximal- und/oder Minimalwerte der Wellen) mit berücksichtigt.

5.10.3. WaveAMoreWaveB

Diese Funktion überprüft das Übermaß an Länge einer Welle im Vergleich zur Länge einer anderen:

int WaveAMoreWaveB(int A,int B)

Die Funktion WaveAMoreWaveB liefert eine Zahl > = 0, wenn Welle A größer als Welle B ist; ansonsten liefert sie -1.

11. Die Funktion zum Leeren des Speichers

5.11.1. ClearTree

Diese Funktion leert den Wellen-Baum mit dem obersten Knoten Node: 

void ClearTree(TNode *Node)

5.11.2. ClearNodeInfoArray

Diese Funktion leert das Array ClearNodeInfoArray: 

void ClearNodeInfoArray()

5.11.3. ClearZigzagArray

Diese Funktion leert das Array ZigzagArray:

void ClearZigzagArray()

5.12. Die Funktion zum Umgehen des Wellen-Baums und Ausgabe der Analyseergebnisse auf das Chart

Nachdem die automatische Analyse der Elliott-Wellen abgeschlossen, erhalten wir einen Baum an Wellen.

Die folgende Abbildung zeigt ein Beispiel:

 Abb. 16 Beispiel eines Wellen-Baums
Abb. 16 Beispiel eines Wellen-Baums

Um nun die Ergebnisse der Analyse auch auf dem Chart anzeigen zu können, müssen wir den gegebenen Baum umgehen. Wie man aus Abb.16 entnehmen kann, gibt es dazu reichlich viele Optionen (da es ja auch mehrere Optionen an Wellen gibt) - und jede Option einer Umgehung führt zu einer anderen Kennzeichnung.

Wir können zwischen zwei Arten von Baumknoten unterscheiden.

Art 1: Knoten mit den Namen der Welle ("Impuls", "Zigzag", usw.). Art 2: Knoten mit der Zahl der Welle ("1", "1<", usw.). Alle Informationen zu den Parametern der Welle ist in Art 1 der Knoten gespeichert . Wen wir daher diese Knoten aufsuchen, fragen wir Informationen über die Welle ab und zeichnen diese auf, um sie dann auf dem Chart anzuzeigen.

Aus Gründen der Einfachheit, umgehen wir den Baum und suchen nur die ersten Versionen der Wellen auf.

Abb. 17 zeigt ein Beispiel für die Umgehung dieses Wellen-Baums, in rot unterlegt.

Abb. 17 Beispiel für die Umgehung eines Wellen-Baums
Abb. 17 Beispiel für die Umgehung eines Wellen-Baums

5.12.1. FillLabelArray

Das ist die Funktion zum Umgehen des Wellen-Baums:

void FillLabelArray(TNode *Node)

Die Funktion FillLabelArray umgeht den Wellen-Baum mit dem Root-Knoten, und widmet sich nur den ersten Versionen der Wellen im Baum. Sie füllt dann ein globales Array LabelArray, deren Indices einen Link auf das Array der Scheitelpunkte speichern (das Array der Objekte der Klasse TLabel), das einen gegebene Index auf dem Chart besitzt.

Das Array LabelArray ist folgendermaßen definiert: 

CArrayObj *LabelArray[];

5.12.2. CreateLabels

Funktion zur Anzeige der Analyseergbnisse auf dem Chart:; 

void CreateLabels()

Die Funktion CreateLabels erzeugt graphische Objekte "Text", entsprechend der Wellen-Markierungen auf dem Chart. Diese Markierungen werden auf Basis des Arrays LabelArray erstellt.

5.12.3. CorrectLabel

Die Funktion zur Aktualisierung (Korrektur) der Spitzen der Wellen auf dem Chart: 

void CorrectLabel()

Die Funktion CorrectLabel korrigiert die Wellen-Markierungen auf dem Chart, wenn es gescrollt wird und/oder während seiner Einschränkung.

 

6. Implementierung der automatischen Partitionierung der Elliott-Wellen 

6.1 Die Zigzag Funktion:

//+------------------------------------------------------------------+
//| The Zigzag function                                              |
//+------------------------------------------------------------------+
int Zigzag(int H,int Start,int Finish,CArrayInt *IndexVertex,CArrayDouble *ValueVertex)
  {
   bool Up=true;
   double dH=H*Point();
   int j=0;
   int TempMaxBar = Start;
   int TempMinBar = Start;
   double TempMax = rates[Start].high;
   double TempMin = rates[Start].low;
   for(int i=Start+1;i<=Finish;i++)
     {
      // processing the case of a rising segment
      if(Up==true)
        {
         // check that the current maximum has not changed
         if(rates[i].high>TempMax)
           {
            // if it has, correct the corresponding variables
            TempMax=rates[i].high;
            TempMaxBar=i;
           }
         else if(rates[i].low<TempMax-dH)
           {
            // otherwise, if the lagged level is broken, fixate the maximum
            ValueVertex.Add(TempMax);
            IndexVertex.Add(TempMaxBar);
            j++;
            // correct the corresponding variables
            Up=false;
            TempMin=rates[i].low;
            TempMinBar=i;
           }
        }
      else
        {
         // processing the case of the descending segment
         // check that the current minimum hasn't changed
         if(rates[i].low<TempMin)
           {
            // if it has, correct the corresponding variables
            TempMin=rates[i].low;
            TempMinBar=i;
           }
         else if(rates[i].high>TempMin+dH)
           {
            // otherwise, if the lagged level is broken, fix the minimum
            ValueVertex.Add(TempMin);
            IndexVertex.Add(TempMinBar);
            j++;
            // correct the corresponding variables
            Up=true;
            TempMax=rates[i].high;
            TempMaxBar=i;
           }
        }
     }
   // return the number of zigzag tops
   return(j);
  }

6.2 Die FillZigzagArray Funktion:

CArrayObj *ZigzagArray; // declare the ZigzagArray global dynamic array
//+------------------------------------------------------------------+
//| The FillZigzagArray function                                     |
//| search through the values of the parameter H zigzag              |
//| and fill the array ZigzagArray                                   |
//+------------------------------------------------------------------+
void FillZigzagArray(int Start,int Finish)
  {
   ZigzagArray=new CArrayObj;                       // create the dynamic array of zigzags
   CArrayInt *IndexVertex=new CArrayInt;         // create the dynamic array of indexes of zigzag tops
   CArrayDouble *ValueVertex=new CArrayDouble;   // create the dynamic array of values of the zigzag tops
   TZigzag *Zigzag;                                 // declare the class for storing the indexes and values of the zigzag tops
   int H=1;
   int j=0;
   int n=Zigzag(H,Start,Finish,IndexVertex,ValueVertex);//find the tops of the zigzag with the parameter H=1
   if(n>0)
     {
      // store the tops of the zigzag in the array ZigzagArray
      Zigzag=new TZigzag; // create the object for storing the found indexes and the zigzag tops, 
                             // fill it and store in the array ZigzagArray
      Zigzag.IndexVertex=IndexVertex;
      Zigzag.ValueVertex=ValueVertex;
      ZigzagArray.Add(Zigzag);
      j++;
     }
   H++;
   // loop of the H of the zigzag
   while(true)
     {
      IndexVertex=new CArrayInt;                            // create a dynamic array of indexes of zigzag tops
      ValueVertex=new CArrayDouble;                        // create a dynamic array of values of the zigzag tops
      n=Zigzag(H,Start,Finish,IndexVertex,ValueVertex); // find the tops of the zigzag
      if(n>0)
        {
         Zigzag=ZigzagArray.At(j-1);
         CArrayInt *PrevIndexVertex=Zigzag.IndexVertex; // get the array of indexes of the previous zigzag
         bool b=false;
         // check if there is a difference between the current zigzag and the previous zigzag
         for(int i=0; i<=n-1;i++)
           {
            if(PrevIndexVertex.At(i)!=IndexVertex.At(i))
              {
               // if there is a difference, store the tops of a zigzag in the array ZigzagArray
               Zigzag=new TZigzag;
               Zigzag.IndexVertex=IndexVertex;
               Zigzag.ValueVertex=ValueVertex;
               ZigzagArray.Add(Zigzag);
               j++;
               b=true;
               break;
              }
           }
         if(b==false)
           {
            // otherwise, if there is no difference, release the memory
            delete IndexVertex;
            delete ValueVertex;
           }
        }
      // search for the tops of the zigzag until there is two or less of them
      if(n<=2)
         break;
      H++;
     }
  }

6.3 Die FindPoints Funktion:

//+------------------------------------------------------------------+
//| The FindPoints function                                          |
//| Fill the ValuePoints and IndexPoints arrays                      |
//| of the Points structure                                          |
//+------------------------------------------------------------------+
bool FindPoints(int NumPoints,int IndexStart,int IndexFinish,double ValueStart,double ValueFinish,TPoints &Points)
  {
   int n=0;
   // fill the array ZigzagArray
   for(int i=ZigzagArray.Total()-1; i>=0;i--)
     {
      TZigzag *Zigzag=ZigzagArray.At(i);             // the obtained i zigzag in the ZigzagArray
      CArrayInt *IndexVertex=Zigzag.IndexVertex;    // get the array of the indexes of the tops of the i zigzags
      CArrayDouble *ValueVertex=Zigzag.ValueVertex; // get the array of values of the tops of the i zigzag
      int Index1=-1,Index2=-1;
      // search the index of the IndexVertex array, corresponding to the first point
      for(int j=0;j<IndexVertex.Total();j++)
        {
         if(IndexVertex.At(j)>=IndexStart)
           {
            Index1=j;
            break;
           }
        }
      // search the index of the IndexVertex array, corresponding to the last point
      for(int j=IndexVertex.Total()-1;j>=0;j--)
        {
         if(IndexVertex.At(j)<=IndexFinish)
           {
            Index2=j;
            break;
           }
        }
      // if the first and last points were found
      if((Index1!=-1) && (Index2!=-1))
        {
         n=Index2-Index1+1; // find out how many points were found
        }
      // if the required number of points was found (equal or greater)
      if(n>=NumPoints)
        {
         // check that the first and last tops correspond with the required top values
         if(((ValueStart!=0) && (ValueVertex.At(Index1)!=ValueStart)) || 
            ((ValueFinish!=0) && (ValueVertex.At(Index1+n-1)!=ValueFinish)))continue;
         // fill the Points structure, passed as a parameter
         Points.NumPoints=n;
         ArrayResize(Points.ValuePoints, n);
         ArrayResize(Points.IndexPoints, n);
         int k=0;
         // fill the ValuePoints and IndexPoints arrays of Points structure
         for(int j=Index1; j<Index1+n;j++)
           {
            Points.ValuePoints[k]=ValueVertex.At(j);
            Points.IndexPoints[k]=IndexVertex.At(j);
            k++;
           }
         return(true);
        };
     };
   return(false);
  };

6.4 Die NotStartedAndNotFinishedWaves Funktion:

//+------------------------------------------------------------------+
//| The NotStartedAndNotFinishedWaves function                       |
//+------------------------------------------------------------------+
void NotStartedAndNotFinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
  {
   int v1,v2,v3,v4,I;
   TPoints Points;
   TNode *ParentNode,*ChildNode;
   int IndexWave;
   string NameWave;
   TWave *Wave;
   int i=0,pos=0,start=0;
   // Put the waves, which we will be analyzing to the ListNameWave array
   string ListNameWave[];
   ArrayResize(ListNameWave,ArrayRange(WaveDescription,0));
   while(pos!=StringLen(Subwaves)-1)
     {
      pos=StringFind(Subwaves,",",start);
      NameWave=StringSubstr(Subwaves,start,pos-start);
      ListNameWave[i++]=NameWave;
      start=pos+1;
     }
   int IndexStart=ParentWave.IndexVertex[NumWave-1];
   int IndexFinish=ParentWave.IndexVertex[NumWave];
   double ValueStart = ParentWave.ValueVertex[NumWave - 1];
   double ValueFinish= ParentWave.ValueVertex[NumWave];
   // find no less than two points on the price chart and put them into the structure Points
   // if they are not found, then exit the function
   if(FindPoints(2,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false)return;
   // the loop of unbegun and incomplete waves with the formula "1<-2-3>"
   v1=0;
   while(v1<=Points.NumPoints-2)
     {
      v2=v1+1;
      while(v2<=Points.NumPoints-1)
        {
         int j=0;
         while(j<=i-1)
           {
            // get the name of the wave for analysis from the ListNameWave
            NameWave=ListNameWave[j++];
            // find the index of the wave in the structure WaveDescription in order to
              // find out the number of its sub-waves and their names
            IndexWave=FindWaveInWaveDescription(NameWave);
            if((WaveDescription[IndexWave].NumWave==5) || (WaveDescription[IndexWave].NumWave==3))
              {
               // create the object of TWave class and fill its fields - parameters of the analyzed waves
               Wave=new TWave;
               Wave.Name=NameWave;
               Wave.Level=Level;
               Wave.Formula="1<-2-3>";
               Wave.ValueVertex[0] = 0;
               Wave.ValueVertex[1] = Points.ValuePoints[v1];
               Wave.ValueVertex[2] = Points.ValuePoints[v2];
               Wave.ValueVertex[3] = 0;
               Wave.ValueVertex[4] = 0;
               Wave.ValueVertex[5] = 0;
               Wave.IndexVertex[0] = IndexStart;
               Wave.IndexVertex[1] = Points.IndexPoints[v1];
               Wave.IndexVertex[2] = Points.IndexPoints[v2];
               Wave.IndexVertex[3] = IndexFinish;
               Wave.IndexVertex[4] = 0;
               Wave.IndexVertex[5] = 0;
               // check the wave by the rules
               if(WaveRules(Wave)==true)
                 {
                  // if a wave passed the check by rules, add it into the wave tree
                  ParentNode=Node.Add(NameWave,Wave);
                  I=1;
                  // create the first sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the first sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the second sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create a third sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                 }
               // otherwise, if the wave did not pass by the rules, release memory
               else delete Wave;
              }
           }
         v2=v2+2;
        }
      v1=v1+2;
     }
   // the loop of unbegun and unfinished waves with the formula "2<-3-4>"
   v2=0;
   while(v2<=Points.NumPoints-2)
     {
      v3=v2+1;
      while(v3<=Points.NumPoints-1)
        {
         int j=0;
         while(j<=i-1)
           {
            // get the name of the wave for analysis from the ListNameWave
            NameWave=ListNameWave[j++];
            // find the index of the wave in the WaveDescription structure in order to know the number of its symbols and its names
            IndexWave=FindWaveInWaveDescription(NameWave);
            if(WaveDescription[IndexWave].NumWave==5)
              {
               // create the object of TWave class and fill its fields - parameters of the analyzed wave
               Wave=new TWave;
               Wave.Name=NameWave;
               Wave.Level=Level;
               Wave.Formula="2<-3-4>";
               Wave.ValueVertex[0] = 0;
               Wave.ValueVertex[1] = 0;
               Wave.ValueVertex[2] = Points.ValuePoints[v2];
               Wave.ValueVertex[3] = Points.ValuePoints[v3];
               Wave.ValueVertex[4] = 0;
               Wave.ValueVertex[5] = 0;
               Wave.IndexVertex[0] = 0;
               Wave.IndexVertex[1] = IndexStart;
               Wave.IndexVertex[2] = Points.IndexPoints[v2];
               Wave.IndexVertex[3] = Points.IndexPoints[v3];
               Wave.IndexVertex[4] = IndexFinish;
               Wave.IndexVertex[5] = 0;
               // check the wave by the rules
               if(WaveRules(Wave)==true)
                 {
                  // if the wave passed the check for rules, add it to the waves tree
                  ParentNode=Node.Add(NameWave,Wave);
                  I=2;
                  // create the second sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the third sub-wave in th waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the fourth sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                 }
               // otherwise, if the wave did not pass the check by rules, release memory
               else delete Wave;
              }
           }
         v3=v3+2;
        }
      v2=v2+2;
     }
   // the loop of the unbegun and the incomplete waves with the formula "3<-4-5>"
   v3=0;
   while(v3<=Points.NumPoints-2)
     {
      v4=v3+1;
      while(v4<=Points.NumPoints-1)
        {
         int j=0;
         while(j<=i-1)
           {
            // get the name of the wave for analysis from the ListNameWave
            NameWave=ListNameWave[j++]; 
            // find the index of the wave in the WaveDescription structure in order to
              // find out the number of its symbols and their names
            IndexWave=FindWaveInWaveDescription(NameWave);
            if(WaveDescription[IndexWave].NumWave==5)
              {
               // create the object of TWave class and fill its fields - parameters of the analyzed wave
               Wave=new TWave;
               Wave.Name=NameWave;
               Wave.Level=Level;
               Wave.Formula="3<-4-5>";
               Wave.ValueVertex[0] = 0;
               Wave.ValueVertex[1] = 0;
               Wave.ValueVertex[2] = 0;
               Wave.ValueVertex[3] = Points.ValuePoints[v3];
               Wave.ValueVertex[4] = Points.ValuePoints[v4];
               Wave.ValueVertex[5] = 0;
               Wave.IndexVertex[0] = 0;
               Wave.IndexVertex[1] = 0;
               Wave.IndexVertex[2] = IndexStart;
               Wave.IndexVertex[3] = Points.IndexPoints[v3];
               Wave.IndexVertex[4] = Points.IndexPoints[v4];
               Wave.IndexVertex[5] = IndexFinish;
               // check the wave for the rules
               if(WaveRules(Wave)==true)
                 {
                  // if the wave passed the check by the rules, add it to the waves tree
                  ParentNode=Node.Add(NameWave,Wave);
                  I=3;
                  // create the third sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the third sub-wave has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the fourth sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the fifth sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the fifth wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                 }
               // otherwise, if the wave has not passed the check by the rules, release the memory
               else delete Wave;
              }
           }
         v4=v4+2;
        }
      v3=v3+2;
     }
   // find no less than three points on the price chart and put them in the Points structure
   // if they were not found, then exit the function
   if(FindPoints(3,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false) return;
   // the loop of unbegun and unfinished waved with the formula "1<-2-3-4>"
   v1=0;
   while(v1<=Points.NumPoints-3)
     {
      v2=v1+1;
      while(v2<=Points.NumPoints-2)
        {
         v3=v2+1;
         while(v3<=Points.NumPoints-1)
           {
            int j=0;
            while(j<=i-1)
              {
               // get the name of the wave for analysis from the ListNameWave
               NameWave=ListNameWave[j++];
               // find the index of the wave in the WaveDescription structure in order to know the number of its sub-waves and their names
               IndexWave=FindWaveInWaveDescription(NameWave);
               if(WaveDescription[IndexWave].NumWave==5)
                 {
                  // create an object of TWave class and fill its fields - parameters of the analyzed wave
                  Wave=new TWave;
                  Wave.Name=NameWave;
                  Wave.Level=Level;
                  Wave.Formula="1<-2-3-4>";
                  Wave.ValueVertex[0] = 0;
                  Wave.ValueVertex[1] = Points.ValuePoints[v1];
                  Wave.ValueVertex[2] = Points.ValuePoints[v2];
                  Wave.ValueVertex[3] = Points.ValuePoints[v3];
                  Wave.ValueVertex[4] = 0;
                  Wave.ValueVertex[5] = 0;
                  Wave.IndexVertex[0] = IndexStart;
                  Wave.IndexVertex[1] = Points.IndexPoints[v1];
                  Wave.IndexVertex[2] = Points.IndexPoints[v2];
                  Wave.IndexVertex[3] = Points.IndexPoints[v3];
                  Wave.IndexVertex[4] = IndexFinish;
                  Wave.IndexVertex[5] = 0;
                  // check the wave by the rules
                  if(WaveRules(Wave)==true)
                    {
                     // if the wave passed the check by the rules, add it to the waves tree
                     ParentNode=Node.Add(NameWave,Wave);
                     I=1;
                     // create the first sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the first sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the second sub-wave in the waved tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the third sub-wave in the waves
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the fourth sub-wave of the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                    }
                  // otherwise, if the wave did not pass by the rules, release the memory
                  else delete Wave;
                 }
              }
            v3=v3+2;
           }
         v2=v2+2;
        }
      v1=v1+2;
     }
   // the loop of unbegun and unfinished waves with the formula "2<-3-4-5>"
   v2=0;
   while(v2<=Points.NumPoints-3)
     {
      v3=v2+1;
      while(v3<=Points.NumPoints-2)
        {
         v4=v3+1;
         while(v4<=Points.NumPoints-1)
           {
            int j=0;
            while(j<=i-1)
              {
               // get the name of the wave for analysis from the ListNameWave
               NameWave=ListNameWave[j++];
               // find the index of the wave in the WaveDescription structure in order to know the number of the symbols and their names
               IndexWave=FindWaveInWaveDescription(NameWave);
               if(WaveDescription[IndexWave].NumWave==5)
                 {
                  // create the object of TWave class and fill its fields - parameters of the analyzed wave
                  Wave=new TWave;
                  Wave.Name=NameWave;
                  Wave.Level=Level;
                  Wave.Formula="2<-3-4-5>";
                  Wave.ValueVertex[0] = 0;
                  Wave.ValueVertex[1] = 0;
                  Wave.ValueVertex[2] = Points.ValuePoints[v2];
                  Wave.ValueVertex[3] = Points.ValuePoints[v3];
                  Wave.ValueVertex[4] = Points.ValuePoints[v4];
                  Wave.ValueVertex[5] = 0;
                  Wave.IndexVertex[0] = 0;
                  Wave.IndexVertex[1] = IndexStart;
                  Wave.IndexVertex[2] = Points.IndexPoints[v2];
                  Wave.IndexVertex[3] = Points.IndexPoints[v3];
                  Wave.IndexVertex[4] = Points.IndexPoints[v4];
                  Wave.IndexVertex[5] = IndexFinish;
                  // check the wave by the rules
                  if(WaveRules(Wave)==true)
                    {
                     // if the wave passed the check by the rules, add it to the waves tree
                     ParentNode=Node.Add(NameWave,Wave);
                     I=2;
                     // create the second sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the third sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the fourth sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the fifth sub-wave in the waved tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the fifth sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                    }
                  // otherwise, if the wave has not passed by the rules, release the memory
                  else delete Wave;
                 }
              }
            v4=v4+2;
           }
         v3=v3+2;
        }
      v2=v2+2;
     }
   // find no less than four point on the price chart and put them into the structure Points
   // if we didn't find any, then exit the function
   if(FindPoints(4,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false) return;
   // the loop of unbegun and unfinished waves with the formula "1<-2-3-4-5>"
   v1=0;
   while(v1<=Points.NumPoints-4)
     {
      v2=v1+1;
      while(v2<=Points.NumPoints-3)
        {
         v3=v2+1;
         while(v3<=Points.NumPoints-2)
           {
            v4=v3+1;
            while(v4<=Points.NumPoints-1)
              {
               int j=0;
               while(j<=i-1)
                 {
                  // get the name of the wave for analysis from the ListNameWave
                  NameWave=ListNameWave[j++];
                  // find the index of the wave in the WaveDescription structure in order to know the number of sub-waves and their names
                  IndexWave=FindWaveInWaveDescription(NameWave);
                  if(WaveDescription[IndexWave].NumWave==5)
                    {
                     // create the object TWave class and fill its fields - parameters of the analyzed wave
                     Wave=new TWave;
                     Wave.Name=NameWave;
                     Wave.Level=Level;
                     Wave.Formula="1<-2-3-4-5>";
                     Wave.ValueVertex[0] = 0;
                     Wave.ValueVertex[1] = Points.ValuePoints[v1];
                     Wave.ValueVertex[2] = Points.ValuePoints[v2];
                     Wave.ValueVertex[3] = Points.ValuePoints[v3];
                     Wave.ValueVertex[4] = Points.ValuePoints[v4];
                     Wave.ValueVertex[5] = 0;
                     Wave.IndexVertex[0] = IndexStart;
                     Wave.IndexVertex[1] = Points.IndexPoints[v1];
                     Wave.IndexVertex[2] = Points.IndexPoints[v2];
                     Wave.IndexVertex[3] = Points.IndexPoints[v3];
                     Wave.IndexVertex[4] = Points.IndexPoints[v4];
                     Wave.IndexVertex[5] = IndexFinish;
                     // check the wave by the rules
                     if(WaveRules(Wave)==true)
                       {
                        // if the wave passed the check by the rules, add it to the waves tree
                        ParentNode=Node.Add(NameWave,Wave);
                        I=1;
                        // create the first sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the first sub-wave has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the second sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the third sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the fourth sub-wave in the waved tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the 5th sub-wave in the wave tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                       }
                     // otherwise, if the wave did not pass the check by the rules, release the memory
                     else delete Wave;
                    }
                 }
               v4=v4+2;
              }
            v3=v3+2;
           }
         v2=v2+2;
        }
      v1=v1+2;
     }
   // find no less than one point on the price chart and record it into the structure Points
   // if we didn't find any, then exit the function
   if(FindPoints(1,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false)return;
   // the loop of unbegun and unfinished waves with the formula "1<-2>"
   v1=0;
   while(v1<=Points.NumPoints-1)
     {
      int j=0;
      while(j<=i-1)
        {
         // get the name of the wave for analysis from ListNameWave
         NameWave=ListNameWave[j++];
         // find the index of the wave in the WaveDescription structure in order to know the number of sub-waves and their names
         IndexWave=FindWaveInWaveDescription(NameWave);
         if(WaveDescription[IndexWave].NumWave==5 || WaveDescription[IndexWave].NumWave==3)
           {
            // create the object of TWave class and fill its fields - parameters of the analyzed wave
            Wave=new TWave;
            Wave.Name=NameWave;
            Wave.Level=Level;
            Wave.Formula="1<-2>";
            Wave.ValueVertex[0] = 0;
            Wave.ValueVertex[1] = Points.ValuePoints[v1];
            Wave.ValueVertex[2] = 0;
            Wave.ValueVertex[3] = 0;
            Wave.ValueVertex[4] = 0;
            Wave.ValueVertex[5] = 0;
            Wave.IndexVertex[0] = IndexStart;
            Wave.IndexVertex[1] = Points.IndexPoints[v1];
            Wave.IndexVertex[2] = IndexFinish;
            Wave.IndexVertex[3] = 0;
            Wave.IndexVertex[4] = 0;
            Wave.IndexVertex[5] = 0;
            // check the wave by the rules
            if(WaveRules(Wave)==true)
              {
               // if the wave passed the check by the rules, add it to the waves tree
               ParentNode=Node.Add(NameWave,Wave);
               I=1;
               // create the first sub-wave in the waves tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the first sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
               I++;
               // create the second sub-wave in the waved tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
              }
            // otherwise, if the wave did not pass the check by the rules, release the memory
            else delete Wave;
           }
        }
      v1=v1+1;
     }
   // loop the unbegun and unfinished waves with the formula "2<-3>"
   v2=0;
   while(v2<=Points.NumPoints-1)
     {
      int j=0;
      while(j<=i-1)
        {
         // get the name of the wave for analysis from ListNameWave
         NameWave=ListNameWave[j++];
         // find the index of the wave in the structure WaveDescription, in order to know the number of its sub-waves and their names
         IndexWave=FindWaveInWaveDescription(NameWave);
         if(WaveDescription[IndexWave].NumWave==5 || WaveDescription[IndexWave].NumWave==3)
           {
            // create the object of TWave class and fill its fields - parameters of the analyzed wave
            Wave=new TWave;
            Wave.Name=NameWave;
            Wave.Level=Level;
            Wave.Formula="2<-3>";
            Wave.ValueVertex[0] = 0;
            Wave.ValueVertex[1] = 0;
            Wave.ValueVertex[2] = Points.ValuePoints[v2];
            Wave.ValueVertex[3] = 0;
            Wave.ValueVertex[4] = 0;
            Wave.ValueVertex[5] = 0;
            Wave.IndexVertex[0] = 0;
            Wave.IndexVertex[1] = IndexStart;
            Wave.IndexVertex[2] = Points.IndexPoints[v2];
            Wave.IndexVertex[3] = IndexFinish;
            Wave.IndexVertex[4] = 0;
            Wave.IndexVertex[5] = 0;
            // check the wave by the rules
            if(WaveRules(Wave)==true)
              {
               // if the wave passed the check by the rules, add it to the waves tree
               ParentNode=Node.Add(NameWave,Wave);
               I=2;
               // create the second sub-wave in the waves tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
               I++;
               // create the third sub-wave in the waved tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
              }
            // otherwise, if the wave did not pass by the rules, release the memory
            else delete Wave;
           }
        }
      v2=v2+1;
     }
   // the loop of unbegun and unfinished waves with the formula "3<-4>"
   v3=0;
   while(v3<=Points.NumPoints-1)
     {
      int j=0;
      while(j<=i-1)
        {
         // get the name of the wave for analysis from ListNameWave
         NameWave=ListNameWave[j++];
         // find the index of the wave in the WaveDescription structure on order to know the number of sub-waved and their names
         IndexWave=FindWaveInWaveDescription(NameWave);
         if(WaveDescription[IndexWave].NumWave==5)
           {
            // create the object of TWave class and fill its fields - parameters of the analyzed wave
            Wave=new TWave;
            Wave.Name=NameWave;
            Wave.Level=Level;
            Wave.Formula="3<-4>";
            Wave.ValueVertex[0] = 0;
            Wave.ValueVertex[1] = 0;
            Wave.ValueVertex[2] = 0;
            Wave.ValueVertex[3] = Points.ValuePoints[v3];
            Wave.ValueVertex[4] = 0;
            Wave.ValueVertex[5] = 0;
            Wave.IndexVertex[0] = 0;
            Wave.IndexVertex[1] = 0;
            Wave.IndexVertex[2] = IndexStart;
            Wave.IndexVertex[3] = Points.IndexPoints[v3];
            Wave.IndexVertex[4] = IndexFinish;
            Wave.IndexVertex[5] = 0;
            // check the wave by the rules
            if(WaveRules(Wave)==true)
              {
               // if the wave passed the check by the rules, add it to the waves tree
               ParentNode=Node.Add(NameWave,Wave);
               I=3;
               // create the third sub-wave in the waves tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
               I++;
               // create the fourth sub-wave in the waves tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
              }
            // otherwise, if the wave did not pass by the rules, release the memory
            else delete Wave;
           }
        }
      v3=v3+1;
     }
   // the loop of unbegun and unfinished waves with the formula "4<-5>"
   v4=0;
   while(v4<=Points.NumPoints-1)
     {
      int j=0;
      while(j<=i-1)
        {
         // get the name of the wave for analysis from ListNameWave
         NameWave=ListNameWave[j++];
         // find the index of the wave in the WaveDescription structure in order to know the number of symbols and their names
         IndexWave=FindWaveInWaveDescription(NameWave);
         if(WaveDescription[IndexWave].NumWave==5)
           {
            // create the object of TWave class and fill its fields - parameters of the analyzed wave
            Wave=new TWave;
            Wave.Name=NameWave;
            Wave.Level=Level;
            Wave.Formula="4<-5>";
            Wave.ValueVertex[0] = 0;
            Wave.ValueVertex[1] = 0;
            Wave.ValueVertex[2] = 0;
            Wave.ValueVertex[3] = 0;
            Wave.ValueVertex[4] = Points.ValuePoints[v4];
            Wave.ValueVertex[5] = 0;
            Wave.IndexVertex[0] = 0;
            Wave.IndexVertex[1] = 0;
            Wave.IndexVertex[2] = 0;
            Wave.IndexVertex[3] = IndexStart;
            Wave.IndexVertex[4] = Points.IndexPoints[v4];
            Wave.IndexVertex[5] = IndexFinish;
            // check the wave by the rules
            if(WaveRules(Wave)==true)
              {
               // if the wave passed the check by the rules, add it to the waves tree
               ParentNode=Node.Add(NameWave,Wave);
               I=4;
               // create the fourth sub-wave in the waves tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
               I++;
               // create the fifth sub-wave in the waves tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the fifth sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
              }
            // otherwise, if the wave did not pass by the rules, release the memory
            else delete Wave;
           }
        }
      v4=v4+1;
     }
  }

6.5 Die NotStartedWaves Funktion:

//+------------------------------------------------------------------+
//| The function NotStartedWaves                                          |
//+------------------------------------------------------------------+
void NotStartedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
  {
   int v1,v2,v3,v4,v5,I;
   TPoints Points;
   TNode *ParentNode,*ChildNode;
   int IndexWave;
   string NameWave;
   TWave *Wave;
   int i=0,Pos=0,Start=0;
   // Put the waves, which we will be analyzing to the ListNameWave array
   string ListNameWave[];
   ArrayResize(ListNameWave,ArrayRange(WaveDescription,0));
   while(Pos!=StringLen(Subwaves)-1)
     {
      Pos=StringFind(Subwaves,",",Start);
      NameWave=StringSubstr(Subwaves,Start,Pos-Start);
      ListNameWave[i++]=NameWave;
      Start=Pos+1;
     }
   int IndexStart=ParentWave.IndexVertex[NumWave-1];
   int IndexFinish=ParentWave.IndexVertex[NumWave];
   double ValueStart = ParentWave.ValueVertex[NumWave - 1];
   double ValueFinish= ParentWave.ValueVertex[NumWave];
   // find no less than two points on the price chart and put them into the structure Points
   // if we didn't find any, then exit the function
   if(FindPoints(2,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false)return;
   // loop the unbegun waves with the formula "4<-5"
   v5=Points.NumPoints-1;
   v4=v5-1;
   while(v4>=0)
     {
      int j=0;
      while(j<=i-1)
        {
         // get the name of the wave for analysis from ListNameWave
         NameWave=ListNameWave[j++];
         // find the index of the wave in the WaveDescription structure in order to know the number of its sub-waves and their names
         IndexWave=FindWaveInWaveDescription(NameWave);
         if(WaveDescription[IndexWave].NumWave==5)
           {
            // create the object of class TWave and fill its fields - parameters of the analyzed wave
            Wave=new TWave;
            Wave.Name=NameWave;
            Wave.Level=Level;
            Wave.Formula="4<-5";
            Wave.ValueVertex[0] = 0;
            Wave.ValueVertex[1] = 0;
            Wave.ValueVertex[2] = 0;
            Wave.ValueVertex[3] = 0;
            Wave.ValueVertex[4] = Points.ValuePoints[v4];
            Wave.ValueVertex[5] = Points.ValuePoints[v5];
            Wave.IndexVertex[0] = 0;
            Wave.IndexVertex[1] = 0;
            Wave.IndexVertex[2] = 0;
            Wave.IndexVertex[3] = IndexStart;
            Wave.IndexVertex[4] = Points.IndexPoints[v4];
            Wave.IndexVertex[5] = Points.IndexPoints[v5];
            // check the wave by the rules
            if(WaveRules(Wave)==true)
              {
               // if the wave passed the check by the rules, add it to the waves tree
               ParentNode=Node.Add(NameWave,Wave);
               I=4;
               // create the fourth sub-wave in the wave tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
               I++;
               // create 5th sub-wave in the waves tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the fifth sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
              }
            // otherwise, if the wave did not pass the check by the rules, release the memory
            else delete Wave;
           }
        }
      v4=v4-2;
     }
   // loop the unbegun waves with the formula "2<-3"
   v3=Points.NumPoints-1;
   v2=v3-1;
   while(v2>=0)
     {
      int j=0;
      while(j<=i-1)
        {
         // in turn, from the ListNameWave, draw the name of the wave for analysis
         NameWave=ListNameWave[j++];
         // find the index of the wave in the WaveDescription structure in order to know the number of sub-waves and their names
         IndexWave=FindWaveInWaveDescription(NameWave);
         if(WaveDescription[IndexWave].NumWave==3)
           {
            // create the object of class TWave and fill its fields - parameters of the analyzed wave
            Wave=new TWave;
            Wave.Name=NameWave;
            Wave.Level=Level;
            Wave.Formula="2<-3";
            Wave.ValueVertex[0] = 0;
            Wave.ValueVertex[1] = 0;
            Wave.ValueVertex[2] = Points.ValuePoints[v2];
            Wave.ValueVertex[3] = Points.ValuePoints[v3];
            Wave.ValueVertex[4] = 0;
            Wave.ValueVertex[5] = 0;
            Wave.IndexVertex[0] = 0;
            Wave.IndexVertex[1] = IndexStart;
            Wave.IndexVertex[2] = Points.IndexPoints[v2];
            Wave.IndexVertex[3] = Points.IndexPoints[v3];
            Wave.IndexVertex[4] = 0;
            Wave.IndexVertex[5] = 0;
            // check the wave by the rules
            if(WaveRules(Wave)==true)
              {
               // if the wave passed the check by the rules, add it to the waves tree
               ParentNode=Node.Add(NameWave,Wave);
               I=2;
               // create the second sub-wave in the waves tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
               I++;
               // create the third sub-wave in the waves tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
              }
            // otherwise, if the wave did not pass by the rules, release the memory
            else delete Wave;
           }
        }
      v2=v2-2;
     }
   // find not less than three points on the price chart and put them into the structure Points
   // if we didn't find any, then exit the function
   if(FindPoints(3,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false)return;
   // loop the unbegun waves with the formula "3<-4-5"
   v5=Points.NumPoints-1;
   v4=v5-1;
   while(v4>=1)
     {
      v3=v4-1;
      while(v3>=0)
        {
         int j=0;
         while(j<=i-1)
           {
            // get the name of the wave for analysis from ListNameWave
            NameWave=ListNameWave[j++];
            // find the index of the wave in the WaveDescription structure in order to know the number of sub-waves and their names
            IndexWave=FindWaveInWaveDescription(NameWave);
            if(WaveDescription[IndexWave].NumWave==5)
              {
               // create the object of class TWave and fill its fields - parameters of the analyzed wave
               Wave=new TWave;
               Wave.Name=NameWave;
               Wave.Level=Level;
               Wave.Formula="3<-4-5";
               Wave.ValueVertex[0] = 0;
               Wave.ValueVertex[1] = 0;
               Wave.ValueVertex[2] = 0;
               Wave.ValueVertex[3] = Points.ValuePoints[v3];
               Wave.ValueVertex[4] = Points.ValuePoints[v4];
               Wave.ValueVertex[5] = Points.ValuePoints[v5];
               Wave.IndexVertex[0] = 0;
               Wave.IndexVertex[1] = 0;
               Wave.IndexVertex[2] = IndexStart;
               Wave.IndexVertex[3] = Points.IndexPoints[v3];
               Wave.IndexVertex[4] = Points.IndexPoints[v4];
               Wave.IndexVertex[5] = Points.IndexPoints[v5];
               // check the wave by the rules
               if(WaveRules(Wave)==true)
                 {
                  // if the wave passed the check by the rules, add it to the waves tree
                  ParentNode=Node.Add(NameWave,Wave);
                  I=3;
                  // create the three sub-waves in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the fourth sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the fifth sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the fifth sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                 }
               // otherwise, if the wave did not pass by the rules, release the memory
               else delete Wave;
              }
           }
         v3=v3-2;
        }
      v4=v4-2;
     }
   // the loop of the unbegun waves with the formula "1<-2-3"
   v3=Points.NumPoints-1;
   v2=v3-1;
   while(v2>=1)
     {
      v1=v2-1;
      while(v1>=0)
        {
         int j=0;
         while(j<=i-1)
           {
            // get the name of the wave for analysis from ListNameWave
            NameWave=ListNameWave[j++];
            // find the index of the wave in the WaveDescription structure in order to know the number of sub-waves and their names
            IndexWave=FindWaveInWaveDescription(NameWave);
            if(WaveDescription[IndexWave].NumWave==3)
              {
               // create the object of class TWave and fill its fields - parameters of the analyzed wave
               Wave=new TWave;
               Wave.Name=NameWave;
               Wave.Level=Level;
               Wave.Formula="1<-2-3";
               Wave.ValueVertex[0] = 0;
               Wave.ValueVertex[1] = Points.ValuePoints[v1];
               Wave.ValueVertex[2] = Points.ValuePoints[v2];
               Wave.ValueVertex[3] = Points.ValuePoints[v3];
               Wave.ValueVertex[4] = 0;
               Wave.ValueVertex[5] = 0;
               Wave.IndexVertex[0] = IndexStart;
               Wave.IndexVertex[1] = Points.IndexPoints[v1];
               Wave.IndexVertex[2] = Points.IndexPoints[v2];
               Wave.IndexVertex[3] = Points.IndexPoints[v3];
               Wave.IndexVertex[4] = 0;
               Wave.IndexVertex[5] = 0;
               // check the wave by the rules
               if(WaveRules(Wave)==true)
                 {
                  // if the wave passed the check by the rules, add it to the waves tree
                  ParentNode=Node.Add(NameWave,Wave);
                  I=1;
                  // create the first sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  //if the interval of the chart, corresponding to the first sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the second sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  //if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the third sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                 }
               // otherwise, if the wave did not pass by the rules, release the memory
               else delete Wave;
              }
           }
         v1=v1-2;
        }
      v2=v2-2;
     }
   // find no less than four points on the price chart and put them into the structure Points
   // if we didn't find any, then exit the function
   if(FindPoints(4,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false)return;
   // the loop of unbegun waves with the formula "2<-3-4-5"
   v5=Points.NumPoints-1;
   v4=v5-1;
   while(v4>=2)
     {
      v3=v4-1;
      while(v3>=1)
        {
         v2=v3-1;
         while(v2>=0)
           {
            int j=0;
            while(j<=i-1)
              {
               // in turn, from the ListNameWave, draw the name of the wave for analysis
               NameWave=ListNameWave[j++];
               // find the index of the wave in the WaveDescription structure in order to know the number of its sub-waves and their names
               IndexWave=FindWaveInWaveDescription(NameWave);
               if(WaveDescription[IndexWave].NumWave==5)
                 {
                  // create the object of class TWave and fill its fields - parameters of the analyzed wave
                  Wave=new TWave;
                  Wave.Name=NameWave;
                  Wave.Level=Level;
                  Wave.Formula="2<-3-4-5";
                  Wave.ValueVertex[0] = 0;
                  Wave.ValueVertex[1] = 0;
                  Wave.ValueVertex[2] = Points.ValuePoints[v2];
                  Wave.ValueVertex[3] = Points.ValuePoints[v3];
                  Wave.ValueVertex[4] = Points.ValuePoints[v4];
                  Wave.ValueVertex[5] = Points.ValuePoints[v5];
                  Wave.IndexVertex[0] = 0;
                  Wave.IndexVertex[1] = IndexStart;
                  Wave.IndexVertex[2] = Points.IndexPoints[v2];
                  Wave.IndexVertex[3] = Points.IndexPoints[v3];
                  Wave.IndexVertex[4] = Points.IndexPoints[v4];
                  Wave.IndexVertex[5] = Points.IndexPoints[v5];
                  // check the wave by the rules
                  if(WaveRules(Wave)==true)
                    {
                     // if the wave passed the check by the rules, add it to the waves tree
                     ParentNode=Node.Add(NameWave,Wave);
                     I=2;
                     // create the second sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the third sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the fourth sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the fifth sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the fifth sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                    }
                  // otherwise, if the wave has not passed the rules, release the memory
                  else delete Wave;
                 }
              }
            v2=v2-2;
           }
         v3=v3-2;
        }
      v4=v4-2;
     }
   // find no less than five points on the price chart and record it into the structure Points
   // if we didn't find any, then exit the function
   if(FindPoints(5,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false)return;
   // the loop of unbegun waves with the formula "1<-2-3-4-5"
   v5=Points.NumPoints-1;
   v4=v5-1;
   while(v4>=3)
     {
      v3=v4-1;
      while(v3>=2)
        {
         v2=v3-1;
         while(v2>=1)
           {
            v1=v2-1;
            while(v1>=0)
              {
               int j=0;
               while(j<=i-1)
                 {
                  // in turn, from the ListNameWave, draw the name of the wave for analysis
                  NameWave=ListNameWave[j++];
                  // find the index of the wave in the WaveDescription structure in order to know the number of sub-waves and their names
                  IndexWave=FindWaveInWaveDescription(NameWave);
                  if(WaveDescription[IndexWave].NumWave==5)
                    {
                     // create the object of class TWave and fill its fields - parameters of the analyzed wave
                     Wave=new TWave;
                     Wave.Name=NameWave;
                     Wave.Level=Level;
                     Wave.Formula="1<-2-3-4-5";
                     Wave.ValueVertex[0] = 0;
                     Wave.ValueVertex[1] = Points.ValuePoints[v1];
                     Wave.ValueVertex[2] = Points.ValuePoints[v2];
                     Wave.ValueVertex[3] = Points.ValuePoints[v3];
                     Wave.ValueVertex[4] = Points.ValuePoints[v4];
                     Wave.ValueVertex[5] = Points.ValuePoints[v5];
                     Wave.IndexVertex[0] = IndexStart;
                     Wave.IndexVertex[1] = Points.IndexPoints[v1];
                     Wave.IndexVertex[2] = Points.IndexPoints[v2];
                     Wave.IndexVertex[3] = Points.IndexPoints[v3];
                     Wave.IndexVertex[4] = Points.IndexPoints[v4];
                     Wave.IndexVertex[5] = Points.IndexPoints[v5];
                     // check the wave by the rules
                     if(WaveRules(Wave)==true)
                       {
                        // if the wave passed the check by the rules, add it to the waves tree
                        ParentNode=Node.Add(NameWave,Wave);
                        I=1;
                        // create the first sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the first sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           NotStartedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the second sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the third sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the fourth sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the fifth sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the chart, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                       }
                     // otherwise, if the wave did not pass by the rules, release the memory
                     else delete Wave;
                    }
                 }
               v1=v1-2;
              }
            v2=v2-2;
           }
         v3=v3-2;
        }
      v4=v4-2;
     }
  }

6.6 Die NotFinishedWaves Funktion:

//+------------------------------------------------------------------+
//| The function FinishedWaves                                         |
//+------------------------------------------------------------------+
void NotFinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
  {
   int v0,v1,v2,v3,v4,I;
   TPoints Points;
   TNode *ParentNode,*ChildNode;
   int IndexWave;
   string NameWave;
   TWave *Wave;
   int i=0,Pos=0,Start=0;
   //we put the waves, which we will be analyzing in the array ListNameWaveg
   string ListNameWave[];
   ArrayResize(ListNameWave,ArrayRange(WaveDescription,0));
   while(Pos!=StringLen(Subwaves)-1)
     {
      Pos=StringFind(Subwaves,",",Start);
      NameWave=StringSubstr(Subwaves,Start,Pos-Start);
      ListNameWave[i++]=NameWave;
      Start=Pos+1;
     }
   int IndexStart=ParentWave.IndexVertex[NumWave-1];
   int IndexFinish=ParentWave.IndexVertex[NumWave];
   double ValueStart = ParentWave.ValueVertex[NumWave - 1];
   double ValueFinish= ParentWave.ValueVertex[NumWave];
   // find not less than two points on the price chart and record it into the structure Points
   // if we didn't find any, then exit the function
   if(FindPoints(2,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false)return;
   // the loop of unfinished waves with the formula "1-2>"
   v0=0;
   v1=v0+1;
   while(v1<=Points.NumPoints-1)
     {
      int j=0;
      while(j<=i-1)
        {
         // get the name of the wave for analysis from the ListNameWave
         NameWave=ListNameWave[j++];
         // find the index of the wave in the WaveDescription structure in order to know the number of sub-waves and their names
         IndexWave=FindWaveInWaveDescription(NameWave);
         if((WaveDescription[IndexWave].NumWave==5) || (WaveDescription[IndexWave].NumWave==3))
           {
            // create the object of TWave class and fill its fields - parameters of the analyzed wave
            Wave=new TWave;
            Wave.Name=NameWave;
            Wave.Level=Level;
            Wave.Formula="1-2>";
            Wave.ValueVertex[0] = Points.ValuePoints[v0];
            Wave.ValueVertex[1] = Points.ValuePoints[v1];
            Wave.ValueVertex[2] = 0;
            Wave.ValueVertex[3] = 0;
            Wave.ValueVertex[4] = 0;
            Wave.ValueVertex[5] = 0;
            Wave.IndexVertex[0] = Points.IndexPoints[v0];
            Wave.IndexVertex[1] = Points.IndexPoints[v1];
            Wave.IndexVertex[2] = IndexFinish;
            Wave.IndexVertex[3] = 0;
            Wave.IndexVertex[4] = 0;
            Wave.IndexVertex[5] = 0;
            // check the wave by the rules
            if(WaveRules(Wave)==true)
              {
               // if the wave passed the check by the rules, add it to the waves tree
               ParentNode=Node.Add(NameWave,Wave);
               I=1;
               // create the first sub-wave in the waves tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the first sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
               I++;
               // create the second sub-wave in the waves tree
               ChildNode=ParentNode.Add(IntegerToString(I));
               // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
               if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                  NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
              }
            // otherwise, if the wave did not pass by the rules, release the memory
            else delete Wave;
           }
        }
      v1=v1+2;
     }
   // find no less than three points on the price chart and put it into the Points structure
   // if none were found, then exit the function
   if(FindPoints(3,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false)return;
   // the loop of unfinished waves with the formula "1-2-3>"
   v0=0;
   v1=v0+1;
   while(v1<=Points.NumPoints-2)
     {
      v2=v1+1;
      while(v2<=Points.NumPoints-1)
        {
         int j=0;
         while(j<=i-1)
           {
            // get the name of the wave for analysis from ListNameWave
            NameWave=ListNameWave[j++];
            // find the index of the wave in the WaveDescription structure in order to know the number of sub-waves and their names
            IndexWave=FindWaveInWaveDescription(NameWave);
            if((WaveDescription[IndexWave].NumWave==5) || (WaveDescription[IndexWave].NumWave==3))
              {
               // create the object of TWave class and fill its fields - parameters of the analyzed wave
               Wave=new TWave;
               Wave.Name=NameWave;
               Wave.Level=Level;
               Wave.Formula="1-2-3>";
               Wave.ValueVertex[0] = Points.ValuePoints[v0];
               Wave.ValueVertex[1] = Points.ValuePoints[v1];
               Wave.ValueVertex[2] = Points.ValuePoints[v2];
               Wave.ValueVertex[3] = 0;
               Wave.ValueVertex[4] = 0;
               Wave.ValueVertex[5] = 0;
               Wave.IndexVertex[0] = Points.IndexPoints[v0];
               Wave.IndexVertex[1] = Points.IndexPoints[v1];
               Wave.IndexVertex[2] = Points.IndexPoints[v2];
               Wave.IndexVertex[3] = IndexFinish;
               Wave.IndexVertex[4] = 0;
               Wave.IndexVertex[5] = 0;
               // check the wave by the rules
               if(WaveRules(Wave)==true)
                 {
                  // if the wave passed the check by the rules, add it to the waves tree
                  ParentNode=Node.Add(NameWave,Wave);
                  I=1;
                  // create the first sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the first sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the second sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the third sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, of the corresponding third sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                 }
               // otherwise, if the wave did not pass by the rules, release the memory
               else delete Wave;
              }
           }
         v2=v2+2;
        }
      v1=v1+2;
     }
   // find no less than four points on the price chart and record it into the Points structure
   // if none were found, then exit the function
   if(FindPoints(4,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false) return;
   // the loop of unfinished waves with the formula "1-2-3-4>"
   v0=0;
   v1=v0+1;
   while(v1<=Points.NumPoints-3)
     {
      v2=v1+1;
      while(v2<=Points.NumPoints-2)
        {
         v3=v2+1;
         while(v3<=Points.NumPoints-1)
           {
            int j=0;
            while(j<=i-1)
              {
               // get the name of the wave for analysis from ListNameWave
               NameWave=ListNameWave[j++];
               // find the index of the wave in WaveDescription structure in order to know the number of sub-waves and the names
               IndexWave=FindWaveInWaveDescription(NameWave);
               if(WaveDescription[IndexWave].NumWave==5)
                 {
                  // create the object of TWave class and fill its fields - parameters of the analyzed wave
                  Wave=new TWave;
                  Wave.Name=NameWave;
                  Wave.Level=Level;
                  Wave.Formula="1-2-3-4>";
                  Wave.ValueVertex[0] = Points.ValuePoints[v0];
                  Wave.ValueVertex[1] = Points.ValuePoints[v1];
                  Wave.ValueVertex[2] = Points.ValuePoints[v2];
                  Wave.ValueVertex[3] = Points.ValuePoints[v3];
                  Wave.ValueVertex[4] = 0;
                  Wave.ValueVertex[5] = 0;
                  Wave.IndexVertex[0] = Points.IndexPoints[v0];
                  Wave.IndexVertex[1] = Points.IndexPoints[v1];
                  Wave.IndexVertex[2] = Points.IndexPoints[v2];
                  Wave.IndexVertex[3] = Points.IndexPoints[v3];
                  Wave.IndexVertex[4] = IndexFinish;
                  Wave.IndexVertex[5] = 0;
                  // check the wave by the rules
                  if(WaveRules(Wave)==true)
                    {
                     // if the wave passed the check for the rules, add it to the waves tree
                     ParentNode=Node.Add(NameWave,Wave);
                     I=1;
                     // create the first sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the first sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the second sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the third sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                     I++;
                     // create the fourth sub-wave in the waves tree
                     ChildNode=ParentNode.Add(IntegerToString(I));
                     // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                     if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                        NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                    }
                  // otherwise, if the wave didn't pass by the rules, release the memory
                  else delete Wave;
                 }
              }
            v3=v3+2;
           }
         v2=v2+2;
        }
      v1=v1+2;
     }
   // find no less than five points on the price chart and put them into the structure Points
   // if none were found, exit the function
   if(FindPoints(5,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false)return;
   // the loop of unfinished waves with the formula "1-2-3-4-5>"
   v0=0;
   v1=v0+1;
   while(v1<=Points.NumPoints-4)
     {
      v2=v1+1;
      while(v2<=Points.NumPoints-3)
        {
         v3=v2+1;
         while(v3<=Points.NumPoints-2)
           {
            v4=v3+1;
            while(v4<=Points.NumPoints-1)
              {
               int j=0;
               while(j<=i-1)
                 {
                  // get the name of the wave for analysis from ListNameWave
                  NameWave=ListNameWave[j++];
                  // find the index of the wave in the WaveDescription structure in order to know the number of its sub-waves and their names
                  IndexWave=FindWaveInWaveDescription(NameWave);
                  if(WaveDescription[IndexWave].NumWave==5)
                    {
                     // create the object of TWave class and fill its fields - parameters of the analyzed wave
                     Wave=new TWave;
                     Wave.Name=NameWave;
                     Wave.Level=Level;
                     Wave.Formula="1-2-3-4-5>";
                     Wave.ValueVertex[0] = Points.ValuePoints[v0];
                     Wave.ValueVertex[1] = Points.ValuePoints[v1];
                     Wave.ValueVertex[2] = Points.ValuePoints[v2];
                     Wave.ValueVertex[3] = Points.ValuePoints[v3];
                     Wave.ValueVertex[4] = Points.ValuePoints[v4];
                     Wave.ValueVertex[5] = 0;
                     Wave.IndexVertex[0] = Points.IndexPoints[v0];
                     Wave.IndexVertex[1] = Points.IndexPoints[v1];
                     Wave.IndexVertex[2] = Points.IndexPoints[v2];
                     Wave.IndexVertex[3] = Points.IndexPoints[v3];
                     Wave.IndexVertex[4] = Points.IndexPoints[v4];
                     Wave.IndexVertex[5] = IndexFinish;
                     // check the wave by the rules
                     if(WaveRules(Wave)==true)
                       {
                        // if the wave passed the check by the rules, add it to the waves tree
                        ParentNode=Node.Add(NameWave,Wave);
                        I=1;
                        // create the first sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the first sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the second sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the third sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the fourth sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the fifth sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the fifth sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           NotFinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                       }
                     // otherwise, if the wave did not pass by the rules, release the memory
                     else delete Wave;
                    }
                 }
               v4=v4+2;
              }
            v3=v3+2;
           }
         v2=v2+2;
        }
      v1=v1+2;
     }
  }

6.7 Die FinishedWaves Funktion:

//+------------------------------------------------------------------+
//| The FinishedWaves function                                       |
//+------------------------------------------------------------------+
void FinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
  {
   int v0,v1,v2,v3,v4,v5,I;
   TPoints Points;
   TNode *ParentNode,*ChildNode;
   int IndexWave;
   string NameWave;
   TWave *Wave;
   int i=0,Pos=0,Start=0;
   // Put the waves, which we will be analyzing to the ListNameWave array
   string ListNameWave[];
   ArrayResize(ListNameWave,ArrayRange(WaveDescription,0));
   while(Pos!=StringLen(Subwaves)-1)
     {
      Pos=StringFind(Subwaves,",",Start);
      NameWave=StringSubstr(Subwaves,Start,Pos-Start);
      ListNameWave[i++]=NameWave;
      Start=Pos+1;
     }
   int IndexStart=ParentWave.IndexVertex[NumWave-1];
   int IndexFinish=ParentWave.IndexVertex[NumWave];
   double ValueStart = ParentWave.ValueVertex[NumWave - 1];
   double ValueFinish= ParentWave.ValueVertex[NumWave];
   // find no less than four points on the price chart and put them into the structure Points
   // if none were found, then exit the function
   if(FindPoints(4,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false) return;
   // the loop of complete waves with the formula "1-2-3"
   v0 = 0;
   v1 = 1;
   v3 = Points.NumPoints - 1;
   while(v1<=v3-2)
     {
      v2=v1+1;
      while(v2<=v3-1)
        {
         int j=0;
         while(j<=i-1)
           {
            // in tuen, from ListNameWave, draw the name of the wave for analysis
            NameWave=ListNameWave[j++];
            // find the index of the wave in the structure WaveDescription in order to know the number of sub-waves and its names
            IndexWave=FindWaveInWaveDescription(NameWave);
            if(WaveDescription[IndexWave].NumWave==3)
              {
               // create the object of class TWave and fill its fields - parameters of the analyzed wave
               Wave=new TWave;;
               Wave.Name=NameWave;
               Wave.Formula="1-2-3";
               Wave.Level=Level;
               Wave.ValueVertex[0] = Points.ValuePoints[v0];
               Wave.ValueVertex[1] = Points.ValuePoints[v1];
               Wave.ValueVertex[2] = Points.ValuePoints[v2];
               Wave.ValueVertex[3] = Points.ValuePoints[v3];
               Wave.ValueVertex[4] = 0;
               Wave.ValueVertex[5] = 0;
               Wave.IndexVertex[0] = Points.IndexPoints[v0];
               Wave.IndexVertex[1] = Points.IndexPoints[v1];
               Wave.IndexVertex[2] = Points.IndexPoints[v2];
               Wave.IndexVertex[3] = Points.IndexPoints[v3];
               Wave.IndexVertex[4] = 0;
               Wave.IndexVertex[5] = 0;
               // check the wave by the rules
               if(WaveRules(Wave)==true)
                 {
                  // if the wave passed the check by the rules, add it to the waves tree
                  ParentNode=Node.Add(NameWave,Wave);
                  I=1;
                  // create the first sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(i));
                  // if the interval of the chart, corresponding to the first sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the second sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(i));
                  // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                  I++;
                  // create the third sub-wave in the waves tree
                  ChildNode=ParentNode.Add(IntegerToString(I));
                  // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                  if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                     FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                 }
               // otherwise, if the wave did not pass the check by the rules, release the memory
               else delete Wave;
              }
           }
         v2=v2+2;
        }
      v1=v1+2;
     }
   // find no less than six points on the price chart and put them into the structure Points
   // if none were found, then exit the function
   if(FindPoints(6,IndexStart,IndexFinish,ValueStart,ValueFinish,Points)==false)return;
   // the loop of complete waves with the formula "1-2-3-4-5"
   v0 = 0;
   v1 = 1;
   v5 = Points.NumPoints - 1;
   while(v1<=v5-4)
     {
      v2=v1+1;
      while(v2<=v5-3)
        {
         v3=v2+1;
         while(v3<=v5-2)
           {
            v4=v3+1;
            while(v4<=v5-1)
              {
               int j=0;
               while(j<=i-1)
                 {
                  // get the name of the wave for analysis from ListNameWave
                  NameWave=ListNameWave[j++];
                  // find the index of the wave in the WaveDescription structure in order to know the number of its sub-waves and their names
                  IndexWave=FindWaveInWaveDescription(NameWave);
                  if(WaveDescription[IndexWave].NumWave==5)
                    {
                     // create the object of class TWave and fill its fields - parameters of the analyzed wave
                     Wave=new TWave;
                     Wave.Name=NameWave;
                     Wave.Level=Level;
                     Wave.Formula="1-2-3-4-5";
                     Wave.ValueVertex[0] = Points.ValuePoints[v0];
                     Wave.ValueVertex[1] = Points.ValuePoints[v1];
                     Wave.ValueVertex[2] = Points.ValuePoints[v2];
                     Wave.ValueVertex[3] = Points.ValuePoints[v3];
                     Wave.ValueVertex[4] = Points.ValuePoints[v4];
                     Wave.ValueVertex[5] = Points.ValuePoints[v5];
                     Wave.IndexVertex[0] = Points.IndexPoints[v0];
                     Wave.IndexVertex[1] = Points.IndexPoints[v1];
                     Wave.IndexVertex[2] = Points.IndexPoints[v2];
                     Wave.IndexVertex[3] = Points.IndexPoints[v3];
                     Wave.IndexVertex[4] = Points.IndexPoints[v4];
                     Wave.IndexVertex[5] = Points.IndexPoints[v5];
                     // check the wave by the rules
                     if(WaveRules(Wave)==true)
                       {
                        // if the wave passed the check by the rules, add it to the waves tree
                        ParentNode=Node.Add(NameWave,Wave);
                        I=1;
                        // create the first sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the first sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the second sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the second sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the third sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the third sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the fourth sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the fourth sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                        I++;
                        // create the fifth sub-wave in the waves tree
                        ChildNode=ParentNode.Add(IntegerToString(I));
                        // if the interval of the chart, corresponding to the fifth sub-wave, has not been analyzed, then analyze it
                        if(Already(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I])==false)
                           FinishedWaves(Wave,I,ChildNode,WaveDescription[IndexWave].Subwaves[I],Level+1);
                       }
                     // otherwise, if the wave did not pass the check by the rules, release the memory
                     else delete Wave;
                    }
                 }
               v4=v4+2;
              }
            v3=v3+2;
           }
         v2=v2+2;
        }
      v1=v1+2;
     }
  }

6.8 Die FindWaveInWaveDescription Funktion:

//+------------------------------------------------------------------+
//| The FindWaveInWaveDescription function                           |
//+------------------------------------------------------------------+
int FindWaveInWaveDescription(string NameWave)
  {
   for(int i=0;i<ArrayRange(WaveDescription,0);i++)
      if(WaveDescription[i].NameWave==NameWave)return(i);
   return(-1);
  }

6.9 Die Already Funktion:

//+------------------------------------------------------------------+
//| The Already function                                             |
//+------------------------------------------------------------------+
bool Already(TWave *Wave,int NumWave,TNode *Node,string Subwaves)
  {
   // obtain the necessary parameters of the wave or the group of waves
   int IndexStart=Wave.IndexVertex[NumWave-1];
   int IndexFinish=Wave.IndexVertex[NumWave];
   double ValueStart = Wave.ValueVertex[NumWave - 1];
   double ValueFinish= Wave.ValueVertex[NumWave];
   // in the loop, proceed the array NodeInfoArray for the search of the marked-up section of the chart
   for(int i=NodeInfoArray.Total()-1; i>=0;i--)
     {
      TNodeInfo *NodeInfo=NodeInfoArray.At(i);
      // if the required section has already been marked-up
      if(NodeInfo.Subwaves==Subwaves && (NodeInfo.ValueStart==ValueStart) && 
         (NodeInfo.ValueFinish==ValueFinish) && (NodeInfo.IndexStart==IndexStart) &&
         (NodeInfo.IndexFinish==IndexFinish))
        {
         // add the child nodes of the found node into the child nodes of the new node
         for(int j=0;j<NodeInfo.Node.Child.Total();j++)
            Node.Child.Add(NodeInfo.Node.Child.At(j));
         return(true); // exit the function
        }
     }
   // if the interval has not been marked-up earlier, then record its data into the array NodeInfoArray
   TNodeInfo *NodeInfo=new TNodeInfo;
   NodeInfo.IndexStart=IndexStart;
   NodeInfo.IndexFinish=IndexFinish;
   NodeInfo.ValueStart=ValueStart;
   NodeInfo.ValueFinish=ValueFinish;
   NodeInfo.Subwaves=Subwaves;
   NodeInfo.Node=Node;
   NodeInfoArray.Add(NodeInfo);
   return(false);
  }

6.10 Die WaveRules Funktion:

int IndexVertex[6];                         // the indexes of the tops of the wave
double ValueVertex[6],Maximum[6],Minimum[6]; // the balues of the tops of the wave, as well as the maximum and minimum values of the wave
string Trend;                                    // direction of the trend - "Up" or "Down"
string Formula;                                  // the formula of the wave - "1<2-3>" or "1-2-3>" etc.
int FixedVertex[6];                             // information about the tops of the wave, whether or not they have been fixed

//+------------------------------------------------------------------+
//| The function WaveRules                                                |
//+------------------------------------------------------------------+
bool WaveRules(TWave *Wave)
  {
   Formula=Wave.Formula;
   bool Result=false;
   // fill the array IndexVertex and ValueVertex - indexes of the tops and values of the tops of the wave
   for(int i=0;i<=5;i++)
     {
      IndexVertex[i]=Wave.IndexVertex[i];
      ValueVertex[i]=Wave.ValueVertex[i];
      FixedVertex[i]=-1;
     }
   // fill the array FixedVertex, the balues of which indicate whether or not the top of the wave is fixed
   int Pos1=StringFind(Formula,"<");
   string Str;
   if(Pos1>0)
     {
      Str=ShortToString(StringGetCharacter(Formula,Pos1-1));
      FixedVertex[StringToInteger(Str)]=1;
      FixedVertex[StringToInteger(Str)-1]=0;
      Pos1=StringToInteger(Str)+1;
     }
   else Pos1=0;
   int Pos2=StringFind(Formula,">");
   if(Pos2>0)
     {
      Str=ShortToString(StringGetCharacter(Formula,Pos2-1));
      FixedVertex[StringToInteger(Str)]=0;
      Pos2=StringToInteger(Str)-1;
     }
   else
     {
      Pos2=StringLen(Formula);
      Str=ShortToString(StringGetCharacter(Formula,Pos2-1));
      Pos2=StringToInteger(Str);
     }
   for(int i=Pos1;i<=Pos2;i++)
      FixedVertex[i]=1;
   double High[],Low[];
   ArrayResize(High,ArrayRange(rates,0));
   ArrayResize(Low,ArrayRange(rates,0));
     // find the maximums and minimums of the waves
     for(int i=1; i<=5; i++)
     {
      Maximum[i]=rates[IndexVertex[i]].high;
      Minimum[i]=rates[IndexVertex[i-1]].low;
      for(int j=IndexVertex[i-1];j<=IndexVertex[i];j++)
        {
         if(rates[j].high>Maximum[i])Maximum[i]=rates[j].high;
         if(rates[j].low<Minimum[i])Minimum[i]=rates[j].low;
        }
     }
   // find out the trend
   if((FixedVertex[0]==1 && ValueVertex[0]==rates[IndexVertex[0]].low) ||
      (FixedVertex[1]==1 && ValueVertex[1]==rates[IndexVertex[1]].high) ||
      (FixedVertex[2]==1 && ValueVertex[2]==rates[IndexVertex[2]].low) ||
      (FixedVertex[3]==1 && ValueVertex[3]==rates[IndexVertex[3]].high) ||
      (FixedVertex[4]==1 && ValueVertex[4]==rates[IndexVertex[4]].low) ||
      (FixedVertex[5]==1 && ValueVertex[5]==rates[IndexVertex[5]].high))
      Trend="Up";
   else Trend="Down";
   // check the required wave by the rules
   if(Wave.Name=="Impulse")
     {
      if(VertexAAboveVertexB(1,0,true)>=0 && VertexAAboveVertexB(2,0,true)>=0 && 
         VertexAAboveVertexB(1,2,false)>=0 && VertexAAboveVertexB(3,2,true)>=0 &&
         VertexAAboveVertexB(3,1,false)>=0 && VertexAAboveVertexB(4,1,true)>=0 &&
         VertexAAboveVertexB(3,4,false)>=0 && VertexAAboveVertexB(5,4,true)>=0 &&
         (WaveAMoreWaveB(3,1)>=0 || WaveAMoreWaveB(3,5)>=0))
         Result=true;
     }
   else if(Wave.Name=="Leading Diagonal")
     {
      if(VertexAAboveVertexB(1,0,true)>=0 && VertexAAboveVertexB(2,0,true)>=0 && 
         VertexAAboveVertexB(1,2,false)>=0 && VertexAAboveVertexB(3,2,true)>=0 &&
         VertexAAboveVertexB(3,1,false)>=0 && VertexAAboveVertexB(4,2,true)>=0 &&
         VertexAAboveVertexB(1,4,false)>=0 &&
         VertexAAboveVertexB(3,4,false)>=0 && VertexAAboveVertexB(5,4,true)>=0&&
         (WaveAMoreWaveB(3,1)>=0 || WaveAMoreWaveB(3,5)>=0))
         Result=true;
     }
   else if(Wave.Name=="Diagonal")
     {
      if(VertexAAboveVertexB(1,0,true)>=0 && VertexAAboveVertexB(2,0,true)>=0 && 
         VertexAAboveVertexB(1,2,false)>=0 && VertexAAboveVertexB(3,2,true)>=0 &&
         VertexAAboveVertexB(3,1,false)>=0 && VertexAAboveVertexB(4,2,true)>=0 &&
         VertexAAboveVertexB(3,4,false)>=0 && VertexAAboveVertexB(5,4,true)>=0&&
         (WaveAMoreWaveB(3,1)>=0 || WaveAMoreWaveB(3,5)>=0))
         Result=true;
     }
   else if(Wave.Name=="Zigzag")
     {
      if(VertexAAboveVertexB(1,0,true)>=0 && VertexAAboveVertexB(2,0,true)>=0 && 
         VertexAAboveVertexB(1,2,false)>=0 && VertexAAboveVertexB(3,2,true)>=0 &&
         VertexAAboveVertexB(3,1,false)>=0)
         Result=true;
     }
   else if(Wave.Name=="Flat")
     {
      if(VertexAAboveVertexB(1,0,false)>=0 &&
         VertexAAboveVertexB(1,2,false)>=0 && VertexAAboveVertexB(3,2,true)>=0)
         Result=true;
     }
   else if(Wave.Name=="Double Zigzag")
     {
      if(VertexAAboveVertexB(1,0,true)>=0 && VertexAAboveVertexB(2,0,true)>=0 && 
         VertexAAboveVertexB(1,2,false)>=0 && VertexAAboveVertexB(3,2,true)>=0 &&
         VertexAAboveVertexB(3,1,false)>=0)
         Result=true;
     }
   else if(Wave.Name=="Double Three")
     {
      if(VertexAAboveVertexB(1,0,true)>=0 && 
         VertexAAboveVertexB(1,2,false)>=0 && VertexAAboveVertexB(3,2,false)>=0)
         Result=true;
     }
   else if(Wave.Name=="Triple Zigzag")
     {
      if(VertexAAboveVertexB(1,0,true)>=0 && VertexAAboveVertexB(2,0,true)>=0 && 
         VertexAAboveVertexB(1,2,false)>=0 && VertexAAboveVertexB(3,2,true)>=0 &&
         VertexAAboveVertexB(3,1,false)>=0 && VertexAAboveVertexB(5,3,false) &&
         VertexAAboveVertexB(3,4,false)>=0 && VertexAAboveVertexB(5,4,true)>=0)
         Result=true;
     }
   else if(Wave.Name=="Triple Three")
     {
      if(VertexAAboveVertexB(1,0,true)>=0 && 
         VertexAAboveVertexB(1,2,false)>=0 && VertexAAboveVertexB(3,2,false)>=0 &&
         VertexAAboveVertexB(3,4,false)>=0 && VertexAAboveVertexB(5,4,false)>=0)
         Result=true;
     }
   else if(Wave.Name=="Contracting Triangle")
     {
      if(VertexAAboveVertexB(1,0,false)>=0 && VertexAAboveVertexB(1,2,false)>=0 && VertexAAboveVertexB(3,2,false)>= 0&&
         VertexAAboveVertexB(3,4,false)>=0 && VertexAAboveVertexB(5,4,false)>=0 &&
         WaveAMoreWaveB(2,3)>=0 && WaveAMoreWaveB(3,4)>=0 && WaveAMoreWaveB(4,5)>=0)
         Result=true;
     }
   else if(Wave.Name=="Expanding Triangle")
     {
      if(VertexAAboveVertexB(1,0,false)>=0 && VertexAAboveVertexB(1,2,false)>=0 && VertexAAboveVertexB(3,2,false)>= 0&&
         VertexAAboveVertexB(3,4,false)>=0 && VertexAAboveVertexB(5,4,false)>=0 &&
         WaveAMoreWaveB(3,2)>=0 && WaveAMoreWaveB(3,2)>=0)
         Result=true;
     }
   return(Result);
  }

6.11 Die VertexAAboveVertexB Funktion:

//+-------------------------------------------------------------------------------------+
//| The function VertexAAboveVertexB checks whether or not the top A is higher than top B,        |
//| transferred as the parameters of the given function                                   |
//| this check can be performed only if the tops A and B - are fixed,          |
//| or the top A - is not fixed and prime, while the top B - is fixed,             |
//| or the top A - is fixed, while the top B - is not fixed and odd,           |
//| or the top A - is not fixed and prime, and the top B - is not fixed and odd |
//+-------------------------------------------------------------------------------------+
int VertexAAboveVertexB(int A,int B,bool InternalPoints)
  {
   double VA=0,VB=0,VC=0;
   int IA=0,IB=0;
   int Result=0;
   if(A>=B)
     {
      IA = A;
      IB = B;
     }
   else if(A<B)
     {
      IA = B;
      IB = A;
     }
   // if the internal points of the wave must be taken into consideration
   if(InternalPoints==true)
     {
      if((Trend=="Up") && ((IA%2==0) || ((IA-IB==1) && (IB%2==0))))
        {
         VA=Minimum[IA];
         IA=IA-IA%2;
        }
      else if((Trend=="Down") && ((IA%2==0) || ((IA-IB==1) && (IB%2==0))))
        {
         VA=Maximum[IA];
         IA=IA-IA%2;
        }
      else if((Trend=="Up") && ((IA%2==1) || ((IA-IB==1) && (IB%2==1))))
        {
         VA=Maximum[IA];
         IA=IA -(1-IA%2);
        }
      else if((Trend=="Down") && (IA%2==1) || ((IA-IB==1) && (IB%2==1)))
        {
         VA=Minimum[IA];
         IA=IA -(1-IA%2);
        }
      VB=ValueVertex[IB];
     }
   else
     {
      VA = ValueVertex[IA];
      VB = ValueVertex[IB];
     }
   if(A>B)
     {
      A = IA;
      B = IB;
     }
   else if(A<B)
     {
      A = IB;
      B = IA;
      VC = VA;
      VA = VB;
      VB = VC;
     }
   if(((FixedVertex[A]==1) && (FixedVertex[B]==1)) || 
      ((FixedVertex[A] == 0) &&(A % 2 == 0) && (FixedVertex[B] == 1)) ||
      ((FixedVertex[A] == 1) && (FixedVertex[B] == 0) && (B %2 == 1)) ||
      ((FixedVertex[A] == 0) & (A %2 == 0) && (FixedVertex[B] == 0) && (B % 2== 1)))
     {
      if(((Trend=="Up") && (VA>=VB)) || ((Trend=="Down") && (VA<=VB)))
         Result=1;
      else
         Result=-1;
     }
   return(Result);
  }

6.12 Die WaveAMoreWaveB Funktion:

//+-----------------------------------------------------------------------+
//| The function WaveAMoreWaveB checks whether or not the wave A is larger than the wave B, |
//| transferred as the parameters of the given function                     |
//| this check can be performed only if wave A - is complete,    |
//| and wave B - is incomplete or incomplete and unbegun               |
//+-----------------------------------------------------------------------+
int WaveAMoreWaveB(int A,int B)
  {
   int Result=0;
   double LengthWaveA=0,LengthWaveB=0;
   if(FixedVertex[A]==1 && FixedVertex[A-1]==1 && (FixedVertex[B]==1 || FixedVertex[B-1]==1))
     {
      LengthWaveA=MathAbs(ValueVertex[A]-ValueVertex[A-1]);
      if(FixedVertex[B]==1 && FixedVertex[B-1]==1) LengthWaveB=MathAbs(ValueVertex[B]-ValueVertex[B-1]);
      else if(FixedVertex[B]==1 && FixedVertex[B-1]==0)
        {
         if(Trend=="Up") LengthWaveB=MathAbs(ValueVertex[B]-Minimum[B]);
         else LengthWaveB=MathAbs(ValueVertex[B]-Maximum[B]);
        }
      else if(FixedVertex[B]==0 && FixedVertex[B-1]==1)
        {
         if(Trend=="Up")LengthWaveB=MathAbs(ValueVertex[B-1]-Minimum[B-1]);
         else LengthWaveB=MathAbs(ValueVertex[B-1]-Maximum[B-1]);
        }
      if(LengthWaveA>LengthWaveB) Result=1;
      else Result=-1;
     }
   return(Result);
  }

6.13 Die ClearTree Funktion:

//+------------------------------------------------------------------+
//| The function of clearing the waves tree with the top node Node   |
//+------------------------------------------------------------------+
void ClearTree(TNode *Node)
  {
   if(CheckPointer(Node)!=POINTER_INVALID)
     {
      for(int i=0; i<Node.Child.Total();i++)
         ClearTree(Node.Child.At(i));
      delete Node.Child;
      if(CheckPointer(Node.Wave)!=POINTER_INVALID)delete Node.Wave;
      delete Node;
     }
  }

6.14 Die ClearNodeInfoArray Funktion:

//+------------------------------------------------------------------+
//| The function of clearing the NodeInfoArray array                 |
//+------------------------------------------------------------------+
void ClearNodeInfoArray()
  {
   for(int i=NodeInfoArray.Total()-1; i>=0;i--)
     {
      TNodeInfo *NodeInfo=NodeInfoArray.At(i);
      if(CheckPointer(NodeInfo.Node)!=POINTER_INVALID)delete NodeInfo.Node;
      delete NodeInfo;
     }
   NodeInfoArray.Clear();
  }

6.15 Die ClearZigzagArray Funktion:

//+------------------------------------------------------------------+
//| The function of clearing the ZigzagArray array                   |
//+------------------------------------------------------------------+
void ClearZigzagArray()
  {
   for(int i=0;i<ZigzagArray.Total();i++)
     {
      TZigzag *Zigzag=ZigzagArray.At(i);
      delete Zigzag.IndexVertex;
      delete Zigzag.ValueVertex;
      delete Zigzag;
     }
   ZigzagArray.Clear();
  }

6.16 Die FillLabelArray Funktion:

CArrayObj *LabelArray[];
int LevelMax=0;
//+------------------------------------------------------------------+
//| The FillLabelArray function                                      |
//+------------------------------------------------------------------+
void FillLabelArray(TNode *Node)
  {
   if(Node.Child.Total()>0)
     {
      // obtain the first node
      TNode *ChildNode=Node.Child.At(0);
      // obtain the structure, in which the information about the wave is stored
      TWave *Wave=ChildNode.Wave;
      string Text;
      // if there is a first top
      if(Wave.ValueVertex[1]>0)
        {
         // mark the top according to the wave
         if(Wave.Name=="Impulse" || Wave.Name=="Leading Diagonal" || Wave.Name=="Diagonal")
            Text="1";
         else if(Wave.Name=="Zigzag" || Wave.Name=="Flat" || Wave.Name=="Expanding Triangle" ||
                Wave.Name=="Contracting Triangle")
            Text="A";
         else if(Wave.Name=="Double Zigzag" || Wave.Name=="Double Three" || 
                Wave.Name=="Triple Zigzag" || Wave.Name=="Triple Three")
            Text="W";
         // obtain the array of the ArrayObj tops, which have the index Wave.IndexVertex[1] on the price chart 
         CArrayObj *ArrayObj=LabelArray[Wave.IndexVertex[1]];
         if(CheckPointer(ArrayObj)==POINTER_INVALID)
           {
            ArrayObj=new CArrayObj;
            LabelArray[Wave.IndexVertex[1]]=ArrayObj;
           }
         // put the information about the top with the index Wave.IndexVertex[1] into the array ArrayObj
         TLabel *Label=new TLabel;
         Label.Text=Text;
         Label.Level=Wave.Level;
         if(Wave.Level>LevelMax)LevelMax=Wave.Level;
         Label.Value=Wave.ValueVertex[1];
         ArrayObj.Add(Label);
        }
      if(Wave.ValueVertex[2]>0)
        {
         if(Wave.Name=="Impulse" || Wave.Name=="Leading Diagonal" || Wave.Name=="Diagonal")
            Text="2";
         else if(Wave.Name=="Zigzag" || Wave.Name=="Flat" || Wave.Name=="Expanding Triangle" ||
                Wave.Name=="Contracting Triangle")
            Text="B";
         else if(Wave.Name=="Double Zigzag" || Wave.Name=="Double Three" ||
                Wave.Name=="Triple Zigzag" || Wave.Name=="Triple Three")
            Text="X";
         CArrayObj *ArrayObj=LabelArray[Wave.IndexVertex[2]];
         if(CheckPointer(ArrayObj)==POINTER_INVALID)
           {
            ArrayObj=new CArrayObj;
            LabelArray[Wave.IndexVertex[2]]=ArrayObj;
           }
         TLabel *Label=new TLabel;
         Label.Text=Text;
         Label.Level=Wave.Level;
         if(Wave.Level>LevelMax)LevelMax=Wave.Level;
         Label.Value=Wave.ValueVertex[2];
         ArrayObj.Add(Label);
        }
      if(Wave.ValueVertex[3]>0)
        {
         if(Wave.Name=="Impulse" || Wave.Name=="Leading Diagonal" || Wave.Name=="Diagonal")
            Text="3";
         else if(Wave.Name=="Zigzag" || Wave.Name=="Flat" || 
                Wave.Name=="Expanding Triangle" || Wave.Name=="Contracting Triangle")
            Text="C";
         else if(Wave.Name=="Double Zigzag" || Wave.Name=="Double Three" ||
                Wave.Name=="Triple Zigzag" || Wave.Name=="Triple Three")
            Text="Y";
         CArrayObj *ArrayObj=LabelArray[Wave.IndexVertex[3]];
         if(CheckPointer(ArrayObj)==POINTER_INVALID)
           {
            ArrayObj=new CArrayObj;
            LabelArray[Wave.IndexVertex[3]]=ArrayObj;
           }
         TLabel *Label=new TLabel;
         Label.Text=Text;
         Label.Level=Wave.Level;
         if(Wave.Level>LevelMax)LevelMax=Wave.Level;
         Label.Value=Wave.ValueVertex[3];
         ArrayObj.Add(Label);
        }
      if(Wave.ValueVertex[4]>0)
        {
         if(Wave.Name=="Impulse" || Wave.Name=="Leading Diagonal" || Wave.Name=="Diagonal")
            Text="4";
         else if(Wave.Name=="Expanding Triangle" || Wave.Name=="Contracting Triangle")
            Text="D";
         else if(Wave.Name=="Triple zigzag" || Wave.Name=="Triple Three")
            Text="XX";
         CArrayObj *ArrayObj=LabelArray[Wave.IndexVertex[4]];
         if(CheckPointer(ArrayObj)==POINTER_INVALID)
           {
            ArrayObj=new CArrayObj;
            LabelArray[Wave.IndexVertex[4]]=ArrayObj;
           }
         TLabel *Label=new TLabel;
         Label.Text=Text;
         Label.Level=Wave.Level;
         if(Wave.Level>LevelMax)LevelMax=Wave.Level;
         Label.Value=Wave.ValueVertex[4];
         ArrayObj.Add(Label);
        }
      if(Wave.ValueVertex[5]>0)
        {
         if(Wave.Name=="Impulse" || Wave.Name=="Leading Diagonal" || Wave.Name=="Diagonal")
            Text="5";
         else if(Wave.Name=="Expanding Triangle" || Wave.Name=="Contracting Triangle")
            Text="E";
         else if(Wave.Name=="Triple Zigzag" || Wave.Name=="Triple Three")
            Text="Z";
         CArrayObj *ArrayObj=LabelArray[Wave.IndexVertex[5]];
         if(CheckPointer(ArrayObj)==POINTER_INVALID)
           {
            ArrayObj=new CArrayObj;
            LabelArray[Wave.IndexVertex[5]]=ArrayObj;
           }
         TLabel *Label=new TLabel;
         Label.Text=Text;
         Label.Level=Wave.Level;
         if(Wave.Level>LevelMax)LevelMax=Wave.Level;
         Label.Value=Wave.ValueVertex[5];
         ArrayObj.Add(Label);
        }
      // proceed the child nodes of the current node
      for(int j=0;j<ChildNode.Child.Total();j++)
         FillLabelArray(ChildNode.Child.At(j));
     }
  }

6.17 Die CreateLabels Funktion:

double PriceInPixels;
CArrayObj ObjTextArray; // declare the array, which will store the graphical objects of "Text" type
//+------------------------------------------------------------------+
//| The function CreateLabels                                        |
//+------------------------------------------------------------------+
void CreateLabels()
  {
   double PriceMax =ChartGetDouble(0,CHART_PRICE_MAX,0);
   double PriceMin = ChartGetDouble(0,CHART_PRICE_MIN);
   int WindowHeight=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
   PriceInPixels=(PriceMax-PriceMin)/WindowHeight;
   int n=0;
   // loop the LabelArray array 
   for(int i=0;i<ArrayRange(LabelArray,0);i++)
     {
      // if there are tops with the same index i
      if(CheckPointer(LabelArray[i])!=POINTER_INVALID)
        {
         // obtain the tops with the same indexes i
         CArrayObj *ArrayObj=LabelArray[i];
         // loop the tops and display them on the chart
         for(int j=ArrayObj.Total()-1;j>=0;j--)
           {
            TLabel *Label=ArrayObj.At(j);
            int Level=LevelMax-Label.Level;
            string Text=Label.Text;
            double Value=Label.Value;
            color Color;
            int Size=8;
            if((Level/3)%2==0)
              {
               if(Text=="1") Text="i";
               else if(Text == "2") Text = "ii";
               else if(Text == "3") Text = "iii";
               else if(Text == "4") Text = "iv";
               else if(Text == "5") Text = "v";
               else if(Text == "A") Text = "a";
               else if(Text == "B") Text = "b";
               else if(Text == "C") Text = "c";
               else if(Text == "D") Text = "d";
               else if(Text == "E") Text = "e";
               else if(Text == "W") Text = "w";
               else if(Text=="X") Text="x";
               else if(Text == "XX") Text = "xx";
               else if(Text == "Y") Text = "y";
               else if(Text == "Z") Text = "z";
              }
            if(Level%3==2)
              {
               Color=Green;
               Text="["+Text+"]";
              }
            if(Level%3==1)
              {
               Color=Blue;
               Text="("+Text+")";
              }
            if(Level%3==0)
               Color=Red;
            int Anchor;
            if(Value==rates[i].high)
              {
               for(int k=ArrayObj.Total()-j-1;k>=0;k--)
                  Value=Value+15*PriceInPixels;
               Anchor=ANCHOR_UPPER;
              }
            else if(Value==rates[i].low)
              {
               for(int k=ArrayObj.Total()-j-1;k>=0;k--)
                  Value=Value-15*PriceInPixels;
               Anchor=ANCHOR_LOWER;
              }
            CChartObjectText *ObjText=new CChartObjectText;
            ObjText.Create(0,"wave"+IntegerToString(n),0,rates[i].time,Value);
            ObjText.Description(Text);
            ObjText.Color(Color);
            ObjText.SetInteger(OBJPROP_ANCHOR,Anchor);
            ObjText.FontSize(8);
            ObjText.Selectable(true);
            ObjTextArray.Add(ObjText);
            n++;
           }
        }
     }
   ChartRedraw();
  }

6.18 Die CorrectLabel Funktion:

//+------------------------------------------------------------------+
//| The CorrectLabel function                                        |
//+------------------------------------------------------------------+
void CorrectLabel()
  {
   double PriceMax=ChartGetDouble(0,CHART_PRICE_MAX,0);
   double PriceMin = ChartGetDouble(0,CHART_PRICE_MIN);
   int WindowHeight=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
   double CurrentPriceInPixels=(PriceMax-PriceMin)/WindowHeight;
   // loop all of the text objects (wave tops) and change their price size
   for(int i=0;i<ObjTextArray.Total();i++)
     {
      CChartObjectText *ObjText=ObjTextArray.At(i);
      double PriceValue=ObjText.Price(0);
      datetime PriceTime=ObjText.Time(0);
      int j;
      for(j=0;j<ArrayRange(rates,0);j++)
        {
         if(rates[j].time==PriceTime)
            break;
        }
      double OffsetInPixels;
      if(rates[j].low>=PriceValue)
        {
         OffsetInPixels=(rates[j].low-PriceValue)/PriceInPixels;
         ObjText.Price(0,rates[j].low-OffsetInPixels*CurrentPriceInPixels);
        }
      else if(rates[j].high<=PriceValue)
        {
         OffsetInPixels=(PriceValue-rates[j].high)/PriceInPixels;
         ObjText.Price(0,rates[j].high+OffsetInPixels*CurrentPriceInPixels);
        }
     }
   PriceInPixels=CurrentPriceInPixels;
  }


7. Die Funktion zur Initialisierung, De-Provisioning und Verarbeitung von Ereignissen

In der OnInit Funktion werden die Schaltflächen zur Kontrolle des automatischen Analyseinstruments für Elliott-Wellen erzeugt.

Dabei handelt es sich um folgende Schaltflächen:

  1. "Analyse beginnen" - eine automatische Analyse der Wellen beginnt
  2. "Ergebnisse anzeigen" - die Wellenmarkierungen auf dem Chart werden angezeigt
  3. "Chart leeren" - der Speicher wird geleert und die Wellenmarkierungen auf dem Chart werden gelöscht
  4. "Markierungen korrigieren" - die Wellenmarkierungen auf dem Chart werden korrigiert.

Die Verarbeitung der entsprechenden Schaltflächenaktivierung findet in der Funktion zur Verarbeitung von Ereignissen, OnChartEvent, statt.

In der Funktion OnDeinit, werden alle graphischen Objekte vom Chart entfernt, einschließlich aller Schaltflächen zur Kontrolle.

#include <Object.mqh>
#include <Arrays\List.mqh>
#include <Arrays\ArrayObj.mqh>
#include <Arrays\ArrayInt.mqh>
#include <Arrays\ArrayDouble.mqh>
#include <Arrays\ArrayString.mqh>
#include <ChartObjects\ChartObjectsTxtControls.mqh>
#include <Elliott wave\Data structures.mqh>
#include <Elliott wave\Analysis functions.mqh>
#include <Elliott wave\Rules functions.mqh>
CChartObjectButton *ButtonStart,*ButtonShow,*ButtonClear,*ButtonCorrect;
int State;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   State=0;
   // create control buttons
   ButtonStart=new CChartObjectButton;
   ButtonStart.Create(0,"Begin analysis",0,0,0,150,20);
   ButtonStart.Description("Begin analysis");
   ButtonShow=new CChartObjectButton;
   ButtonShow.Create(0,"Show results",0,150,0,150,20);
   ButtonShow.Description("Show results");
   ButtonClear=new CChartObjectButton;
   ButtonClear.Create(0,"Clear chart",0,300,0,150,20);
   ButtonClear.Description("Clear chart");
   ButtonCorrect=new CChartObjectButton;
   ButtonCorrect.Create(0,"Correct the marks",0,450,0,150,20);
   ButtonCorrect.Description("Correct the marks");
   ChartRedraw();
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   //clear waves tree
   ClearTree(FirstNode);
   //clear NodeInfoArray
   ClearNodeInfoArray();
   //clear ZigzagArray
   ClearZigzagArray();
   //clear LabelArray
   for(int i=0;i<ArrayRange(LabelArray,0);i++)
     {
      CArrayObj *ArrayObj=LabelArray[i];
      if(CheckPointer(ArrayObj)!=POINTER_INVALID)
        {
         for(int j=0;j<ArrayObj.Total();j++)
           {
            TLabel *Label=ArrayObj.At(j);
            delete Label;
           }
         ArrayObj.Clear();
         delete ArrayObj;
        }
     }
   //delete all of the graphical elements from the chart
   for(int i=ObjTextArray.Total()-1;i>=0;i--)
     {
      CChartObjectText *ObjText=ObjTextArray.At(i);
      delete ObjText;
     }
   ObjTextArray.Clear();
   delete ButtonStart;
   delete ButtonShow;
   delete ButtonClear;
   delete ButtonCorrect;
   ChartRedraw();
  }
MqlRates rates[];
TNode *FirstNode;
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
   if(id==CHARTEVENT_OBJECT_CLICK && sparam=="Begin analysis" && State!=0)
      MessageBox("First press the button \"Clear char\"");
   if(id==CHARTEVENT_OBJECT_CLICK && sparam=="Show results" && State!=1)
      MessageBox("First press the button \"Begin analysis\"");
   if(id==CHARTEVENT_OBJECT_CLICK && sparam=="Clear chart" && State!=2)
      MessageBox("First press the button \"Show results\"");
   if(id==CHARTEVENT_OBJECT_CLICK && sparam=="Correct the mark" && State!=2)
      MessageBox("First press the button \"Show results\"");
   //if the "Begin analysis" is pressed
   if(id==CHARTEVENT_OBJECT_CLICK && sparam=="Begin analysis" && State==0)
     {
      //fill the rates array
      CopyRates(NULL,0,0,Bars(_Symbol,_Period),rates);
      //fill the array ZigzagArray
      FillZigzagArray(0,Bars(_Symbol,_Period)-1);
      //create the first node
      TWave *Wave=new TWave;
      Wave.IndexVertex[0] = 0;
      Wave.IndexVertex[1] = Bars(_Symbol,_Period)-1;
      Wave.ValueVertex[0] = 0;
      Wave.ValueVertex[1] = 0;
      FirstNode=new TNode;
      FirstNode.Child=new CArrayObj;
      FirstNode.Wave=Wave;
      FirstNode.Text="First node";
      string NameWaves="Impulse,Leading Diagonal,Diagonal,Zigzag,Flat,Double Zigzag,Triple Zigzag,
                          Double Three,Triple Three,Contracting Triangle,Expanding triangle";
      //call the search for unbegun and incomplete waves function
      NotStartedAndNotFinishedWaves(Wave,1,FirstNode,NameWaves,0);
      MessageBox("Analysis is complete");
      State=1;
      ButtonStart.State(false);
      ChartRedraw();
     }
   // if "Show results" is pressed
   if(id==CHARTEVENT_OBJECT_CLICK && sparam=="Show results" && State==1)
     {
      ArrayResize(LabelArray,ArrayRange(rates,0));

      //fill the LabelArray array
      FillLabelArray(FirstNode);
      //show the mark-up of the waves on the chart
      CreateLabels();
      State=2;
      ButtonShow.State(false);
      ChartRedraw();
     }
   //if "Clear chart" is pressed"  
   if(id==CHARTEVENT_OBJECT_CLICK && sparam=="Clear chart" && State==2)
     {
      //clear the waves tree
      ClearTree(FirstNode);
      //clear the NodeInfoArray array
      ClearNodeInfoArray();
      //clear the ZigzagArray array
      ClearZigzagArray();
      //clear LabelArray
      for(int i=0;i<ArrayRange(LabelArray,0);i++)
        {
         CArrayObj *ArrayObj=LabelArray[i];
         if(CheckPointer(ArrayObj)!=POINTER_INVALID)
           {
            for(int j=0;j<ArrayObj.Total();j++)
              {
               TLabel *Label=ArrayObj.At(j);
               delete Label;
              }
            ArrayObj.Clear();
            delete ArrayObj;
           }
        }
      // delete mark-up from the chart
      for(int i=ObjTextArray.Total()-1;i>=0;i--)
        {
         CChartObjectText *ObjText=ObjTextArray.At(i);
         ObjText.Delete();
        }
      ObjTextArray.Clear();
      State=0;
      ButtonClear.State(false);
      ChartRedraw();
     }
   if(id==CHARTEVENT_OBJECT_CLICK && sparam=="Correct the marks" && State==2)
     {
      CorrectLabel();
      ButtonCorrect.State(false);
      ChartRedraw();
     }
  }

Wir haben uns jetzt alle Funktionen des automatischen Analyseinstruments für Elliott-Wellen angesehen.

 

8. Möglichkeiten zur Verbesserung des Programms

Das Programm zur automatischen Kennzeichnung der Elliott-Wellen, das in MQL5 geschrieben ist, besitzt einige Schwachstellen:

  1. Ein ungenügendes System zur Prüfung der Kennzeichnung Regeln. So werden z.B. beim Prüfen gemäß der Regeln, die Fibonacci-Beziehungen zwischen den Wellen, nach sowohl Uhrzeit und Kurs, nicht berücksichtigt
  2. Die Anwesenheit nicht partitionierter Bereiche auf dem Chart (Lücken in der Kennzeichnung). Das bedeutet, dass sich auf Basis der Punkte, die man aus einem gegebenen Zeitintervall erhalten hat, keine korrekte Welle bauen lässt. Der einzige Ausweg hier ist die Erhöhung der Anzahl an Punkten, um eine bestimmte Welle identifizieren zu können. Um z.B. den Impuls zu finden, sollte man nach 8 oder mehr, anstatt nur nach 6 Punkten, suchen.
  3. Die Ergebnisse der Kennzeichnung zeigen keinerlei Zusatzinformationen an: so werden z.B. Kanäle nicht automatisch gebaut, Ziele nicht bewertet, usw.
  4. Die Implementierung einer Arbeit mit dem Wellenbaumist in diesem Beitrag nicht behandelt Beitrag (man kann keine bestimmte Version der Kennzeichnung auswählen), sodass daher das Chart nur eine von vielen Optionen für eine Kennzeichnung anzeigt (nämlich seine erste Version).
  5. Ungeachtet der Tatsache, dass das Chart nur eine Variante von Wellen anzeigt, werden dennoch alle anderen Optionen im Speicher abgelegt und brauchen entsprechend Speicherplatz auf.
  6. Das Programm konzentriert sich auf die Kennzeichnung von Monatlich auf Täglich Charts, sodass dieser Vorgang bei einer großen Anzahl von Bars extrem langsam ist (die Kennzeichnung eines stündlichen Graphs kann bis zu einigen Stunden dauern). Abb. 18 zeigt ein Beispiel eine Kennzeichnung eines monatlichen Charts von EURUSD.

Abb. 18 Elliott-Wellen, die vom automatischen Analyseinstrument in MQL5 identifiziert wurden
Abb. 18 Elliott-Wellen, die vom automatischen Analyseinstrument in MQL5 identifiziert wurden

Fazit

Dieser Beitrag behandelte einen Algorithmus zur automatischen Analyse von Elliott-Wellen. Dieser Algorithmus wurde in die MQL5-Sprache implementiert.

Das Programm besitzt eine Menge Schwachstellen, die oben explizit erwähnt wurden, die auf jeden Fall in Zukunft beseitigt werden sollten. Ich hoffe, dass dieses Thema alle Fans von Elliott-Wellen interessiert und dass es bald viele Programme mit einer automatischen Analyse dieser Wellen gibt.