2015年5月28日木曜日

EA開発者視点でのMT4バックテストの注意点

※こちらの記事もご覧ください。
[MT4プログラミング]小ネタ バックテスト時のiCloseは1000本前までに限定される。
http://mt4program.blogspot.jp/2015/10/mt4-iclose1000.html

EA開発時にバックテストをおこないますが、バックテスト時の独自挙動が存在します。

開発時に注意する点として特に問題となることを自分向けのメモとしてまとめます。

■OnTimerが動作しない。
 EventSetTimerで設定してもOnTimerは動作しません。
 EAとしてOnTimerで何かするのはやめておいた方がよさそうです。
 私はEA稼働時のコメントの更新の為だけに使用してポジションの状態に影響しないようにしました。

 ポジションの状態に時間ごとに影響させたい場合OnTick内で、定期的に呼び出すしか方法はなさそうです。これも気配値の更新タイミングで呼び出し時間がずれますが、通常は大きな影響はないと思われます。たとえば60秒ごとに呼び出す場合はこんな感じ。
void OnTick()
{
static datetime beforeTime = TimeCurrent();
if( TimeCurrent() - beforeTime > 60)
{
//なんか定期的な処理
beforeTime = TimeCurrent();
}
}


■TimeGMTが機能しない。
TimeGMT・・・GMTが取れる超便利な関数ですよね。
ところが、バックテストだとTimeCurrentと同じ値が取れてきます。バックテスト用データのチャート時間の値であってGMTではありません。バックテスト用にGMTを補正する必要があります。さらにMT4でよく採用されているGMT+2ですが、アメリカ夏時間帯になると+3になるデータが多い為、夏時間の判定も必要です。

以前紹介したMT4プログラムの小ネタ アメリカ夏時間を判定するプログラムを使って夏時間かどうかを判定した上でバックテストを行う必要が出てきます。
こんな感じで、バックテスト中のみGMTに対するオフセット値を適用するコードが必要です。
   if( !IsTesting() ) return TimeGMT();

// バックテストの場合TimeGMTの値はサーバータイムが帰ってくる。
// 夏時間が有効なヒストリカルデータの場合、夏時間は+1時間されて
// 帰ってくる。
datetime gmt = TimeGMT();
gmt = gmt - (int)(m_gmtOffset * ONEHOUR);

//切り替えタイミングの場合 おかしくなるが日曜日早朝切り替えの為
//EA動作には影響しない。
if( m_type == ST_TYPE_AMERICA && IsAmericaSummerTime(gmt) )
{
gmt -= ONEHOUR;
}

バックテスト用のパラメータコードとしてGMT補正が必要になるのではれば、結局のところTimeGMTいらないという結果に・・・(バックテストせずにEA動かす人なんてそうそういないですよね?)

IsTestingはバックテスト中かどうかをbool値で返してくれる関数です。このようにバックテスト時だけどうしても動作を変える必要がある部分などでは重宝します。

■初値で判断するなら、初値時しか動かない判定が必要。
 バックテストで、初値のみでテストしている場合、実運用上で正しく初値のみでしか動作しないようにしないといけません。
 全チックでやっても初値のみでやってもテスト結果としては大差ないのが基本です。(実際やってみると判定式を入れていたとしてもずれることがあるので、何かしらのアルゴリズムが入っているのかもしれませんが・・・)切り替え時だけ動作させる判定式はこんな感じになります。

   static datetime beforeTime = 0 ;
datetime currentTime = iTime(m_symbol, PERIOD_M5, 0);
if( beforeTime == currentTime )
{
return ;
}
beforeTime = currentTime;


■最適化をする場合は、利益だけを見てはいけない。
 最適化を何回かやっていると最大の利益が出るように調整していく事になるかと思います。利益の差が大きいEAの場合、たまたま引っかかったでかい利益のポジションの影響を受けることがあります。
 そのため、ドローダウンや勝率、取引数などを含めて確認することが必要と感じました。
 また、期間をいくつかに分けて確認することも重要で、長い期間だとうまくいっても実は直近NGだったりすることが多々ありました。

■履歴データを追いかけるときは注意
 バックテストでは普通に全履歴がとれますが、実運用では取れません。
 MT4「ターミナル」内「口座履歴」のタブにて表示期間を「全期間」に指定する必要があります。

■最後は力技
 ただ今デバッグ中ですが、デバッグになると割と力技です。
 チャートとインジケータを見比べて取引がアルゴリズム通りかどうか結局一個一個見ていく必要がありました。そして結構バグがある・・・・・泣
 このあたりは、まだまだ人の手による目視確認が有効でした。
 この場合も、切り分けて確認する必要があります。私の場合、売りだけ・買いだけといったモードをEAに組み込み買いのアルゴリズムのみを確認・売りのアルゴリズムを確認といった形で行いました。チャートの確認だけなら長い時間は必要ないため、ひと月ぐらいのスパンで何回も実行することが重要でした。

 ただ今自作EAをFX-ON様に登録すべく全ティックでのバックテストを実施中です。重いーw