multi lot scalper image

ここでは、Multi Lot ScalperというEAのコードを解読していきます。前回記事【Multi_Lot_Scalperの解読3】の続きからです。

前回記事【Multi_Lot_Scalperの解読3】へ

ダウンロード元はこちら↓
https://www.mql5.com/en/code/9330

Multi Lot Scalperのソースコード

EAのコードを解読(続き)

では、早速続きを見ていきましょう!

最新ポジション情報取得と合計損益額を算出

ここでまた、最新ポジション情報を取得しています。さらに各ポジションの獲得幅(ポイント)×ロット数の合計がProfitに格納されるようにしてPipValueを掛けて利益額にしています。

   Profit = 0;
   LastTicket = 0;
   LastType = 0;
   LastClosePrice = 0;
   LastLots = 0;
   
   for (cnt=0; cnt<OrdersTotal(); cnt++)
   {
      OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
      if(OrderSymbol() == Symbol())
      {
         LastTicket = OrderTicket();
         if(OrderType() == OP_BUY) LastType = OP_BUY;
         if(OrderType() == OP_SELL) LastType = OP_SELL;
         LastClosePrice = OrderClosePrice();
         LastLots = OrderLots();
         
         if(LastType == OP_BUY)
         {
            if(OrderClosePrice() < OrderOpenPrice())
               Profit = Profit - (OrderOpenPrice() - OrderClosePrice()) * OrderLots() / Point;
            if(OrderClosePrice() > OrderOpenPrice()) 
               Profit = Profit + (OrderClosePrice() - OrderOpenPrice()) * OrderLots() / Point;
         }
         
         if(LastType==OP_SELL)
         {
            if(OrderClosePrice() > OrderOpenPrice())
               Profit = Profit - (OrderClosePrice() - OrderOpenPrice()) * OrderLots() / Point;
            if(OrderClosePrice() &tl; OrderOpenPrice())
               Profit = Profit + (OrderOpenPrice() - OrderClosePrice()) * OrderLots() / Point;
         }
      }
   }
   Profit = Profit * PipValue;
   text2 = "Profit: $" + DoubleToStr(Profit, 2) + " +/-";

前々回の記事でも最新ポジションの情報取得を説明しましたが、ここでまとめて処理した方が効率がよいですね。あと、利益額はOrderProfit()で取得した方が楽です。他にも気になる点がありますが次に進みましょう。

AccountProtection機能

次にAccountProtection機能が書かれています。(分かりやすいように少し変形しています)

   if (AccountProtection == 1)
   {
      if(OpenOrders >= (MaxTrades - OrderstoProtect) && Profit >= SecureProfit) 
      {
         OrderClose(LastTicket, LastLots, LastClosePrice, slippage, Yellow);
         ContinueOpening = False;
         return(0);
      }
   }
AccountProtectionが1の場合、
   もし、合計ポジション数がMaxTrades - OrderstoProtect 以上で、合計利益額がSecureProfitの場合、
      最新ポジションを決済
      ContinueOpening にfalseを代入
      start()関数終了。

意味がないコードがあっても、特に触れずに進めます。

現在状況をチャート上に表示

テスターでの実行ではない場合に、Comment()関数でチャート左上にポジション情報などを表示するようにしています。

   if(!IsTesting())
   {
      if(myOrderType == 3)
         text="No conditions to open trades";
      else
         text="   ";
      
      Comment("LastPrice=", LastPrice, " Previous open orders=", PreviousOpenOrders,
              "\nContinue opening=", ContinueOpening, " OrderType=", myOrderType, "\n",
              text2, "\nLots=", lotsi, "\n", text);
   }

エントリー注文処理

myOrderType = 1 のとき、すなわち売りポジション保有中かポジション無しで売りシグナルのときの処理が次のように書かれています。

   if(myOrderType == 1 && ContinueOpening) 
   {
      if(Bid - LastPrice >= Pips*Point || OpenOrders < 1)
      {
         SellPrice = Bid;
         LastPrice = 0;
         
         if(TakeProfit == 0)
            tp = 0;
         else
            tp = SellPrice - TakeProfit*Point;
         
         if(InitialStop == 0)
            sl = 0;
         else
            sl = SellPrice + InitialStop*Point;
         
         if(OpenOrders != 0)
         {
            mylotsi = lotsi;
            for(cnt=1; cnt<=OpenOrders; cnt++)
               if(MaxTrades > 12)
                  mylotsi = NormalizeDouble(mylotsi*1.5, 1);
               else
                  mylotsi = NormalizeDouble(mylotsi*2, 1); 
         }
         else
            mylotsi=lotsi;
         
         if(mylotsi > 100) mylotsi = 100;
         
         OrderSend(Symbol(), OP_SELL, mylotsi, SellPrice, slippage, sl, tp, NULL, 0, 0, Red);
         return(0);
      }
   }
myOrderType が 1 で ContinueOpeningがtrueのとき
   Bid - LastPrice が Pipsポイント以上 または ポジション無しのとき
      SellPrice に Bidを代入
      LastPrice に 0 を代入
         
      TakeProfit が0より大きい場合にtp を SellPrice - TakeProfitポイントとする
      InitialStop が0より大きい場合にsl を SellPrice + InitialStopポイントとする
      
      ポジション保有時
         mylotsi に lotsiを代入

         MaxTrades が 12の場合、mylotsi に1.5を保有ポジション数と同じ回数を掛ける
         そうでない場合、mylotsi に2を保有ポジション数と同じ回数を掛ける
      ポジション保有していないとき
         mylotsi に lotsiを代入
         
         mylotsi が 100を超えていたら100にする
         
      売り注文実行
      start()関数終了

買い注文処理部分も同様に書かれています。

あとがき

なかなか分かりづらいですよね^^;
そこで、余分な情報などを削除して、取引部分を再構築してみました!
変数名やコード配置などの変更はありますが、まったく同じ取引をするものを作りました。
ブロックごとに内容をメモしてあるので参考にしてください。
しかし、このままではマネーマネジメントの部分や損失を抱え込んでしまうなどの難ありなので、今後改良していきたいと思います。
【MetatoreLotScalper.zip】をダウンロード

2019.11.12 追記
新MQL4で最近のMT4事情を踏まえてリメイクしたものをアップします。
最新バージョン【MetatoreLotScalper_2019.mq4】をダウンロード