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

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

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

前回のマイナス収支MACDのソースの何処に手を加えたら利益がUPしたかも記載しています。

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

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

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

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

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

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

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

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

ソースコード

修正箇所をわかりやすくするため、前回のソースに以下のソースコメント仕様でソース変更を加えています。

  • ■■■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("エラー");
         }
      }
      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レポート結果

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

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

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

(おまけ)さらに改善

上記の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で、これだけの成績が出るとは思っていませんでした。今回もちょこっと修正するだけで割と利益が改善したのでまだまだ上がりそうな気はします。

ただ、私の場合国内業者のFXTFで利用する前提なのでスプレッドを0.2銭でバックテストしています。海外業者向けに1.5銭とかで確認するとマイナス圏になってしまうかもしれないですね。ただ、まだまだここからEAの精度を上げれる可能性は十分にあると思います。



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

コメント

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