一目均衡表EAをご要望の内容に修正していく流れを解説(サンプルソース付)

記事内に商品プロモーションを含む場合があります
スポンサーリンク

今回は、MT4のEAサンプルソース(FX用)を公開します。

トレードに使うテクニカル分析は一目均衡表で、既存のEAを修正していく流れの記事になります。

はじめに

ブログのお問合せで以下のような内容を頂きました。

先日、3_Ichimoku.ex4についてダウンロードさせていただきましたが、以下の実現は可能でしょうか?
・三役好転/逆転の解消時に決済するように設定されておりますが、エントリーと同時に損切も設定
・三役好転/逆転時にエントリーされますがそのうちの二つ(転換線と遅行線の上抜け)だけでエントリー


もしよろしければご検討のほどよろしくお願いいたします。

一目均衡表は結構機能追加要望が来ます。これぐらいの改良であればすぐ出来るので記事を書きながら対応させて頂く事にしました。

ということで!

早速改良していきましょう!

今回のEAのベースソース

まずは、今回EAを作るためのベースソースはこちらとします。

こちらの機能は担保しつつ、追加要望に対応していきます。

損切り設定の追加

今回要望のあった以下をまずは対応していきます。
・三役好転/逆転の解消時に決済するように設定されておりますが、エントリーと同時に損切も設定

設定の追加

まずは、ソースコードの先頭部にこんな感じで損切り設定を追加します。

#property version   "1.00"
  
input int A_SPREAD = 20;
input double Lots = 0.01;
input int SL = 200;
        
datetime prevtime;

設定名称や初期値は適当でOKです。

損切り設定を反映させる処理を追加

次は追加した損切り設定を実際にEAに反映させるように処理を修正します。

【修正前】

   else if(total == 0 && orderPtn > 0)   
   {
      ea_order_stop_price = 0;
      ea_order_good_price = 0;         
        
      //新規注文
      OrderKekka = funcOrder_Send(orderPtn - 1,ea_order_stop_price,ea_order_good_price,0,0);
        
   }

【修正後】

   else if(total == 0 && orderPtn > 0)   
   {
      if(orderPtn == 1)
      {
         ea_order_stop_price = Ask - SL * Point;  //損切りポイント
         ea_order_good_price = 0;  //利喰いポイント
      }
      else if(orderPtn == 2)
      {
         ea_order_stop_price = Bid + SL * Point;  //損切りポイント
         ea_order_good_price = 0;  //利喰いポイント 
      }    
        
      //新規注文
      OrderKekka = funcOrder_Send(orderPtn - 1,ea_order_stop_price,ea_order_good_price,0,0);
        
   }  

すこし難しいですが、ロング時とショート時で損切りの計算方法が少し違うため、if文を使った修正になります。

スポンサーリンク

エントリー条件設定の追加

次に要望のあった以下を対応していきます。
・三役好転/逆転時にエントリーされますがそのうちの二つ(転換線と遅行線の上抜け)だけでエントリー

設定の追加

まずは、先ほどと同様ソースコードの先頭部にこんな感じでエントリー条件を変える設定を追加します。

#property version   "1.00"
  
input int A_SPREAD = 20;
input double Lots = 0.01;
input int SL = 200;
input bool Jyouken2 = false;
      
datetime prevtime;

設定名称や初期値は適当でOKです。Jyouken2 = true;で転換線と遅行線の上抜けでエントリー、Jyouken2 = false;で転換線と遅行線とローソク足の上抜けでエントリーという感じです。

設定を追加せずに転換線と遅行線の上抜けでエントリーという風に作り変えてしまってもいいですが、せっかくなので元の条件でもできるように改修します。

エントリー条件を変える処理を追加

次は追加したエントリー条件を変える設定を実際にEAに反映させるように処理を修正します。

【修正前】

//***売買判断箇所***//
   //△三役好転△
   if(Tenkansen > Kijunsen && SenkouSpanA < iClose(NULL,0,1) && SenkouSpanB < iClose(NULL,0,1) &&  ChikouSpan > iHigh(NULL,0,27)){
      orderPtn = 1;
   }
   //▼三役逆転▼
   else if(Tenkansen < Kijunsen && SenkouSpanA > iClose(NULL,0,1) && SenkouSpanB > iClose(NULL,0,1) &&  ChikouSpan < iLow(NULL,0,27)){ 
      orderPtn = 2;
   }else{
      orderPtn = 0;
   }

【修正後】

//***売買判断箇所***//

   if(Jyouken2 == false){
      //△三役好転△   
      if(Tenkansen > Kijunsen && SenkouSpanA < iClose(NULL,0,1) && SenkouSpanB < iClose(NULL,0,1) &&  ChikouSpan > iHigh(NULL,0,27)){
         orderPtn = 1;
      }
      //▼三役逆転▼
      else if(Tenkansen < Kijunsen && SenkouSpanA > iClose(NULL,0,1) && SenkouSpanB > iClose(NULL,0,1) &&  ChikouSpan < iLow(NULL,0,27)){ 
         orderPtn = 2;
      }else{
         orderPtn = 0;
      }
   }
   else{
      if(Tenkansen > Kijunsen && SenkouSpanA < iClose(NULL,0,1) && SenkouSpanB < iClose(NULL,0,1)){
         orderPtn = 1;
      }
      else if(Tenkansen < Kijunsen && SenkouSpanA > iClose(NULL,0,1) && SenkouSpanB > iClose(NULL,0,1)){ 
         orderPtn = 2;
      }else{
         orderPtn = 0;
      }
   } 

こちらもすこし難しいですが、エントリー条件の所をJyouken2 設定を見て、条件を2つにするか元の3つにするかのif文で修正しています。

ダウンロード

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

“一目均衡表-改良” をダウンロード 26_Ichimoku_kai.ex4 – 522 回のダウンロード – 15.22 KB
スポンサーリンク

ソースコード

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

//+------------------------------------------------------------------+
//|                                              26_Ichimoku_kai.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"
  
input int A_SPREAD = 20;
input double Lots = 0.01;
input int SL = 200;
input bool Jyouken2 = false;

datetime prevtime;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//---
            
//---
   return(INIT_SUCCEEDED);
  }
         
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
int start()
{
//---
int orderPtn=0; //0:何もしない 1:買い 2:売り
int total=0;
        
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);
   }
     
        
    //***一目均衡表の値取得***//
   double Tenkansen = iCustom(NULL,0,"Ichimoku",9,26,52,0,1);
   double Kijunsen = iCustom(NULL,0,"Ichimoku",9,26,52,1,1);
   double SenkouSpanA = iCustom(NULL,0,"Ichimoku",9,26,52,2,1);
   double SenkouSpanB = iCustom(NULL,0,"Ichimoku",9,26,52,3,1);
   double ChikouSpan = iCustom(NULL,0,"Ichimoku",9,26,52,4,27);
     
//***売買判断箇所***//

   if(Jyouken2 == false){
      //△三役好転△   
      if(Tenkansen > Kijunsen && SenkouSpanA < iClose(NULL,0,1) && SenkouSpanB < iClose(NULL,0,1) &&  ChikouSpan > iHigh(NULL,0,27)){
         orderPtn = 1;
      }
      //▼三役逆転▼
      else if(Tenkansen < Kijunsen && SenkouSpanA > iClose(NULL,0,1) && SenkouSpanB > iClose(NULL,0,1) &&  ChikouSpan < iLow(NULL,0,27)){ 
         orderPtn = 2;
      }else{
         orderPtn = 0;
      }
   }
   else{
      if(Tenkansen > Kijunsen && SenkouSpanA < iClose(NULL,0,1) && SenkouSpanB < iClose(NULL,0,1)){
         orderPtn = 1;
      }
      else if(Tenkansen < Kijunsen && SenkouSpanA > iClose(NULL,0,1) && SenkouSpanB > iClose(NULL,0,1)){ 
         orderPtn = 2;
      }else{
         orderPtn = 0;
      }
   }
        
//***決済判断箇所***//
   total=OrdersTotal();
   if(total == 1 ){
           
      bool OrderKekka = OrderSelect(0,SELECT_BY_POS,MODE_TRADES); 
      
      if(OrderType() == OP_BUY && (orderPtn == 0 || orderPtn == 2)){
         OrderKekka = funcOrder_Close();
      }
          
      if(OrderType() == OP_SELL && (orderPtn == 0 || orderPtn == 1)){
         OrderKekka = funcOrder_Close();
      }

   }
//***エントリー箇所***//
   else if(total == 0 && orderPtn > 0)   
   {
      if(orderPtn == 1)
      {
         ea_order_stop_price = Ask - SL * Point;  //損切りポイント
         ea_order_good_price = 0;  //利喰いポイント
      }
      else if(orderPtn == 2)
      {
         ea_order_stop_price = Bid + SL * Point;  //損切りポイント
         ea_order_good_price = 0;  //利喰いポイント 
      }    
        
      //新規注文
      OrderKekka = funcOrder_Send(orderPtn - 1,ea_order_stop_price,ea_order_good_price,0,0);
        
   }  
         
         
   return(0);
}
        
        
        
     
//+------------------------------------------------------------------+
//|【関数】新規注文関数
//|
//|【引数】 ea_order_entry_Type:売買(0:買 1:売)
//|【引数】 ea_order_stop_price:損切値  ea_order_good_price:利確値
//|【引数】 orderComment:オーダーコメント    ea_order_MagicNo:マジックNo
//|
//|【戻値】True:成功 False:失敗
//|
//|
bool funcOrder_Send(int ea_order_entry_Type, double ea_order_stop_price, double ea_order_good_price,string orderComment,int ea_order_MagicNo)
{
       
   int order_resend_num;        // エントリー試行回数
   int ea_ticket_res;           // チケットNo
   double ea_order_entry_price; // エントリーレート
   color order_Color;
   bool kekka;
       
   kekka=false;
         
   for( order_resend_num = 0; order_resend_num < 10; order_resend_num++ ) {    // エントリー試行回数上限:10回
       
      //スプレッドが1銭未満の場合のみ新規注文する(2銭未満にしたい場合は20にする)
      if(MarketInfo(NULL,MODE_SPREAD) < A_SPREAD){
       
         if(ea_order_entry_Type == OP_BUY){   
            ea_order_entry_price = Ask;               // 現在の買値でエントリー
            order_Color = clrBlue;
         }else if(ea_order_entry_Type == OP_SELL){        
            ea_order_entry_price = Bid;               // 現在の売値でエントリー
            order_Color = clrRed;            
         }
       
         ea_ticket_res = OrderSend(   // 新規エントリー注文
            NULL,                     // 通貨ペア
            ea_order_entry_Type,      // オーダータイプ[OP_BUY / OP_SELL]
            Lots,                      // ロット数
            ea_order_entry_price,     // オーダープライスレート
            20,                       // スリッページ
            ea_order_stop_price,      // ストップレート
            ea_order_good_price,      // リミットレート
            orderComment,             // オーダーコメント
            ea_order_MagicNo,         // マジックナンバー
            0,                        // オーダーリミット時間
            order_Color               // オーダーアイコンカラー
            );
                
         if ( ea_ticket_res == -1) { 
            Print("エントリー失敗 エラーNo=",GetLastError()," リトライ回数=",order_resend_num+1);
                   
            Sleep(5000);                                           // msec待ち
            RefreshRates();                                        // レート更新
          
         } else {    // 注文約定
            Print("新規注文約定。 レート:",ea_order_entry_price," チケットNo=",ea_ticket_res," オーダーマジックNo=",ea_order_MagicNo);
                   
            Sleep(500);                                           // 500msec待ち
            kekka=true;
            break;
         }
       
      }else{
          Print("スプレッド拡大中(銭)=",MarketInfo(NULL,MODE_SPREAD) / 10," リトライ回数=",order_resend_num+1);
                 
          Sleep(5000);                                           // msec待ち
          RefreshRates();                                        // レート更新
      }
       
   }
   return kekka;   
}
     
//+------------------------------------------------------------------+
//|【関数】決済関数
//|
//|【引数】 なし
//|
//|【戻値】True:成功 False:失敗
//|
//|
bool funcOrder_Close()
{
   bool kekka,OrderKekka;
   int total,order_resend_num;
   double ea_order_entry_price; // エントリーレート
   color order_Color;
          
   kekka=false;
       
   for(order_resend_num = 0; order_resend_num < 100; order_resend_num++ ) {
      if(MarketInfo(NULL,MODE_SPREAD) < A_SPREAD){
       
         total=OrdersTotal();
                
         if(total >0 && OrderSelect(0,SELECT_BY_POS,MODE_TRADES)==true){
       
            if(OrderType() == OP_BUY){   
               ea_order_entry_price = Bid;               // 現在の売値で決済
               order_Color = clrLightBlue;
            }else if(OrderType() == OP_SELL){
               ea_order_entry_price = Ask;               // 現在の買値で決済
               order_Color = clrLightPink;            
            }
       
            OrderKekka = OrderClose(OrderTicket(),OrderLots(),ea_order_entry_price,10,order_Color);
       
            if(OrderKekka==false){
               Print("決済失敗 エラーNo=",GetLastError()," リトライ回数=",order_resend_num+1);
                      
               RefreshRates();
               Sleep(1000);
            }else{
               Print("決済注文約定。 レート=",ea_order_entry_price);
                   
               kekka=true;
               break;
            }
         }
      }else{
          Print("スプレッド拡大中(銭)=",MarketInfo(NULL,MODE_SPREAD) / 10," リトライ回数=",order_resend_num+1);
                 
          Sleep(5000);                                           // msec待ち
          RefreshRates();                                        // レート更新
      }
   }
   return kekka;   
}

さいごに

以上、『一目均衡表のEAを改良する』でした。

今回は、過去に作った一目均衡表のEAを改良する感じでした。既存の動きも残しつつパラメータ設定を追加する事により新たな動きもするようにしています。

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

※オンラインレッスンやってます


コメント