ブログタイトルを「FX自動売買システム開発部」から「autoFX」に変更しました!

ZigZagの直近の山・谷を取得する関数

取得する山・谷は2本の線の頂点として構成されているもの

とある方からZigZagインジケーターを使った損切り設定を行いたいと依頼されました。

話を聞くと、「ZigZagの直近の山・谷を取得し、そこを損切りラインにしたい」というもので、「取得する山・谷は、2本の線の頂点として構成されているものだけにしたい」という追加リクエストもありました。

ZigZagにはリペイントする性質があって、なかなかトリッキーなデータ構造だったので、結構苦戦しました。

というわけで、ZigZagの直近の山・谷を取得する関数を紹介します。

同じ悩みを持っている人の参考になれば幸いです。

//+------------------------------------------------------------------+
//|【関数】ZigZagの直近の山・谷取得                                  |
//|                                                                  |
//|【引数】 IN OUT  引数名             説明                          |
//|        --------------------------------------------------------- |
//|         ○      aZIGZAG            インジケーターファイル名      |
//|         ○      tf                 時間足                        |
//|         ○      aExtDepth          インジケーター引数1          |
//|         ○      aExtDeviation      インジケーター引数2          |
//|         ○      aExtBackstep       インジケーター引数3          |
//|         ○      aMaxLoopCount      最大ループカウント            |
//|            ○   aYama              山                            |
//|            ○   aTani              谷                            |
//|                                                                  |
//|【戻値】なし                                                      |
//|                                                                  |
//|【備考】なし                                                      |
//+------------------------------------------------------------------+
void zigzagYamaTani(string aZIGZAG, int aTf, int aExtDepth, int aExtDeviation, int aExtBackstep, int aMaxLoopCount, double &aYama, double &aTani)
{
  bool yamaFlg = false;
  bool taniFlg = false;

  for(int i = 0; i < aMaxLoopCount; i++){
    double zigzag  = NormalizeDouble(iCustom(NULL, aTf, aZIGZAG, aExtDepth, aExtDeviation, aExtBackstep, 0, i), Digits);
    double zigzagH = NormalizeDouble(iCustom(NULL, aTf, aZIGZAG, aExtDepth, aExtDeviation, aExtBackstep, 1, i), Digits);
    double zigzagL = NormalizeDouble(iCustom(NULL, aTf, aZIGZAG, aExtDepth, aExtDeviation, aExtBackstep, 2, i), Digits);

    if(zigzag == 0){
      continue;
    }

    // 最初に出現する山または谷は無視する(取得する山と谷は2本の線の頂点として構成されているものだけ)
    if(zigzag == zigzagH){
      if(yamaFlg || (yamaFlg == false && taniFlg)){
        aYama = zigzag;
      }
      yamaFlg = true;
    }else if(zigzag == zigzagL){
      if(taniFlg || (taniFlg == false && yamaFlg)){
        aTani = zigzag;
      }
      taniFlg = true;
    }

    if(aYama != 0.0 && aTani != 0.0){
      break;
    }
  }
}

引数のaMaxLoopCountの役割がピンと来ないかと思います。これは、現在の足から何本まで遡って山・谷を探索するかという探索回数を表しています。

殆どの場合、数十本以内には見つかりますので無限ループでも良かったのですが、見つからなかった場合はPCが固まってしまうので、念のため探索回数に制限を設けました。

2019/11/17追記 ZigZagはリペイントするインジケーターです。一度形成した山もしくは谷を破棄して無かったことにすることがあります(この記事を初投稿した時は気づきませんでした)。そのため、一見山も谷もないのに、上記関数を使うと値が返ってくることがあります。しかし、それはZigZagのリペイントのせいです。バグではありません。あれ?動きがおかしい!と思った時はぜひビジュアルモードでバックテストしてみてください。問題の時間をリアルタイムで観察することでこの意味が分かると思います。

MQL4プログラミングの最新記事8件

>完全放ったらかしEA 「AutoEndlessCatchRange」

完全放ったらかしEA 「AutoEndlessCatchRange」

「本業が忙しい!」「でも資産運用したい!」そんなあなたに最適なEAです。兼業トレーダーの方はチャートを毎日みて分析してトレードする時間はなかなか確保できないものです。トレードは本EAに任せて、本業やプライベートの時間をもっと増やしませんか?元々は自分自身のために開発したEAですので、手抜き無しのガチものです。

CTR IMG