English Русский 中文 Español Deutsch 日本語 Português Français Italiano Türkçe
MQL5에서의 엘리엇 파동(Elliot Waves) 자동 분석 도입

MQL5에서의 엘리엇 파동(Elliot Waves) 자동 분석 도입

MetaTrader 5 | 11 10월 2021, 15:07
727 0
MRoVas
[삭제]


들어가며

시장 분석에서 가장 인기 좋은 방법 중 하나는 엘리엇 파동(Elliot Wave) 이론입니다. 하지만 이 과정은 꽤나 복잡하기때문에 다른 툴을 사용해야합니다. 그런 툴 중 하나는 자동 마커입니다.

본 문서에서는 MQL5 로 엘리엇 파동 자동 분석기를 만드는 법에 대해서 다뤄보겠습니다.. 이 문서에서는 독자들이 파동 이론에 이미 익숙하다고 가정하고 시작할 것입니다. 만약 그렇지 않은 경우 적절한 소스를 참조하십시오.


1. 엘리엇 파동 이론

엘리엇의 파동 - 랄프 넬슨 엘리엇이 개발한 시장 행동의 이론적 모델로서, 이 모델에 따르면 시장에서의 모든 가격 움직임은 심리학으로 설명할 수 있으며, 충동 파동의 순환적 변화 과정이며, 그 반대의 경우도 마찬가지입니다.

충격파는 5번의 가격 변동의 시퀀스이며, 교정파는 3번 혹은 5번의 가격 변동 시퀀스입니다. 형태, 구조 및 적용 가능한 규칙의 충격파는 다음과 같은 유형입니다.

1. 충격들
1번 그림. 충격
1번 그림. 충격
  • 두번째 파동의 끝은 첫번째 파동 시작 전에 오지 않습니다.
  • 세번째 파동은 언제나 첫번째 파동 너머까지 이어집니다.
  • 네번째 파동의 끝은 첫번째 파동 시작 전에 오지 않습니다.
  • 세번째 파동은 모든 활동파 중에서 가장 짧지않습니다.
  • 세번째 파동은 언제나 충격파입니다.
  • 첫번째 파동은 충격파이거나 선행 대각선입니다.
  • 다섯번째 파동은 충격선이거나 대각선입니다.
  • 두번째 파동은 삼각형을 제외한 어떠한 교정파의 형태건 취할 수 있습니다.
  • 네번째 파동은 어떠한 교정파의 형태건 취할 수 있습니다.
2. 선행 대각선들
2번 그림. 선행 대각선
2번 그림. 선행 대각선
  • 두번째 파동의 끝은 첫번째 파동 시작 전에 오지 않습니다.
  • 세번째 파동은 언제나 첫번째 파동 너머까지 이어집니다.
  • 네번째 파동의 끝은 항상 첫번째 파동의 꼭대기를 넘지만, 세번째 파동의 시작 부분을 넘지는 않습니다.
  • 세번째 파동은 모든 활동파 중에서 가장 짧지않습니다.
  • 세번째 파동은 언제나 충격파입니다.
  • 첫번째 파동은 충격파이거나 선행 대각선입니다.
  • 다섯번째 파동은 충격선이거나 대각선입니다.
  • 두번째 파동은 삼각형을 제외한 어떠한 교정파의 형태건 취할 수 있습니다.
  • 네번째 파동은 어떠한 교정파의 형태건 취할 수 있습니다.
3. 대각선
3번 그림. 대각선
3번 그림. 대각선
  • 두번째 파동의 끝은 첫번째 파동 시작 전에 오지 않습니다.
  • 세번째 파동은 언제나 첫번째 파동 너머까지 이어집니다.
  • 네번째 파동의 끝은 보통 첫번째 파동의 꼭대기를 넘어오지만, 세번째 파동의 꼭대기는 절대 넘지 않습니다.
  • 세번째 파동은 모든 활동파 중에서 가장 짧지않습니다.
  • 첫번째 두번째 세번째 파동은 삼각형을 제외한 어떠한 교정파의 형태건 취할 수 있습니다.
  • 네번째와 다섯번째 파동은 어떠한 교정파 형태건 취할 수 있습니다.
교정파는 다음과같이 나뉩니다.
4. 지그재그들
4번 그림. 지그재그
4번 그림. 지그재그
  • A 파동은 충격파나 선행 대각선 형태를 취합니다.
  • C 파동은 충격파나 대각선 형태를 취합니다.
  • B 파동은 어떠한 교정파의 형태건 취할 수 있습니다.
  • C 파동은 A 파동의 꼭지점 위로 지나갑니다.
  • B 파동의 끝은 A 파동 시작보다 먼저 끝납니다.
5. 수평들
5번 그림. 수평
5번 그림. 수평
  • A 파동은 삼각형을 제외한 어떠한 교정파 형태건 취할 수 있습니다.
  • B 파동은 어떠한 교정파의 형태건 취할 수 있습니다.
  • C 파동은 충격파나 대각선 형태를 취합니다.
6. 이중 지그재그들
6번 그림. 이중 지그재그
6번 그림. 이중 지그재그
  • X 파동과 Y 파동은 지그재그 형태입니다.
  • X 파동은 어떠한 교정파의 형태건 취할 수 있습니다.
  • Y 파동은 W 파동의 꼭지점 위로 넘어갑니다.
  • X 파동의 끝은 W 파동의 시작 전에 끝납니다.
7. 삼중 지그재그들
7번 그림. 삼중 지그재그
7번 그림. 삼중 지그재그
  • W 파동, Y 파동, Z 파동은 지그재그의 형태를 취합니다.
  • X 파동은 삼각형을 제외한 어떠한 교정파 형태를 취할 수 있습니다.
  • XX 파동은 어떠한 교정파의 형태건 취할 수 있습니다.
  • Y 파동은 W 파동의 꼭지점 위로 넘어갑니다.
  • Z 파동은 Y 파동의 위로 지나갑니다.
  • X 파동의 끝은 W 파동의 시작 전에 끝납니다.
  • XX 파동의 끝은 Y 파동의 시작 전에 끝납니다.
8. 3x2(Double Three)들
8번 그림. 3x2
8번 그림. 3x2
  • W 파동은 삼각형을 제외한 어떠한 교정파 형태건 취할 수 있습니다.
  • X 파동과 Y 파동은 어떠한 교정파의 형태건 취할 수 있습니다.
9. 3x3(Triple Threes)
9번 그림. 3x3
9번 그림. 3x3
  • 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 파동, E 파동은 어떠한 교정파의 형태건 취할 수 있습니다.

위에서 설명한 파동 모델과 규칙은 파동 분석의 고전적 개념에만 해당합니다.

외환 시장을 연구하면서 형성된 현대적인 개념도 있습니다. 예를 들어, 경사(슬라이딩) 삼각형의 새로운 모델이 발견되었고, 두 번째 파동에서 삼각형이 있는 충격파가 식별되는 등이 있습니다

그림 1-11에서 볼 수 있듯이, 각 충격파 또는 교정파는 동일한 충격파 및 교정파(파선으로 표시됨)로 구성되지만 정도가 낮습니다. 엘리엇의 파동의 이른바 프랙탈(둥지)인데, 큰 도수의 파동은 작은 도수의 파동으로 구성되며, 그 도수가 훨씬 적은 파동으로 구성됩니다.

이에 엘리엇 파동 이론에 대한 간략한 소개를 마치고 파도의 자동 표시 주제에 대해 알아보겠습니다.


2. 엘리엇 파동 자동 강조 알고리즘

이미 알고 있겠지만 엘리엇 파동 분석은 복잡하고 다면적인 프로세스입니다. 그래서 처음부터 사람들은 난이도를 낮출 도구를 찾아 헤멨습니다.

그 중 하나는 엘리엇 파동의 자동 강조 메카니즘입니다.

자동 강조에는 두가지 기본 이론이 있습니다.

  1. 파동의 프랙탈성에 따르면 분석은 언제나 위에서 아래로 이루어지며, 큰 파동에서 작은 파동 순으로 이루어집니다.
  2. 모든 가능한 선택지를 검토하는 식으로 분석이 이루어집니다..

엘리엇 파동의 자동 분석 블록 다이어그램을 12번 그림에서 보실 수 있습니다.

12번 그림. 엘리엇 파동의 자동 분석 블록 다이어그램
12번 그림. 엘리엇 파동의 자동 분석 블록 다이어그램

충격파의 자동 표시의 예에 기초하여 알고리즘을 좀 더 자세히 고려합니다(13번 그림 참조).

첫 번째 단계에서는 가격 차트의 필요한 시간 간격에 "지그재그"를 사용하여 강조를 하는 데 필요한 포인트 양을 강조합니다. 어떤 종류의 파동을 분석하느냐에 따라 포인트 수가 달라집니다. 따라서 충격파 분석에는 꼭짓점 5개와 시작점 1개 등 6개의 점이 필요합니다. 만약 우리가 지그재그를 분석한다면, 필요한 점의 수는 4 - 3개의 꼭짓점과 1개의 시작점이었을 것입니다.

만약 "지그재그"가 가격 차트에서 6개의 포인트를 식별했다면, 충격파 마크를 바로 생성할 수 있습니다. 첫 포인트 - 첫 파동의 시작점, 두번째 포인트 - 첫 파동의 꼭짓점, 세번째 포인트 - 두번째 파동의 꼭짓점, 네번째 포인트 - 세번째 파동의 꼭짓점, 다섯번째 포인트 - 네번째 파동의 꼭짓점, 여섯번째 포인트 - 다섯번째 포인트의 꼭짓점.

하지만 13번 그림에서 보듯이 "지그재그"에 8개 포인트가 식별되었습니다. 이 경우에서는 파동에서 모든 가능한 선택지와 강조내용을 포인트로 삼아 셀 필요가 있습니다. 총 다섯개 입니다 (각기 다른 색으로 강조된). 각 강조내용은 규칙에 따라 점검해보아야합니다.

강조 옵션
13번 그림. 충격파 강조 마킹 옵션

규칙에 대해 확인한 후 모든 파라미터에 의해 파형의 표시가 충격파일 경우 모든하위 파동이 동일한 방식으로 분석됩니다.

다른 모든 충격파 및 교정파의 분석에도 동일하게 적용됩니다.

 

3. 자동 강조용 파동의 타입

앞서 언급한 것처럼 프로그램은 주어진 간격에 따라 일부 파동을 찾도록 위에서 아래로 분석을 수행합니다. 그러나 가장 큰 간격에서는 파동의 상태, 시작 및 끝을 확인할 수 없습니다. 우리는 그런 파동을 시작하지않은 파동(unbegun)끝나지않은 파동(unfinished)이라고 부릅니다.

모든 파동은 아래의 카테고리로 분류할 수 있습니다.

  1. 시작하지 않은 파동
    1. 시작하지않은 파동이 첫 파동인 파동들 1-2-3-4-5 (예를 들어 시작하지않은 파동 1이 있는 충격파인 경우 필요한 포인트의 수는 5), 그리고 1-2-3 (예를 들어 시작하지않은 파동 A가 있는 지그재그는 필요한 포인트의 수가 3);
    2. 시작하지않은 파동이 두번째 파동인 파동들 2-3-4-5 (예를 들어 시작하지않은 파동 2이 있는 대각선인 경우 필요한 포인트의 수는 4), 그리고 2-3 (예를 들어 시작하지않은 파동 B이 있는 수평인 경우 필요한 포인트의 수는 2);
    3. 시작하지않은 파동이 세번째 파동인 파동들 - 3-4-5 (예를 들어 시작하지않은 파동 Y이 있는 삼중 지그재그인 경우 필요한 포인트의 수는 3);
    4. 시작하지않은 파동이 네번째 파동인 파동들 - 4-5 (예를 들어 시작하지않은 파동 D가 있는 삼각형인 경우 필요한 포인트의 수는 2);
    5. 시작하지않은 파동이 다섯번째 파동인 파동들 - 5 (예를 들어 시작하지않은 파동 5가 있는 충격파인 경우 필요한 포인트의 수는 1);
    6. 시작하지않은 파동이 세번째 파동인 파동들 - 3 (예를 들어 시작하지않은 파동 Z가 있는 2x3인 경우 필요한 포인트의 수는 1);
  2. 끝나지않은 파동
    1. 끝나지않은 파동이 다섯번째 파동인 파동들 - 1-2-3-4-5 (예를 들어 끝나지않은 파동 5이 있는 충격파인 경우 필요한 포인트의 수는 5);
    2. 끝나지않은 파동아 네번째 파동인 파동들 - 1-2-3-4> (예를 들어 끝나지않은 파동 XX이 있는 삼중 지그재그인 경우 필요한 포인트의 수는 4);
    3. 끝나지않은 파동이 세번째 파동인 파동들 - 1-2-3> (예를 들어 끝나지않은 파동 3이 있는 선행 대각선인 경우 필요한 포인트의 수는 3);
    4. 끝나지않은 파동이 두번째 파동인 파동들 - 1-2> (예를 들어 끝나지않은 파동 B가 있는 지그재그인 경우 필요한 포인트의 수는 2);
    5. 끝나지않은 파동이 첫번째 파동인 파동들 - 1> (예를 들어 끝나지않은 파동 A가 있는 수평인 경우 필요한 포인트의 수는 1);
  3. 시작하지않은 파동과 끝나지않은 파동들
    1. 시작되지않은 첫번째 파동과 끝나지않은 두번째 파동이 있는 파동 -1-2>(예를들어 시작되지않은 파동 A와 끝나지않은 파동 B가 있는 지그재그인 경우 필요한 포인트의 수는 1);
    2. 시작되지않은 두번째 파동과 끝나지않은 세번째 파동이 있는 파동 - 2-3>(예를들어 시작되지않은 파동 B와 끝나지않은 파동 C가 있는 지그재그인 경우 필요한 포인트의 수는 1);
    3. 시작되지않은 세번째 파동과 끝나지않은 네번째 파동이 있는 파동 - 3-4>< (예를들어 시작되지않은 파동 3와 끝나지않은 파동 4가 있는 충격파의 경우 필요한 포인트의 수는 1);
    4. 시작되지않은 네번째 파동과 끝나지않은 다섯번째 파동이 있는 파동 - 4-5> (예를들어 시작되지않은 파동 4와 끝나지않은 파동 5가 있는 충격파인 경우 필요한 포인트의 수는 1);
    5. 시작되지않은 첫번째 파동과 끝나지않은 세번째 파동이 있는 파동 - 1-2-3>(예를들어 시작되지않은 파동 W와 끝나지않은 파동 Y가 있는 3x3인 경우 필요한 포인트의 수는 2);
    6. 시작되지않은 두번째 파동과 끝나지않은 네번째 파동이 있는 파동 -2-3-4>(예를들어 시작되지않은 파동 2와 끝나지않은 파동 4가 있는 선행 대각선인 경우 필요한 포인트의 수는 2);
    7. 시작되지않은 세번째 파동과 끝나지않은 다섯번째 파동이 있는 파동 - 3-4-5>(예를들어 시작되지않은 파동 3와 끝나지않은 파동 5가 있는 대각선인 경우 필요한 포인트의 수는 2);
    8. 시작되지않은 첫번째 파동과 끝나지않은 네번째 파동이 있는 파동 -1-2-3-4>(예를들어 시작되지않은 파동 W와 끝나지않은 파동 XX가 있는 3x3인 경우 필요한 포인트의 수는 3);
    9. 시작되지않은 두번째 파동과 끝나지않은 다섯번째 파동이 있는 파동 - 2-3-4-5 (예를들어 시작되지않은 파동 2와 끝나지않은 파동 5가 있는 충격파인 경우 필요한 포인트의 수는 3);
    10. 시작되지않은 첫번째 파동과 끝나지않은 다섯번째 파동이 있는 파동 -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와 끝나지않은 두번째 파동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. Zigzag의 각 꼭지점 인덱스와 값 저장용 클래스

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

4.4. 파동 트리 클래스

// 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. Zigzag를 통해 찾은 포인트들을 저장하는 구조

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

4.6. 차트 내 기존 분석된 섹션의 패러미터 저장용 클래스

// 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)

엘리엇 파동 자동 분석기의 핵심 요소는 파도가 만들어질 "지그재그"입니다. 어떤 패러미터를 받건 "지그재그"의 계산은 매우 빠르게 이루어져야 합니다.

우리 분석기에서는 "어떻게해야 빠르게 일회성 지그재그를 그릴 수 있을까" 문서에서 가져온 "지그재그"를 씁니다.

Zigzag 함수는 시작에서 완료까지의 간격에서 패러미터 H를 사용하여 지그재그를 계산한 다음 이 함수에 전달되는 주소인 IndexVertex 및 ValueVertex 어레이에 각각 기록합니다.

Zigzag 함수는 "지그재그" 내에서 발견된 꼭지점의 숫자를 리턴합니다. 

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 함수는 IndexStart에서 IndexFinish까지의 필수 범위에서 첫 번째 및 마지막 포인트 ValueStart 및 ValueFinish의 필수 값으로 최소 세 개의 NumPoints를 검색하여 이 함수에 전달되는 포인트 구조(즉, 포인트)에 저장합니다.

FindPoints 함수는 true를 반환하고, 필요한 수의 포인트가 발견되면 true를 반환하고, 그렇지 않으면 false를 반환합니다.

5.4. NotStartedAndNotFinishedWaves

이 함수는 시작하지않은, 그리고 끝나지않은 파동을 분석합니다.

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

NotStartedAndNotFinishedWaves는 파동의 제3 그룹(시작되지않은, 끝나지않은)에 속하는 모든 파동을 분석합니다. 이 함수는 파동 레벨의 NumWave 파형(ParentWave)을 분석합니다.이름 - 하위 파동(지그재그, 플랫, 이중 지그재그 및 (또는 등)의 형태를 취할 수 있습니다. 분석을 마친 파동 NumWave은 파동 트리의 노드, 차일드 노드인 Node에 저장될 것입니다.

예를들어 ParentWave.Name = "Impulse", NumWave = 5, Subwaves = "Impulse, Diagonal, and Level = 2, 라면 NotStartedAndNotFinishedWaves 함수는 파동 레벨 2인 충격파의 5번째 파동을 분석하여 충격파나 대각선의 형태를 취할 것이라고 할 수 있습니다.

예를 들어, NotStartedAndNotFinishedWaves 함수 안의 시작되지않고 끝나지않은 파동 1<-2-3>을 분석하는데에 블록 다이어그램을 사용합니다.

  <img alt="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 및 FinishedWaves.

5.5. NotStartedWaves

시작하지않은 파동 분석용 함수 

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

NotStartedWaves 함수는 파동의 첫 그룹인 시작하지않은 파동을 전부 분석합니다. 이 함수는 ParentWave.Name라고 불리는 파동의 NumWave 파동 (파동 레벨 Level)을 분석하며 하위파동의 형태를 취할 가능성이 있습니다. 분석을 마친 파동 NumWave은 파동 트리의 노드, 차일드 노드인 Node에 저장될 것입니다.

NotStartedWaves 함수가 작업중일 때 이하의 함수들이 호출됩니다 NotStartedWaves 및 FinishedWaves.

모든 함수는 15번 그림의 블록 다이어그램과 비슷하게 분석됩니다. 

5.6. NotFinishedWaves

끝나지않은 파동을 분석하는 함수 

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

NotFinishedWaves 함수는 파동의 두번째 그룹인 끝나지않은 파동을 전부 분석합니다. 이 함수는 ParentWave.Name 파동의 NumWave 파동 (파동 레벨 Level)을 분석하며, 하위 파동 형태를 취할 가능성이 있습니다. 분석을 마친 파동 NumWave은 파동 트리의 노드, 차일드 노드인 Node에 저장될 것입니다.

NotFinishedWaves 함수가 작업중일땐 이하의 함수가 호출됩니다 NotFinishedWaves 및 FinishedWaves.   

모든 함수는 15번 그림의 블록 다이어그램과 비슷하게 분석됩니다.

5.7. FinishedWaves

완료된 파동을 분석하는 함수 

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

FinishedWaves 함수는 파동의 네번째 그룹, 완료 파동에 속하는 모든 파동을 분석합니다. 이 함수는 ParentWave.Name 파동의 NumWave 파동 (파동 레벨 Level)을 분석하며, 하위 파동의 형태를 취할 가능성이 있습니다. 분석을 마친 파동 NumWave은 파동 트리의 노드, 차일드 노드인 Node에 저장될 것입니다.

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 함수는 이하의 파동 분석 함수에서 사용됩니다. NotStartedAndNotFinishedWaves, NotStartedWaves, NotFinishedWaves, 및 FinishedWaves. 

5.9. Already

주어진 차트 부분이 이미 분석되었는지 확인하는 함수입니다. 

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

엘리엇 파동 자동 분석은 순서대로 이루어지기 때문에, 이미 분석된 파트가 다시 주어지는 경우가 있습니다. 이걸 미리 알기 위해서는 파동 트리의 노드로의 링크를 저장하고 나서야 링크를 빼야 합니다. 일련의 작업은 Already 함수 안에서 이루어집니다.

Already 함수는 TNodeInfo 클래스 객체, 파동 NumWave에 대응하는 차트 인터벌을 보관하는 글로벌 어레이 NodeInfoArray 에서 Wave라고 이름지어진 파동을 찾습니다. Name은 하위 파동의 형태로 Node에 노드의 주소와 차트 내 이미 강조된 부분의 주소를 기록합니다. 만약 이 섹션이 존재하지않는다면 새로운 TNodeInfo 클래스 객체가 생성되어 메워지며, NodeInfoArray 어레이에 기록됩니다.

이 함수는 만약 차트의 해당 인터벌이 분석되었다면 true를 아니면 false를 리턴합니다. 

NodeInfoArray 어레이는 다음과 같이 선언되어있습니다. 

CArrayObj NodeInfoArray;

5.10. 파동의 규칙을 확인하는 함수

VertexAAboveB, WaveAMoreWaveB 및 WaveRules 함수를 포함하며 앞의 두개가 호출됩니다. 시험 시 파동이 시작되지 않거나 (또는) 불완전할 수 있으며, 예를 들어 공식 "1<-2-3>"인 파동의 경우, 아직 네번째 파동이 없기 때문에 네번째 파동이 첫번째 파동의 영역을 벗어났는지 여부를 판단할 수 없습니다.

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 파동 위로 지나가면 number > = 0,를 아니면 -1를 리턴합니다. 만약 InternalPoints = true인 경우 파동의 내부 포인트 수 (최대값 과(혹은) 최소값)을 고려합니다.

5.10.3. WaveAMoreWaveB

한 파장이 다른 파장에 겹치는지 확인하는 함수.

int WaveAMoreWaveB(int A,int B)

WaveAMoreWaveB 함수는 만약 A 파동이 B 파동보다 크다면 number >=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번 그림에서 볼 수 있듯이, (파동의 여러 옵션이 있으므로) 몇 가지 옵션이 있으며, 바이패스의 각 옵션은 서로 다른 강조로 이어집니다.

두가지 다른 트리 노드 타입으로 구분할 수 있습니다.

첫번째 타입은 파동의 이름이 담긴 노드 ("Impulse", "Zigzag" 등). 두번째 타입은 파동 번호가 담긴 노드 ("1", "1<", 등). 파동의 패러미터들에 대한 모든 정보는 첫번째 타입의 노드에 담깁니다. 따라서 이러한 노드를 방문할 때 파동에 대한 정보를 검색 및 기록하여 차트에 표시합니다

간단하게하기 위해 트리를 우회할 것이며, 파동의 첫 버전만을 확인할 것입니다.

우회 예시는 17번 그림에 있으며 빨갛게 강조되어 있습니다.

17번 그림. 파동 트리 우회 예시
17번 그림. 파동 트리 우회 예시

5.12.1. FillLabelArray

파동 트리 우회 함수

void FillLabelArray(TNode *Node)

FillLabelArray 함수는 루트 노드가 있는 웨이브 트리를 바이패스하고 트리의 첫 번째 파동 버전에만 있는 글로벌 어레이 LabelArray를 채웁니다. 여기서 인덱스는 지정된 인덱스를 사용하여 정점 배열(클래스 TLabel의 개체 배열)에 대한 링크를 저장합니다.

LabelArray 함수는 다음과 같이 정의되어있습니다. 

CArrayObj *LabelArray[];

5.12.2. CreateLabels

분석 결과를 차트에 게시하는 함수 

void CreateLabels()

CreateLabels 함수는 차트 상 파동 태그에 해당되는 그래픽 객체 "Text"를 생성합니다. 생성된 파동 태그는 LabelArray 어레이에 저장됩니다.

5.12.3. CorrectLabel

차트 상 파동들을 교정하거나 업데이트하는 함수 

void CorrectLabel()

CorrectLabel 함수는 스크롤중이나(혹은) 정지 중 차트 상의 파동 태그를 수정합니다.

 

6. 엘리엇 파동 자동 파티셔닝 구현 

6.1. Zigzag 함수:

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

6.2. 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. "분석 개시" - 파동 자동 분석 개시
  2. "결과 표시" - 차트 상의 파동 마크들이 표시됩니다.
  3. "차트 초기화" - 차트 상의 파동 마크가 삭제되고 메모리가 비워집니다,
  4. "마크 수정" - 차트 상의 파동 강조를 수정합니다

이들 버튼을 누르는 이벤트는 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. 이 프로그램은 월간에서 일간 차트 강조에 초점을 두어 만약 막대 수가 매우 많은 경우 처리 속도가 몹시 느립다. (시간 그래프 강조에 수 시간 소요) EURUSD 월간차트의 강조 예시를 18번 그림에서 볼 수 있습니다.

18번 그림. 엘리엇 파동, MQL5 자동 분석기를 통해 확인한 것
18번 그림. 엘리엇 파동, MQL5 자동 분석기를 통해 확인한 것

마치며

이 문서에서는 엘리엇 파동에 대한 자동 분석 알고리즘을 살펴보았습니다. 이 알고리즘은 MQL5 언어로 구현되어있습니다.

본문 중에 언급한대로 일부 부족한 점이 있으며, 차후 수정되어야할 숙제로 남게됩니다. 이 요소가 엘리엇 파동의 팬들에게 흥미로운 것이 될 것으로 기대하며, 엘리엇 파동을 자동 분석하는 프로그램들이 많이 나오길 기원합니다.


MetaQuotes 소프트웨어 사를 통해 러시아어가 번역됨.
원본 기고글: https://www.mql5.com/ru/articles/260

파일 첨부됨 |
elliott_wave_en.zip (150.91 KB)
MQL5에서 WinInet 사용하기 파트 2: POST 리퀘스트 및 파일 MQL5에서 WinInet 사용하기 파트 2: POST 리퀘스트 및 파일
본 문서에서는 우리는 인터넷을 HTTP 리퀘스트를 다루는 법에 대하여 계속하여 알아보고 실제 서버와 정보 교환을 해볼 것입니다. CMqlNet 클래스 내의 신규 함수를 다뤄보고 POST 리퀘스트를 통해 정보를 보내는 메소드, 그리고 Cookies를 이용해 홈페이지 로그인 인증을 처리하는 것을 다뤄봅니다.
보조 인디케이터 메모리 소모량 감소시키기 보조 인디케이터 메모리 소모량 감소시키기
인디케이터가 다른 인디케이터들의 값을 받아와 계산하는 경우 많은 메모리량이 필요합니다. 본 문서에서는 보조 인디케이터를 사용할 때에 소모되는 메모리량을 감소시키는 다양한 방법에 대하여 논할 것입니다. 메모리를 절약하면 클라이언트 내에서 동시에 이용 가능한 화폐쌍, 인디케이터, 전략을 늘려 더욱 ㅏㄴ은 여지를 줍니다. 이는 매매 포트폴리오의 안정성을 증진시킵니다. 이러한 간단한 관리만으로도 당신의 컴퓨터 리소스가 자산으로 환원될 수 있습니다.
결제 및 결제 수단 결제 및 결제 수단
MQL5.커뮤니티 서비스는 트레이더들 뿐만 아니라 MetaTrader 터미널용 어플리케이션을 개발하는 개발자들에게도 최고의 기회를 제공합니다. 이 기사에서는 MQL5 서비스에 대한 결제가 어떻게 수행되는지, 번 돈이 어떻게 인출될 수 있는지, 운영 보안이 어떻게 보장되는지 설명합니다.
MQL5 마법사에 나만의 Expert Advisor 만들기 MQL5 마법사에 나만의 Expert Advisor 만들기
이제는 프로그래밍 언어를 몰라도 매매 봇을 만들 수 있게 되었습니다. 옛날에는 프로그래밍을 할 줄 모르면 자신의 매매 전략을 도입하여 봇을 만들기가 무척 어려웠습니다만, MQL5 마법사가 도입되면서 상황은 급반전하였습니다. 이제 신규 트레이더들은 프로그래밍 경험이 없다고해서 두려워할 필요가 없어졌습니다. 새로운 MQL5 마법사와 함께라면 Expert Advisor를 짜는데에 프로그래밍 경험은 필요 없습니다.