1分足から全ての時間足を生成する

period_converter_ALL.mq4で正常動作するなら不要

FxProで作成中のインジケーターをテスト中に処理が進まなくなる現象が発生しました。原因を調べると、1時間足(H1)のチャートデータがおかしなことになっていました。これが直接の原因のようです。

テストにはいつもFXDDのから取得した1分足(M1)のヒストリカルデータを用いています。

ここに置いてあるのは1分足だけなので、他の時間足も必要になります。そこで、使うのがperiod_converter_ALL.mq4という便利なスクリプトです。

これを使えば、M1から全ての足(M5, M15, M30, H1, H4, D1, W1, MN1)を作ってくれます。使い方はGoogle等で検索すれば沢山ヒットすると思いますので、割愛します。

今まで私もこのスクリプトを使ってきたのですが、どうもFxProのMT4とは相性が悪いらしく、H1のチャートデータが生成されません。

まぁ、随分昔に作られたスクリプトですし、現在のMT4(Build 600で大きな仕様変更がありました)とかみ合わないことがあってもおかしくはありません。

じゃあ、現在のMT4に合ったperiod_converter_ALL.mq4にリニューアルすればいいやということで作ったのが以下のスクリプトです。その名も「PeriodConverterALL.mq4」。そのまんまです(笑)。

中身は以下の通りです。

//+------------------------------------------------------------------+
//|                                           PeriodConverterALL.mq4 |
//|                   Copyright 2006-2014, MetaQuotes Software Corp. |
//|                                             Modified by りゅーき |
//+------------------------------------------------------------------+
#property copyright   "2006-2014, MetaQuotes Software Corp."
#property link        "http://www.mql4.com"
#property description "Period Converter to updated format of history base"
#property strict
//#property show_inputs

#include <WinUser32.mqh>

int         ExtHandle = -1;
static int  ArrayPeriod[];

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
  if(Period() != PERIOD_M1){
    Comment("Start Period Must be M1."); 
    return;
  }

  datetime time0;
  ulong    last_fpos = 0;
  long     last_volume = 0;
  int      i;
  int      start_pos;
  int      periodseconds;
  int      hwnd = 0;
  int      cnt = 0;
  string   cmnt;

  ArrayResize(ArrayPeriod, 8);
  ArrayPeriod[0] = PERIOD_M5;
  ArrayPeriod[1] = PERIOD_M15;
  ArrayPeriod[2] = PERIOD_M30;
  ArrayPeriod[3] = PERIOD_H1;
  ArrayPeriod[4] = PERIOD_H4;
  ArrayPeriod[5] = PERIOD_D1;
  ArrayPeriod[6] = PERIOD_W1;
  ArrayPeriod[7] = PERIOD_MN1;

  //---- History header
  int      file_version = 401;
  string   c_copyright = "(C)opyright 2003, MetaQuotes Software Corp.";
  string   c_symbol = Symbol();
  int      i_period;
  int      i_digits = Digits;
  int      i_unused[13];
  MqlRates rate;

  for(int idx = 0; idx < ArraySize(ArrayPeriod); idx++){
    i_period = ArrayPeriod[idx];

    cmnt = "Converting to Period (" + (string)i_period + "), bars to end: ";

    ExtHandle = FileOpenHistory(c_symbol + (string)i_period + ".hst", FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ|FILE_ANSI);

    if(ExtHandle < 0){
      return;
    }

    ArrayInitialize(i_unused, 0);

    //--- write history file header
    FileWriteInteger(ExtHandle, file_version, LONG_VALUE);
    FileWriteString(ExtHandle, c_copyright, 64);
    FileWriteString(ExtHandle, c_symbol, 12);
    FileWriteInteger(ExtHandle, i_period, LONG_VALUE);
    FileWriteInteger(ExtHandle, i_digits, LONG_VALUE);
    FileWriteInteger(ExtHandle, 0, LONG_VALUE);
    FileWriteInteger(ExtHandle, 0, LONG_VALUE);
    FileWriteArray(ExtHandle, i_unused, 0, 13);

    //--- write history file
    periodseconds    = i_period * 60;
    start_pos        = Bars - 1;
    rate.open        = Open[start_pos];
    rate.low         = Low[start_pos];
    rate.high        = High[start_pos];
    rate.tick_volume = (long)Volume[start_pos];
    rate.spread      = 0;
    rate.real_volume = 0;

    //--- normalize open time
    rate.time  = Time[start_pos] / periodseconds;
    rate.time *= periodseconds;

    for(i = start_pos - 1; i >= 0; i--){
      if(IsStopped()){
        break;
      }

      if(MathMod(i, 1000) == 0){
        Comment(cmnt + " " + (string)i);
      }

      time0 = Time[i];

      //--- history may be updated
      if(i == 0){
        //--- modify index if history was updated
        if(RefreshRates()){
          i = iBarShift(NULL, 0, time0);
        }
      }

      if(time0 >= rate.time + periodseconds || i == 0){
        if(i == 0 && time0 < rate.time + periodseconds){
          rate.tick_volume += (long)Volume[0];

          if(rate.low > Low[0]){
            rate.low = Low[0];
          }

          if(rate.high < High[0]){
            rate.high = High[0];
          }

          rate.close = Close[0];
        }

        last_fpos = FileTell(ExtHandle);

        last_volume = (long)Volume[i];

        FileWriteStruct(ExtHandle, rate);

        cnt++;

        if(time0 >= rate.time + periodseconds){
          rate.time        = time0 / periodseconds;
          rate.time       *= periodseconds;
          rate.open        = Open[i];
          rate.low         = Low[i];
          rate.high        = High[i];
          rate.close       = Close[i];
          rate.tick_volume = last_volume;
        }
      }else{
        rate.tick_volume += (long)Volume[i];

        if(rate.low > Low[i]){
          rate.low = Low[i];
        }

        if(rate.high < High[i]){
          rate.high = High[i];
        }

        rate.close = Close[i];
      }
    } 

    FileFlush(ExtHandle);

    Print(cnt, " record(s) written");

    if(ExtHandle >= 0){
      FileClose(ExtHandle);
      ExtHandle = -1;
    }

    Comment("");
  }
}

使い方はperiod_converter_ALL.mq4と一緒です。ちなみに、ベースとなっているのはMT4をインストールすると標準で付属されているPeriodConverter.mq4です。プログラムで躓いた時は標準で付属されているものを参考にするのもアリだと思います。学ぶは真似るから。

MT4の無料プログラミング講座

メルマガ登録して、MT4のプログラミング講座を無料で受けちゃおう!

超豪華プレゼントも盛りだくさん♪

MT4プログラミングを習得すると、オリジナルEA運用、作成代行、商品販売等、複数の収入源を手に入れられるよ。副業に最適だね!

↓↓↓ 詳細はこちら ↓↓↓

アイキャッチ

>

エターナル・パートナーPRO ~MT4裁量トレード支援ツール~ 「MT4は裁量トレーダーに優しくない」そう思ったことありませんか?もっと快適にトレードするための強力な売買ツールが必要だと考え、開発したのが「エターナル・パートナーPRO」です。元々は自分自身のために開発したツールですので、手抜き無しのガチものです。既に200名近い方に手に取っていただき、喜びの声が続々と届いております。ぜひご覧ください!

CTR IMG