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を作って良いトレードライフをお過ごしください。