2015年5月1日金曜日

MT4プログラムの小ネタ アメリカ夏時間を判定するプログラム

自作EAのバックテストによる調整に時間をとられていて、プログラムネタが少々つきかけてます。(^^;;
ゴールデンウィーク中にまた貯めたいと思いますので、今日は小ネタで。

EA作っていると、特定の時間帯は取引を避けたり逆に取引したりしたくなることありませんか?
大体アメリカの重要指標の発表時間帯(現地8:30or11:00)だったりします。あちらは夏時間を採用していて特定の期間だけ標準時より1時間早くなったりするので面倒です。夏時間になったらEAを止めて時間補正パラメータを入れ替えるとかもありでしょうが、ここははやりプログラムで判定してあげる方が親切ですしバックテストの精度も上がるかと思います。

で、TimeGMT()で取得した値を返すとアメリカが夏時間かどうかを判定するプログラムです。
なおバックテストではTimeGMT()が正しくGMTを返してこない為、工夫が必要です。このあたりのお話はまた別途したいと思います。
EU夏時間も同じような計算で取得可能です。

// 曜日
#define SUNDAY 0
#define MONDAY 1
#define TUESDAY 2
#define WEDNESDAY 3
#define THURSDAY 4
#define FRIDAY 5
#define SATURDAY 6

// 一時間(秒)
#define ONEHOUR   (3600)

// GMTと東アメリカ標準時間の差(-5時間)
#define GMT_TO_AMERICA (-18000)

//------------------------------------------------------------------
// サマータイム指定日時がサマータイムかどうか
// return 指定GMT時間がサマータイムの場合 true
bool IsAmericaSummerTime(
datetime gmt         // GMT
)
{
datetime americaTime = gmt + GMT_TO_AMERICA;

MqlDateTime dt;
TimeToStruct(americaTime, dt);

//夏時間判定
datetime startSummerTime;
datetime endSummerTime;
MqlDateTime work;
int week;
if( dt.year < 2007 )
{
// 標準時ベースで4月第1日曜日 AM2:00 ~ 10月最終日曜日AM1:00
work.year = dt.year;
work.mon = 4;
work.day = 1;
work.hour = 2;
work.min = 0 ;
work.sec = 0 ;
week = TimeDayOfWeek(StructToTime(work));

if( week != SUNDAY )
work.day = work.day + 7 - week;
startSummerTime = StructToTime(work) ;

work.mon = 10;
work.day = EndOfMonth(work.year, work.mon);
work.hour = 2;
work.min =  0;
work.sec = 0 ;
week = TimeDayOfWeek(StructToTime(work));
work.day = work.day - week;

endSummerTime = StructToTime(work) ;
}
else
{
// 標準時ベースで3月第2日曜日 AM2:00 ~ 11月第1日曜日AM1:00
work.year = dt.year;
work.mon = 3;
work.day = 8;
work.hour = 2;
work.min = 0 ;
work.sec = 0 ;

week = TimeDayOfWeek(StructToTime(work));
if( week != SUNDAY )
work.day = work.day + 7 - week;
startSummerTime = StructToTime(work) ;

work.mon = 11;
work.day = 1;
work.hour = 2;
work.min = 0 ;
work.sec = 0 ;
week = TimeDayOfWeek(StructToTime(work));
if( week != SUNDAY )
work.day = work.day + 7 - week;
endSummerTime = StructToTime(work) ;
}

return startSummerTime <= americaTime && americaTime < endSummerTime ;
}


なお、関数内で「MQL4でEndOfMonth 月末日付を取得する。」を使用しています。

まぁ、こーいった面倒なところの判定を勝手にやってくれるようにできるのがEAのいいところです。
テクニカルだけ見て裁量取引しているとたまに重要指標発表の時間帯のことをすっかり忘れて手痛い目に合う事がありますよね??^^;;