Error 4051 (Code Pasted) - Lots that are not divisible?

 

I am using 3x variations of my EA across 15+ pairs. On version_2 of my EA, I am getting an error of 4051 (as I have recently placed all my prints back in - don't know why I greyed them out in the first place :P)

I'm guessing it's because of the number of lots that are currently open can not be divisible by the "Second_Target" value of "4"... In which case, how do I close out the CLOSEST lot value to the math shown in here:

"double Target_2 = MathFloor(OrderLots()/Second_Target/lotStep)*lotStep;" ----- See code below with arrows.

Also, when I print out the above^ code, it is saying that the lots to close is "0.00000", on a position with "0.58" lots open. Now technically, this should be: "0.145" - I'm not sure if this third decimal number is messing it up? If so, how do I drop that and round it up to: "0.15" lots?

void CloseHalfOrder()
{   
   
   static datetime partclosedonce;
   static datetime partclosedtwice;
   static datetime partclosedthird;
   
   double minLot=MarketInfo(Symbol(),MODE_MINLOT);
    //Print("The minimum lots are: ",DoubleToStr(minLot,Digits));
   double lotStep=MarketInfo(Symbol(),MODE_LOTSTEP);
    //Print("The Lotstep is: ",DoubleToStr(lotStep,Digits));
   double half_1st=MathFloor(OrderLots()/First_Target/lotStep)*lotStep;
    //Print("The Lots to close is: ",DoubleToStr(half_1st,Digits));
   double half_2nd=MathFloor(OrderLots()/EMA_Target/lotStep)*lotStep;
    //Print("The Lots to close is: ",DoubleToStr(half_2nd,Digits));
   double Target_2 = MathFloor(OrderLots()/Second_Target/lotStep)*lotStep;    <<<<<<------ "Second_Target" is "4" in the global area. 
    //Print("The Lots to close is: ",DoubleToStr(Target_2,Digits));
   
   double EMA_Bar = iClose(NULL, PERIOD_H1, 1);
   double EMA_MA = iMA(Symbol(),60,21,0,1,0,0);
   
   double FirstTarget_Buy = OrderOpenPrice()+(( OrderTakeProfit()-OrderOpenPrice())/6);
    //Print("FirstTarget_Buy: ",DoubleToStr(FirstTarget_Buy,Digits));
   double TwoRatio_Buy = OrderOpenPrice()+(( OrderTakeProfit()-OrderOpenPrice())/3);  
    //Print("SecondTarget_Buy: ",DoubleToStr(TwoRatio_Buy,Digits)); 
   int PositionIndex;    //  <-- this variable is the index used for the loop
   int TotalNumberOfOrders;   //  <-- this variable will hold the number of orders currently in the Trade pool
   TotalNumberOfOrders = OrdersTotal();    // <-- we store the number of Orders in the variable
   
for(PositionIndex = TotalNumberOfOrders - 1; PositionIndex >= 0 ; PositionIndex --) 
    {
      if(!OrderSelect(PositionIndex,SELECT_BY_POS,MODE_TRADES))continue;
       if(OrderMagicNumber()==MagicNumber)
        if(OrderSymbol() == Symbol())
        { 
         
          if(OrderOpenTime() != partclosedonce)  
           if(OrderType()==OP_BUY && Bid >= FirstTarget_Buy+(Point/2) && OrderLots()>minLot) 
              {
              bool Close_Half_Order_Buy=OrderClose(OrderTicket(),half_1st,Bid,5,Blue);
              if(Close_Half_Order_Buy!=TRUE)Print("Close_Half_Order_Buy Last Error = ",GetLastError(), " On: ", OrderSymbol());
              if(Close_Half_Order_Buy==True)Print("BUY First Target Closed: ", OrderLots(), " On: ", OrderSymbol());
              }
               
          if(Close_Half_Order_Buy==True && OrderOpenPrice() > OrderStopLoss())
              {
              MoveToBreakEven(); 
              }
              if(Close_Half_Order_Buy==True)
                 {
                 partclosedonce = OrderOpenTime();
                 } 
      
          if(partclosedonce != partclosedtwice && OrderOpenTime() != partclosedtwice)
           if(Bid - OrderOpenPrice() > Point / 2. 
            && OrderType()==OP_BUY && EMA_Bar < EMA_MA && OrderLots()>minLot)
              {
              //Print("Current Bid: ",DoubleToStr(Bid,Digits)," EMA_MA > H1 Close: ",DoubleToStr(EMA_MA,Digits));
              bool EMA_Buy_Close=OrderClose(OrderTicket(),half_2nd,Bid,5,CLR_NONE);
              if(EMA_Buy_Close!=TRUE)Print("EMA_Buy_Close Last Error = ",GetLastError(), " On: ", OrderSymbol());
              if(EMA_Buy_Close==True)Print("EMA Buy Target Closed: ", OrderLots(), " On: ", OrderSymbol());
              if(EMA_Buy_Close==True)partclosedtwice = OrderOpenTime();
              }     
                 
          if(OrderOpenTime() != partclosedthird)
           if(OrderType()==OP_BUY && Bid >= TwoRatio_Buy+(Point/2) && OrderLots()>minLot)
              {
              //Print("Current Bid: ",DoubleToStr(Bid,Digits)," 2:1 Target: ",DoubleToStr(TwoRatio_Buy,Digits));
              bool Two_Ratio_Buy = OrderClose(OrderTicket(),Target_2,Bid,5,CLR_NONE);
              if(Two_Ratio_Buy! = TRUE)Print("Two_Ratio_Buy Last Error = ",GetLastError(), " On: ", OrderSymbol());  <<<<<<<<<---- This is what is giving me the error of 4051.
              if(Two_Ratio_Buy == True)Print("Two_Ratio_Buy Target Closed: ", OrderLots(), " On: ", OrderSymbol());
              if(Two_Ratio_Buy == True)partclosedthird = OrderOpenTime();
              }     
        }
     }
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
DomGilberto:

I am using 3x variations of my EA across 15+ pairs. On version_2 of my EA, I am getting an error of 4051 (as I have recently placed all my prints back in - don't know why I greyed them out in the first place :P)

I'm guessing it's because of the number of lots that are currently open can not be divisible by the "Second_Target" value of "4"... In which case, how do I close out the CLOSEST lot value to the math shown in here:

"double Target_2 = MathFloor(OrderLots()/Second_Target/lotStep)*lotStep;"



Is the 4051 due to the lots ? have you confirmed this ? is the resultant lots value >= the min lots value ? where do you check in your code ?
 
RaptorUK:

Is the 4051 due to the lots ? have you confirmed this ? is the resultant lots value >= the min lots value ? where do you check in your code ?


Yea, It is the lots I am trying to close relative to what I am trying to divide it by. I have updated my original post^

Current lots open is 0.58 lots... divide by "4" gives me 0.145....? It is telling me that the lots to close is "0.00000" ? I thought Mathfloor took care of rounding it down? (correct me if I am wrong) - Need to understand how to tell it to close out a pre-defined lot value, as CLOSE to the answer (in which case, what I am wanting to divide it by = "4") as possible... ?

 
DomGilberto:


Yea, It is the lots I am trying to close relative to what I am trying to divide it by. I have updated my original post^

Current lots open is 0.58 lots... divide by "4" gives me 0.145....? It is telling me that the lots to close is "0.00000" ? I thought Mathfloor took care of rounding it down? (correct me if I am wrong) - Need to understand how to tell it to close out a pre-defined lot value, as CLOSE to the answer (in which case, what I am wanting to divide it by = "4") as possible... ?

MathFloor will round down to the nearest integer, 0 can be the nearest integer, you said the calculation should be 0.58/5 = 0.145 OK, what is lotStep ? if it's greater than 0.145 then MathFloor would round down to 0.
 
RaptorUK:
MathFloor will round down to the nearest integer, 0 can be the nearest integer, you said the calculation should be 0.58/5 = 0.145 OK, what is lotStep ? if it's greater than 0.145 then MathFloor would round down to 0.


"double Target_2 =MathFloor(OrderLots()/Second_Target/lotStep)*lotStep;" = MathFloor(0.58/4/0.01)*0.01 ---- "Second_Target" I have as an "extern double" up in the global area. So I have that currently set to "4".

I have lotstep printing out, which is: "0.01000"
 
DomGilberto:

"double Target_2 =MathFloor(OrderLots()/Second_Target/lotStep)*lotStep;" = MathFloor(0.58/4/0.01)*0.01 ---- "Second_Target" I have as an "extern double" up in the global area. So I have that currently set to "4".

I have lotstep printing out, which is: "0.01000"

Looks OK to me . . . to be certain I always, always add brackets . . . so . . .

double Target_2 = MathFloor( ( OrderLots() / Second_Target ) / lotStep) * lotStep; 

. . . try it, see if it fixes the issue. If it does then we have one more question to resolve about the documentation . . .

 
Hmmm... Yea still no change in what I am seeing with the prints....? I am also getting "invalid lots number for OrderClose function"
 
DomGilberto:
Hmmm... Yea still no change in what I am seeing with the prints....?
In the code above you are not printing OrderLots(), perhaps you have the wrong Order selected and have the wrong Lots value compared to what you think you have . . . add a print for OrderLots() and check.
 
RaptorUK:
In the code above you are not printing OrderLots(), perhaps you have the wrong Order selected and have the wrong Lots value compared to what you think you have . . . add a print for OrderLots() and check.


Ok, I have printed out the order lots using OrderSymbol() too, and I can confirm that the correct order is being selected AND the correct lot sizing too...? This is really odd :s?
 
DomGilberto:

Ok, I have printed out the order lots using OrderSymbol() too, and I can confirm that the correct order is being selected AND the correct lot sizing too...? This is really odd :s?

Break it down, print each step, find what is going wrong . . . there is always an explanation. For example . . .

Print("OrderLots(): ", OrderLots(), " Second_Target: ", Second_Target, " Lots/target: ", OrderLots() / Second_Target );

double Target_2 = MathFloor( ( OrderLots() / Second_Target ) / lotStep) * lotStep; 

etc, print every variable and each part of the workings in the Target_2 calculation so you can see where it is going wrong . . .

 

I have tried that...

Lots are 0.58

Current Order selected is GBPUSD

Lot step is: 0.01

SecondTarget_Buy: 1.34584 & yen prices!

FirstTarget_Buy: 1.34254 & yen prices!

The Lots to close is: 0.00000


The SecondTarget_Buy and FirstTarget_Buy seem to be giving me the price of the EURUSD...? Which is odd, because I call this "void CloseHalfOrder()" from this: (therefore, I thought it would have the correct order selected?)

Update: It seems to be pulling price's even from the Yen Pairs... ? So when I print firsttarget_buy and secondtarget_buy I am getting conflicting prices?

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+

int start()
 {
   if(IsNewCandle())
      {
      CheckForMaTrade();//signals, deletions and candle trails only need checked on a new candle.
      }

   if(OpenOrdersThisPair(Symbol())>0)
      {
      if(UseMoveToBreakEven)MoveToBreakEven();//Move to b/e, normal trail and MA_trail need to trail on each tick
      if(Use_MA_Trail)MA_Trail();
      }
   
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int PositionIndex; 
int TotalNumberOfOrders;
TotalNumberOfOrders  = OrdersTotal();

for(PositionIndex = TotalNumberOfOrders - 1; PositionIndex >= 0 ; PositionIndex --) 
  {  
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;
    if( OrderMagicNumber() == MagicNumber  // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol() )        // <-- does the Order's Symbol match the Symbol our EA is working on ?         
         {
            if(OpenOrdersThisPair(Symbol())>0 && OrderType()==OP_SELL)
               {
               CloseHalfOrder1(); 
               }
   
            if(OpenOrdersThisPair(Symbol())>0 && OrderType()==OP_BUY)
               {
               CloseHalfOrder();    <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Called here? Would this not pass through to the void the correct order? Or does that all need to be done again within the void properly? 
               }   
         }
   }

}  
Reason: