EAでMACDを使う(サンプルソース)

EA
スポンサーリンク

FXで売買タイミングとして使うMACDの、簡単なMT4のEAサンプルです。

MT4に既存で付属しているものではなく自作です。利益等全く気にせず作ったため、バックテストをしたら凄いマイナスになっていますがMACD自体は使えています。
(※後日別記事でプラス収支版もあげました

今回、以下の記事では順張り目線でエントリーしていくサンプルを載せています。MACDをEAに取り入れる際のご参考になればと思います!

主な構文

iCustom()

【使用例】
iCustom(NULL,0,"MACD",12,26,9,0,1);

引数は以下の通りです。

  1. 通貨ペア(NULLで当該通貨)
  2. 時間軸(0で当該時間軸)
  3. インジケータ名称(MACDを使う場合”MACD”でOKです)
  4. 短期EMA期間
  5. 長期EMA期間
  6. シグナルライン期間
  7. 取得する値(0:MACD値 1:Signal値)
  8. バーシフト

iMACD()関数は使わずに、iCustom()関数でMACDの値を取得しています。
※iMACD()関数と基本的に全く同じ値が返ってきますので、以下のようにiMACD()関数に書き換えてもらっても結果は同じです

【使用例】
iCustom(NULL,0,"MACD",12,26,9,0,n); //MACD値
↓
iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,n); //MACD値

iCustom(NULL,0,"MACD",12,26,9,1,n); //Signal値
↓
iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,n); //Signal値

ソースコード


//+------------------------------------------------------------------+
//|                                                  MACD_Sample.mq4 |
//|                                    Copyright 2020, mef Software. |
//|                                             https://fx-prog.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, mef Software."
#property link      "https://fx-prog.com/"
#property version   "1.00"
#property strict
  
input int FAST_EMA_PERIOD = 12;
input int SLOW_EMA_PERIOD = 26;
input int SIGNAL_SMA_PERIOD = 9;
input double Lots = 1;
  
datetime prevtime;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---
            
//---
   return(INIT_SUCCEEDED);
  }
         
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
int start()
{
int orderPtn=0; //0:何もしない 1:買い 2:売り
int total=0;
         
int errorcode;               // エラーコード
int ea_ticket_No,ea_order_entry_Type=0,ea_order_MagicNo;  // チケットNo,エントリタイプ,マジックNo.
double ea_order_stop_price=0,ea_order_good_price=0,ea_order_entry_price=0; //ストップロスレート,利確レート,エントリーレート
         
//---
   //新しい足ができた時だけやる
   if(Time[0] != prevtime){
      prevtime = Time[0];
   }else{
      return(0);
   }
         
//***売買判断箇所***//
   //MACD状態取得関数から状態を取得
   if(getMACDSign(3,1,0)==true)
   {
      orderPtn=1;
   }
   else if(getMACDSign(4,1,0)==true)
   {
      orderPtn=2;
   }
   else
   {
      orderPtn=0;
   }
//***売買判断箇所***//
         
//***エントリー箇所***//
   //エントリーカウント(既に建玉を保有していたらエントリーしない)
   total=OrdersTotal();
         
   if(total == 0 && orderPtn > 0)
   {
      if(orderPtn == 1)
      {
         ea_order_entry_price = Ask;               // 現在の買値でエントリー
         ea_order_entry_Type = OP_BUY;             //OP_BUY
         ea_order_stop_price = Ask - 200 * Point;  //損切りポイント(-20銭)
         ea_order_good_price = Ask + 200 * Point;  //利喰いポイント(+20銭)  
      }
      else if(orderPtn == 2)
      {
         ea_order_entry_price = Bid;               // 現在の売値でエントリー
         ea_order_entry_Type = OP_SELL;            //OP_SELL      
         ea_order_stop_price = Bid + 200 * Point;  //損切りポイント(-20銭)
         ea_order_good_price = Bid - 200 * Point;  //利喰いポイント(+20銭)  
      }
               
      ea_order_MagicNo=0000;  //マジックナンバーは0000固定とする
         
      ea_ticket_No = OrderSend(   // 新規エントリー注文
            NULL,                     // 通貨ペア
            ea_order_entry_Type,      // オーダータイプ[OP_BUY / OP_SELL]
            Lots,                     // ロット(0.01単位,FXTFは1=10Lot)
            ea_order_entry_price,     // オーダープライスレート
            20,                       // スリップ上限
            ea_order_stop_price,      // ストップレート
            ea_order_good_price,      // リミットレート
            "テストオーダー",             // オーダーコメント
            ea_order_MagicNo,         // マジックナンバー(識別用)
            0,                        // オーダーリミット時間
            clrRed                    // オーダーアイコンカラー
          );
                 
      if ( ea_ticket_No == -1)           // オーダーエラー
      {
         errorcode = GetLastError();      // エラーコード取得
         if( errorcode != ERR_NO_ERROR)   // エラー発生
         {
             printf("エラー");
         }
      }
      else {    // 注文約定
         Print("新規注文約定。 チケットNo=",ea_ticket_No);
      }
   }
         
         
   return(0);
}
//***エントリー箇所***//
         
//+------------------------------------------------------------------+
         
//+------------------------------------------------------------------+
//|【関数】MACDのクロスを探す                                              
//|                                                                  
//|【引数】 IN OUT  引数名             説明                            
//|        --------------------------------------------------------- 
//|       ○      aType              上下                             
//|                                      1:下から上へ                 
//|                                      2:上から下へ                 
//|                                      3:下から上へ(マイナス域の場合のみ)
//|                                      4:上から下へ(プラス域の場合のみ) 
//|                                                                  
//|       ○      limit              どこまで遡るか                      
//|       ○      i                  現在のBar位置                    
//|【戻値】True(クロス有り) or False(クロス無し)                             
//|                                                                  
//|【備考】なし                                                         
//+------------------------------------------------------------------+
bool getMACDSign(int type,int limit,int i)
{
   int n;
   bool sign = false;
   double MACD_1,Signal_1,MACD_2,Signal_2;
          
   limit = i + limit;
   i     = i + 1;
             
   //下から上へのクロス
   if(type==1){
      for(n=i;n<=limit;n++){
         MACD_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n);
         MACD_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n+1);         
         Signal_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n);      
         Signal_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n+1);      
                
         if(MACD_2 <= Signal_2 && MACD_1 > Signal_1)      
         {
            sign=true;
            break;
         }
      }
   }
   //上から下へのクロス
   else if(type==2){
      for(n=i;n<=limit;n++){
         MACD_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n);
         Signal_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n);      
         MACD_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n+1);
         Signal_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n+1);
                   
         if(MACD_2 >= Signal_2 && MACD_1 < Signal_1)
         {
            sign=true;
            break;
         }
      }
   }
          
   //下から上へのクロス
   if(type==3){
      for(n=i;n<=limit;n++){
         MACD_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n);
         MACD_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n+1);         
         Signal_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n);      
         Signal_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n+1);      
                
         if(MACD_2 <= Signal_2 && MACD_1 > Signal_1 && MACD_1 <= 0 )
         {
            sign=true;
            break;
         }
      }
   }
   //上から下へのクロス
   else if(type==4){
      for(n=i;n<=limit;n++){
         MACD_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n);
         Signal_1 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n);      
         MACD_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,0,n+1);
         Signal_2 = iCustom(NULL,0,"MACD",FAST_EMA_PERIOD,SLOW_EMA_PERIOD,SIGNAL_SMA_PERIOD,1,n+1);
                   
         if(MACD_2 >= Signal_2 && MACD_1 < Signal_1 && MACD_1 >= 0 )
         {
            sign=true;
            break;
         }
      }
   }
             
   return(sign);
}


エントリータイミング

MACDの値が0より下で、MACD値が下から上へゴールデンクロスした場合にロングエントリーし、 MACDの値が0より上で、MACD値が上から下へデッドクロスした場合にショートエントリーをするだけのものになります。

決済タイミング

損切、利確共に20pips固定です。
※トレード内容からもわかる通り、ここはもっと工夫したら良くなっていきそうです

その他の仕様

設定値は以下の通りです。

  1. FAST_EMA_PERIOD = 12 ⇒ 短期EMA期間です
  2. SLOW_EMA_PERIOD = 26 ⇒ 長期EMA期間です
  3. SIGNAL_SMA_PERIOD = 9 ⇒ シグナル値です
  4. Lots = 1 ⇒ ロット数です(0.01=1000通貨)

既に建玉がある場合は追加でエントリーはしません。

新しい足(バー)が出来た際に1度だけ処理を行います。※1時間足の場合だと1時間に1回処理する

getMACDSign() ※自作関数

getMACDSign()関数を作ってそこで判断するようにしています。この関数だけコピペしてもらえばMACDのクロス判断はできるようになります。

やっていることは簡単で、iCustom()関数でMACDの値及びSignalの値を取得し、大小を比較しています。

デッドクロス後の例ですが、クロス後は必ずSignal値(赤の線)よりMACD値(水色の線)の方が小さくなるので、Signal値よりもMACD値の方が小さい場合はクロスしたと判定しています。

引数についてはサンプルソースに記載の通り3つです。戻り値は、クロスしていたらTrue、クロスしていなければFalseです。

MACDの0ラインに関わらずエントリーしたい場合(引数1)

サンプルソースでは、MACDの0ラインより上でゴールデンクロスした場合、ロングエントリーしません。逆(ショート時)もしかりです。

もし0ラインに関わらずエントリーしたい場合、サンプルソースのgetMACDSign(3,1,0)をgetMACDSign(1,1,0)にすると、MACDの値が0より下かどうかに関係なく下から上へクロスした場合にロングエントリーするようになり、getMACDSign(4,1,0)をgetMACDSign(2,1,0)にすると、MACDの値が0より上かどうかに関係なく上から下へクロスした場合にショートエントリーするようになります。

クロス状態を維持したい場合(引数2)

ゴールデン(デッド)クロス後、しばらくクロスしたという状態を返したい場合は、getMACDSign(3,1,0)をgetMACDSign(3,5,0)のようにすれば、クロスした後も5つバーまではクロスしたという(trueが返ってくる)状態になります。

これは、主にMACD以外のエントリータイミングも併用する場合に使えます。例えば、ゴールデンクロス後、RSIの値が落ち着いたらエントリーする等です。

バーシフトの役割(引数3)

クロスしたと判断するタイミングを1つ後ろにずらしたい場合、getMACDSign(3,1,0)をgetMACDSign(3,2,1)にすることでずらすことが可能です。
※基本的な関数にも常備されているバーシフトと同じ役割です

EAレポート結果

※サンプルEAの作り上、始値のみの確認となっています

2005年~2020年の期間の1時間足でバックテスト確認してみました。 やはり、MACDを単純に取り入れるだけでは上手くいきませんね。というか、MACDをうまく生かせていない気が・・・。

※2020/2/17追記 プラス収支になるよう、このソースに少し修正してプラス収支版のMACD-EAを作ってみました。詳細は以下のページで!

 

※ EAのサンプルソースを一覧表にまとめました


※ オススメ記事(EAが使える国内FX業者の一覧)


※ 1からEAの作り方を学びたい人はこちら

コメント

タイトルとURLをコピーしました