Is there a fault in the EA's code or a broker issue?

 

Hi,

For simplicity, I have inserted only the basic code of an EA below. I believe it is enough and easier to understand my question.

void OnTick()  
  {
   CountBuyOrders();    //gets the BuyOrders
   CountSellOrders();    //gets the SellOrders
   if(BuyOrders+SellOrders==0)    //check if there are any orders on the chart
     {
      PlaceOrder();    //sends a command to open an order
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PlaceOrder()
  {
   while(IsTradeAllowed()==false)
      Sleep(100);
   RefreshRates();
   TheOrder=OrderSend(Symbol(),OP_SELLSTOP,NormalizeLots(CalcLots),NormalizePrice(SellPendingLevel),int(Slippage*PipValue),0,0,TradeComment,MagicNumber,0);
   if(TheOrder>0)
     {
      Print("TheOrder success");
     }
   else
     {
      error=GetLastError();
      Print(" TheOrder failed "+Symbol()+" ("+string(error)+") "+ErrorDescription(error));
     }
   return;
  }

What normally does, is to place an order (in this case pending sell stop), if there are no other orders on the chart. THIS WORKS, however

The problem:

Sometimes it seems to open 2 orders instead on one.

Is there anything wrong with the code or something I can do to avoid this?

Will a Sleep command after the OrderSend help in any way? I'm out of ideas.

My opinion (please tell me if I'm wrong): the broker delays the execution of the trade, so on the next tick the BuyOrders+SellOrders equals 0 again; so the EA sends the command second time. Am I right? Is there something that can be avoided? Or I should just change the broker :) 

Thanks.

 
Daniel George:

Hi,

For simplicity, I have inserted only the basic code of an EA below. I believe it is enough and easier to understand my question.

What normally does, is to place an order (in this case pending sell stop), if there are no other orders on the chart. THIS WORKS, however

The problem:

Sometimes it seems to open 2 orders instead on one.

Is there anything wrong with the code or something I can do to avoid this?

Will a Sleep command after the OrderSend help in any way? I'm out of ideas.

My opinion (please tell me if I'm wrong): the broker delays the execution of the trade, so on the next tick the BuyOrders+SellOrders equals 0 again; so the EA sends the command second time. Am I right? Is there something that can be avoided? Or I should just change the broker :) 

Thanks.

Could you please rather paste your CountBuys & CountSells function ?

 
Icham Aidibe:

Could you please rather paste your CountBuys & CountSells function ?

Dear how can I automate my account?? 
 
46009300:
Dear how can I automate my account?? 
He reffered to the functions implemented into the EA , to be able to establish if the calculations are correctly done : CountBuyOrders and CountSellOrders .Are these functions defined before or after the OnTick void ? You could try to add "return" after PlaceOrder in the OnTick .
 

There are 2 things I would recommend.

Add curly brackets to demark code blocks - such as the while statement.

Move the calls to CountBuyOrders() and CountSellOrders() and the check for number of orders inside PlaceOrder() function - as close to OrderSend as possible.

If that doesn't help, it is possible that this is a Broker issue.

 
Catalin Zachiu:
He reffered to the functions implemented into the EA , to be able to establish if the calculations are correctly done : CountBuyOrders and CountSellOrders .Are these functions defined before or after the OnTick void ? You could try to add "return" after PlaceOrder in the OnTick .

IMO they are defined properly, because it normally works. However, from time to time  :(

Also, they are inserted after OnTick.

void CountSellOrders() 
  {
   SellOrders=0;
   for(count=0;count<OrdersTotal();count++)
     {
      if(OrderSelect(count,SELECT_BY_POS,MODE_TRADES)==FALSE) break;
      if(OrderSymbol()==Symbol() && (OrderMagicNumber()==MagicNumber || MagicNumber==-1))
        {
         if(OrderType()== OP_SELL)
           {
            SellOrders = SellOrders+1;
           }
        }
     }
   return;
  }
 
Daniel George:

IMO they are defined properly, because it normally works. However, from time to time  :(

Also, they are inserted after OnTick.

You are using sell stop orders ... 

TheOrder=OrderSend(Symbol(),OP_SELLSTOP,NormalizeLots(CalcLots),NormalizePrice(SellPendingLevel),int(Slippage*PipValue),0,0,TradeComment,MagicNumber,0);

... you're not counting : 

if(OrderType()== OP_SELL)
  {
  SellOrders = SellOrders+1;
  }

OrderType

Returns order operation type of the currently selected order.

int  OrderType();

Returned value

Order operation type of the currently selected order. It can be any of the following values:

OP_BUY - buy order,
OP_SELL - sell order,
OP_BUYLIMIT - buy limit pending order,
OP_BUYSTOP - buy stop pending order,
OP_SELLLIMIT - sell limit pending order,
OP_SELLSTOP - sell stop pending order.

Note

The order must be previously selected by the OrderSelect() function.

Order Properties - Trade Constants - Constants, Enumerations and Structures - MQL4 Reference
Order Properties - Trade Constants - Constants, Enumerations and Structures - MQL4 Reference
  • docs.mql4.com
Order Properties - Trade Constants - Constants, Enumerations and Structures - MQL4 Reference
 
Icham Aidibe:

You are using sell stop orders ... 

... you're not counting : 

OrderType

Returns order operation type of the currently selected order.

int  OrderType();

Returned value

Order operation type of the currently selected order. It can be any of the following values:

OP_BUY - buy order,
OP_SELL - sell order,
OP_BUYLIMIT - buy limit pending order,
OP_BUYSTOP - buy stop pending order,
OP_SELLLIMIT - sell limit pending order,
OP_SELLSTOP - sell stop pending order.

Note

The order must be previously selected by the OrderSelect() function.

I don't get what you mean. Yes, counts the sell orders and IF there are none, then it places a sell stop. So far it works just fine EXCEPT THAT ... sometimes it places 2 sell-stops.

Is this a broker or a code issue I can fix? How to fix?

 
Daniel George:

I don't get what you mean. Yes, counts the sell orders and IF there are none, then it places a sell stop. So far it works just fine EXCEPT THAT ... sometimes it places 2 sell-stops.

Is this a broker or a code issue I can fix? How to fix?

:) it's a Daniel George's issue : 

if(OrderType()== OP_SELL || OrderType()== OP_SELLSTOP) // <--- will count sell positions & sell stops
  {
  SellOrders = SellOrders+1;
  }
Sometimes it places a first sell stop which hasn't be executed, so at the loop it places another one -----> you see 2 sells positions.
 
Icham Aidibe:

:) it's a Daniel George's issue : 

Sometimes it places a first sell stop which hasn't be executed, so at the loop it places another one -----> you see 2 sells positions.

hahaha Right... I see what you mean. In my rush to make things simpler I've actually deleted the part that counts the pending sells.

Please consider the revised code below. Is there anything I can do so the EA will place only 1 pending trade, not 2 (or maybe more)? Thanks in advance.

SellOrders and SellStopOrders are int.

void OnTick()  
  {
   CountSellOrders();    //gets the SellOrders
   if(SellOrders==0)    //check if there are any sell orders on the chart
     {
     if (SellStopOrders==0) PlaceOrder();    //sends a command to open a sellstop order if no sell pending orders
     }
  }

void PlaceOrder()
  {
   while(IsTradeAllowed()==false)
      Sleep(100);
   RefreshRates();
   TheOrder=OrderSend(Symbol(),OP_SELLSTOP,NormalizeLots(CalcLots),NormalizePrice(SellPendingLevel),int(Slippage*PipValue),0,0,TradeComment,MagicNumber,0);
   return;
  }

void CountSellOrders() //  This block counts SELL trades details
  {
   SellOrders=0; SellStopOrders=0;
   for(count=0;count<OrdersTotal();count++)
     {
      if(OrderSelect(count,SELECT_BY_POS,MODE_TRADES)==FALSE) break;
      if(OrderSymbol()==Symbol() && (OrderMagicNumber()==MagicNumber || MagicNumber==-1))
        {
         if(OrderType()== OP_SELLSTOP) SellStopOrders=SellStopOrders+1;
         if(OrderType()== OP_SELL) SellOrders = SellOrders+1;
        }
     }
   return;
  }
 
Daniel George:

hahaha Right... I see what you mean. In my rush to make things simpler I've actually deleted the part that counts the pending sells.

Please consider the revised code below. Is there anything I can do so the EA will place only 1 pending trade, not 2 (or maybe more)? Thanks in advance.

SellOrders and SellStopOrders are int.

It continues to place many orders ?