0 0 ? strange EA behaviour

 

Hi there!

I have run into a strange EA behaviour, I will first post the code, then the output

this is the part of the code that behaves strange:

Lot = GetLot(MaxRisk);
OpenPartOrders(OP_SELL,Lot);

the GetLot function:

double GetLot(int Risk)
{double Free    =AccountFreeMargin();
 double One_Lot =MarketInfo(Symbol(),MODE_MARGINREQUIRED);
 double Min_Lot =MarketInfo(Symbol(),MODE_MINLOT);
 double Max_Lot =MarketInfo(Symbol(),MODE_MAXLOT);
 double Step    =MarketInfo(Symbol(),MODE_LOTSTEP);
 double Lot     =MathFloor(Free*Risk/100/One_Lot/Step)*Step;
 if(Lot<Min_Lot) Lot=Min_Lot;
 if(Lot>Max_Lot) Lot=Max_Lot;
 if(Lot*One_Lot>Free) {
 Alert(" free= ", AccountFreeMargin()," for one lot= ", MarketInfo(Symbol(),MODE_MARGINREQUIRED)," lot= ", Lot);
 return(0.0);}
return(Lot);}

OpenPartOrders function: (I need to open orders like that because my broker sometimes opens orders partially)

int OpenPartOrders(int Cmd, double Lot)
{
 int NumOrders = 0;
 int LastTic = -1;
 double Step = MarketInfo(Symbol(),MODE_LOTSTEP);
 double LotRemains = Lot;
 
 //MathFloor( /Step)*Step;;
while ((LotRemains>0)  && (!IsStopped()) )
 {
  LastTic = NewOrder(Cmd, LotRemains);
  NumOrders++;
  if(OrderSelect(LastTic, SELECT_BY_TICKET)==true)
     {
      LotRemains = LotRemains - OrderLots();
      Alert("NumberOfOrders ", NumOrders, " Ticket ", LastTic, " LotRemains ", LotRemains, " initial Lot ", Lot);                
     }
  else
   {
    Alert("OrderSelect returned the error of ",GetLastError(), " order ticket ", LastTic);
    LotRemains = 0; //not to create an endless loop opening new orders again and again
   }
 } 
return(NumOrders);}

and the NewOrder function:

int NewOrder(int Cmd,double Lot)
{double TP=0; //тейкпрофит
 double SL=0; //стоплосс
 double PR=0; //Цена
 color clr = CLR_NONE;
 while ((!IsTradeAllowed())  && (!IsStopped())) Sleep(10);
 RefreshRates();
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=NormPrice(Ask + Ask*TakeProfit/100);
    if(StopLoss>0) SL=NormPrice(Ask - Ask*StopLoss/100);
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Green;}
 if(Cmd==OP_SELL)
   {PR=Bid;
    if(TakeProfit>0) TP=NormPrice(Bid - Bid*TakeProfit/100);
    if(StopLoss>0) SL=NormPrice(Bid + Bid*StopLoss/100);
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr=Red;}
 int tic=OrderSend(Symbol(),Cmd,Lot,PR,Slippage,SL,TP,"",0,0,clr);

 if(tic<0)
  {
   Alert("Error opening order: ",GetLastError());
   Alert("cmd ", Cmd, " Lot ", Lot, " PR ", PR, " Slip ", Slippage, " SL ", SL, " TP ", TP, " Ask ", Ask, " Bid ", Bid);   
  }
return(tic);}

And here is the output:

1) 2014.01.12 08:59:53 myEMA-nomagic-24-12-2110 BTCUSD,H1: open #1404883915 sell 0.83 BTCUSD at 856.234 ok

2) 2014.01.12 08:59:53 myEMA-nomagic-24-12-2110 BTCUSD,H1: Alert: NumberOfOrders 1 Ticket 1404883915 LotRemains 0 initial Lot 0.83

3) 2014.01.12 08:59:53 myEMA-nomagic-24-12-2110 BTCUSD,H1: Alert: Error opening order: 131

4) 2014.01.12 08:59:53 myEMA-nomagic-24-12-2110 BTCUSD,H1: Alert: cmd 1 Lot 0 PR 857.001 Slip 1000 SL 0 TP 0 Ask 857.001 Bid 857.001

5) 2014.01.12 08:59:53 myEMA-nomagic-24-12-2110 BTCUSD,H1: Alert: OrderSelect returned the error of 0 order ticket -1

the output messages should be read from top to bottom, so the earlier ones are at the top and the latter ones are in the bottom, I numbered them in chronological order

so, the second alert states that LotRemains 0, so the cycle while ((LotRemains>0) && (!IsStopped()) ) should stop, but the next alert indicates that it didn't and tried to open another order with 0 volume

how is that possible?




 
prupru:

Hi there!

I have run into a strange EA behaviour, I will first post the code, then the output

so, the second alert states that LotRemains 0, so the cycle while ((LotRemains>0) && (!IsStopped()) ) should stop, but the next alert indicates that it didn't and tried to open another order with 0 volume

how is that possible?

Does this Lot have Local or Global scope ?

Lot   = GetLot(MaxRisk);
OpenPartOrders(OP_SELL,Lot);

probably not connected, but this is wrong . . .

  LastTic = NewOrder(Cmd, LotRemains);
  NumOrders++;

. . even if the OrderSend() fails you still increment the number of orders . . .

I suspect that the issue is one of comparing doubles, yet again. In this code . . .

LotRemains = LotRemains - OrderLots();

. . . if LotRemains > OrderLots() even by 0.00000000001 your while loop will not exit. Instead try this . . .

while ((LotRemains >   Point  )  && (!IsStopped()) )
 

Thanks for your reply!

>Does this Lot have Local or Global scope ?

here is the main frame where Lot is declared

int start()
  {
//----
double Lot;

   if (TrailingStop > 0) DoTrailing();
        
        static datetime Time0;
        if (Time0 == Time[0]) return;
        Time0 = Time[0];
      {
       CheckCross();                 
      }

   
//----
   return(0);
  }

and it is used in CheckCross() then:

Lot = GetLot(MaxRisk);
OpenPartOrders(OP_SELL,Lot);

where should I declare it?

maybe inside CheckCross function?

edit:

oh, it was declared both in start() and CheckCross(), shame on me...

I deleted all the declaration and made it like this:

OpenPartOrders(OP_BUY,GetLot(MaxRisk));

>I suspect that the issue is one of comparing doubles

thanks for the solution, but I wonder how can this happen? I mean, this is computer, not a human who can be mistaken even for 0.00000000001

edit:

found this https://www.mql5.com/en/forum/138355

and this https://www.mql5.com/en/forum/136997

reading into it right now

wow never thought this could take place

 
prupru:

Thanks for your reply!

>Does this Lot have Local or Global scope ?

here is the main frame where Lot is declared

and it is used in CheckCross() then:

where should I declare it?

It's OK as it is, if it had been Globally declared it could have caused you issues . . . it's just local, so you need it declared in each function that uses it . . . but it is a different variable in each function.


wow never thought this could take place

Nor me, hence "Can price != price ?" there is always something more to learn.
 
well, ok, are there any other tricks in mql4 like this one?
 
prupru:
well, ok, are there any other tricks in mql4 like this one?
It's not a mql4 thing it's a double thing . . . same "issue" has to be faced in many languages.