2016年5月13日金曜日

[MQL超入門] その023 バックテストを活用しよう。その2 パラメータの最適化1

EAの良し悪しは、プログラムのロジックだけでは決まりません。同じロジックでも、パラメータが変わることで全く違う成績にもなります。

EAのパラメータとは、例えば前に作成した移動平均線のEAであれば、移動平均の期間や、移動平均の種類などを指します。

その時の記事はこちら
※これを書いたのはこの記事の公開前なのでURLは適当てす!!
[MQL超入門] その021 本格的にEAを作ってみよう。その2 カスタム指標を使用する

とはいえパラメータを少しずつ変えてバックテストを実行して検証するのは大変なんですが、MT4には最適化という便利な機能があります。最適化とは、指定したパラメータの組み合わせを自動的に実行し、結果を比較することができる機能です。
今回は、最適化の手順を説明します。

ストラテジーテスターの[セッティング]タブの[最適化]にチェックを付けます。
・図023.01 最適化の選択

[エキスパート設定]ボタンをクリックします。
・図023.02 エキスパート設定の表示

EAの設定画面が表示されます。
まず[テスト設定]タブの設定を行います。
・図023.03 エキスパート設定 テスト設定
[最適化パラメータ]では、パラメータの良し悪しを何の数値で評価するかを選択します。
基本的には[Balance]でよいと思いますが、以下から選択することが出来ます。
 ・Balance (残高)
 ・Profit Factor (プロフィットファクタ)
 ・Expected Payoff (期待利得)
 ・Maximal Drawdown (最大ドローダウン)
 ・Drawdown percent (相対ドローダウン)
 ・Custom (EAに埋め込まれた評価値算出処理の出力する数値)

[遺伝的アルゴリズム]も、基本的にチェックでよいです。
遺伝的アルゴリズムは、ランダムなパラメータの組み合わせから評価の良いものを抽出し、それを何度も繰り返すことで、高い確率で最適な組み合わせに行き着くと言われています。
遺伝的アルゴリズムのチェックを外した場合、パラメータの組み合わせを総当りで実行します。組み合わせが少ない場合は総当りの方が確実ですが、組み合わせが多い場合には遺伝的アルゴリズムを使用することで短時間で最適化が行えます。

必要に応じて、[初期証拠金]を増やすこともできます。
また、[ポジション]でロング(買)とショート(売)どちらかしか持たないこともできます。
ただ基本的にこれらは変更しなくてもよいかと思います。

次に[パラメーターの入力]タブで、最適化したいパラメータを選択します。
・図023.04 エキスパート設定 パラメーターの入力
最適化するパラメータを、左のチェックを入れて選択します。最適化するパラメータの数が増えるとそれだけ時間がかかりますので、2~3個までに留めておくのがよいと思います。
今回は[移動平均の期間]と[移動平均線の種類]を最適化します。
その右の設定値は、[スタート]の値から[ストップ]の値までを[ステップ]の値刻みで変化させて最適化を行うという意味になります。また、チェックを入れたパラメータは[値]の値は無視されます。

[最適化]タブでは、EAを停止するための制限を設けることができますが、下手に制限をかけるとEAの成績が正しく評価できないこともありますので、基本的には何もせず無制限としておきます。

これらの設定を行ってから、ストラテジーテスターの[スタート]ボタンをクリックすると、最適化が開始されます。
時間がかかると思いますが、通常のバックテストと同様で、緑のバーが右端まで到達し、[ストップ]が[スタート]に戻ったら完了です。

では最適化の結果を確認したいと思いますが、長くなりましたので続きは次回に。


「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。

2016年5月12日木曜日

[販売中インジケータ]予告 フラクタルバンドを使ったトレンド判定機能追加

Gewinn7に組み込んだ、フラクタルを利用したもう一つのインジケータも合わせて公開します。
本業がそこそそ忙しかったため、こちらのインジケータのことをすっかり忘れていました^^;;;;

このバージョンアップを持ちまして現在980円で販売中のフラクタルバンドを1680円に値上げします。5/16のバージョンアップを予定しています。5/16までは現状の980円にて販売いたします。

■フラクタルの位置関係をインデックス化したインジケータ USDJPY H1

波を打ちながら高値安値のラインを更新している場合、ある程度の行き過ぎ状態が表れる事がわかってきました。Gewinn7にて、この行き過ぎ時からの反転タイミングで利食いを行うとPFを0.15ほど押し上げる効果がありました。

考え方としてはS/Rオシレータのカスタムフラクタル版的インジケータになっています。

フラクタルバンド 980円 ~5/16まで
頂点位置からレンジ帯を表示する
フラクタルバンド

「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。

[Gewinn7]V1.11リリースのお知らせ

Gewinn7 V1.11をFX-ONにリリース申請しました。

修正点は下記の通りです。

・利食いにおいてフラクタルでの頂点タイミングを見るように変更しました。
・変化率分散バンドトレンド判定において、ある一定期間一方方向に動いた際値幅が±1σを超えるようならトレンドととらえるような判定を追加しました。
・利食いに関するパラメータを少し修正しました。

■Gewinn7 バックテスト 2007-2015 複利運用なし 0.02ロット 片側最大11ポジション
通貨ペアEURUSD (Euro vs US Dollar)
期間5分足(M5) 2007.01.02 08:00 - 2015.12.30 23:55 (2007.01.01 - 2015.12.31)
モデル全ティック (利用可能な最小時間枠による最も正確な方法)
パラメーターMagicNumber=55357260; TestGmt=2; IsCountdong=false; SpreadFilter=5; Lot=0.02; PermitSlip=2; MaxPosition=22; Comment="Gewinn7 EURUSD"; IsCompund=false; BaseRiskP=1; EnableNewPosition=true;
テストバー数666103モデルティック数106135364モデリング品質90.00%
不整合チャートエラー0
初期証拠金10000.00スプレッド15
純益15270.68総利益28022.95総損失-12752.28
プロフィットファクタ2.20期待利得4.78
絶対ドローダウン21.10最大ドローダウン652.65 (2.98%)相対ドローダウン4.18% (608.08)
総取引数3195売りポジション(勝率%)1659 (78.84%)買いポジション(勝率%)1536 (83.20%)
勝率(%)2586 (80.94%)負率 (%)609 (19.06%)
最大勝トレード80.28敗トレード-40.76
平均勝トレード10.84敗トレード-20.94
最大連勝(金額)87 (741.39)連敗(金額)13 (-240.89)
最大連勝(トレード数)819.40 (45)連敗(トレード数)-301.65 (9)
平均連勝11連敗3


ゴールデンウィーク中に大負けしました。考え方としては想定していた通りなのですが、ちょっと負けすぎとおもい、あれこれ調査していました。

結果トレンド判定にて中心値に対して±2σを超えたら、トレンド発生というのが基本的な考え方ですが、高値や安値から ±1σの幅を超えての値動きは上記に匹敵するという判定を加えたところPFが2を超えてきましたのでバージョンアップを行いました。

ご購入済みの皆さまには、ご迷惑おかけいたします。FX-ONのバージョンアップが終わり次第、バージョンアップよろしくお願いいたします。

ご購入はこちらから 9800円にて販売中です。
変化率分散バンドと平均足を利用したトレンドフォロー型EA
Gewinn7(EURUSD)


・・フォワードのチャートが崩れまくっていますが、日々改善していますので、ぜひご検討ください。

「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。

2016年5月11日水曜日

[MQL超入門] その021 本格的にEAを作ってみよう。その2 カスタム指標を使用する

それでは、独自に作成したインジケータ(カスタム指標)を使用したEAを作成しましょう。

インジケータは標準で入っている「Custom Moving Averages」を使用します。
移動平均線のインジケータなので、戦略や結果は前回とほとんど変わりませんが、これを使って独自のインジケータの使い方を説明します。

それではコードを見てみましょう。
今回は[EA_MACustom]という名前で新しいEAを作成しています。
//+------------------------------------------------------------------+
//|                                                  EA_MACustom.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#include <Custom/TradingWrapper.mqh>

input int MagicNumber = 37858262; //マジックナンバー 他のEAと当らない値を使用する。
input int MaxPosition = 1;        //最大ポジション数
input double SpreadFilter = 2;    //最大スプレット値(PIPS)

input double Lot = 0.02;          //売買ロット
input uint Slippage = 2;          //許容スリップページ(pips)
input uint StopLoss = 200;        //ストップロス
input uint TakeProfit = 200;      //利益確定

input int Period = 25;                    //移動平均の期間
input int Shift = 0;                      //移動平均線の表示を右シフトする本数
input ENUM_MA_METHOD Method = MODE_SMA;   //移動平均線の種類

const string IndicatorName = "Custom Moving Averages";

// トレード補助クラス
CTradingWrapper m_wrapper(Symbol(), MagicNumber, MaxPosition, SpreadFilter);

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
//---
   
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
   
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//---
   string symbol = Symbol();
   static ENUM_TIMEFRAMES target = PERIOD_H1;
   static datetime before = 0;

   // 1時間の確定足でのみ動作
   datetime current = iTime(symbol, target, 0);
   if( before == current )
   {
      return ;
   }
   before = current;

   m_wrapper.RefreshPositions();

   // 1つ前と2つ前の足の終値を取得する
   double close1 = iClose( symbol, target, 1 );
   double close2 = iClose( symbol, target, 2 );
   
   // 1つ前と2つ前の移動平均の値を取得する
   double ma1 = iCustom(symbol, target, IndicatorName, Period, Shift, Method, 0, 1 );
   double ma2 = iCustom(symbol, target, IndicatorName, Period, Shift, Method, 0, 2 );
   
   int orderCmd = OP_NONE;
   if ( close1 > ma1 && close2 < ma2 )
   {
      // 終値が移動平均線を上抜けたら買う
      orderCmd = OP_BUY;
   }
   else if ( close1 < ma1 && close2 > ma2 )
   {
      // 終値が移動平均線を下抜けたら売る
      orderCmd = OP_SELL;
   }
   
   if ( orderCmd != OP_NONE )
   {
      bool hasPosition = ( m_wrapper.GetPositionCount() > 0 );
      if ( hasPosition )
      {
         // ポジションを保持していれば決済する
         m_wrapper.CloseOrder( 0, Slippage );
      }

      m_wrapper.RefreshPositions();
      
      // 注文する
      m_wrapper.SendOrder( orderCmd, Lot, 0, Slippage, StopLoss, TakeProfit );
   }   
}
//+------------------------------------------------------------------+
見れば分かると思いますが、前回とほとんど同じですね。
前回との違いだけ説明していきます。

input int Period = 25;                    //移動平均の期間
input int Shift = 0;                      //移動平均線の表示を右シフトする本数
input ENUM_MA_METHOD Method = MODE_SMA;   //移動平均線の種類
移動平均線の条件を入力パラメータとして宣言しています。
これらの条件は「Custom Moving Averages」インジケータのパラメータです。
基本的にインジケータのパラメータはEAの入力パラメータとしておくとよいです。

const string IndicatorName = "Custom Moving Averages";
使用するインジケータの名前です。
[Indicators]フォルダに格納されている名前どおりに指定します。この場合は[Indicators]フォルダ直下にあるインジケータを使用しているので名前のみですが、子フォルダの下にあるインジケータの場合はフォルダ階層も含めて指定します。
例えば、このインジケータが[Indicators]フォルダの下の[Custom]フォルダに格納されている場合は、"Custom/Custom Moving Averages"のように指定します。

   // 1つ前と2つ前の移動平均の値を取得する
   double ma1 = iCustom(symbol, target, IndicatorName, Period, Shift, Method, 0, 1 );
   double ma2 = iCustom(symbol, target, IndicatorName, Period, Shift, Method, 0, 2 );
ここでカスタムインジケータの値を取得しています。
前回のiMA()関数ではなく、カスタムインジケータの値を取得するiCustom()関数を使用しています。
iCustom()関数の引数は以下の通りです。
・string symbol
  通過ペア名。
・int timeframe
  時間軸。時間軸は、以下のように定義されています。
  ENUM_TIMEFRAMES列挙型
・string name
  使用するインジケータの名前。
・(インジケータのパラメータ)
  インジケータのパラメータ。(数は可変)
  パラメータの数だけ、順番に指定します。
・int mode
  インジケータの中の取得したいライン(バッファ)の番号。(0~)
  インジケータによっては、1つのインジケータの中に複数のラインを表示するものがあります。
  その中のどのラインの値を取得するかを、0から始まるライン番号で指定します。
・int shift
  インジケータの値を取得する足の位置。(0~)

引数の中のインジケータのパラメータは、インジケータをチャートに表示した時の[パラメーターの入力]タブの通りの内容と順番になります。
・図021.01 インジケータ パラメーターの入力
また、コードでインジケータのパラメータを確認したい場合、ナビゲーターの[インディケータ]の中のインジケータを右クリックし、[修正]をクリックします。
・図021.02 インジケータのコード表示
メタエディターにてインジケータのコードが表示されますので、入力パラメータの宣言を確認できます。
・図021.03 インジケータのコード確認

後ろから2番目のmode引数のインジケータのライン番号は、インジケータをチャートに表示した時の[色の設定]タブで確認できます。
ラインの一覧が表示されますので、一番左の#の列がラインの番号になります。
・図021.04 インジケータ 色の設定
コードでインジケータのラインを確認したい場合は、パラメータの場合と同様にメタエディターでインジケータのコードを開きます。
SetIndexBuffer()関数でライン番号とラインの元になるデータを指定していますので、こちらで確認することができます。

このように、iCustom()関数を使用することによって、独自のインジケータの値を取得することができます。

ここまでで、簡単にですが一通りEAを作成することが出来るようになったかと思います。これらを参考に、ぜひ自作のEAを作ってみてください。
本ブログでも公開している無料インジケータもありますので、よければそちらなども使用して試してみてください。


「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。

2016年5月10日火曜日

[MT4インジケータ]フラクタルバンドを販売開始しました。アルゴリズム紹介

MT4の標準にフラクタルというインジケータがあります。これは5本の頂点位置を算出するものです。考え方としては単純ですが、反発位置ということで、そこに抵抗があると判断してトレンドラインや抵抗線支持線を描画するのに使用されています。

これをフィルタなどを利用して精度を高めたうえで、何かしらのルールでバンドを描けないか?と考えたのが第一のスタートでした。

■EURUSD1H フラクタルバンド


まず、フラクタルですが、MT4標準のフラクタルを使ってみると描画される矢印が多すぎます。どれを採用すればよいのかさっぱりわかりません。
そこで、算出方法の変更とフィルタを追加してみました。算出方法の変更について図にて解説します。

■MT4標準のフラクタル描画位置


■カスタム版フラクタル描画位置

■フィルタ
また、フラクタルを描画する際、二つのフィルタを搭載しています。
1.Tick値によるフィルタ
デフォルトの設定では次のようになっています。過去48本のTick値平均に対して、Fractals対象のバーが50%以上のTick数を保持していること。

2.ATFによるフィルタ
頂点位置から、以降2本の高値安値のレンジが、100期間ATR未満の場合は無視します。
ATRは2本の足における高値安値の幅ですので3本分と比較すると十分これを超えてくるはずです。


■バンドの描画
上記のフィルタ付きフラクタルから、さらに価格帯バンドを表示しています。
デフォルトの設定では、次のようになっています。上限バンドの例を示します。

過去10個の上矢印を価格順にソートします。高い値から9個目と8個目の値を採用します。最高値は異常値として無視しています。
9個目と8個目の値が近すぎる場合は、7個目の値を採用します。

フラクタルは価格の反発位置を抽出します。反発位置というのは、そこの価格で何かしらの抵抗を
受けたということになります。その抵抗位置をバンドとして描画しました。


■フラクタルバンド設定

・このPips以下の差分は・・・・
 バンドを描画する際の値が近すぎると判断するPips数です。また、この値を大きくするとバンド幅が広がります。

・trueの場合Close値を対象とする。
 trueのフラクタルの計算をClose値にて行います。falseの場合は高値安値から計算します。

・Tick値平均期間
 Tick値フィルタにおけるTick値を平均する期間です。

・Tick値とTick値を比較する際に・・・・
 Tick値と比較する場合に、Tick値平均に欠けるレートです。本値を0にするとTick値フィルタが無効化します。

・ATRフィルタにおけるATR期間
 ATRフィルタ比較元となるATR期間です。

・ATRフィルタ倍率
 ATRと比較する際に、ATR側に欠ける倍率です。
 本値を0にすると、ATRフィルタが無効化します。

・計算対象矢印数
 バンドを計算する際に、ソート対象となる矢印数です。

・上矢印タイプ/下矢印タイプ
 フラクタルを描画する際の矢印タイプです。特に変更は不要です。


最初はブログネタにと思ったのですが、結構手間がかかったのと、Gewinn7に組み込んでみたらPFの改善が見られたため、効果ありそうということで980円にて販売いたします。認証は入っていません。値上げの予定も特にありませんが、要望等が発生してアップデートがかかる場合には値上げを検討いたします。

頂点位置からレンジ帯を表示する
フラクタルバンド


「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。

[MQL超入門] その022 バックテストを活用しよう。その1 レポートの見方

EAを作ったら、どんどんバックテストして確認していきましょう。
バックテスト結果の詳細はストラテジーテスターの[レポート]タブで確認できるので、この見方を理解して、望ましい結果を得れるようなEAを作っていきましょう。

・図022.01 ストラテジーテスター レポート
それぞれの項目の意味を、一通り説明します。

・テストバー数
  バックテストで使用したバー(足)の数
・モデルティック数
  バックテストで使用したティック数。
・モデリング品質
  バックテストで使用したティックの割合。
・不整合チャートエラー
  エラーのあったバーの数。
・初期証拠金
  用意する初期資金。
・スプレッド
  バックテストに適用するスプレッド(0.1pips単位)。

ここまではあまり重要ではありません。ここから下が、EAの成績として確認すべき内容です。
その中で、特に重要な項目を赤色にしてあります。

・純益
  総利益 - 総損失。
  トータルの利益です。
・総利益
  勝ちトレードの合計金額。
・総損失
  負けトレードの合計金額。
・プロフィットファクタ
  総利益 ÷ 総損失。
・期待利得
  総損益 ÷ 総取引数。
  取引1回あたりどれくらいの利益が期待できるかということになります。
・絶対ドローダウン
  初期資金がいくら減ったか。
・最大ドローダウン
  テスト期間において最大の損失額。
・相対ドローダウン
  資金が最大何パーセント減ったか。
・総取引数
  テスト期間において取引した回数。
・売りポジション(勝率%)
  売りトレードの回数と勝率。
・買いポジション(勝率%)
  買いトレードの回数と勝率。
・勝率(%)
  全トレードに対する勝ちトレードの割合。
・負率(%)
  全トレードに対する負けトレードの割合。
・最大勝トレード
  1回のトレードで勝った最大額。
・最大敗トレード
  1回のトレードで負けた最大額。
・平均勝トレード
  勝ちトレードで勝った金額の平均。
・平均敗トレード
  負けトレードで負けた金額の平均。
・最大連勝(金額)
  連勝の最大回数と、その時の利益。
・最大連敗(金額)
  連敗の最大回数と、その時の損失。
・最大連勝(トレード数)
  連勝の最大利益と、その時の連勝数。
・最大連敗(トレード数)
  連敗の最大損失と、その時の連敗数。
・平均連勝
  連勝回数の平均。
・平均連敗
  連敗回数の平均。

赤色で書いた、特に重要な項目について少し補足します。

■純益
このEAがどれだけ利益を出すのかになるので、まず確認すべき項目です。もちろん多いほうが良いです。
バックテストでプラスにならないEAが使われることはまずないと思います。

■プロフィットファクタ
リスクに対してリターンがどれだけ大きいかを表します。1未満だと損失が出ていて、1より大きいと利益が出ていることになります。
これも大きいほうが良いのですが、バックテストでのプロフィットファクタは大きすぎると逆に注意が必要です。なぜなら、プロフィットファクタが大きすぎることは、カーブフィッティングが疑われるからです。
カーブフィッティングとは、バックテスト期間の相場にぴったり合うように、パラメータ等を過剰に最適化することです。過去の相場はあくまで過去のものなので、未来の相場には当てはまらず役に立たない、逆にマイナスになる、という場合も多々あります。
それを理解して、あくまで参考程度に留めましょう。一般的に1.5~2.0くらいが優秀と言われます。

■最大ドローダウン
連敗も含めて、実際に連続で失った金額で、最も負けた時の負け幅です。
これだけのリスクは覚悟する必要があるという意味になるので、これらを元に用意すべき資金などを判断するのに使用します。

■総取引数
これ自体は成績には直接関係ありませんが、この数字が小さいと各指標の信頼性が下がります。
なので最低でも100以上が望ましいです。

■勝率 / 平均勝トレード / 平均敗トレード
勝率だけではあまり重要ではありません。
勝率の数字は1回の勝ち/負けの金額に関わらないので、例えば9回負けて1回勝っても(勝率10%でも)その1回でトータルがプラスになることもありますし、その逆の勝率90%でも1回の負けでトータルがマイナスになることもあるためです。
これはEAの特徴によりますのでどちらが良いというものではありませんが、このように勝率に加えて、平均の勝ち/負け額とのバランスで判断することが重要になります。


また、レポートは保存することができます。
[レポート]タブの中で右クリックし、[レポートの保存(S)]をクリックすると、保存先を指定して任意の場所に保存できます。
・図022.02 レポートの保存
レポートはグラフの画像と共にHTML形式で保存されるので、後から見るのにも便利です。
・図022.03 保存されたレポート


「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。

2016年5月9日月曜日

[MQL超入門] その020 本格的にEAを作ってみよう。その1 テクニカル指標を使用する

いよいよテクニカル指標を使って本格的にEAを作ってみましょう。
本格的に、と言ってもまずはシンプルに、移動平均線に対して終値が上抜ければ買い、下抜ければ売る、という戦略にします。1ポジションのみで両建てなし、いわゆるドテン注文です。
とりあえず時間軸を1時間、25本での単純移動平均として作りましょう。

始めに断っておきますが、この戦略が有効だという意味では全くありません。
あくまでテクニカル指標を使ったEAを作る例としているだけです。

それでは前に作った簡単EAと同様に、[テスト]フォルダの下に[EA_MA]という名前のEAを新たに作成しましょう。

新しいEAの作成方法はこちら
[MQL超入門] その014 とりあえずやってみよう!簡単EA作成1

そして、次の変更を加えます。
//+------------------------------------------------------------------+
//|                                                        EA_MA.mq4 |
//|                        Copyright 2016, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

#include <Custom/TradingWrapper.mqh>

input int MagicNumber = 37858261; //マジックナンバー 他のEAと当らない値を使用する。
input int MaxPosition = 1;        //最大ポジション数
input double SpreadFilter = 2;    //最大スプレット値(PIPS)

input double Lot = 0.02;          //売買ロット
input uint Slippage = 2;          //許容スリップページ(pips)
input uint StopLoss = 200;        //ストップロス
input uint TakeProfit = 200;      //利益確定

input int MaPeriod = 25;                              //移動平均の期間
input ENUM_MA_METHOD MaMethod = MODE_SMA;             //移動平均線の種類
input ENUM_APPLIED_PRICE AppliedPrice = PRICE_CLOSE;  //移動平均を計算する価格の種類

// トレード補助クラス
CTradingWrapper m_wrapper(Symbol(), MagicNumber, MaxPosition, SpreadFilter);

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
//---
   
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
   
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
//---
   string symbol = Symbol();
   static ENUM_TIMEFRAMES target = PERIOD_H1;
   static datetime before = 0;

   // 1時間の確定足でのみ動作
   datetime current = iTime(symbol, target, 0);
   if( before == current )
   {
      return ;
   }
   before = current;

   m_wrapper.RefreshPositions();

   // 1つ前と2つ前の足の終値を取得する
   double close1 = iClose( symbol, target, 1 );
   double close2 = iClose( symbol, target, 2 );
   
   // 1つ前と2つ前の移動平均の値を取得する
   double ma1 = iMA( symbol, target, MaPeriod, 0, MaMethod, AppliedPrice, 1 );
   double ma2 = iMA( symbol, target, MaPeriod, 0, MaMethod, AppliedPrice, 2 );
   
   int orderCmd = OP_NONE;
   if ( close1 > ma1 && close2 < ma2 )
   {
      // 終値が移動平均線を上抜けたら買う
      orderCmd = OP_BUY;
   }
   else if ( close1 < ma1 && close2 > ma2 )
   {
      // 終値が移動平均線を下抜けたら売る
      orderCmd = OP_SELL;
   }
   
   if ( orderCmd != OP_NONE )
   {
      bool hasPosition = ( m_wrapper.GetPositionCount() > 0 );
      if ( hasPosition )
      {
         // ポジションを保持していれば決済する
         m_wrapper.CloseOrder( 0, Slippage );
      }

      m_wrapper.RefreshPositions();
      
      // 注文する
      m_wrapper.SendOrder( orderCmd, Lot, 0, Slippage, StopLoss, TakeProfit );
   }   
}
//+------------------------------------------------------------------+
今までの説明で、内容も大体理解できるのではないかと思いますが、前の説明と重複する部分を除いて説明していきます。

input int MaPeriod = 25;                              //移動平均の期間
input ENUM_MA_METHOD MaMethod = MODE_SMA;             //移動平均線の種類
input ENUM_APPLIED_PRICE AppliedPrice = PRICE_CLOSE;  //移動平均を計算する価格の種類
使用する移動平均線の条件です。入力パラメータとして宣言しています。

   // 1つ前と2つ前の足の終値を取得する
   double close1 = iClose( symbol, target, 1 );
   double close2 = iClose( symbol, target, 2 );
ここでまず終値を取得しています。
標準で用意されている、終値を取得するiClose()関数を使用しています。
iClose()関数の引数は以下のとおりです。
・string symbol
  終値を取得する通過ペア名。
・int timeframe
  終値を取得する時間軸。時間軸は、以下のように定義されています。
  ENUM_TIMEFRAMES列挙型
・int shift
  終値を取得する足の位置。(0~)

最後の引数は0から始まる足の位置を指定しますが、数字が小さいほど新しい足を表すため0が最新の足になります。
ここで最新の足とは、現在形成中の足のことですので、取得される値が変わる事があります。
既に確定済みの値を使用したい場合、1が確定済みの最新の足ということになります。
このコードでは1つ前と2つ前なので、確定済みの最新2本の終値を取得しています。

なお、チャートの価格を取得する関数は、iClose()の他にもiOpen()、iHigh()、iLow()があります。
名前から分かると思いますが、それぞれ始値、高値、安値を取得する関数です。使い方はiClose()と変わりません。

   // 1つ前と2つ前の移動平均の値を取得する
   double ma1 = iMA( symbol, target, MaPeriod, 0, MaMethod, AppliedPrice, 1 );
   double ma2 = iMA( symbol, target, MaPeriod, 0, MaMethod, AppliedPrice, 2 );
ここでは移動平均の値を取得しています。
標準で用意されている、移動平均を計算するiMA()関数を使用しています。
iMA()関数の引数は以下のとおりです。
・string symbol
  移動平均を計算する通過ペア名。
・int timeframe
  移動平均を計算する時間軸。時間軸は、以下のように定義されています。
  ENUM_TIMEFRAMES列挙型
・int period
  移動平均の期間。
・int ma_shift
  移動平均線をシフトする本数。
・ENUM_MA_METHOD ma_method
  移動平均線の種類。種類は、以下のように定義されています。
  ENUM_MA_METHOD列挙型
・ENUM_APPLIED_PRICE applied_price
  移動平均を計算する価格の種類。種類は、以下のように定義されています。
  ENUM_APPLIED_PRICE列挙型
・int shift
  移動平均の値を取得する足の位置。(0~)

終値と同じように1つ前と2つ前の位置の移動平均を取得しています。
また引数として渡す条件が、入力パラメータとなっています。

なお、標準で用意されているテクニカル指標を取得する関数も、iMA()の他にもたくさん存在します。以下を参考にしてください。
テクニカル指標関数

   int orderCmd = OP_NONE;
   if ( close1 > ma1 && close2 < ma2 )
   {
      // 終値が移動平均線を上抜けたら買う
      orderCmd = OP_BUY;
   }
   else if ( close1 < ma1 && close2 > ma2 )
   {
      // 終値が移動平均線を下抜けたら売る
      orderCmd = OP_SELL;
   }
ここはコメントにも書いてあるので分かると思いますが、上抜けた場合と下抜けた場合に、それぞれの注文の方向を決めています。
close1とclose2が1つ前と2つ前の終値、ma1とma2が1つ前と2つ前の移動平均線の値なので、直近のclose1がma1を超えていて、その前のclose2がma2未満の場合、上抜けたと判断しています。
下抜けはその反対ですね。

後はorderCmdに代入された注文種別によって取引を行っています。この辺は簡単EAとほとんど変わりませんので分かるかと思います。

コンパイルが通ったら、バックテストをしてみましょう。

赤い線が移動平均線で、上抜けと下抜けで売買していることが確認できます。
成績は見てもらえば分かるので載せませんが、まぁずいぶん負けてますw

こんな単純な戦略だけで勝てたら誰も苦労しないという話ですよね。実際は独自の複雑なインジケータなども組み合わせながら戦略を立てるかと思います。
なので次は、独自のインジケータを使ったEAを作ってみたいと思います。


「MT4でFXを勝ち抜く研究をするブログ」で公開している無料インジケータは、こちらの一覧から。
インジケータ一覧

Twitterもよろしくお願いします。
https://twitter.com/mt4program

ブログランキングにご協力よろしくお願いします。m(._.)m
にほんブログ村 為替ブログ MetaTraderへ
にほんブログ村

お約束ですが、本ブログは、投資に対する利益を約束する物ではありません。最終的には自己責任によるご判断よろしくお願いいたします。