EAでMACDを使う_利益UP版(サンプルソース)

EA-MACD結果1 EA
スポンサーリンク

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

概要

MACDのEAサンプルを前回作りましたが結構なマイナス収支になっていたので、ソースを少し修正して利益UP版のMACDのEAを作成しました。

※前回のマイナス収支版MACDのソースはこちら

今回はエントリーポイントは前回と全く同じMACDの値が0より下で、MACD値が下から上へゴールデンクロスした場合にロングエントリーし、 MACDの値が0より上で、MACD値が上から下へデッドクロスした場合にショートエントリーという感じです。

利確、損切りを新たに設けたサンプルを載せています。

修正①(明確な利確条件を設ける)

最初の修正は、明確な利確条件を設けます。サンプルソースでは、+20銭で利確していましたが、今回は以下の処理に変更します。

  • 買いエントリー中に、上から下にMACDがクロスしたら決済する
  • 売りエントリー中に、下から上にMACDがクロスしたら決済する

あと、決済後すぐにドテンで逆のエントリーはしない事とします。

修正②(明確な損切り条件を設ける)

2つ目の修正は、明確な損切り条件を設けます。サンプルソースでは、-20銭で損切りしていましたが、今回は以下の処理に変更します。

  • 買いエントリー時、直近24本(約1日)のバーで最安値付近を損切りとする
  • 売りエントリー時、直近24本(約1日)のバーで最高値付近を損切りとする

EAレポート結果

修正内容としては、特に難しい事はやらず基本的な所に手を加えていっただけですが、プラス収支にすることができました。

EAの作り込みとしては全然ですが、あっさりとプラス収支のEAが作れました。

 
やはり、MACDは偉大ですね!

ダウンロード

上記のEAファイルになります。

“MACD-EAその②” をダウンロード

7_MACD2.ex4 – 993 回のダウンロード – 9.81 KB

以下サンプルソースコードになります。
※丸々コピペでコンパイルできます

ソースコード

前回のマイナス収支MACDのソースの何処に手を加えたら利益がUPしたか、修正箇所をわかりやすくするため前回のソースに以下のソースコメント仕様でソース変更を加えています。

  • ■■■INSERT START■■■ → 新規コードの新規追加開始
  • ■■■INSERT END■■■ → 新規コードの新規追加開始
  • ■■■CHANGE START■■■ → 既存コードの変更開始
  • ■■■CHANGE END■■■ → 既存コードの変更終了
  • ■■■DELETE START■■■ → 既存コードの削除開始
  • ■■■DELETE END■■■ → 既存コードの削除終了
//+------------------------------------------------------------------+
//|                                                  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;
   }
//***売買判断箇所***//
         
//■■■INSERT START■■■修正①
//***決済判断箇所***//
   total=OrdersTotal();
   if(total == 1){
      bool OrderKekka = OrderSelect(0,SELECT_BY_POS,MODE_TRADES);
      //買いエントリー中に、上から下にMACDがクロスしたら決済する
      if(OrderKekka == true && OrderType() == OP_BUY && getMACDSign(2,1,0)==true){
         OrderKekka = OrderClose(OrderTicket(),OrderLots(),Bid,10,Violet);           
      }
      //売りエントリー中に、下から上にMACDがクロスしたら決済する      
      else if(OrderKekka == true && OrderType() == OP_SELL &&getMACDSign(1,1,0)==true){
         OrderKekka = OrderClose(OrderTicket(),OrderLots(),Ask,10,Violet);           
      }
   }
//***決済判断箇所***//   
//■■■INSERT END■■■修正①
//***エントリー箇所***//
   //エントリーカウント(既に建玉を保有していたらエントリーしない)
   //■■■CHANGE START■■■修正①
   //total=OrdersTotal();
   //if(total == 0 && orderPtn > 0)
   else if(total == 0 && orderPtn > 0)   
   //■■■CHANGE END■■■修正①
   {
      if(orderPtn == 1)
      {
         ea_order_entry_price = Ask;               // 現在の買値でエントリー
         ea_order_entry_Type = OP_BUY;             //OP_BUY
         //■■■CHANGE START■■■修正②
         //ea_order_stop_price = Ask - 200 * Point;  //損切りポイント(-20銭)     
         int index = iLowest(NULL,0,MODE_LOW,24,1);  //直近24本前の最安値のバーを探す
         ea_order_stop_price = iLow(NULL, 0, index) + 30 * Point;
         //■■■CHANGE END■■■修正②
         //■■■DELETE START■■■修正①
         //ea_order_good_price = Ask + 200 * Point;  //利喰いポイント(+20銭)     
         //■■■DELETE END■■■修正①         
      }
      else if(orderPtn == 2)
      {
         ea_order_entry_price = Bid;               // 現在の売値でエントリー
         ea_order_entry_Type = OP_SELL;            //OP_SELL
         //■■■CHANGE START■■■修正②
         //ea_order_stop_price = Bid + 200 * Point;  //損切りポイント(-20銭)
         int index = iHighest(NULL,0,MODE_HIGH,24,1);    //直近24本前の最高値のバーを探す
         ea_order_stop_price = iHigh(NULL, 0, index) - 30 * Point;
         //■■■CHANGE END■■■修正②
         //■■■DELETE START■■■修正①
         //ea_order_good_price = Bid - 200 * Point;  //利喰いポイント(+20銭)
         //■■■DELETE END■■■修正① 
      }
               
      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("エラー:"+ IntegerToString(errorcode));
         }
      }
      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);
}

(おまけ)さらに改善

上記のEAはドテンですぐに逆エントリーしないように作っていたのですが、よくよく考えてみるとMACDのゴールデン・デッドクロス判断なのでドテンするのも有効かなと思い、以下のようにドテンで逆エントリーするようコメント部を入れ替えました。

//エントリーカウント(既に建玉を保有していたらエントリーしない)
//■■■CHANGE START■■■修正①
total=OrdersTotal();
if(total == 0 && orderPtn > 0)
//else if(total == 0 && orderPtn > 0)    

結果、若干トレード成績が向上しました。

前回は-300万円だったのが、今回は+600万円まで行きました(約900万円近く変化)
※上記金額は10万通貨での取引です
 
時間足を1時間より下(15分足、5分足等)にするとマイナス収支になりました。
逆に、時間足を1時間より上(4時間足、日足、週足)にするとプラス収支になりました。
 

さいごに

以上、MACDを使ったEAのサンプルソース(利益UP版)でした。

正直、テクニカル分析のMACD検証用として簡単に作ったEAで、これだけの成績が出るとは思っていませんでした。今回もちょこっと修正するだけで割と利益が改善したのでまだまだ上がりそうな気はします。

こんな感じで、修正を加えると一気にプラスになったりするので焦らず色々試してみて下さい。

※ MT4・EAが使えるFX会社のおすすめ

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


コメント