
La mise en œuvre de l'analyse automatique des vagues d'Elliott dans MQL5
Introduction
L'une des méthodes les plus populaires d'analyse du marché est le principe des vagues d'Elliott. Toutefois, ce processus est assez compliqué, ce qui nous amène à utiliser des instruments supplémentaires. L’un de ces instruments est le marqueur automatique.
Cet article décrit la création d’un analyseur automatique de vagues d'Elliott dans le langage MQL5. Il est supposé que le lecteur est déjà familiarisé avec la théorie des vagues, sans quoi il convient de se référer aux sources appropriées.
1. Le principe des vagues d'Elliott
Les vagues d'Elliott - est un modèle théorique du comportement du marché, développé par Ralph Nelson Elliott, selon lequel tous les mouvements de prix sur le marché sont soumis à la psychologie humaine et sont un processus cyclique de changements de vagues d'impulsion, à la correctionnelle et vice versa.
Les vagues d'impulsion sont une séquence de cinq fluctuations de prix, les vagues correctives - une séquence de trois ou cinq fluctuations de prix. Les vagues d'impulsion, dans leur forme, leur structure et les règles qui leur sont applicables, sont des types suivants :
1. Impulsions : | |
---|---|
![]() Figure 1. Impulsion |
|
2. Diagonales de tête : | |
![]() Figure 2. Diagonale de tête |
|
3. Diagonales : | |
![]() Figure 3. Diagonale |
|
Les vagues correctives sont classées en : | |
4. Zigzags : | |
![]() Figure 4. Zigzag |
|
5. Plats : | |
![]() Figure 5. Plats |
|
6. Double Zigzags : | |
![]() Figure 6. Double Zigzag |
|
7. Triple Zigzags : | |
![]() Figure 7. Triple Zigzag |
|
8. Double Trois : | |
![]() Figure 8. Double Trois |
|
9. Triple Trois : | |
![]() Figure 9. Triple Trois |
|
10. Triangle contractuel : | |
![]() Figure 10. Triangle contractuel |
|
11. Triangles en expansion : | |
![]() Figure 11. Triangle en expansion |
|
Les modèles et règles de vagues, présentés ci-dessus, ne correspondent qu'à la notion classique de l'analyse des vagues.
Il y a aussi sa conception moderne, formée lors de l'étude du marché Forex. Par exemple, un nouveau modèle de triangle oblique (glissant) est trouvé, les impulsions avec le triangle dans la deuxième vague sont identifiées, etc.
Comme le montrent les figures 1 à 11, chaque vague d'impulsion ou de correction est constituée des mêmes vagues d'impulsion et de correction (indiquées par la ligne pointillée), mais à un degré moindre. C'est ce que l'on appelle la fractale (emboîtement) des vagues d'Elliott : les vagues d'un grand degré se composent de vagues de degrés inférieurs, qui à leur tour, se composent de vagues beaucoup moins importantes, et ainsi de suite.
Sur cette note, nous pouvons terminer la brève introduction au principe des vagues d'Elliott et passer au sujet du balisage automatique des vagues.
2. Algorithme du balisage automatique des vagues d'Elliott
Comme vous l'avez probablement déjà compris, l'analyse des vagues d'Elliott est un processus complexe et à multiples facettes. C'est pourquoi, depuis le début, les gens ont commencé à chercher et à appliquer des instruments qui permettent de la faciliter.
L'un de ces outils est devenu le mécanisme de balisage automatique des vagues d'Elliott.
Nous pouvons distinguer deux principes de balisage automatique :
- Selon la fractalité des vagues, l'analyse est effectuée de haut en bas, des plus grandes aux plus petites vagues ;
- L'analyse se fait par une énumération directe de toutes les options possibles.
Un schéma fonctionnel de l'analyse automatique des vagues d'Elliott est présenté à la figure 12.
Figure 12. Schéma fonctionnel de l'analyse automatique des vagues d'Elliott
Examinez l'algorithme plus en détail, en vous basant sur l'exemple du balisage automatique de l'impulsion (voir Figure 13).
Lors de la première étape, à l’intervalle de temps requis du graphique des prix, à l’aide du « Zigzag », le nombre de points nécessaires à la réalisation du balisage est mis en évidence. Le nombre de points dépend du type de vagues que nous voulons analyser. Ainsi, pour l'analyse de l'Impulsion, il faut six points - 5 sommets et un point de départ. Si nous analysions le zigzag, le nombre de points requis aurait été de 4 - 3 sommets et un point de départ.
Si le « Zigzag » a identifié six points sur le graphique des prix, alors nous pouvons immédiatement générer un balisage de l’Impulsion : le premier point - le point de départ de la première vague, le deuxième point - le sommet de la première vague, le troisième point - le sommet de la deuxième vague, le quatrième point - le sommet de la troisième vague, le cinquième point - le sommet de la quatrième vague, et le sixième point - le sommet de la cinquième vague.
Cependant, sur la figure 13, le « Zigzag » a identifié 8 points. Dans ce cas, il sera nécessaire d'énumérer par ces points, toutes les options et balisages possibles de la vague. Et il y en aura cinq (marqués de couleurs différentes). Et chaque version du balisage devra être vérifiée selon les règles.
Figure 13. Options de marquage du balisage d’une impulsion
Après vérification par rapport aux règles, si le balisage de la vague est une impulsion par tous les paramètres, toutes ses sous-vagues sont analysées de la même manière.
Il en va de même pour l'analyse de toutes les autres vagues d'impulsion et de correction.
3. Les types de vagues pour le balisage automatique
Comme indiqué précédemment, l'analyse sera menée de haut en bas, en donnant au programme des instructions pour trouver une certaine vague sur un intervalle donné. Cependant, sur le plus grand intervalle, il est impossible de déterminer l'état de la vague, son début et sa fin. Nous appellerons une telle vague non commencée et non terminée.
Toutes les vagues peuvent être réparties dans les groupes suivants :
- Vagues non commencées :
- Vagues avec une première vague non commencée - 1-2-3-4-5 (par exemple, une impulsion avec une vague 1 non commencée 1, le nombre requis de points - 5), et 1-2-3 (par exemple, un Zigzag avec une vague 1 non commencée A ; le nombre requis de points - 3) ;
- Vagues avec une deuxième vague 1 non commencée - 2-3-4-5 (par exemple, une diagonale avec une vague 1 non commencée 2, le nombre requis de points - 4) et 2-3 (par exemple, un plat avec une vague 1 non commencée B ; le nombre requis de points -2) ;
- Vagues avec une troisième vague 1 non commencée - 3-4-5 (par exemple, un Triple Zigzag avec une vague 1 non commencée Y ; le nombre requis de points - 3) ;
- Vagues avec une quatrième vague 1 non commencée - 4-5 (par exemple, un triangle avec une vague 1 non commencée D ; le nombre requis de points -2) ;
- Vagues avec une cinquième vague 1 non commencée - 5 (par exemple, une Ipulse avec une vague 1 non commencée 5, le nombre requis de points - 1) ;
- Vagues avec une troisième vague 1 non commencée - 3 (par exemple, un double trois avec une vague 1 non commencée Z ; le nombre requis de points - 1) ;
- Vagues non terminées :
- Vagues avec une cinquième vague non terminée - 1-2-3-4-5 (par exemple, une impulsion avec une vague non terminée 5 ; le nombre requis de points - 5) ;
- Vagues avec une quatrième vague non terminée - 1-2-3-4> (par exemple, un triple zigzag avec une vague non terminée XX ; le nombre requis de points - 4) ;
- Vagues avec une troisième vague non terminée - 1-2-3> (par exemple, une diagonale de tête de la vague non terminée 3, le nombre requis de points -3 );
- Vagues avec une deuxième vague non terminée - 1-2> (par exemple, un Zigzag avec une vague B non terminée ; le nombre requis de points -2) ;
- Vagues avec une première vague non terminée - 1> (par exemple, un plat avec une vague A non terminée ; le nombre requis de points -1 );
- Vagues non commencée et non terminée :
- Vagues avec une première vague non commencée et une deuxième vague non terminée -1-2>(par exemple, un Zigzag avec une vague non commencée A et une vague non terminée B ; le nombre requis de points - 1) ;
- Vagues avec une deuxième vague non commencée et une troisième vague non terminée - 2-3>(par exemple, un Zigzag avec une vague B non commencée et une vague C non terminée ; le nombre requis de points - 1) ;
- Vagues avec une troisième vague non commencée et une quatrième vague non terminée - 3-4>< (par exemple, une impulsion avec une vague non commencée 3 et une vague non terminée 4, le nombre requis de points - 1) ;
- Vagues avec une quatrième vague non terminée et une cinquième vague non achevée - 4-5> (par exemple, une impulsion avec une vague non commencée 4 et une vague non terminée 5, le nombre requis de points - 1) ;
- Vagues avec une première non commencée et une troisième vague non terminée - 1-2-3>(par exemple, les trois triples avec une vague non commencée W et une vague non terminée Y ; le nombre requis de points - 2) ;
- Vagues avec une deuxième vague non commencée et une quatrième vague non terminée -2-3-4>(par exemple, une diagonale de tête avec une vague non commencée 2 et une vague non terminée 4, le nombre requis de points - 2) ;
- Vagues avec une troisième vague non commencée et une cinquième vague non terminée - 3-4-5>(par exemple, une diagonale avec une onde non commencée 3 et une vague non terminée 5, le nombre requis de points - 2) ;
- Vagues avec une première vague non commencée et avec une quatrième vague non terminée -1-2-3-4>(par exemple, un triple trois avec une vague non commencée W et une vague non terminée XX ; le nombre de points requis - 3) ;
- Vagues avec une deuxième vague non commencée et une cinquième vague non terminée - 2-3-4-5 (par exemple, une impulsion avec une vague 2 non commencée et une vague 5 non terminée ; le nombre de points requis - 3) ;
- Vagues avec une première vague non commencée et une cinquième vague non terminée -1-2-3-4-5>(par exemple, un triple zigzag avec une vague non commencée W et une vague non terminée Z ; le nombre de points requis - 4) ;
- Vagues complétées - 1-2-3-4-5 (le nombre de points requis - 6) et 1-2-3 (le nombre requis de points - 4).
Le signe « < » après le numéro de la vague, indique qu’elle n’a pas commencé. Le signe « > »après le numéro d'une vague, indique qu'elle est incomplète.
Sur la figure 14, nous pouvons voir les vagues suivantes :
- Une vague avec une première vague non commencée A -A -B-C;
- Une vague avec un premier W non commencée et une deuxième vague X non terminée -W<-X>;
- Vagues Bet Cterminées;
non terminéeset vagues non terminée
Figure 14. Non commencée et vagues non terminées
4. La description des structures de données de l'analyseur automatique des vagues d'Elliott
Pour écrire l'analyseur automatique des vagues d'Elliott, nous avons besoin des structures de données suivantes :
4.1. La structure de la description des vagues analysées dans le programme :
// 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. Une classe pour stocker les paramètres d'une vague spécifique :
// 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. Une classe pour stocker les valeursdes sommets et les index des sommets du Zigzag :
// 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. Classe pour représenter l’arbre des vagues :
// 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. La structure pour stocker les points, trouvés par le Zigzag :
// 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. Une classe pour stocker les paramètres de la section déjà analysée du graphique :
// 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. Une classe pour stocker le marquage des vagues avant de le placer sur le graphique :
// 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. La description de la fonction de l'analyseur automatique des vagues d'Elliott
Pour écrire l'analyseur automatique des vagues d'Elliott, nous avons besoin des fonctions suivantes :
int Zigzag(intH,int Start,int Finish,CArrayInt *IndexVertex,CArrayDouble *ValueVertex)
Un élément clé de l’analyseur automatique des vagues d'Elliott est le « Zigzag », par lequel les vagues seront construites. Le calcul du « Zigzag » par n’importe quel paramètre doit être fait très rapidement.
Dans notre analyseur, nous utiliserons le « Zigzag », tiré de l’article « Comment écrire des zigzags rapides sans dessin ».
La fonction Zigzag calcule le Zigzag, avec le paramètre H dans l’intervalle du début à la fin, puis enregistre les index trouvés des sommets et les valeurs des sommets, respectivement, dans les tableaux IndexVertex et ValueVertex, dont les adresses sont transmises à cette fonction.
La fonction Zigzag renvoie le nombre de sommets trouvés du « Zigzag ».
Fonction du remplissage de « Zigzag » et du stockage de ses paramètres :
void FillZigzagArray(int Start,int Finish)
Comme indiqué précédemment, nous devrons trouver le nombre de points nécessaire sur le graphique des prix pour le balisage de la vague. Et donc nous aurons besoin d’avoir un tableau de sommets du « Zigzag », avec différents paramètres, que nous allons ensuite itérer pour trouver ces points.
La fonction FillZigzagArray calcule le « Zigzag » sur l’intervalle du graphique du début à la fin, avec toutes les valeurs possibles du paramètre H (jusqu’à ce que le nombre de sommets du « Zigzag » ne devienne pas égal ou inférieur à deux), stocke les informations sur les sommets trouvés dans les objets de la classe TZigzag, et enregistre ces objets dans le tableau global ZigzagArray, dont l’annonce est la suivante :
CArrayObj *ZigzagArray;
La fonction de recherche sur l’intervalle donné nécessite le nombre de points sur le graphique des prix :
bool FindPoints(int NumPoints,int IndexStart,int IndexFinish,double ValueStart,double ValueFinish,TPoints &Points)
La fonction FindPoints recherche au moins trois points NumPoints sur le graphique des prix, sur la plage requise, de IndexStart à IndexFinish, avec les valeurs requises des premier et dernier points ValueStart et ValueFinish, et les enregistre (c’est-à-dire des points) dans la structure des Points, dont le lien est transmis à cette fonction.
La fonction FindPoints renvoie true, si le nombre de points requis est trouvé, sinon, elle renvoie false.
5.4. NotStartedAndNotFinishedWaves
La fonction d'analyse des vagues non commencées et non terminées :
void NotStartedAndNotFinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
La fonction NotStartedAndNotFinishedWaves analyse toutes les vagues du troisième groupe de vagues - non commencées et non terminées. La fonction analyse la vague NumWave (avec un niveau de vague Level), les vagues avec le nom ParentWave.Name, qui peuvent prendre la forme de vagues secondaires (une forme de Zigzag, plats, Double zigzag, et (ou), etc). La vague analysée NumWave sera stockée dans le nœud de l'arbre des vagues, le nœud enfant Node.
Par exemple, si les ParentWave.Name = « Impulsion », NumWave = 5, Subwaves = « Impulsion, Diagonale et Niveau = 2, alors nous pouvons dire que la fonction NotStartedAndNotFinishedWaves analysera la cinquième vague de l’Impulsion, qui a un niveau de vague de deux, et peut prendre la forme d’une Impulsion ou d’une Diagonale.
À titre d’exemple, nous utilisons un diagramme fonctionnel de l’analyse algorithmique des vagues 1<-2-3> non terminées dans la fonction NotStartedAndNotFinishedWaves :
<img alt="Figure 15. Le schéma fonctionnel de l’analyse des vagues avec la formule « 1" » title="Figure 15. Le diagramme fonctionnel de l’analyse des vagues avec la formule « 1" » src=« http://p.mql5.com/data/2/260/fig15.gif » style=« vertical-align:middle; » height=« 1746 » width=« 750 »>
Figure 15. Le schéma fonctionnel de l’analyse des vagues avec la formule « 1<-2-3> »
Lors de l’utilisation de la fonction NotStartedAndNotFinishedWaves, les fonctions suivantes sont appelées : NotStartedWaves, NotFinishedWaves et FinishedWaves.
La fonction d’analyse des vagues non commencées :
void NotStartedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
La fonction NotStartedWaves analyse toutes les vagues du premier groupe de vagues - les vagues non commencées. La fonction analyse la vague NumWave (avec le niveau de vague Level) de la vague appelée ParentWave.Name, qui peut prendre la forme de vagues secondaires. La vague analysée NumWave sera stockée dans le nœud de l'arbre des vagues, le nœud enfant Node.
Lorsque la fonction NotStartedWaves est à l'œuvre, les fonctions suivantes sont appelées : NotStartedWaves et FinishedWaves.
Toutes les vagues sont analysées de la même manière que le schéma fonctionnel de la figure 15.
L'analyse fonctionnelle des vagues non terminées :
void NotFinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
La fonction NotFinishedWaves analyse toutes les vagues du deuxième groupe de vagues - les vagues non terminées. La fonction analyse la vague NumWave (avec le niveau de vague Level) de la vague appelée ParentWave.Name, qui peut prendre la forme de vagues secondaires. La vague analysée NumWave sera stockée dans le nœud de l'arbre des vagues, le nœud enfant Node.
Lorsque la fonction NotFinishedWaves est à l’œuvre, les fonctions suivantes sont appelées : NotFinishedWaves et FinishedWaves.
Toutes les vagues sont analysées de la même manière que le schéma fonctionnel de la figure 15.
L'analyse des fonctions des vagues achevées (terminées) :
void FinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
La fonction FinishedWaves analyse toutes les vagues du quatrième groupe - les vagues achevées. La fonction analyse la vague NumWave (avec un niveau de vague Level) de la vague appelée ParentWave.Name, qui peut prendre la forme d'une vague secondaire. La vague analysée NumWave sera stockée dans le nœud de l'arbre des vagues, le nœud enfant Node.
Lorsque la fonction FinishedWaves est à l'œuvre, la fonction FinishedWaves est appelée.
Toutes les vagues sont analysées de la même manière que le schéma fonctionnel de la figure 15.
5.8. FindWaveInWaveDescription
La fonction de recherche de vagues dans la structure de données WaveDescription :
int FindWaveInWaveDescription(string NameWave)
La fonction FindWaveInWaveDescription, par le nom de la vague NameWave, passé en paramètre, la recherche dans le tableau de structures WaveDescription, et renvoie le numéro d'index, correspondant à cette vague.
Le tableau de structures WaveDescription se présente comme suit :
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," } } };
La fonction FindWaveInWaveDescription est utilisée dans l’analyse fonctionnelle des vagues suivantes : NotStartedAndNotFinishedWaves, NotStartedWaves, NotFinishedWaves et FinishedWaves.
La fonction qui vérifie si la section donnée du graphique a déjà été analysée :
bool Already(TWave *Wave,int NumWave,TNode *Node,string Subwaves)
Étant donné que l'analyse automatique des vagues d'Elliott se fait par la méthode d'énumération, une situation peut se produire lorsque la section donnée du graphique a déjà été analysée pour la présence d'une vague ou d'un groupe de vagues. Pour ce faire, vous devez enregistrer le lien vers le nœud dans l’arborescence des vagues de la vague déjà analysée, et seulement ensuite sortir le lien. Tout cela se passe dans la fonction Déjà.
La fonction Already recherche dans un tableau global NodeInfoArray, qui stocke les objets de la classe TNodeInfo, l'intervalle du graphique, correspondant à la vague NumWave, de la vague nommée Wave. Nom, qui a la forme de vagues et enregistre dans le nœud l’adresse du nœud de la section déjà balisée du graphique. Si cette section n’existe pas, un nouvel objet de la classe TNodeInfo est créé et rempli, puis enregistré dans le tableau NodeInfoArray.
La fonction renvoie true si l’intervalle du graphique a déjà été analysé, sinon elle renvoie false.
Le tableau NodeInfoArray est déclaré de la manière suivante :
CArrayObj NodeInfoArray;
5.10. Les fonctions de vérification des vagues pour les règles
Il comprend les fonctions VertexAAboveB, WaveAMoreWaveB et WaveRules, à partir desquelles les deux premières fonctions sont appelées. Lors des tests, n'oubliez pas que les vagues peuvent être non commencées et (ou) incomplètes, et, par exemple, pour la vague avec la formule « 1<-2-3> », on ne peut pas déterminer si la quatrième vague a dépassé le territoire de la première vague car il n'y a pas encore de quatrième vague.
Fonction de vérification des vagues pour les règles :
bool WaveRules(TWave *Wave)
La fonction WaveRules renvoie true si une vague, portant le nom Wave.Name, est « correcte », sinon, elle renvoie false. Dans son travail, la fonction WaveRules est appelée par la fonction VertexAAboveVertexB et WaveAMoreWaveB.
La fonction de vérification de l'excès d'un sommet sur un autre sommet :
int VertexAAboveVertexB(int A,int B,bool InternalPoints)
La fonction VertexAAboveVertexB renvoie le nombre > = 0, si le sommet de la vague A a dépassé le sommet de la vague B, sinon elle renvoie -1. Si l'option InternalPoints = true, alors les points internes des vagues ( maximum et (ou) minimum) valeursdes vagues) sont prises en considération.
Fonction consistant à vérifier l'excès de la longueur d'une vague par rapport à la longueur d'une autre :
int WaveAMoreWaveB(int A,int B)
La fonction WaveAMoreWaveB renvoie un nombre >=0 si la vague A est plus grande que la vague B, sinon elle renvoie -1.
11. La fonction de nettoyage de la mémoire
La fonction de nettoyage de l’arbre des vagues avec le nœud supérieur Node :
void ClearTree(TNode *Node)
La fonction nettoie le tableau ClearNodeInfoArray :
void ClearNodeInfoArray()
La fonction permettant de vider le tableau ZigzagArray :
void ClearZigzagArray()
5.12. La fonction de contournement des vagues de l'arbre et l'émission des résultats de l'analyse vers le graphique
Après l'achèvement de l'analyse automatique des vagues d'Elliott, nous avons un arbre de vagues.
Son exemple peut être présenté comme sur la figure ci-dessous :
Figure 16. Un exemple d’arbre de vagues
Maintenant, pour afficher les résultats de l’analyse sur le graphique, nous devons contourner l’arbre donné. Comme le montre la figure 16, il y a peu d'options (puisqu'il y a plusieurs options de vagues), et chaque option de dérivation conduit à un balisage différent.
On peut distinguer deux types de nœuds d'arbre.
Le premier type - les nœuds avec les noms de vagues (« Impulsion », « Zigzag », etc.). Le deuxième type - les nœuds avec le nombre de vagues (« 1 », « 1< », « etc.). Toutes les informations sur les paramètres de l'onde sont stockées dans le premier type de nœuds. Par conséquent, lorsque nous visitons ces nœuds, nous récupérons et enregistrons des informations sur la vague, afin de les afficher ensuite sur le graphique.
Pour simplifier, nous allons contourner l'arbre, en ne visitant que les premières versions des vagues.
Un exemple de contournement est illustré à la figure 17 et est surligné en rouge.
Figure 17. Exemple de contournement d'une arborescence de vagues
La fonction de contournement d'une arborescence de vagues :
void FillLabelArray(TNode *Node)
La fonction FillLabelArray contourne l’arborescence de vagues avec le nœud racine, ne s'occupe que des premières versions des vagues dans l'arbre, et remplit un tableau global LabelArray, dont les indices, stockent un lien vers le tableau de vertex (tableau d'objets de la classe TLabel), avec l'indice donné sur le graphique.
Le tableau LabelArray est défini comme suit :
CArrayObj *LabelArray[];
La fonction d’affichage des résultats d’analyse sur le graphique :
void CreateLabels()
La fonction CreateLabels crée les objets graphiques « Text », correspondant aux balises de vagues sur le graphique. Les balises des vagues sont créées en fonction du tableau LabelArray.
La fonction de mise à jour de (correction) des sommets des vagues sur le graphique :
void CorrectLabel()
La fonction CorrectLabel corrige les balises de vagues sur le graphique lorsqu’il est défilé et (ou) pendant sa restriction.
6. La mise en place du partitionnement automatique des vagues d'Elliott
6.1. La fonction Zigzag :
//+------------------------------------------------------------------+ //| 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. La fonction FillZigzagArray :
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. La fonction FindPoints :
//+------------------------------------------------------------------+ //| 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. La fonction NotStartedAndNotFinishedWaves :
//+------------------------------------------------------------------+ //| 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. La fonction NotStartedWaves :
//+------------------------------------------------------------------+ //| 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. La fonction NotFinishedWaves :
//+------------------------------------------------------------------+ //| 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. La fonction FinishedWaves :
//+------------------------------------------------------------------+ //| 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. La fonction FindWaveInWaveDescription :
//+------------------------------------------------------------------+ //| 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. La fonction Already :
//+------------------------------------------------------------------+ //| 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. La fonction WaveRules :
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. La fonction VertexAAboveVertexB :
//+-------------------------------------------------------------------------------------+ //| 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. La fonction WaveAMoreWaveB :
//+-----------------------------------------------------------------------+ //| 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. La fonction ClearTree :
//+------------------------------------------------------------------+ //| 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. La fonction ClearNodeInfoArray :
//+------------------------------------------------------------------+ //| 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. La fonction ClearZigzagArray :
//+------------------------------------------------------------------+ //| 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. La fonction FillLabelArray :
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. La fonction CreateLabels :
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. La fonction CorrectLabel :
//+------------------------------------------------------------------+ //| 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. Fonction d’initialisation, de déprovisionnement et de traitement des événements
Dans la fonction OnInit, les boutons de commande de l’analyseur automatique Elliott Wave sont créés.
Les boutons suivants sont créés :
- « Commencer l'analyse » - une analyse automatique des vagues se produit
- « Afficher les résultats » - l’affichage des marques des vagues sur le graphique se produit,
- « Effacer le graphique » - la mémoire est effacée et les marques de vagues sont supprimées du graphique,
- « Corriger les marques » - corrige les marques des vagues sur le graphique.
Le traitement de l’appui sur ces boutons a lieu dans la fonction de traitement des événements OnChartEvent.
Dans la fonction OnDeinit, tous les objets graphiques sont supprimés du graphique, y compris les boutons de contrôle.
#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(); } }
Nous avons passé en revue toutes les fonctions de l'analyseur automatique des vagues d'Elliott.
8. Les moyens d'améliorer le programme
Le balisage automatique du programme Elliott Waves, écrit en MQL5, présente plusieurs lacunes :
- Un système imparfait de vérification des règles de balisage. Par exemple, lors de la vérification selon les règles, les relations de Fibonacci entre les vagues ne sont pas prises en compte, en fonction du temps et du prix.
- La présence de sections non partitionnés sur le graphique (lacunes dans le balisage). Cela signifie qu’une vague correcte ne peut pas être construite en fonction des points pris dans l’intervalle de temps donné. Pour sortir de cette situation, il faut augmenter le nombre de points afin d'identifier une vague particulière. Par exemple, pour trouver l’impulsion, recherchez 8 points ou plus, plutôt que 6 points.
- Les résultats du balisage n'affichent pas d'informations supplémentaires, par exemple, les canaux ne sont pas construits automatiquement, les objectifs ne sont pas évalués, etc.
- La mise en œuvre de l’utilisation de l’arborescence des vagues n’est pas fournie dans cet article (vous ne pouvez pas sélectionner une version spécifique du balisage), c’est pourquoi le graphique n’affiche qu’une seule des nombreuses options pour un balisage (la première version du balisage).
- Indépendamment du fait que le graphique n'affiche qu'une seule variante des vagues, toutes les autres options sont stockées dans la mémoire et occupent son espace.
- Le programme se concentre sur le balisage des graphiques mensuels à quotidiens, car l’opération est très lente lorsqu’il y a un grand nombre de barres (cela peut prendre des heures pour baliser un graphique horaire). Un exemple de balisage d’un graphique mensuel de l’EURUSD est illustré à la figure 18.
Figure 18. Vagues d'Elliott, identifiées par l'analyseur automatique de MQL5
Conclusion
Cet article passe en revue un algorithme d'analyse automatique des vagues d'Elliott. Cet algorithme a été mis en œuvre dans le langage MQL5.
Le programme présente un certain nombre de lacunes, évoquées plus haut, et donne des raisons de les éliminer davantage. J'espère que ce numéro intéressera les fans des vagues d'Elliott, et que bientôt apparaîtront de nombreux programmes avec l'analyse automatique des vagues.
Traduit du russe par MetaQuotes Ltd.
Article original : https://www.mql5.com/ru/articles/260





- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation