
MQL5のエリオット波動の自動分析の実装
はじめに
市場分析の最も人気なメソッドの一つとして、エリオット波動法則があります。しかし、このプロセスは、かなり複雑であり、追加ツールを使用せざるをえません。その一つとして、自動マーカーがあります。
この記事は、MQL5言語でのエリオット波動の自動分析ツールの作成を紹介します。読者はすでにそのエリオット波動理論に親しみがあると想定し、そうでなければ、適切な情報源を参照する必要があります。
1. エリオット波動理論
エリオット波動 - は、 Ralph Nelson Elliottにより提唱された市場行動の理論モデルであり、それによると、市場での価格の動きの全ては、人間心理の影響を受け、衝撃波の変化の周期的プロセスです。
その衝撃波は、5つの価格変動、矯正波動 - 一連の3つから5つの価格変動です。それらに適用されるルールや形式での衝撃波は、以下の種類です:
1. 衝撃: | |
---|---|
![]() 図1. 衝撃 |
|
2. メインの対角線: | |
![]() 図2. メインの対角線 |
|
3. 対角線: | |
![]() 図3. 対角線 |
|
矯正波動は、以下に分類されます; | |
4. ジグザグ: | |
![]() 図4. ジグザグ |
|
5. フラット: | |
![]() 図5. フラット |
|
6. 二重ジグザグ: | |
![]() 図6. 二重ジグザグ |
|
7. 三重ジグザグ: | |
![]() 図7. 三重ジグザグ |
|
8. ダブルスリー: | |
![]() 図8. ダブルスリー |
|
9. トリプルスリー: | |
![]() 図9. トリプルスリー |
|
10. 締約三角形: | |
![]() 図10. 締約三角形 |
|
11. 拡大三角形: | |
![]() 図11. 拡大三角形 |
|
その波動モデルやルールは、波動分析の古典的な観念に飲み適応します。
Forex市場の研究にて形成された現代版のコンセプトもあります。例えば、直角を持たない三角形の新しいモデルが見つかり、2番目の波動の衝撃波が特定されます。
図1-11で分かるとおり、それぞれの衝撃波、矯正波動は、(ダッシュ線で示されている通り)同じ衝撃、矯正波動から成り立ちますが、程度は小さめです。これは、いわゆるエリオット波動のフラクタルです:大きい波動は小さい波動から成り立っています。
この記述にて、エリオット波動の原則についての簡単な導入を終了し、波動の自動マークアップのトピックへ移ります。
2. エリオット波動の自動マークアップのアルゴリズム
すでに気づかれたかと思いますが、エリオット波動は、複雑で多面的なプロセスです。したがって、人々は、簡単にするような手段を探し、適用し始めました。
そのようなツールの一つが、エリオット波動の自動マークアップのためのメカニズムです。
自動マークアップについて二つの原則を区別することができます:
- 波動のフラクタルによれば、その分析は上から下に実行され、大きい波動から小さい波動にかけて行われます;
- その分析は、すべての可能なオプションの直接列挙によって実行されます。
エリオット波動の自動分析の図式は図12にて示されています。
図12. エリオット波動の自動分析の図式
衝撃波の自動マークアップの例をもとに、詳しくそのアルゴリズムを見ていきましょう(図13をご覧ください。)
その最初のステージでの価格チャートの必要な時間のインターバルにて、「ジグザグ」を用いてマークアップの作成に必要なポイントの量がハイライトで表示されています。ポイントの数は、どの種類の波動を分析したいかに依存します。衝撃波の分析において、必要な6つのポイント - 5頂点と一つの開始点があります。もしジグザグを分析しているなら、必要なポイント数は、4つ - 3つの頂点と、一つの開始点です。
もしその「ジグザグ」が価格チャートにて6つの点を特定すると、即座に衝撃波のマークアップを生成することができます:最初のポイント-最初の波動の開始点、2番目のポイント-最初の波動の頂点、3番目のポイント-2番目の波動の頂点、4番目の波動-さんばんめの波動の頂点、5番目のポイント-4番目の波動の頂点、6番目のポイント-5番目の波動の頂点
しかし、図13では、その「ジグザグ」は8つの点を特定しました。この場合、これらの点によってすべての可能なオプションや波動のマークアップを列挙する必要があります。そして、(異なる色でマークされた)5つがあります。マークアップの各バージョンは、ルールによってチェックされる必要があります。
図13. 衝撃波のマークアップの作成におけるオプション
ルールをチェックしたのち、その波動のマークアップが、すべてのパラメーターによる衝撃波である場合、すべての副波動は、同じ方法で分析されます。
同じことが、その他衝撃波と強制波動の分析が適用されます。
3. 自動マークアップにおける波動の種類
以前述べられた通り、その分析は、上から下までプログラムに特定の期間での波動を見つけるよう指示を与えることで、行われます。しかし、最も長いインターバルで、波動の状態や始まりや終わりを決定することは不可能です。そのような波動を非開始・非停止と呼びます。
すべての波動は、以下のグループに分類されます。
- 非開始波動:
- 非開始状態の最初の波動を持つ波動 - 1-2-3-4-5 (例えば、非開始波動1の衝撃波、必要なポイント数 - 5)、1-2-3 (例えば、非開始波動Aのジグザグ;必要なポイント数 - 3);
- 非開始状態の2番目の波動を持つ波動 - 2-3-4-5 (例えば、非開始波動2の対角線、必要なポイント数 2、必要なポイント数 - 4)、 2-3 (例えば、非開始波動Aのフラット;必要なポイント数 -2);
- 非開始状態の3番目の波動を持つ波動 - 3-4-5 (例えば、非開始波動Yのトリプルジグザグ、必要なポイント数 - 3);
- 非開始状態の4番目の波動を持つ波動 - 4-5 (例えば、非開始波動Dの三角形、必要なポイント数 - 2); -2);
- 5番目の非開始状態の波動を持つ波動 - 5 (例えば、非開始波動5の衝撃波、必要なポイント数 - 1); );
- 3番目の非開始状態の波動を持つ波動 - 3 (例えば、非開始状態の波動Zのダブルスリー;必要なポイント数 - 1);
- 非停止波動:
- 5番目の非停止波動を持つ波動 - 1-2-3-4-5 (例えば、非停止波動5を持つ衝撃波;必要なポイント数 - 5);
- 4番目の非停止波動を持つ波動 - 1-2-3-4> (例えば、非停止波動XXを持つ衝撃波;必要なポイント数 - 5);
- 3番目の非停止波動を持つ波動 - 1-2-3> (例えば、非停止波動3のメイン対角線;必要なポイント数 - 3);
- 2番目の非停止波動を持つ波動 - 1-2> (例えば、非停止波動Bを持つジグザグ;必要なポイント数 - 2);
- 最初の非停止波動を持つ波動 - 1> (例えば、非停止波動Aを持つフラット;必要なポイント数 - 1);
- 非開始・非停止波動:
- 最初の非開始波動と2番目の非停止波動を持つ波動 -1-2>(例えば、1番目の非開始波動Aと非停止波動Bを持つジグザグ;必要なポイント数 - 1);
- 2番目の非開始波動と3番目の非停止波動を持つ波動 - 2-3>(例えば、1番目の非開始波動Bと非停止波動Cを持つジグザグ;必要なポイント数 - 1);
- 3番目の非開始波動と4番目の非停止波動を持つ波動 - 3-4>< (例えば、3番目の非開始波動と非停止波動4を持つ衝撃波;必要なポイント数 - 1);
- 4番目の非開始波動と5番目の非停止波動を持つ波動 - 4-5> (例えば、4番目の非開始波動と非停止波動5を持つ衝撃波;必要なポイント数 -1);
- 最初の非開始波動と3番目の非停止波動を持つ波動 - 1-2-3>(例えば、非開始波動Wと非停止波動Yを持つトリプルスリー;必要なポイント数 -2);
- 2番目の非開始波動と4番目の非停止波動を持つ波動 -2-3-4>(例えば、非開始波動2と非停止波動4を持つメイン対角線;必要なポイント数 -2);
- 3番目の非開始波動と5番目の非停止波動を持つ波動 - 3-4-5>(例えば、非開始波動3と非停止波動5を持つ対角線;必要なポイント数 -2);
- 最初の非開始波動と4番目の非停止波動を持つ波動 -1-2-3-4>(例えば、非開始波動Wと非停止波動XXを持つトリプルスリー;必要なポイント数 -3);
- 2番目の非開始波動と5番目の非停止波動を持つ波動 - 2-3-4-5 (例えば、非開始波動2と非停止波動5を持つ衝撃波;必要なポイント数 -3);
- 最初の非開始波動と5番目の非停止波動を持つ波動 -1-2-3-4-5>(例えば、非開始波動Wと非停止波動Zを持つトリプルジグザグ;必要なポイント数 -4);
- 終了済み波動 - 1-2-3-4-5 (必要なポイント数 - 6) と1-2-3 (必要なポイント数 - 4).
波動数の後のその "<"という記号は、開始していないということを示しています。波動数の後のその ">"という記号は、終了していないということを示しています。
図14では、以下の波動を見ることができます:
- 最初の非開始波動を持つ波動 A -A -B-C;
- 非停止 Wの波動と2番目の非停止X 波動 -W<-X>;
- 終了済み波動 Bと C;
図14. 非開始・非停止波動
4. エリオット波動の自動分析データストラクチャーの詳細
エリオット波動の自動分析ツールを記述するために、以下のデータストラクチャーが必要です:
4.1. プログラムにて分析された波動の詳細に関するデータストラクチャー:
// 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. 特定の波動のパラメーターを保管するクラス:
// 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. 頂点の値と、ジグザグの頂点のインデックスを保持するためのクラス:
// 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. 波動ツリーを表現するクラス:
// 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. ジグザグによって発見されるポイントを保持するストラクチャー:
// 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. そのチャートのすでに分析されたセクションのパラメーターを維持するためのクラス:
// 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. チャートに添付前の波動のマークを保持するクラス:
// 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. エリオット波動の自動分析ツールの機能の詳細
エリオット波動の自動分析ツールを記述するために、以下の機能が必要です:
int Zigzag(intH,int Start,int Finish,CArrayInt *IndexVertex,CArrayDouble *ValueVertex)
エリオット波動の自動分析ツールの重要な要素は”ジグザグ”であり、それによって波動が作成されます。パラメーターによる「ジグザグ」の計算は、すぐに行われます。
その分析ツールでは、"How to Write Fast Non-Redrawing ZigZags"という記事から取得した「ジグザグ」を使用します。
そのジグザグ関数は、StarttからFinishの間のインターバルでのパラメーターHを持つジグザグを計算し、頂点のインデックスと頂点の値をそれぞれIndexVertexとValueVertexに記録します。それらのアドレスはこの関数の中に渡されます。
そのジグザグ関数は、その「ジグザグ」の頂点の数を返します。
「ジグザグ」に格納する関数と、そのパラメーターの保存:
void FillZigzagArray(int Start,int Finish)
以前示された通り、波動のマークアップのための価格チャートにおける必要なポイント数を発見する必要があります。そして、異なるパラメーターを持つ”ジグザグ”の頂点を持つ配列を保持する必要があり、これらのポイントを見つけるようループを行います。
FillZigzagArray関数は、StartからFinishまでのチャートの期間でのすべての可能なパラメーターHの値で”ジグザグ”を計算します。(”ジグザグ”の頂点の数が2以下になるまで)そして、TZigzagのクラスオブジェクトで見つかった頂点についての情報を保持し、これらのオブジェクトをグローバル配列ZigzagArrayに記録し、それは以下のように宣言されます:
CArrayObj *ZigzagArray;
特定の期間での検索関数は、価格チャートのポイント数を必要とします:
bool FindPoints(int NumPoints,int IndexStart,int IndexFinish,double ValueStart,double ValueFinish,TPoints &Points)
そのFindPoints関数は、少なくとも3つのNumPointsポイントをIndexStartからIndexFinishまでの必要な範囲で価格チャートにて探索します。そして、それらをPointsストラクチャーに保存し、そちらのアドレスはこの関数に渡されます。
FindPoints関数は、必要なポイント数が見つかれば、trueを返し、さもなければ、falseを返します。
5.4. NotStartedAndNotFinishedWaves
非開始・非停止波動の分析関数:
void NotStartedAndNotFinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
NotStartedAndNotFinishedWavesは、3つの波動グループすべてを分析します- 非開始・非停止その関数は、(波動レベルの)NumWave波動、ParentWave.Nameの波動を分析し、後者はサブ波動の形をとります(ジグザグ、フラット、ダブルジグザグの形式など). その分析された波動NumWaveは、波動ツリーのノード、子ノードに保存されます。
例えば、もしParentWave.Name = "Impulse", NumWave = 5, Subwaves = "Impulse, DiagonalやLevel = 2、 NotStartedAndNotFinishedWaves 関数は衝撃波の5番目の波動を分析します。それは、波動レベル2で、対角線か衝撃波の形をとります。
例として、NotStartedAndNotFinishedWaves関数の非1<-2-3>の非開始・非停止波動のアルゴリズム分析の図式を使用します:
<img alt="Figure 15. 公式"1"" title=" 図15の波動分析の図式. 波動分析の図式 公式"1"" src="http://p.mql5.com/data/2/260/fig15.gif" style="vertical-align:middle;" height="1746" width="750">
図15公式"1<-2-3>"の波動分析の図式
NotStartedAndNotFinishedWaves関数を用いたときに、以下の関数が呼ばれます:NotStartedWaves, NotFinishedWaves and FinishedWaves
非開始波動の分析のための関数:
void NotStartedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
NotStartedWaves関数は、最初の波動グループの分析を行いますー非開始波動その関数は、サブ波動の形をとる、ParentWave.Nameと呼ばれる波動のNumwaveを分析します。その分析された波動NumWaveは、波動ツリーのノード、子ノードに保存されます。
NotStartedWaves関数が開始されると、以下の関数が呼ばれます:NotStartedWaves、FinishedWaves.
すべての波動は、図15の図式と同様に分析されます。
非停止波動の分析関数
void NotFinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
NotFinishedWaves関数は、2番目の波動グループを分析します - 非停止波動その関数は、サブ波動の形式をとるParentWave.Nameと呼ばれる波動のNumWave波動を分析します。その分析された波動NumWaveは、波動ツリーのノード、子ノードに保存されます。
NotFinishedWaves 関数が開始されると、以下の関数が呼ばれます: NotFinishedWaves and FinishedWaves.
すべての波動は、図15の図式と同様に分析されます。
終了済みの波動の分析関数
void FinishedWaves(TWave *ParentWave,int NumWave,TNode *Node,string Subwaves,int Level)
FinishedWaves関数は、4つ目のグループの波動を分析しますー終了済み波動。その関数は、サブ波動であるParentWave.Nameと呼ばれる波動のNumWave波動を分析します。その分析された波動NumWaveは、波動ツリーのノード、子ノードに保存されます。
FinishedWaves関数が稼働すると、関数FinishedWavesが呼ばれます。
すべての波動は、図15の図式と同様に分析されます。
5.8. FindWaveInWaveDescription
WaveDescriptionデータストラクチャーの波動探索用関数:
int FindWaveInWaveDescription(string NameWave)
FindWaveInWaveDescription関数は、NameWaveの名前により、パラメーターとして渡され、WaveDescriptionの配列内でそれを探索し、この波動に合致するインデックス数を返します。
WaveDescriptionストラクチャーの配列は、以下のようになります:
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," } } };
FindWaveInWaveDescription function関数は以下の波動の分析関数にて使用されます: NotStartedAndNotFinishedWaves, NotStartedWaves, NotFinishedWaves、FinishedWaves.
チャートの特定の部分がすでに分析されているかをチェックする関数:
bool Already(TWave *Wave,int NumWave,TNode *Node,string Subwaves)
エリオット波動の自動分析が列挙型メソッドにより起こるので、特定のチャートのセクションがすでに分析されて居る状況が発生します。これを知るために、そのリンクをすでに分析されて居る波動ツリーのノードに保存する必要があります。このすべてはAlready関数にて行われます。
Already関数は、グローバル配列NodeInfoArrayを探します。それは、TNodeInfoクラスのオブジェクト、NumWave波動に一致するチャートのインターバルを保持します。サブ波動の形であるものを列挙し、すでにマークアップされて居るノードのアドレスをNodeに記録します。もしこのセクションが存在しない場合、TNodeInfoの新しいオブジェクトは、作成・格納され、NodeInfoArray配列に記録されます。
この関数はもしチャートのインターバルがすでに分析されていればtrueを返し、さもなければFalseを返します。
NodeInfoArray配列は、以下の方法で宣言されます;
CArrayObj NodeInfoArray;
5.10. そのルールにおいて波動をチェックする関数
それは、VertexAAboveB, WaveAMoreWaveBやWaveRulesなどの関数を含み、その最初の二つの関数が呼ばれます。テストの際に、その波動は開始されず、非停止状態であり、例えば、その公式 "1<-2-3>"の波動において、まだ4つ目の波動がないため、4つ目の波動が最初の波動の領域を超えるか否かは決定されません。
ルールにおける波動のチェックを行う関数;
bool WaveRules(TWave *Wave)
WaveRules関数は、Wave,Nameという名前の波動が「正しい」のであれば、trueを、そうでなければfalseを返します。その作業においては、関数WaveRulesがVertexAAboveVertexB、WaveAMoreWaveB関数により呼ばれます。
そのほかの頂点からある頂点の超過をチェックする関数です。
int VertexAAboveVertexB(int A,int B,bool InternalPoints)
VertexAAboveVertexB 関数は、もし波動Aの頂点がBの頂点を越えていれば、0以上の数字を返し、そうでなければ、-1を返します。もしInternalPoints = trueであれば、波動の内部ポイント(波動の最大値と最小値)は考慮されます。
ある波動の長さの別の波動の長さの超過をチェックする関数
int WaveAMoreWaveB(int A,int B)
WaveAMoreWaveB関数は、もし波動Aが波動Bよりも大きければ、0以上の数字を返し、さもなければ-1を返します。
11. メモリ除去の関数
Nodeの波動ツリーの除去用関数:
void ClearTree(TNode *Node)
その関数は配列ClearNodeInfoArrayを除去します:
void ClearNodeInfoArray()
ZigzagArray配列の除去のための関数:
void ClearZigzagArray()
5.12. ツリー波動を迂回し、チャートに分析結果を発行する関数
エリオット波動の自動分析終了後、波動ツリーを持ちます。
その例は、以下の図に示されています:
図16. 波動ツリーの例
チャートの分析結果を表示するために、特定のツリーを迂回する必要があります。図16にて示されているように、(波動のオプションが幾つかあるので、)少数のオプションがあり、迂回のそれぞれのオプションは、異なるマークアップにつながります。
3つのノードにおいて二つの種類に区別することができます。
最初の種類 - 波動名("Impulse", "Zigzag" など)を持つノード. 2番目の種類 - 波動数("1", "1<", "etc.)を持つノードその波動のパラメーターについてのすべての情報は、ノードの最初の種類に保存されています。したがって、これらのノードを訪れる際、チャートに表示するためにその波動について情報を取得し、記録します。
単純さにおいて、波動の最初のバージョンを訪れ、そのツリーを迂回します。
迂回例は図17にて示され、赤色でハイライト表示されています。
図17. 波動ツリーの迂回例
波動ツリーの迂回関数:
void FillLabelArray(TNode *Node)
FillLabelArray関数は、Nodeルートを持つ波動ツリーを迂回し、ツリーの波動の最初のバージョンに到達し、グローバル配列LabeLArrayに格納し、そのインデックスは頂点の配列へのリンクを保存するgあ、チャートの特定のインデックスを持ちます。
LabelArray配列は、以下のように定義されます;
CArrayObj *LabelArray[];
分析結果をチャート上に表示する関数:
void CreateLabels()
CreateLabels関数は、グラフィカルオブジェクト「Text」を作成し、チャートの波動タグに一致します。その波動のタグは、LabelArray配列に基づき作成されます.
チャートの波動の頂点の関数
void CorrectLabel()
CorrectLabel 関数は、スクロールされた際にチャートの波動タグを訂正します。
6. エリオットはどうの自動パーティション分割の実装
//+------------------------------------------------------------------+ //| 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); }
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++; } }
//+------------------------------------------------------------------+ //| 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. 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; } }
//+------------------------------------------------------------------+ //| 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; } }
//+------------------------------------------------------------------+ //| 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; } }
//+------------------------------------------------------------------+ //| 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. 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); }
//+------------------------------------------------------------------+ //| 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); }
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); }
//+-------------------------------------------------------------------------------------+ //| 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); }
//+-----------------------------------------------------------------------+ //| 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); }
//+------------------------------------------------------------------+ //| 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; } }
//+------------------------------------------------------------------+ //| 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(); }
//+------------------------------------------------------------------+ //| 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(); }
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)); } }
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(); }
//+------------------------------------------------------------------+ //| 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. 初期化、非プロビジョニンング、イベント処理の関数
OnInit関数にて、その自動エリオット波動分析ツールんコントロールボタンは作成されます。
以下のボタンは作成されます:
- "Begin Analysis" - その波動の自動分析が発生されます。
- "Show results" - チャートの波動のマーク表示が行われます、
- "Clear chart" - チャートの波動マークの除去とメモリ削除が起こります。
- "Correct the marks" - チャートの波動マークを訂正します。
これらのボタンを押す処理は、OnChartEventイベント処理関数にて起こります。
OnDeinit関数にて、すべてのグラフィカルオブジェクトは、コントロールボタンを含めてチャートから除去されます。
#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(); } }
エリオット波動の自動分析機能の全てを紹介しました。
8. プログラムの改善方法
MQL5にて書かれたエリオット波動プログラムの自動マークアップは幾つかの欠点を持ちます:
- マークアップルールの不完全なチェックシステム例えば、ルールによりチェックする際、波動のフィボナチ関係は、時間と価格に沿って考慮されません。
- チャートのパーティション分割されていないセクションの存在(マークアップの隙間)これは、矯正波動が特定のインターバルにて取得されたポイントに基づき作成できないということです。この状況の打開策は、特定の波動を認識するためのポイント数を向上させることです。例えば、6ではなく8かそれ以上のポイントを探し、衝撃波を探すことです。
- そのマークアップの結果は、追加の情報を表示せず、例えば、チャネルは自動的に構築されず、ゴールは評価されません。
- その波動ツリーを扱う実装は、この記事では提供されていません。(そのマークアップの特定のバージョンを選択できません)したがって、そのチャートは、幾つかのオプションのうち一つのみを表示します。
- そのチャートは、その波動のうちのバリアント一つのみを表示するという事実にもかかわらず、その他のオプションはメモリに保存され、スペースを占めます。
- そのプログラムは、Monthly to Dailyチャートのマークアップに焦点を当て、その処理はたくさんのバーがあるととても遅くなります(一時間ごとのグラフをマークアップするのに何時間もかかります。)EURUSDの月ごとのチャートのマークアップ例は、図18に示されています。
図18. MQL5の自動分析ツールによって特定されるエリオット波動
結論
この記事は、エリオット波動の自動分析アルゴリズムを紹介しました。このアルゴリズムは、MQL5言語にて実装されました。
そのプログラムは、上記で述べられた通り、たくさんの欠点があります。この問題が、エリオット波動のファンの皆様の興味を引き、波動の自動分析を持つプログラムがたくさん現れることを期待しています。
MetaQuotes Ltdによってロシア語から翻訳されました。
元の記事: https://www.mql5.com/ru/articles/260





- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索