見出し画像

(MQL4)グリッドトレードのコードを書いてみるよ(準備編後半/コードあり)


コーディングしてみるよ!

 前回の設定値を使って、グリッドトレードのキモとなるエントリーロジックを中心に書いていきます。というか、「そこしかない」感じです。
 作成にあたっては、MT4にプリインストールされているMACD sample.mq4を基にします。めちゃ便利ですね。

 先に全体のコードです。

実際のコードはこちら

//+------------------------------------------------------------------+
//|                                           GRID_TRADE_2024_1 .mq4 |
//|                                                                  |
//| MACDのEAから派生している		  								 |
//|                                                                  |
//+------------------------------------------------------------------+
#property strict
#property copyright   "MAME_Tak Hg"
#property link        ""
#property version "1.0"

string ea_comment = "GRID_TRADE_2024"; // 取引欄に記載されるコメント
int MAGIC_NO = 2024021611; // マジックナンバー

double sellupperprice = 1.3825; // SELL側上限レート
double selllowerprice = 1.3581; // 同下限レート
double buyupperprice = 1.3497; // BUY側上限レート
double buylowerprice = 1.3255; // 同下限レート

double trappoints = 250; // グリッド幅(1point=0.1pip)
double takeprofit = 200; // 利確幅(1point=0.1pip)

double Stoploss = 3000; // ストップロス幅(1point=0.1pip)

double Lots          =0.1;  //取引ロット

double FirstBuyPrice;
double FirstSellPrice;

//+------------------------------------------------------------------+
void OnTick(void){
   int cnt; 	// forループ用カウンタ変数
   int ticket; 	// チケットNo.
   int total;	// オーダー済注文数

   total = OrdersTotal();
   
   // エントリーがまだないとき
   if ( total < 1 ){

      if ( Ask < buyupperprice && Ask > buylowerprice ){
        
         ticket = OrderSend( _Symbol,OP_BUY,Lots,Ask,5,Stoploss,Ask+takeprofit*_Point,ea_comment,MAGIC_NO,0,clrBlue);
         if(ticket>0){
           
            FirstBuyPrice = Ask; 
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("BUY order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening BUY order : ",GetLastError());
         return;
        }
      if ( Bid < sellupperprice && Bid > selllowerprice ){
        
         ticket = OrderSend( _Symbol,OP_SELL,Lots,Bid,5,Stoploss,Bid-takeprofit*_Point,ea_comment,MAGIC_NO,0,clrRed);
         if(ticket>0){
           
            FirstSellPrice = Bid;
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("SELL order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening SELL order : ",GetLastError());
         return;
         }
      }
   
   // エントリーがある場合

   for ( cnt=0; cnt < total; cnt ++ ){
     
      if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))
         continue;
         
      if(OrderType()<=OP_SELL && OrderSymbol()==_Symbol){
      
         if(OrderType()==OP_BUY){
         
            if(Ask < FirstBuyPrice-trappoints*total*_Point)
              {
               ticket = OrderSend( _Symbol,OP_BUY,Lots,Ask,5,Stoploss,Ask+takeprofit*_Point,ea_comment,MAGIC_NO,0,clrBlue);
               if(ticket > 1)
                 {
                  if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                     Print("BUY order opened :",OrderOpenPrice());
                  else Print("Error opening BUY order :",GetLastError());
                  return;
                 }
              }
           }

         if(OrderType()==OP_SELL)
           {
            if(Bid > FirstSellPrice+trappoints*total*_Point)
              {
               ticket = OrderSend(_Symbol,OP_SELL,Lots,Bid,5,Stoploss,Bid-takeprofit*_Point,ea_comment,MAGIC_NO,0,clrRed);
               if(ticket > 1)
                 {
                  if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
                     Print("SELL order opened :",OrderOpenPrice());
                  else Print("Error opening SELL order :",GetLastError());
                     return;
                 }
              }
           }
        }
     }
}

説明するよ!

 EAですので、OnTick関数の中がメインループです。
メインループの前に、グローバル変数として前回で設定した値をセットします。それぞれの意味についてはコメント欄を参照ください。

 メインループの中を見ていきます。
 『エントリーがまだないとき』『エントリーがすでにある時』とで分けて記載しています。エントリーの有無はOrdersTotal関数で確認しています。

 エントリーがまだないときは、
1. BUY側上限レートと下限レートの間に買い気配値があるかどうかを判定し、間にあればBUYオーダーを仕掛ける
2. Sell側上限レートと下限レートの間に売り気配値があればSELLオーダーを仕掛ける

 エントリーがすでにある場合は、
注文数分のループを回し、
1. BUYエントリーであればグリッド幅以上前回のエントリーレートから開いているか、かつエントリー可能範囲内かを確認してさらにBUYオーダーを仕掛ける。
2. SELLエントリーでも考え方は同じで、コードはその逆になります。

約束だぞ^^

設定について

【設定値】
 とりあえず、USD/CADの通貨ペアで設定してみました。
ご利用の通貨ペアによって各値は適宜変えてみてください。現在のレートをSELL、BUYどちらかのエリア内になるように設定することで、稼働させたときにエントリーして楽しい(?)です。

【ロット数】
 ロット数は初期値0.1としました。グリッドトレードはエントリーが積み上がりやすいため、できるだけ小さいほうがお勧めです。ちなみに私は1,000通貨単位から始めました。

【SELLエリアとBUYエリア】
 設定通りだと重なっていませんが、もし一部重ねて設定した場合、上記のコードでは想定外の動きをすることがあります。
 また、このままだとエリアを広く設定した場合やグリッド幅を小さく設定した場合に、延々とエントリーし続けることになります。
 これは今後改良していきます。

だからデモトレードでとあれほど

【マジックナンバー:MAGIC_NO】
 マジックナンバーは好きに変えて良いです。ただし今後、稼働→マジックナンバーを変えた/変えない→稼働とした場合で挙動が変わりますので
デモ口座で稼働させてみて違いを見ていただくのが良いかも。まあ慣れるまでは変更しないのが吉。

【スリッページ】
 最近のブローカーさんはスリップしないことが多いとのことですが、グリッドトレードをしてると結構気になります。コード中では5ポイント(0.5pips)で設定しています。これは次回、設定を変えられるようにしましょう。

今後の予定

 このコードを骨子として、改良を加えたり機能を追加していきたいと思います。
では~


この記事が気に入ったらサポートをしてみませんか?