2015年5月25日月曜日

MT4プログラム 毎月第1金曜日は米雇用統計・・いいえ違います。雇用統計発表日を計算する。

FXで相場が大きく動くアメリカ雇用統計です。
雇用統計に向けて仕掛けるにしても、逆に雇用統計前にポジションをきれいにするにしても、雇用統計発表時間は判定したいですよね。

毎週金曜日のアメリカ時間8:30を取引しないというアルゴリズムでもいいのですが、何にもない日で利益の機会を逃してしまう事も多々あります。

さて、アメリカ雇用統計ですが、第一金曜日とよく日本のページには記載されていますが、たまに第2金曜日になる事ありませんか?

実は、アメリカ 雇用統計 発表日は第1金曜日ではありません。
非農業部門雇用者数(アメリカwiki)によると、12を含む週が終わった後の第三金曜日に発表されるとなります。Wikiには特に書いてありませんが、1月は1~3が金曜日になった場合は、次の週に回すようです。また7月は独立記念日があるため、木曜日に回る事があります。2月が短いために3月はほぼ第2金曜日になったりします。

判定プログラムを作るとたぶんこんな感じになるかと。
#define ONEDAY (3600 * 24)
// 曜日
#define SUNDAY 0
#define MONDAY 1
#define TUESDAY 2
#define WEDNESDAY 3
#define THURSDAY 4
#define FRIDAY 5
#define SATURDAY 6

//------------------------------------------------------------------
// 指定された日が雇用統計日か判定する。
// return true
bool IsEmplymentStatisticDay(
int year,      // 年
int month,     //月
int day        //日
)
{
// 12を含む週終了後の3回目の金曜日
// 1月だけは1~3が金曜日の場合、次の金曜日

MqlDateTime current;
current.year = year;
current.mon = month;
current.day = day;
current.hour = 12;
current.min = 0 ;
current.sec = 0;
TimeToStruct(StructToTime(current), current);

if( current.mon == 1 )
{
// 1月は4~10日の金曜日が雇用統計で確定。
if( 4 <= current.day && current.day <= 10 && current.day_of_week == FRIDAY )
{
return true;
}
}
else if( current.mon == 7 && (current.day == 2 || current.day == 3) && current.day_of_week == THURSDAY)
{
// 7/4は独立記念日の為、重なった場合は木曜日にずれる。
// 7/3が金曜日の場合も振替休日のためずれる。
return true;
}
else if( current.mon == 7 && (current.day == 3 || current.day == 4) && current.day_of_week == FRIDAY)
{
return false;
}
else if(  1 <= current.day && current.day <= 10 && (current.day_of_week == THURSDAY || current.day_of_week == FRIDAY ))
{
//前の月の12日を含む週から3番目
MqlDateTime beforeMonth;
beforeMonth.year = current.year;
beforeMonth.mon = current.mon - 1;
beforeMonth.day = 12;
beforeMonth.hour = 12;
beforeMonth.min = 0;
beforeMonth.sec = 0;

datetime beforeMonthTime = StructToTime(beforeMonth);
TimeToStruct( beforeMonthTime, beforeMonth);

datetime emplymentDay = beforeMonthTime + (5 - TimeDayOfWeek(beforeMonthTime) + 21) * ONEDAY;

if( current.day == TimeDay(emplymentDay) )
{
return true;
}
}
return false;
}


ちなみに2013年の10月~11月は予算承認問題で全く違う日に発表されています。
バックテスト用にEAを停止していたか動かしていたか?という判断で別途判定する必要があります。