MQL5のエリオット波動の自動分析の実装

MRoVas | 28 10月, 2015


はじめに

市場分析の最も人気なメソッドの一つとして、エリオット波動法則があります。しかし、このプロセスは、かなり複雑であり、追加ツールを使用せざるをえません。その一つとして、自動マーカーがあります。

この記事は、MQL5言語でのエリオット波動の自動分析ツールの作成を紹介します。読者はすでにそのエリオット波動理論に親しみがあると想定し、そうでなければ、適切な情報源を参照する必要があります。


1. エリオット波動理論

エリオット波動 - は、 Ralph Nelson Elliottにより提唱された市場行動の理論モデルであり、それによると、市場での価格の動きの全ては、人間心理の影響を受け、衝撃波の変化の周期的プロセスです。

その衝撃波は、5つの価格変動、矯正波動 - 一連の3つから5つの価格変動です。それらに適用されるルールや形式での衝撃波は、以下の種類です:

1. 衝撃:
図1. 衝撃
図1. 衝撃
  • 2番目の波動の最後は、初めの波動の最初の地点ではきません。
  • 3番目の波動は、常に最初の波動の先端を超えます。
  • 4つ目の波動の終点は、最初の波動の頂点は超えません。
  • 3つ目の波動は、すべての波動の中での最短とはなりません。
  • 3つ目の波動は、常に衝撃波動です;
  • 最初の波動は、衝撃波動か、対角線になります;
  • 5つ目の波動は、衝撃波動か、対角線になります;
  • 2番目の波動は、三角以外の矯正波動の形をとります。
  • 5つ目の波動は、矯正波動の形式を則ります。
2. メインの対角線:
図2. メインの対角線
図2. メインの対角線
  • 2番目の波動の最後は、初めの波動の最初の地点ではきません。
  • 3番目の波動は、常に最初の波動の先端を超えます。
  • 4つ目の終点は、常に1つ目の波動の頂点を越えますが、最初の波動の始点は過ぎることはありません。
  • 3つ目の波動は、すべての波動の中での最短とはなりません。
  • 3つ目の波動は、常に衝撃波動です;
  • 最初の波動は、衝撃波動か、対角線になります;
  • 5つ目の波動は、衝撃波動か、対角線になります;
  • 2番目の波動は、三角以外の矯正波動の形をとります。
  • 5つ目の波動は、矯正波動の形式を則ります。
3. 対角線:
図3. 対角線
図3. 対角線
  • 2番目の波動の最後は、初めの波動の最初の地点ではきません。
  • 3番目の波動は、常に最初の波動の先端を超えます。
  • 4つ目の終点は、普段最初の波動の頂点に来ますが、3つ目の波動よりも上にはいきません。
  • 3つ目の波動は、すべての波動の中での最短とはなりません。
  • 1番目、2番目、3番目の波動は三角以外の矯正波動の形になります。
  • 4つ目と5つ目の波動は、矯正波動の形式をとります。
矯正波動は、以下に分類されます;
4. ジグザグ:
図4. ジグザグ
図4. ジグザグ
  • 波動Aは、衝撃波動か、メイン対角線の形をとります。
  • 波動Cは、衝撃波動か、対角線の形をとります。
  • 波動Bは矯正波動の形式となります。
  • 波動Cは、波動Aの頂点を越えて広がります。
  • 波動Bの終点は、波動Aの開始地点を超えることはありません。
5. フラット:
図5. フラット
図5. フラット
  • 波動Аは、三角以外の矯正波動の形式となります。
  • 波動Bは矯正波動の形式となります。
  • 波動Cは、衝撃波動か、対角線の形をとります。
6. 二重ジグザグ:
図6. 二重ジグザグ
図6. 二重ジグザグ
  • 波動Wと波動Yは、ジグザグになります;
  • 波動Xは、矯正波動の形になります;
  • 波動Yは、波動Wの頂点を超えます;
  • 波動Xの終点は、波動Wの始点は超えません;
7. 三重ジグザグ:
図7. 三重ジグザグ
図7. 三重ジグザグ
  • 波動W、波動Y、波動Zは、ジグザグになります。
  • 波動Xは、矯正波動となります。
  • 波動XXは、矯正波動となります。
  • 波動Yは、波動Wの頂点を超えます;
  • 波動Zは、波動Yの頂点を超えます。
  • 波動Xの終点は、波動Wの始点は超えません;
  • 波動XXは、波動Yの始点を超えません。
8. ダブルスリー:
図8. ダブルスリー
図8. ダブルスリー
  • 波動Wは、三角以外の矯正波動の形になります。
  • 波動Xと波動Yも矯正波動になります。
9. トリプルスリー:
図9. トリプルスリー
図9. トリプルスリー
  • 波動W、波動X、波動Yは、三角以外の矯正波動の形になります。
  • 波動XX、波動Zは、矯正波動の形なります。
10. 締約三角形:
図10. 締約三角形
図10. 締約三角形
  • 波動Cは、波動Bの価格制限を超えません。
  • 波動Dは、Cの価格制限値を超えません。
  • 波動Eは、波動Dの価格制限を超えません。
  • 波動A、B、Cは、矯正波動になります。
  • DとEは矯正波動になるかもしれません。
11. 拡大三角形:
図11. 拡大三角形
図11. 拡大三角形
  • 波動Cは、常に波動Bより長さで勝ります。
  • 波動Dは常に波動Cよりも長さで勝ります。
  • 波動A、波動B、波動Cは三角形を除き矯正波動の形になります。
  • 波動D、波動エは、矯正波動となります。

その波動モデルやルールは、波動分析の古典的な観念に飲み適応します。

Forex市場の研究にて形成された現代版のコンセプトもあります。例えば、直角を持たない三角形の新しいモデルが見つかり、2番目の波動の衝撃波が特定されます。

図1-11で分かるとおり、それぞれの衝撃波、矯正波動は、(ダッシュ線で示されている通り)同じ衝撃、矯正波動から成り立ちますが、程度は小さめです。これは、いわゆるエリオット波動のフラクタルです:大きい波動は小さい波動から成り立っています。

この記述にて、エリオット波動の原則についての簡単な導入を終了し、波動の自動マークアップのトピックへ移ります。


2. エリオット波動の自動マークアップのアルゴリズム

すでに気づかれたかと思いますが、エリオット波動は、複雑で多面的なプロセスです。したがって、人々は、簡単にするような手段を探し、適用し始めました。

そのようなツールの一つが、エリオット波動の自動マークアップのためのメカニズムです。

自動マークアップについて二つの原則を区別することができます:

  1. 波動のフラクタルによれば、その分析は上から下に実行され、大きい波動から小さい波動にかけて行われます;
  2. その分析は、すべての可能なオプションの直接列挙によって実行されます。

エリオット波動の自動分析の図式は図12にて示されています。

図12. エリオット波動の自動分析の図式
図12. エリオット波動の自動分析の図式

衝撃波の自動マークアップの例をもとに、詳しくそのアルゴリズムを見ていきましょう(図13をご覧ください。)

その最初のステージでの価格チャートの必要な時間のインターバルにて、「ジグザグ」を用いてマークアップの作成に必要なポイントの量がハイライトで表示されています。ポイントの数は、どの種類の波動を分析したいかに依存します。衝撃波の分析において、必要な6つのポイント - 5頂点と一つの開始点があります。もしジグザグを分析しているなら、必要なポイント数は、4つ - 3つの頂点と、一つの開始点です。

もしその「ジグザグ」が価格チャートにて6つの点を特定すると、即座に衝撃波のマークアップを生成することができます:最初のポイント-最初の波動の開始点、2番目のポイント-最初の波動の頂点、3番目のポイント-2番目の波動の頂点、4番目の波動-さんばんめの波動の頂点、5番目のポイント-4番目の波動の頂点、6番目のポイント-5番目の波動の頂点

しかし、図13では、その「ジグザグ」は8つの点を特定しました。この場合、これらの点によってすべての可能なオプションや波動のマークアップを列挙する必要があります。そして、(異なる色でマークされた)5つがあります。マークアップの各バージョンは、ルールによってチェックされる必要があります。

マークアップオプション
図13. 衝撃波のマークアップの作成におけるオプション

ルールをチェックしたのち、その波動のマークアップが、すべてのパラメーターによる衝撃波である場合、すべての副波動は、同じ方法で分析されます。

同じことが、その他衝撃波と強制波動の分析が適用されます。

 

3. 自動マークアップにおける波動の種類

以前述べられた通り、その分析は、上から下までプログラムに特定の期間での波動を見つけるよう指示を与えることで、行われます。しかし、最も長いインターバルで、波動の状態や始まりや終わりを決定することは不可能です。そのような波動を非開始非停止と呼びます。

すべての波動は、以下のグループに分類されます。

  1. 非開始波動:
    1. 非開始状態の最初の波動を持つ波動 - 1-2-3-4-5 (例えば、非開始波動1の衝撃波、必要なポイント数 - 5)、1-2-3 (例えば、非開始波動Aのジグザグ;必要なポイント数 - 3);
    2. 非開始状態の2番目の波動を持つ波動 - 2-3-4-5 (例えば、非開始波動2の対角線、必要なポイント数 2、必要なポイント数 - 4)、 2-3 (例えば、非開始波動Aのフラット;必要なポイント数 -2);
    3. 非開始状態の3番目の波動を持つ波動 - 3-4-5 (例えば、非開始波動Yのトリプルジグザグ、必要なポイント数 - 3);
    4. 非開始状態の4番目の波動を持つ波動 - 4-5 (例えば、非開始波動Dの三角形、必要なポイント数 - 2); -2);
    5. 5番目の非開始状態の波動を持つ波動 - 5 (例えば、非開始波動5の衝撃波、必要なポイント数 - 1); );
    6. 3番目の非開始状態の波動を持つ波動 - 3 (例えば、非開始状態の波動Zのダブルスリー;必要なポイント数 - 1);
  2. 非停止波動:
    1. 5番目の非停止波動を持つ波動 - 1-2-3-4-5 (例えば、非停止波動5を持つ衝撃波;必要なポイント数 - 5);
    2. 4番目の非停止波動を持つ波動 - 1-2-3-4> (例えば、非停止波動XXを持つ衝撃波;必要なポイント数 - 5);
    3. 3番目の非停止波動を持つ波動 - 1-2-3> (例えば、非停止波動3のメイン対角線;必要なポイント数 - 3);
    4. 2番目の非停止波動を持つ波動 - 1-2> (例えば、非停止波動Bを持つジグザグ;必要なポイント数 - 2);
    5. 最初の非停止波動を持つ波動 - 1> (例えば、非停止波動Aを持つフラット;必要なポイント数 - 1);
  3. 非開始・非停止波動:
    1. 最初の非開始波動と2番目の非停止波動を持つ波動 -1-2>(例えば、1番目の非開始波動Aと非停止波動Bを持つジグザグ;必要なポイント数 - 1);
    2. 2番目の非開始波動と3番目の非停止波動を持つ波動 - 2-3>(例えば、1番目の非開始波動Bと非停止波動Cを持つジグザグ;必要なポイント数 - 1);
    3. 3番目の非開始波動と4番目の非停止波動を持つ波動 - 3-4>< (例えば、3番目の非開始波動と非停止波動4を持つ衝撃波;必要なポイント数 - 1);
    4. 4番目の非開始波動と5番目の非停止波動を持つ波動 - 4-5> (例えば、4番目の非開始波動と非停止波動5を持つ衝撃波;必要なポイント数 -1);
    5. 最初の非開始波動と3番目の非停止波動を持つ波動 - 1-2-3>(例えば、非開始波動Wと非停止波動Yを持つトリプルスリー;必要なポイント数 -2);
    6. 2番目の非開始波動と4番目の非停止波動を持つ波動 -2-3-4>(例えば、非開始波動2と非停止波動4を持つメイン対角線;必要なポイント数 -2);
    7. 3番目の非開始波動と5番目の非停止波動を持つ波動 - 3-4-5>(例えば、非開始波動3と非停止波動5を持つ対角線;必要なポイント数 -2);
    8. 最初の非開始波動と4番目の非停止波動を持つ波動 -1-2-3-4>(例えば、非開始波動Wと非停止波動XXを持つトリプルスリー;必要なポイント数 -3);
    9. 2番目の非開始波動と5番目の非停止波動を持つ波動 - 2-3-4-5 (例えば、非開始波動2と非停止波動5を持つ衝撃波;必要なポイント数 -3);
    10. 最初の非開始波動と5番目の非停止波動を持つ波動 -1-2-3-4-5>(例えば、非開始波動Wと非停止波動Zを持つトリプルジグザグ;必要なポイント数 -4);
  4. 終了済み波動 - 1-2-3-4-5 (必要なポイント数 - 6) と1-2-3 (必要なポイント数 - 4).

波動数の後のその "<"という記号は、開始していないということを示しています。波動数の後のその ">"という記号は、終了していないということを示しています。

図14では、以下の波動を見ることができます:

  1. 最初の非開始波動を持つ波動 A -A -B-C;
  2. 非停止 Wの波動と2番目の非停止X 波動 -W<-X>;
  3. 終了済み波動 BC;

非開始・非停止波動 
図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. エリオット波動の自動分析ツールの機能の詳細

エリオット波動の自動分析ツールを記述するために、以下の機能が必要です:

5.1. ジグザグ

”ジグザグ”の極値の検索機能;

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

エリオット波動の自動分析ツールの重要な要素は”ジグザグ”であり、それによって波動が作成されます。パラメーターによる「ジグザグ」の計算は、すぐに行われます。

その分析ツールでは、"How to Write Fast Non-Redrawing ZigZags"という記事から取得した「ジグザグ」を使用します。

そのジグザグ関数は、StarttからFinishの間のインターバルでのパラメーターHを持つジグザグを計算し、頂点のインデックスと頂点の値をそれぞれIndexVertexとValueVertexに記録します。それらのアドレスはこの関数の中に渡されます。

そのジグザグ関数は、その「ジグザグ」の頂点の数を返します。 

5.2. FillZigZagArray

「ジグザグ」に格納する関数と、そのパラメーターの保存: 

void FillZigzagArray(int Start,int Finish)

以前示された通り、波動のマークアップのための価格チャートにおける必要なポイント数を発見する必要があります。そして、異なるパラメーターを持つ”ジグザグ”の頂点を持つ配列を保持する必要があり、これらのポイントを見つけるようループを行います。 

FillZigzagArray関数は、StartからFinishまでのチャートの期間でのすべての可能なパラメーターHの値で”ジグザグ”を計算します。(”ジグザグ”の頂点の数が2以下になるまで)そして、TZigzagのクラスオブジェクトで見つかった頂点についての情報を保持し、これらのオブジェクトをグローバル配列ZigzagArrayに記録し、それは以下のように宣言されます:

CArrayObj *ZigzagArray;

5.3. FindPoints

特定の期間での検索関数は、価格チャートのポイント数を必要とします: 

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

5.5. NotStartedWaves

非開始波動の分析のための関数: 

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

NotStartedWaves関数は、最初の波動グループの分析を行いますー非開始波動その関数は、サブ波動の形をとる、ParentWave.Nameと呼ばれる波動のNumwaveを分析します。その分析された波動NumWaveは、波動ツリーのノード、子ノードに保存されます。

NotStartedWaves関数が開始されると、以下の関数が呼ばれます:NotStartedWaves、FinishedWaves.

すべての波動は、図15の図式と同様に分析されます。 

5.6. NotFinishedWaves

非停止波動の分析関数 

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

NotFinishedWaves関数は、2番目の波動グループを分析します - 非停止波動その関数は、サブ波動の形式をとるParentWave.Nameと呼ばれる波動のNumWave波動を分析します。その分析された波動NumWaveは、波動ツリーのノード、子ノードに保存されます。

NotFinishedWaves 関数が開始されると、以下の関数が呼ばれます: NotFinishedWaves and FinishedWaves.   

すべての波動は、図15の図式と同様に分析されます。

5.7. FinishedWaves

終了済みの波動の分析関数 

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. 

5.9. Already

チャートの特定の部分がすでに分析されているかをチェックする関数: 

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つ目の波動が最初の波動の領域を超えるか否かは決定されません。

5.10.1. WaveRules

ルールにおける波動のチェックを行う関数;

bool WaveRules(TWave *Wave)

WaveRules関数は、Wave,Nameという名前の波動が「正しい」のであれば、trueを、そうでなければfalseを返します。その作業においては、関数WaveRulesがVertexAAboveVertexB、WaveAMoreWaveB関数により呼ばれます。

5.10.2. VertexAAboveVertexB

そのほかの頂点からある頂点の超過をチェックする関数です。 

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

VertexAAboveVertexB 関数は、もし波動Aの頂点がBの頂点を越えていれば、0以上の数字を返し、そうでなければ、-1を返します。もしInternalPoints = trueであれば、波動の内部ポイント(波動の最大値と最小値)は考慮されます。

5.10.3. WaveAMoreWaveB

ある波動の長さの別の波動の長さの超過をチェックする関数

int WaveAMoreWaveB(int A,int B)

WaveAMoreWaveB関数は、もし波動Aが波動Bよりも大きければ、0以上の数字を返し、さもなければ-1を返します。

11. メモリ除去の関数

5.11.1. ClearTree

Nodeの波動ツリーの除去用関数: 

void ClearTree(TNode *Node)

5.11.2. ClearNodeInfoArray

その関数は配列ClearNodeInfoArrayを除去します: 

void ClearNodeInfoArray()

5.11.3. ClearZigzagArray

ZigzagArray配列の除去のための関数:

void ClearZigzagArray()

5.12. ツリー波動を迂回し、チャートに分析結果を発行する関数

エリオット波動の自動分析終了後、波動ツリーを持ちます。

その例は、以下の図に示されています:

 図16. 波動ツリーの例
図16. 波動ツリーの例

チャートの分析結果を表示するために、特定のツリーを迂回する必要があります。図16にて示されているように、(波動のオプションが幾つかあるので、)少数のオプションがあり、迂回のそれぞれのオプションは、異なるマークアップにつながります。

3つのノードにおいて二つの種類に区別することができます。

最初の種類 - 波動名("Impulse", "Zigzag" など)を持つノード. 2番目の種類 - 波動数("1", "1<", "etc.)を持つノードその波動のパラメーターについてのすべての情報は、ノードの最初の種類に保存されています。したがって、これらのノードを訪れる際、チャートに表示するためにその波動について情報を取得し、記録します。

単純さにおいて、波動の最初のバージョンを訪れ、そのツリーを迂回します。

迂回例は図17にて示され、赤色でハイライト表示されています。

図17. 波動ツリーの迂回例
図17. 波動ツリーの迂回例

5.12.1. FillLabelArray

波動ツリーの迂回関数:

void FillLabelArray(TNode *Node)

FillLabelArray関数は、Nodeルートを持つ波動ツリーを迂回し、ツリーの波動の最初のバージョンに到達し、グローバル配列LabeLArrayに格納し、そのインデックスは頂点の配列へのリンクを保存するgあ、チャートの特定のインデックスを持ちます。

LabelArray配列は、以下のように定義されます; 

CArrayObj *LabelArray[];

5.12.2. CreateLabels

分析結果をチャート上に表示する関数: 

void CreateLabels()

CreateLabels関数は、グラフィカルオブジェクト「Text」を作成し、チャートの波動タグに一致します。その波動のタグは、LabelArray配列に基づき作成されます.

5.12.3. CorrectLabel

チャートの波動の頂点の関数 

void CorrectLabel()

CorrectLabel 関数は、スクロールされた際にチャートの波動タグを訂正します。

 

6. エリオットはどうの自動パーティション分割の実装 

6.1. ジグザグ関数:

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

6.2. FillZigzagArray 関数:

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

6.3. FindPoints 関数:

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

6.4. NotStartedAndNotFinishedWaves 関数:

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

6.5. NotStartedWaves 関数:

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

6.6. NotFinishedWaves 関数:

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

6.7. FinishedWaves 関数:

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

6.8. FindWaveInWaveDescription 関数:

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

6.9. Already 関数:

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

6.10. WaveRules 関数:

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

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

6.11. VertexAAboveVertexB 関数:

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

6.12. WaveAMoreWaveB 関数:

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

6.13. ClearTree 関数:

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

6.14. ClearNodeInfoArray 関数:

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

6.15. ClearZigzagArray 関数:

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

6.16. FillLabelArray 関数:

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

6.17. CreateLabels 関数:

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

6.18. CorrectLabel 関数:

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


7. 初期化、非プロビジョニンング、イベント処理の関数

OnInit関数にて、その自動エリオット波動分析ツールんコントロールボタンは作成されます。

以下のボタンは作成されます:

  1. "Begin Analysis" - その波動の自動分析が発生されます。
  2. "Show results" - チャートの波動のマーク表示が行われます、
  3. "Clear chart" - チャートの波動マークの除去とメモリ削除が起こります。
  4. "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にて書かれたエリオット波動プログラムの自動マークアップは幾つかの欠点を持ちます:

  1. マークアップルールの不完全なチェックシステム例えば、ルールによりチェックする際、波動のフィボナチ関係は、時間と価格に沿って考慮されません。
  2. チャートのパーティション分割されていないセクションの存在(マークアップの隙間)これは、矯正波動が特定のインターバルにて取得されたポイントに基づき作成できないということです。この状況の打開策は、特定の波動を認識するためのポイント数を向上させることです。例えば、6ではなく8かそれ以上のポイントを探し、衝撃波を探すことです。
  3. そのマークアップの結果は、追加の情報を表示せず、例えば、チャネルは自動的に構築されず、ゴールは評価されません。
  4. その波動ツリーを扱う実装は、この記事では提供されていません。(そのマークアップの特定のバージョンを選択できません)したがって、そのチャートは、幾つかのオプションのうち一つのみを表示します。
  5. そのチャートは、その波動のうちのバリアント一つのみを表示するという事実にもかかわらず、その他のオプションはメモリに保存され、スペースを占めます。
  6. そのプログラムは、Monthly to Dailyチャートのマークアップに焦点を当て、その処理はたくさんのバーがあるととても遅くなります(一時間ごとのグラフをマークアップするのに何時間もかかります。)EURUSDの月ごとのチャートのマークアップ例は、図18に示されています。

図18. MQL5の自動分析ツールによって特定されるエリオット波動
図18. MQL5の自動分析ツールによって特定されるエリオット波動

結論

この記事は、エリオット波動の自動分析アルゴリズムを紹介しました。このアルゴリズムは、MQL5言語にて実装されました。

そのプログラムは、上記で述べられた通り、たくさんの欠点があります。この問題が、エリオット波動のファンの皆様の興味を引き、波動の自動分析を持つプログラムがたくさん現れることを期待しています。