MetaTrader 4 プログラム中級編

MetaTrader4 Proactiveへの対応




 今回は「MetaTrader4 Proactiveへの対応」について説明します。


 MetaTrader4 Proactiveが発表され、暫く時間がたちました。従来のMetaTrader4からMetaTrader4 Proactive対応の証券会社に変えたことで、「今までのEAが突然動かなくなった。」などのお便りが多数寄せられています。 どうしたらEAが動くのかというご質問に、今回は答えさせて頂こうと思います。


 サンプルプログラムはこちらです。


 http://jidoubaibai.com/Samples/Sample%20TPSL.mq4


 サンプルプログラムの使い方は、こちらで説明しています。 


 http://jidoubaibai.com/burogu11.html



 なぜ突然EAが動かなくなったのでしょうか。それはMetaTrader4 Proactiveの仕様に原因があります。 決してMetaTrader4 Proactiveの性能の問題ではなく、「ポジション取得時にリミットとストップを設定できない。」という仕様に引っかかっていたのです。


 MetaTrader4 Proactiveでは、ポジションを取得すると同時にリミットとストップを設定していると、エラーが発生し、注文がキャンセルされる仕様となっています。 以前のEAでは、ポジション取得と同時にリミットとストップの設定がされているものがほとんどです。その為にEAが突如ポジションを取得しなくなる現象が起っています。 つまりポジションを取得する時には、ストップとリミットを設定していてはいけません。


 動かなくなったほとんどのEAはリミットとストップロスを無くせば、また動くようになるでしょう。
ストップとリミットを設定する場合は、ポジションを取得した後に設定することになります。


 今回はMACDのゴールデンクロスで買い、デッドクロスで売るシステムのリミットとストップを後からつけるプログラムを紹介します。
決済はリミットとストップのみで行い、MACDの判定は以前こちらで紹介したオリジナル関数を使ってみましょう。


 では、MetaEditorを起動して下さい。


 NameはTPSLなどにして下さい。


 では、まとめてコードを書きますので、同じようにコードを半角英数で書いていってください。


int start()
{
   //変数の宣言
   int cnt, CurrentPosition;
   int Ticket;   

     
   // オーダーチェック(ポジションなどのデータ)
   CurrentPosition=-1;
   for(cnt=0;cnt < OrdersTotal();cnt++){
      OrderSelect(cnt,SELECT_BY_POS);
      if(OrderSymbol() == Symbol()) CurrentPosition=cnt;
   }




   // ポジションチェック ポジション無し
   if(CurrentPosition == -1)
   {   
      //もしメインがシグナルを下から上にクロスしたら
      if( CrossMACD(12,26,9) == 1 )      
      {
         //買いポジションを取る  
         Ticket = OrderSend(Symbol(), OP_BUY, 1, Ask, 3, 0, 0, "Buy", 0, 0, Red);
      }  
      
      //もしメインがシグナルを上から下にクロスしたら
      if( CrossMACD(12,26,9) == 2)     
      {
         //売りポジションを取る  
         Ticket = OrderSend(Symbol(), OP_SELL, 1, Bid, 3, 0, 0, "Sell", 0, 0, Blue);
      }  
         
           
   
   }
   // ポジション有り
   else 
   {
      
      //ポジションの選択
      OrderSelect(CurrentPosition,SELECT_BY_POS);
      
      //通貨ペアの確認
      if(Symbol() == OrderSymbol())
      {
         //もし買いポジションだったら
         if(OrderType()==OP_BUY)    
         {
            if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)
            {
            //ストップロス更新
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-(200*Point),
            OrderOpenPrice()+(200*Point), 0, MediumSeaGreen);
            }
         }
         //もし売りポジションだったら
         else if(OrderType()==OP_SELL)
         {
            if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)
            {
            //ストップロス更新
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()+(200*Point),
            OrderOpenPrice()-(200*Point), 0, MediumSeaGreen);
            }
         }
      }      
   
      
   }
   return(0);
}



/*------------------------------------------------------
関数名   CrossMACD
内容     MACDのゴールデンクロスとデッドクロスを判断する関数

引数     int fast    短期EMA
         int slow    長期EMA
         int signal  シグナル
         
戻り値   0:何も出来ていない 1:ゴールデンクロス
         2:デッドクロス
-------------------------------------------------------*/
int CrossMACD(int fast,int slow,int signal)
{
   double kakoa,gennzaia;
   double kakob,gennzaib;
     

   //一つ前のMACDのメイン
   kakoa = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_MAIN,1);
   //一つ前のMACDのシグナル
   kakob = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_SIGNAL,1);

   //現在のMACDのメイン
   gennzaia = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_MAIN,0);
   //現在のMACDのシグナル
   gennzaib = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_SIGNAL,0);


   //もしメインがシグナルを下から上にクロスしたら
   if( kakoa < kakob && gennzaia >= gennzaib)      
   {
      return(1);
   }  
   
   //もしメインがシグナルを上から下にクロスしたら
   if( kakoa > kakob && gennzaia <= gennzaib)     
   {
      return(2);
   }  


   return(0);
}

 書けましたか?


 今回は以前こちら で説明したオリジナル関数を使い、MACDのゴールデンクロスとデッドクロスでポジションをとり、 その後にポジションを持っていて、リミットとストップロスが設定されていない場合に、 リミットとストップロスを入れるプログラムになっています。


先ず下記のポジションを取るプログラムの説明です。

   // ポジションチェック ポジション無し
   if(CurrentPosition == -1)
   {   
      //もしメインがシグナルを下から上にクロスしたら
      if( CrossMACD(12,26,9) == 1 )      
      {
         //買いポジションを取る  
         Ticket = OrderSend(Symbol(), OP_BUY, 1, Ask, 3, 0, 0, "Buy", 0, 0, Red);
      }  
      
      //もしメインがシグナルを上から下にクロスしたら
      if( CrossMACD(12,26,9) == 2)     
      {
         //売りポジションを取る  
         Ticket = OrderSend(Symbol(), OP_SELL, 1, Bid, 3, 0, 0, "Sell", 0, 0, Blue);
      }   

 ここでは、ポジションを持っていないとき、関数内で計算された内容でMACDがゴールデンクロス、 またはデッドクロスと判定された時にポジションを取るようになっています。 普段と違うのは、ストップロスとリミットが0になっていることです。

次に、ポジションを持っている場合にリミットとストップロスが0の場合に新たに設定する為のプログラムです。


   // ポジション有り
   else 
   {
      
      //ポジションの選択
      OrderSelect(CurrentPosition,SELECT_BY_POS);
      
      //通貨ペアの確認
      if(Symbol() == OrderSymbol())
      {
         //もし買いポジションだったら
         if(OrderType()==OP_BUY)    
         {
            if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)
            {
            //ストップロス更新
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-(200*Point),
            OrderOpenPrice()+(200*Point), 0, MediumSeaGreen);
            }
         }
         //もし売りポジションだったら
         else if(OrderType()==OP_SELL)
         {
            if(OrderStopLoss() == NULL || OrderTakeProfit() == NULL)
            {
            //ストップロス更新
            OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()+(200*Point),
            OrderOpenPrice()-(200*Point), 0, MediumSeaGreen);
            }
         }
      }      
   
      
   }
   return(0);
}

 今回初めて登場するのはOrderModify関数OrderOpenPrice関数OrderStopLoss関数OrderTakeProfit関数OrderTicket関数です。


 プログラムの内容は、ポジションを持っている時で尚且つストップロスかリミットに0が入っていた場合、 ストップロスとリミットの値を変更するという内容です。


OrderOpenPrice関数は、ポジションのオープンレートを調べる関数です。

OrderStopLoss関数は、ポジションのストップロス値を調べる関数です。

OrderTakeProfit関数は、ポジションのリミット値を調べる関数です。

OrderTicket関数は、ポジションのチケット番号を調べる関数です。


 OrderModify(OrderTicket(), OrderOpenPrice(), OrderOpenPrice()-(200*Point),
 OrderOpenPrice()+(200*Point), 0, MediumSeaGreen);

 上記がOrderModify関数です。
注文の内容を変更するのに使われる関数となっています。 サイズの関係上2行に分けて表記しましたが、皆さんは1行で書いても大丈夫です。


OrderModify関数(チケット番号, 指値, ストップロス値,リミット値, 有効期限, 表示される色)


個別に説明していきます。


チケット番号は変更する注文のチケット番号を選択します。

指値は指値を変更するときなどに使います。今回はオープンレートが入っています

ストップロス値はここに入力された数値をストップロスにします。

リミット値はここに入力された数値をリミットにします。

有効期限は指値などの未約定の注文の有効期限を指定します。

表示される色は色の設定です。


 今回はストップロスとリミットを変更しています。

 買いの場合、ストップロスに「OrderOpenPrice()-(200*Point)」、 リミットに「OrderOpenPrice()+(200*Point)」を入力していますので、ストップロスはオープンレートから200pips下で、 リミットはオープンレートから200pips上になるようにしています。


/*------------------------------------------------------
関数名   CrossMACD
内容     MACDのゴールデンクロスとデッドクロスを判断する関数

引数     int fast    短期EMA
         int slow    長期EMA
         int signal  シグナル
         
戻り値   0:何も出来ていない 1:ゴールデンクロス
         2:デッドクロス
-------------------------------------------------------*/
int CrossMACD(int fast,int slow,int signal)
{
   double kakoa,gennzaia;
   double kakob,gennzaib;
     

   //一つ前のMACDのメイン
   kakoa = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_MAIN,1);
   //一つ前のMACDのシグナル
   kakob = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_SIGNAL,1);

   //現在のMACDのメイン
   gennzaia = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_MAIN,0);
   //現在のMACDのシグナル
   gennzaib = iMACD(NULL,0,fast,slow,signal,PRICE_CLOSE,MODE_SIGNAL,0);


   //もしメインがシグナルを下から上にクロスしたら
   if( kakoa < kakob && gennzaia >= gennzaib)      
   {
      return(1);
   }  
   
   //もしメインがシグナルを上から下にクロスしたら
   if( kakoa > kakob && gennzaia <= gennzaib)     
   {
      return(2);
   }  


   return(0);
}


 上記の内容はMACDのオリジナル関数です。
ここでMACDのクロスの判定を行っています。
詳しくは、オリジナル関数の作り方で説明しています。


 余談ですが、MetaTrader4 Proactiveがリリースされた後にオーダーシステムでご注文頂いたシステムには、全て上記の対処がされていますので、正常に稼動します。


 今回はこれで終了です。OrderModify関数は出来ることがたくさんありますので、是非マスターしてください。  



---------------------------------------注意---------------------------------------

 内容には注意を払っていますが、保障は出来ません。
 実際に運用する場合は、自己責任でお願いします。

<< レートを取得する関数 | TOP | リミットとストップロスを計算で設定する >>

トップページ プロフィール ブログ リンク オーダーシステム 利用規約 問い合わせ