【EA開発ガイド】Part 5 バックテスト基礎 – Chapter 5 EAの性能チューニング

あまりにもEAの検証時間が長すぎたので簡単な性能チューニングをしたら劇的に改善した。EAの処理でそこまで重い処理はないと思っていたが甘かったビジュアルモードで使うチャートへの描画処理はかなり重く性能悪化の原因となっていた。結論としてビジュアルモード処理の除外とデバッグコードの削除で30倍近く性能が改善した。性能改善をさぼったせいでかなり無駄に時間を使ってしまった。悪いことは言わないのでバックテスト前に性能チューニングはしておいた方がいい。

注意事項

本記事はFXの自動売買に使用されるプログラムについて解説していますが内容を保証するものではありません。金銭にかかわる内容であるためご注意ください。参考にする場合は自己責任でお願いします。

留意事項

本記事ではMT4を使用する。

実行環境

FXDD – MetaTrader
・Version: 4.00 build 1322
・8Feb 2021

MetaEditor
・Version 5.00 build 2375
・7 Jan 2021

過去10年のバックテストに12時間以上かかる

バックテストに時間がかかるため多くの組み合わせを検証できない。

時間がかかりすぎて色々なパターンを試せない

パラーメーター値や条件などの組み合わせを考えると数多くの組み合わせがあり、バランス良く効く組み合わせを見つけるにはより多くのパターンを試す必要がある。1年以内のバックテストであれば数時間で終わるが別の年の成績が悪い可能性もあり最終的には長期のバックテストが必要となる。

マシン3台での検証生活

過去10年のバックテストが12時間以上かかるのでデスクトップ1台とノートPC2台、合計3台のPCをつあって検証。電気代の問題もあるが寝室にマシンがあるためファンの音が気になってしまう。

システムの性能問題

仕事で性能チューニングを色々やってきた。性能問題の原因によく上げられるのがデータベースへのアクセスである。

記憶媒体へのアクセスがネックになる

通常ハードディスク等のデバイスへのアクセスが性能問題の原因となることが多い。データベースも性能問題の原因になりやすい。データベースではインデックスと呼ばれる機能を使い検索スピードを上げたりできるがシステム全体でみればボトルネックである。物理デバイスへのアクセスが圧倒的にコストがかかる。すべての情報がメモリ上にあるシステムであれば比較的性能はよいはず。

キャストや変換関数やメソッド

文字列から数値、数値から文字列にする関数なども一般的に性能のボトルネックになると言われている。言語ごとにコストのかかる(処理時間が長い)関数やメソッドがあるので性能改善する場合は回避したり代替機能を使って問題を解決する。

デバイスへのアクセス

ディスプレイ表示処理などもコストがかかる。プログレスバーなどで進捗状況をレポートする場合はマルチスレッドと呼ばれる仕組みを使って表示処理と計算処理を分けたりする。標準出力なども含め性能を上げたい場合は外部への出力処理を出来るだけ少なくした方がよい。

EAの性能チューニング

バックテストで使うEAはファイルアクセスなどしないので筆者はあまり性能を気にしていなかった。しかしそれは大間違い。バックテストのような大量の処理を連続して行う場合はファイルアクセスが無くても性能チューニングが重要になってくる。特に全ティックでバックテストをするならなおさらである。

EA性能計測

EAの開始と終了に時間計測処理を追加。

uint g_startTime;
uint g_endTime;

int OnInit()
{
    // EA開始時刻を記録
    g_startTime = GetTickCount();
    return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{   
    // EA終了時刻を記録
    g_endTime = GetTickCount();
    // EA稼働時間をレポート
    Print(
        "処理時間:" +
        string((double)(g_endTime - g_startTime) / 1000) +
        "秒"
    );
}

 

1. チューニング前

チューニング前は一カ月のテストで約13秒。

2021.06.19 01:21:54.161 2021.01.19 23:59:42  ea008-trend02kai-back USDJPY,M5: 処理時間:13.188秒
2021.06.19 01:28:35.846 2021.01.19 23:59:42  ea008-trend02kai-back USDJPY,M5: 処理時間:13.266秒
2021.06.19 01:29:26.256 2021.01.19 23:59:42  ea008-trend02kai-back USDJPY,M5: 処理時間:13.172秒

 

2. ビジュアルモード用コードの除外

ビジュアルモードでデバッグ用のメッセージをチャート上に表示していたのでそれを抑止する。非ビジュアルモードではビジュアルモードでしか使わない処理をすべて動かないように切り替える。

// ビジュアルモードの取得
bool g_visualMode = IsVisualMode();

if(g_visualMode)
{
    // ビジュアルモードの処理
}

 

チューニング後10倍近く性能が改善。非ビジュアルモードであってもチャートへの描画処理が影響していたようだ。ObjectCreateのような描画処理はボトルネックになる可能性が高いので注意した方がよさそう。

2021.06.19 01:41:46.708	2021.01.19 23:59:42  ea008-trend02kai-back USDJPY,M5: 処理時間:1.64秒
2021.06.19 01:42:22.920	2021.01.19 23:59:42  ea008-trend02kai-back USDJPY,M5: 処理時間:1.656秒
2021.06.19 01:47:33.539	2021.01.19 23:59:42  ea008-trend02kai-back USDJPY,M5: 処理時間:1.641秒

 

3. デバック用文字列変換関数を削除

デバッグ用で使っているIntegerToStringなどの変換関数を削除。手当たり次第削除したので4倍ほど性能が改善した。

2021.06.19 02:58:28.528 2021.01.19 23:59:42  ea008-trend02kai-back USDJPY,M5: 処理時間:0.407秒
2021.06.19 02:58:57.383 2021.01.19 23:59:42  ea008-trend02kai-back USDJPY,M5: 処理時間:0.375秒
2021.06.19 02:59:45.295 2021.01.19 23:59:42  ea008-trend02kai-back USDJPY,M5: 処理時間:0.39秒

 

性能改善

ビジュアルモードとデバッグコードを削除しただけで30倍近く性能が改善した。まさかビジュアルモードの処理がここまで悪影響しているとは思いもしなかった。デバッグコードも想像以上に重い。結論を言うとバックテストが余分な処理で30倍遅かったことないなる。1時間で終わる処理が30時間と・・・。

セクション 1回目 2回目 3回目 平均
1. チューニング前 13.19 13.27 13.17 13.21
2. ビジュアルモード用コードの除外 1.64 1.66 1.64 1.65
3. デバック用文字列変換関数を削除 0.41 0.38 0.39 0.39

まとめ

しばらくチューニングしないでテストしていないので、とてつもなく無駄な時間を過ごしてしまった。多くのパターンを検証するためにも性能チューニングはテスト前に必ずやっておいた方がいい。

ポイント
  • 多くの組み合わせテストを効率的にするためEAの性能チューニングは必須
  • ビジュアルモードでしか使わない処理は非ビジュアルモードで除外する
  • デバッグコードは極力削除しておく

チャートへの描画は重い処理なのでご注意ください。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です