Bladeren bron

Ticket: 5360 Partial Closing Logic Updated

Huzaifa-MQLDev 7 maanden geleden
bovenliggende
commit
2094935e8f

BIN
client/localHedgingClientCopierMt5.ex5


+ 116 - 30
client/localHedgingClientCopierMt5.mq5

@@ -43,9 +43,11 @@ struct order
    int               contractSize;
    string            comments;
    int               magicNo;
+   double            closedPercentageOfTrade;
                      order()
      {
       ticket =-1;
+      closedPercentageOfTrade = 0;
      }
   };
 
@@ -214,7 +216,7 @@ void OnTimer()
    read_history_file();
 
    readData();
-   writeDataClientCof();
+//writeDataClientCof();
   }
 //+------------------------------------------------------------------+
 //|                                                                  |
@@ -672,7 +674,7 @@ void readData()
                string Order_specs [];
                StringSplit(OrderToRead,StringGetCharacter(",",0),Order_specs);
                Print("Array Size: ", ArraySize(Order_specs));
-               if(ArraySize(Order_specs) == 11 || ArraySize(Order_specs) == 12)
+               if(ArraySize(Order_specs) == 12 || ArraySize(Order_specs) == 13)
                  {
                   string symbol = getSymbol(Order_specs[1]);//prefix+Order_specs[1]+suffix;
                   int orderType=StringToInteger(Order_specs[2]);
@@ -692,23 +694,24 @@ void readData()
                      //Saving master order ticket to order magic number
                      order_array[ArraySize(order_array)-1].magicNo = StringToInteger(Order_specs[7]);
                      order_array[ArraySize(order_array)-1].accountBalance=StringToDouble(Order_specs[9]);
-                     order_array[ArraySize(order_array)-1].contractSize=StringToInteger(Order_specs[10]);
+                     order_array[ArraySize(order_array)-1].closedPercentageOfTrade  = StringToDouble(Order_specs[10]);
+                     order_array[ArraySize(order_array)-1].contractSize=StringToInteger(Order_specs[11]);
 
-                     if(ArraySize(Order_specs) == 12)
-                        order_array[ArraySize(order_array)-1].comments=Order_specs[11];
+                     if(ArraySize(Order_specs) == 13)
+                        order_array[ArraySize(order_array)-1].comments=Order_specs[12];
                      else
                         order_array[ArraySize(order_array)-1].comments="";
 
-                     if(ArraySize(Order_specs) == 12)
+                     if(ArraySize(Order_specs) == 13)
                        {
-                        StringReplace(Order_specs[11],"from #","");
-                        StringReplace(Order_specs[11]," ","");
+                        StringReplace(Order_specs[12],"from #","");
+                        StringReplace(Order_specs[12]," ","");
 
-                        Print(" Order_specs[11] ",Order_specs[11]," order_array[ArraySize(order_array)-1].ticket ",order_array[ArraySize(order_array)-1].ticket);
+                        Print(" Order_specs[12] ",Order_specs[12]," order_array[ArraySize(order_array)-1].ticket ",order_array[ArraySize(order_array)-1].ticket);
 
                         for(int l=0; l<orderCount; l++)
                           {
-                           if(cod[l].magic == int(Order_specs[11]))
+                           if(cod[l].magic == int(Order_specs[12]))
                              {
                               cod[l].magic = order_array[ArraySize(order_array)-1].ticket;
                              }
@@ -716,7 +719,12 @@ void readData()
                        }
 
 
-                     Print(" Symbol: ",order_array[ArraySize(order_array)-1].symbol,"Open Price: ",order_array[ArraySize(order_array)-1].price," Lot: ",  order_array[ArraySize(order_array)-1].lots,"OPen time: ",order_array[ArraySize(order_array)-1].opentime);
+                     Print(" Symbol: ", order_array[ArraySize(order_array)-1].symbol,
+                           " Open Price: ", order_array[ArraySize(order_array)-1].price,
+                           " Lot: ", order_array[ArraySize(order_array)-1].lots,
+                           " Open time: ", order_array[ArraySize(order_array)-1].opentime,
+                           " Closed %: ", order_array[ArraySize(order_array)-1].closedPercentageOfTrade);
+
                      ArrayResize(order_array,ArraySize(order_array)+1);
                      addToMarketWatch(symbol);
                     }
@@ -773,6 +781,10 @@ void readData()
                //Print(" ------------------------------------------  Ticket: ", order_array[ArraySize(order_array)-1].ticket, " Magic Number: ", order_array[ArraySize(order_array)-1].magicNo, " Array Size: ", ArraySize(order_array), " Index: ", i);
                int trade_taken = 2;
                int partialCloseOrderPosition=-1;
+               double percentageToClose = 0;
+               double closedPercentage = 0.0;
+               double currentLot  = 0.0;
+               double totalLot = 0;
                for(int j=0; j<orderCount; j++)
                  {
                   //if(OrderSelect(cod[j].ticket,SELECT_BY_POS))
@@ -782,12 +794,25 @@ void readData()
                        {
                         trade_taken = 0;
                        }
+                     if(PositionSelectByTicket(cod[j].ticket))
+                       {
+                        double sumOfClosed = dealOutLotsCheck(0, PositionGetInteger(POSITION_TICKET));
+                        currentLot  = PositionGetDouble(POSITION_VOLUME);
+
+                        totalLot = sumOfClosed + currentLot;
+
+                        if(totalLot > 0.0)
+                           closedPercentage = (sumOfClosed / totalLot) * 100.0;
+                       }
+                     //Print(" Magic: ", cod[j].magic, " Ticket: ", order_array[i].ticket, " Master Lot: ", cod[j].masterLot, " Client Lot: ", order_array[i].lots);
                      if(cod[j].magic==order_array[i].ticket)
                        {
-                        if(cod[j].masterLot != order_array[i].lots)
+                        if(closedPercentage < order_array[i].closedPercentageOfTrade)
                           {
-                           Print(" Cod Lot Size: ", cod[j].masterLot, " Order Array Lot: ", order_array[i].lots);
-                           Print("Order is partial close:",cod[j].magic);
+                           percentageToClose = MathAbs(order_array[i].closedPercentageOfTrade - closedPercentage);
+                           //Print(" Cod Lot Size: ", cod[j].masterLot, " Order Array Lot: ", order_array[i].lots);
+                           Print("Closed % = ", closedPercentage, " Master Ticket Percentage: ", order_array[i].closedPercentageOfTrade);
+                           Print("Order is partial close:",cod[j].magic, " Percentage To Be Closed: ", percentageToClose);
                            trade_taken=1;
                            partialCloseOrderPosition=j;
                           }
@@ -802,29 +827,48 @@ void readData()
                      if(partialCloseOrderPosition!=-1)
                        {
                         bool isOrderClose=false;
-                        if(cod[partialCloseOrderPosition].masterLot <= 0)
+                        //if(cod[partialCloseOrderPosition].masterLot <= 0)
+                        //  {
+                        //   Print("Error: Invalid masterLot for partial close");
+                        //   continue;
+                        //  }
+                        //if(OrderSelect(partialCloseOrderPosition,SELECT_BY_TICKET))
                           {
-                           Print("Error: Invalid masterLot for partial close");
-                           continue;
+                           //Print("Master lot: ",order_array[i].lots," last save lot: ",cod[partialCloseOrderPosition].masterLot);
+                           //double lotClosePer = NormalizeDouble(100 - (order_array[i].lots/cod[partialCloseOrderPosition].masterLot*100),2);
+                           //Print("Order in master is closed in percentage: ",lotClosePer," last client lot: ",cod[partialCloseOrderPosition].lots);
+                           //double closeLot=NormalizeDouble(lotClosePer/100 *cod[partialCloseOrderPosition].lots,2);
+                           //Print("Close lot in client: ",closeLot);
+                           //if(!trade.PositionClosePartial(cod[partialCloseOrderPosition].ticket,closeLot))
+                           //  {
+                           //   Print("Partial order did not close:",cod[partialCloseOrderPosition].ticket);
+                           //  }
+                           //else
+                           //  {
+                           // isOrderClose=true;
+                           //   cod[partialCloseOrderPosition].lots=cod[partialCloseOrderPosition].lots-closeLot; //PositionGetDouble(POSITION_VOLUME);
+                           //   cod[partialCloseOrderPosition].masterLot = order_array[i].lots;
+                           //  }
                           }
-                        //if(OrderSelect(partialCloseOrderPosition,SELECT_BY_TICKET))
+                        double lotClosePer = NormalizeDouble((totalLot * percentageToClose) / 100,2);
+                        if(percentageToClose > 0)
                           {
-                           Print("Master lot: ",order_array[i].lots," last save lot: ",cod[partialCloseOrderPosition].masterLot);
-                           double lotClosePer = NormalizeDouble(100 - (order_array[i].lots/cod[partialCloseOrderPosition].masterLot*100),2);
-                           Print("Order in master is closed in percentage: ",lotClosePer," last client lot: ",cod[partialCloseOrderPosition].lots);
-                           double closeLot=NormalizeDouble(lotClosePer/100 *cod[partialCloseOrderPosition].lots,2);
-                           Print("Close lot in client: ",closeLot);
-                           if(!trade.PositionClosePartial(cod[partialCloseOrderPosition].ticket,closeLot))
+                           if(!trade.PositionClosePartial(cod[partialCloseOrderPosition].ticket, lotClosePer))
                              {
-                              Print("Partial order did not close:",cod[partialCloseOrderPosition].ticket);
+                              // ExpertRemove();
+                              Print("Partial order did not close:",cod[partialCloseOrderPosition].ticket, " Lot To Close is: ", lotClosePer);
                              }
                            else
                              {
                               isOrderClose=true;
-                              cod[partialCloseOrderPosition].lots=cod[partialCloseOrderPosition].lots-closeLot; //PositionGetDouble(POSITION_VOLUME);
-                              cod[partialCloseOrderPosition].masterLot = order_array[i].lots;
+                              //cod[partialCloseOrderPosition].lots=cod[partialCloseOrderPosition].lots-closeLot; //PositionGetDouble(POSITION_VOLUME);
+                              //cod[partialCloseOrderPosition].masterLot = order_array[i].lots;
+                              Print("Order Partial Close. currentLot Was =", currentLot,
+                                    " Percentage to close = ", percentageToClose,
+                                    " Lot I am Going To close = ", lotClosePer);
                              }
                           }
+
                        }
                     }
                   else
@@ -973,13 +1017,13 @@ void readData()
                         int digitss = getDoubleSymbolInfo(PositionGetString(POSITION_SYMBOL), "digits");
                         trade_close = false;
                         // if(PositionGetDouble(POSITION_TP)!=order_array[j].takeprofit || PositionGetDouble(POSITION_SL)!=order_array[j].stoploss)
-                        if(NormalizeDouble(cod[i].takeprofit, digitss) != order_array[j].takeprofit || NormalizeDouble(cod[i].stoploss, digitss) != order_array[j].stoploss)
+                        if(NormalizeDouble(cod[i].takeprofit, digitss) != NormalizeDouble(order_array[j].takeprofit, digitss) || NormalizeDouble(cod[i].stoploss, digitss) != NormalizeDouble(order_array[j].stoploss, digitss))
                           {
                            if(trade.PositionModify(PositionGetInteger(POSITION_TICKET),order_array[j].stoploss,order_array[j].takeprofit))
                              {
                               Print("Order modified ticket:",PositionGetInteger(POSITION_TICKET));
-                              cod[i].takeprofit=order_array[j].takeprofit;
-                              cod[i].stoploss=order_array[j].stoploss;
+                              cod[i].takeprofit=NormalizeDouble(order_array[j].takeprofit, digitss);
+                              cod[i].stoploss=NormalizeDouble(order_array[j].stoploss, digitss);
                              }
                            else
                              {
@@ -1130,6 +1174,32 @@ void deleteAllArray()
 //+------------------------------------------------------------------+
 //|                                                                  |
 //+------------------------------------------------------------------+
+double dealOutLotsCheck(datetime cutOffTimeIs, ulong positionId)
+  {
+   double sumOfLots = 0.0;
+
+   if(HistorySelect(cutOffTimeIs,LONG_MAX))
+     {
+      int totalDeals = HistoryDealsTotal();
+
+      for(int i = 0; i < totalDeals; i++)
+        {
+         ulong dealTicket      = HistoryDealGetTicket(i);
+         ulong dealPositionID  = (ulong)HistoryDealGetInteger(dealTicket, DEAL_POSITION_ID);
+
+         if(HistoryDealGetInteger(dealTicket, DEAL_ENTRY) == DEAL_ENTRY_OUT
+            && dealPositionID == positionId)
+           {
+            sumOfLots += HistoryDealGetDouble(dealTicket, DEAL_VOLUME);
+           }
+        }
+     }
+
+   return sumOfLots;
+  }
+//+------------------------------------------------------------------+
+//|                                                                  |
+//+------------------------------------------------------------------+
 bool addOrderMaster(ulong ticket,ulong magic,double lot, string calledBy)
   {
    Print("in addOrderMaster: ", ticket);
@@ -1173,6 +1243,21 @@ bool addOrderMaster(ulong ticket,ulong magic,double lot, string calledBy)
                cod[i].comments=PositionGetString(POSITION_COMMENT);
                cod[i].masterLot = lot;
                Print("Ticket stored in master:",PositionGetInteger(POSITION_TICKET)," stored in index:",i);
+
+               Print("========== CLIENT ORDER STORED ==========");
+               Print(" index=", i,
+                     " | master_magic=", cod[i].magic,
+                     " | client_ticket=", cod[i].ticket,
+                     " | symbol=", cod[i].symbol,
+                     " | order_type=", cod[i].ordertype,
+                     " | open_price=", DoubleToString(cod[i].price, _Digits),
+                     " | lots=", DoubleToString(cod[i].lots, 2),
+                     " | master_lot=", DoubleToString(cod[i].masterLot, 2),
+                     " | sl=", DoubleToString(cod[i].stoploss, _Digits),
+                     " | tp=", DoubleToString(cod[i].takeprofit, _Digits),
+                     " | comment=", cod[i].comments);
+               Print("========================================");
+
                return true;
               }
             else
@@ -1492,6 +1577,7 @@ void clearOrderArray()
    order_array[0].accountBalance=0;
    order_array[0].contractSize=0;
    order_array[0].comments="";
+   order_array[0].closedPercentageOfTrade = 0;
 
   }
 //+------------------------------------------------------------------+

BIN
master/localHedgingMasterCopierMt5.ex5


BIN
master/localHedgingMasterCopierMt5.mq5