19.最適化を行う

最適化は、EAが使用する設定値に関して、どんな設定が最も良い結果を記録するかを調べる機能です。
ただし、テストで使用するヒストリカルデータでのバックテスト上の話なので、カーブフィッティングには注意しましょう。

最適化を行うにあたり、前回までで作成したsimple.mq4にもう少し外部入力パラメータを追加します。
EAで20SMAと200SMAを使っていましたが、このそれぞれのMAの期間を外部入力させるようにしましょう。
(ボリンジャーバンドの期間は短い方のMA期間を使うようにします。)

ソースコードは以下のようになります。

#property copyright ""
#property link      ""
#property version   "1.00"
#property strict

input double Lots = 0.1;   //ロット
input int StopLoss = 200;  //ストップロス(ポイント指定)
input int ShortMaPeriod = 20; //短期MA期間
input int LongMaPeriod = 200; //長期MA期間

int OnInit() {
   return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason) {
}
void OnTick() {
   if(OrdersTotal() == 0) {
      //ポジションを持っていない時は、ここに処理が入る
      double sma_long = iMA(Symbol(), Period(), LongMaPeriod, 0, MODE_SMA, PRICE_CLOSE, 0); //現在時点での長期SMA
      double sma_long_prev = iMA(Symbol(), Period(), LongMaPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);  //1本前のバー時点での長期SMA
      double sma_short = iMA(Symbol(), Period(), ShortMaPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);   //現在時点での短期SMA
      double sma_short_prev = iMA(Symbol(), Period(), ShortMaPeriod, 0, MODE_SMA, PRICE_CLOSE, 1); //1本前のバー時点での短期SMA
      double bb_upper = iBands(Symbol(), Period(), ShortMaPeriod, 2.0, 0, PRICE_CLOSE, MODE_UPPER, 0);  //ボリンジャーバンド+2σ
      double bb_lower = iBands(Symbol(), Period(), ShortMaPeriod, 2.0, 0, PRICE_CLOSE, MODE_LOWER, 0);  //ボリンジャーバンド-2σ
      if(sma_long > sma_long_prev) {
         //長期SMAが上昇なら、ここに処理が入る
         if(sma_short > sma_long) {
            //短期SMAが長期SMAより上に位置するなら、ここに処理が入る
            if(Open[1] < sma_short_prev && Close[1] >= sma_short_prev && Bid > sma_short) {
               //バーが短期SMAを上抜けたら、ここに処理が入る
               if(bb_lower > sma_long) {
                  //長期SMAがボリンジャーバンドの外側(下)にある場合のみエントリー
                  OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, Bid-StopLoss*Point(), 0, NULL, 12345);   //買い注文・マジックナンバー12345
               }
            }
         }
      } else if(sma_long < sma_long_prev) {
         //長期SMAが下降なら、ここに処理が入る
         if(sma_short < sma_long) {
            //短期SMAが長期SMAより下に位置するなら、ここに処理が入る
            if(Open[1] > sma_short_prev && Close[1] <= sma_short_prev && Bid < sma_short) {
               //バーが短期SMAを下抜けたら、ここに処理が入る
               if(bb_upper < sma_long) {
                  //長期SMAがボリンジャーバンドの外側(上)にある場合のみエントリー
                  OrderSend(Symbol(), OP_SELL, Lots, Bid, 3, Bid+StopLoss*Point(), 0, NULL, 12345);   //売り注文・マジックナンバー12345
               }
            }
         }
      } else {
         //長期SMAが水平移動しているなら、ここに処理が入る
      }
   } else {
      //ポジションを持っている時は、ここに処理が入る
      double sma_long = iMA(Symbol(), Period(), LongMaPeriod, 0, MODE_SMA, PRICE_CLOSE, 0); //現在時点での長期SMA
      for(int i=OrdersTotal()-1; i>=0; i--) {
         if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
            if(OrderMagicNumber() == 12345) {
               //このEAによるポジションがあればここに処理が入る
               if(OrderType() == OP_BUY && Bid <= sma_long) {
                  //長期SMAタッチで決済
                  OrderClose(OrderTicket(), OrderLots(), Bid, 3);
               } else if(OrderType() == OP_SELL && Bid >= sma_long) {
                  //長期SMAタッチで決済
                  OrderClose(OrderTicket(), OrderLots(), Ask, 3);
               }
            }
         }
      }
   }
}

コンパイルしたら、ストラテジーテスターのエキスパート設定を開きます。
下図のように、「短期MA期間」と「長期MA期間」にチェックを入れ、スタート・ステップ・ストップを入力して「OK」をクリックします。
スタートが初期値、ステップが増分、ストップが上限値です。

短期MA期間を10~20まで2ずつ増やす6通り、長期MA期間を100~200まで20ずつ増やす6通りです。
次に、ストラテジーテスターの「最適化」にチェックを入れます。

テストをスタートします。
最適化をONにしたテストは、ビジュアルモードがありません。

エキスパート設定で入力した内容を元に、外部入力パラメータの組み合わせを網羅して、設定別の結果を一覧することができます。
今回であれば、全部で36通りのバックテストを一度に実行してくれます。
組み合わせが多いほどテストには時間がかかりますので、沢山のパラメータを細かく刻んで最適化するような場合は、寝る前とかにしましょう。

最適化が終了すると、「最適化結果」「最適化グラフ」タブが表示されます。
下図は最適化結果を開いています。

最適化結果タブには、損益がプラスのもののみ表示されます。
マイナスになったものも含め全て表示したい場合は、タブの中を右クリックして、「マイナスの結果を表示しない」のチェックを外します。

最適化結果タブに表示される表の一番右「パラメーターの入力」を確認して外部入力パラメータの組み合わせが分かります。
また、結果の行をダブルクリックすると、その行のパラメータ設定の状態にしてセッティングタブに戻ることができますので、その設定ですぐに通常のテストを実行することができます。

以上が最適化です。

今回で初心者向けEAの作り方は終了です。ここまで読んでくださった方は大変お疲れ様でした。
優秀なEAを作って良いトレードライフをお過ごしください。

コメントを残す

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

コメントする