Ordersend() not working as expected

 

Hello All,

I wrote a very simple EA following a tutorial in youtube. The code just checks for a cross over between 2 moving averages and places a buy or a sell order depending on the direction of the cross over. My problem is - the ordersend() function does not execute the buy or the sell orders when i run this EA through the strategy tester in MT4. The ticket number is 0 and the GetLastError() function returns 0. I tried increasing the stop loss as per one of the threads I googled but the error persists.

Could you help me to understand where am i going wrong pls?


extern int TakeProfit=50;
extern int StopLoss=40;
extern int FastEma=5;
extern int SlowEma=21;
extern double LotSize=0.1;
double pips;
double ticksize;
int ticket;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ticksize = MarketInfo(Symbol(),MODE_TICKSIZE);
   pips = ticksize*10;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

double PreviousFast = iMA(NULL, 0, FastEma, 0, MODE_EMA, PRICE_CLOSE, 2);
double CurrentFast = iMA(NULL, 0, FastEma, 0, MODE_EMA, PRICE_CLOSE, 1);
double PreviousSlow = iMA(NULL, 0, SlowEma, 0, MODE_EMA, PRICE_CLOSE, 2);
double CurrentSlow = iMA(NULL, 0, SlowEma, 0, MODE_EMA, PRICE_CLOSE, 1);
if(PreviousFast<PreviousSlow && CurrentFast>CurrentSlow)
   if(OrdersTotal()== 0)
      ticket=OrderSend("NZDUSD",OP_BUY,LotSize,Ask,10,Ask-StopLoss*pips,Ask+TakeProfit*pips,"Myorder",12345,0,Green);
      Print("Buy tkt:",ticket);
      if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("SELL order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening BUY order : ",GetLastError());
        
        
if(PreviousFast>PreviousSlow && CurrentFast<CurrentSlow)
   if(OrdersTotal()== 0)
      ticket=OrderSend("NZDUSD",OP_SELL,LotSize,Bid,10,Bid+StopLoss*pips,Ask-TakeProfit*pips,"Mysorder",12345,0,Red);
      Print("Sell tkt:",ticket);
      if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("SELL order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening SELL order : ",GetLastError());
  }
//+------------------------------------------------------------------+
 
Aj_Rev:

Hello All,

I wrote a very simple EA following a tutorial in youtube. The code just checks for a cross over between 2 moving averages and places a buy or a sell order depending on the direction of the cross over. My problem is - the ordersend() function does not execute the buy or the sell orders when i run this EA through the strategy tester in MT4. The ticket number is 0 and the GetLastError() function returns 0. I tried increasing the stop loss as per one of the threads I googled but the error persists.

Could you help me to understand where am i going wrong pls?



extern double TakeProfit=5.0;
extern double StopLoss=4.0;
extern int FastEma=5;
extern int SlowEma=21;
extern double LotSize=0.1;
double pips;
double ticksize;
int ticket,digits;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ticksize = MarketInfo(Symbol(),MODE_POINT);
   digits=(int)MarketInfo(Symbol(),MODE_DIGITS);

   if((digits==5||digits==3))
   pips = ticksize*10;
   else
   pips=ticksize;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

double PreviousFast = iMA(NULL, 0, FastEma, 0, MODE_EMA, PRICE_CLOSE, 2);
double CurrentFast = iMA(NULL, 0, FastEma, 0, MODE_EMA, PRICE_CLOSE, 1);
double PreviousSlow = iMA(NULL, 0, SlowEma, 0, MODE_EMA, PRICE_CLOSE, 2);
double CurrentSlow = iMA(NULL, 0, SlowEma, 0, MODE_EMA, PRICE_CLOSE, 1);
if(PreviousFast<PreviousSlow && CurrentFast>CurrentSlow)
   if(OrdersTotal()== 0)
      ticket=OrderSend("NZDUSD",OP_BUY,LotSize,Ask,10,Ask-StopLoss*pips,Ask+TakeProfit*pips,"Myorder",12345,0,Green);
      Print("Buy tkt:",ticket);
      if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("SELL order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening BUY order : ",GetLastError());
        
        
if(PreviousFast>PreviousSlow && CurrentFast<CurrentSlow)
   if(OrdersTotal()== 0)
      ticket=OrderSend("NZDUSD",OP_SELL,LotSize,Bid,10,Bid+StopLoss*pips,Bid-TakeProfit*pips,"Mysorder",12345,0,Red);
      Print("Sell tkt:",ticket);
      if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("SELL order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening SELL order : ",GetLastError());
  }
//+------------------------------------------------------------------+

did some changes to the code (highlighted) but did not check your entry conditions. Code not tested. Also you should look at the use of OrdersTotal==0 which you should remove. Using this makes your code incompatible with any other ea's you run on your account. You need a proper check for orders by symbol and magic

 
  1. Aj_Rev: ticket number is 0 and the GetLastError() function returns 0. I

    The error is not zero. Between your call and your get are other functions. Check immediately!

  2. ticket=OrderSend("NZDUSD",OP_BUY,LotSize,Ask,10,Ask-StopLoss*pips,Ask+TakeProfit*pips,"Myorder",12345,0,Green);
    You buy at the Ask and sell at the Bid. So for buy orders you pay the spread on open. For sell orders you pay the spread on close.
    1. Your buy order's TP/SL (or Sell Stop's/Sell Limit's entry) are triggered when the Bid reaches it. Not the Ask. Your SL is shorter by the spread and your TP would be longer. Don't you want the same/specified amount for either direction?
    2. Your sell order's TP/SL (or Buy Stop's/Buy Limit's entry) will be triggered when the Ask reaches it. To trigger at a specific Bid price, add the average spread.
                MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25
    3. The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools → Options (control+O) → charts → Show ask line.)
 
William Roeder:
  1. The error is not zero. Between your call and your get are other functions. Check immediately!

  2. You buy at the Ask and sell at the Bid. So for buy orders you pay the spread on open. For sell orders you pay the spread on close.
    1. Your buy order's TP/SL (or Sell Stop's/Sell Limit's entry) are triggered when the Bid reaches it. Not the Ask. Your SL is shorter by the spread and your TP would be longer. Don't you want the same/specified amount for either direction?
    2. Your sell order's TP/SL (or Buy Stop's/Buy Limit's entry) will be triggered when the Ask reaches it. To trigger at a specific Bid price, add the average spread.
                MODE_SPREAD (Paul) - MQL4 programming forum - Page 3 #25
    3. The charts show Bid prices only. Turn on the Ask line to see how big the spread is (Tools → Options (control+O) → charts → Show ask line.)


Thank you William for your time!

1. The error is not zero. Between your call and your get are other functions. Check immediately!

I followed this article: https://www.mql5.com/en/articles/1473 and attempted to capture GetLastError() but it still said 0. Are there any other methods that I could use to capture the actual error pls?

2. I tried the following but I can't seem to get past the error.

  • I manually set the spread to 2 in the strategy tester.
  • Captured the output of Ask-(StopLoss*pips) and I can see that its computed to 25 pips.

Another puzzling behaviour is that it alternates between BUY and SELL orders. The test period that I'm using is between 02 Jan and 10 Jan on the daily chart of NZDUSD in my live account. 

I suppose the solution lies is in getting the actual error from the GetLastError() function but it beats me.

Regards,

Aj

How to Make the Detection and Recovery of Errors in an Expert Advisor Code Easier
How to Make the Detection and Recovery of Errors in an Expert Advisor Code Easier
  • www.mql5.com
The development of trading EAs in the MQL4 language is not an easy matter from the points of view of several aspects: first, algorithmization of any more are less difficult trading system is already a problem itself, because one needs to take into account many details, from the peculiarities of an algorithmized EA and till the specific...
 
Kenneth Parling:

did some changes to the code (highlighted) but did not check your entry conditions. Code not tested. Also you should look at the use of OrdersTotal==0 which you should remove. Using this makes your code incompatible with any other ea's you run on your account. You need a proper check for orders by symbol and magic

Thank You Kenneth!

I tried your changes. The ticksize is 0.0001. The stoploss and the take profit is being calculated correctly but the ordersend function still ends up in error.

Regards,

Aj  

 
Aj_Rev:


Thank you William for your time!

1. The error is not zero. Between your call and your get are other functions. Check immediately!

I followed this article: https://www.mql5.com/en/articles/1473 and attempted to capture GetLastError() but it still said 0. Are there any other methods that I could use to capture the actual error pls?

2. I tried the following but I can't seem to get past the error.

  • I manually set the spread to 2 in the strategy tester.
  • Captured the output of Ask-(StopLoss*pips) and I can see that its computed to 25 pips.

Another puzzling behaviour is that it alternates between BUY and SELL orders. The test period that I'm using is between 02 Jan and 10 Jan on the daily chart of NZDUSD in my live account. 

I suppose the solution lies is in getting the actual error from the GetLastError() function but it beats me.

Regards,

Aj

Just want to add the logs of the test results.

2020.03.30 12:20:16.329 2020.01.02 00:30:59  AjMaCrossover NZDUSD,Daily: Error opening SELL order : 0
2020.03.30 12:20:16.329 2020.01.02 00:30:59  AjMaCrossover NZDUSD,Daily: Bid in SellOrder: 0.67217
2020.03.30 12:20:16.329 2020.01.02 00:30:59  AjMaCrossover NZDUSD,Daily: stoploss-SellOrder: 0.6696700000000001
2020.03.30 12:20:16.329 2020.01.02 00:30:59  AjMaCrossover NZDUSD,Daily: Error opening BUY order : 0
2020.03.30 12:20:16.329 2020.01.02 00:30:59  AjMaCrossover NZDUSD,Daily: Ask in BuyOrder: 0.67217
2020.03.30 12:20:16.329 2020.01.02 00:30:59  AjMaCrossover NZDUSD,Daily: stoploss-BuyOrder: 0.6696700000000001
2020.03.30 12:20:16.263 2020.01.02 00:30:52  AjMaCrossover NZDUSD,Daily: Error opening SELL order : 0
2020.03.30 12:20:16.263 2020.01.02 00:30:52  AjMaCrossover NZDUSD,Daily: Bid in SellOrder: 0.67216
2020.03.30 12:20:16.263 2020.01.02 00:30:52  AjMaCrossover NZDUSD,Daily: stoploss-SellOrder: 0.66966
2020.03.30 12:20:16.263 2020.01.02 00:30:52  AjMaCrossover NZDUSD,Daily: Error opening BUY order : 0
2020.03.30 12:20:16.263 2020.01.02 00:30:52  AjMaCrossover NZDUSD,Daily: Ask in BuyOrder: 0.67216
2020.03.30 12:20:16.263 2020.01.02 00:30:52  AjMaCrossover NZDUSD,Daily: stoploss-BuyOrder: 0.66966
2020.03.30 12:20:16.197 2020.01.02 00:30:46  AjMaCrossover NZDUSD,Daily: Error opening SELL order : 0
2020.03.30 12:20:16.197 2020.01.02 00:30:46  AjMaCrossover NZDUSD,Daily: Bid in SellOrder: 0.67218
2020.03.30 12:20:16.197 2020.01.02 00:30:46  AjMaCrossover NZDUSD,Daily: stoploss-SellOrder: 0.6696800000000001
2020.03.30 12:20:16.197 2020.01.02 00:30:46  AjMaCrossover NZDUSD,Daily: Error opening BUY order : 0
2020.03.30 12:20:15.737 2020.01.02 00:30:00  AjMaCrossover NZDUSD,Daily: stoploss-SellOrder: 0.66961
2020.03.30 12:20:15.737 2020.01.02 00:30:00  AjMaCrossover NZDUSD,Daily: Error opening BUY order : 0
2020.03.30 12:20:15.737 2020.01.02 00:30:00  AjMaCrossover NZDUSD,Daily: Ask in BuyOrder: 0.67211
2020.03.30 12:20:15.737 2020.01.02 00:30:00  AjMaCrossover NZDUSD,Daily: stoploss-BuyOrder: 0.66961
2020.03.30 12:20:15.671 2020.01.02 00:29:07  AjMaCrossover NZDUSD,Daily: Error opening SELL order : 0
2020.03.30 12:20:15.671 2020.01.02 00:29:07  AjMaCrossover NZDUSD,Daily: Bid in SellOrder: 0.67216

At some point, the number of decimals in the stoploss value goes very high, like the one highlighted in the log file. Is that a problem?

 

So where is your modified code?

It is no good showing the log without anyone knowing what code created the log.

 
Aj_Rev:

Just want to add the logs of the test results.

At some point, the number of decimals in the stoploss value goes very high, like the one highlighted in the log file. Is that a problem?

The number of decimals can go quite high, it's related to the internal representation of double type - it's not exact value.

You may want to consider using NormalizeDouble(value, _Digits) - this way you will have precise value you're looking for.

 
rigal:

The number of decimals can go quite high, it's related to the internal representation of double type - it's not exact value.

You may want to consider using NormalizeDouble(value, _Digits) - this way you will have precise value you're looking for.

Using NormalizeDouble will make no difference when it is printed.

The Print should include DoubleToString()

 
Keith Watford:

So where is your modified code?

It is no good showing the log without anyone knowing what code created the log.I 

Hi Keith, 

I haven't changed much of the code except that I've refactored the pip value calculation and printed out the stoploss, bid and ask. From the logs I posted, it's placing buy and sell orders alternatively, although the EA is running on a daily chart. I don't understand why. I'm sort of stuck as I can't see the error from the GetLastError() function. Like William mentioned, there could be several functions between my ordersend and the GetLastError function. It would be very helpful if you could help me to gather those errors. Thanks again for your time.


#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
extern int TakeProfit=55;
extern int StopLoss=40;
extern int FastEma=5;
extern int SlowEma=21;
extern double LotSize=0.1;
double pips;
double ticksize;
int ticket,digits;



//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   ticksize = MarketInfo(Symbol(),MODE_TICKSIZE);
   digits=(int)MarketInfo(Symbol(),MODE_DIGITS);
   
   if((digits==5||digits==3))
      pips = ticksize*10;
   else
      pips=ticksize;

//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

double PreviousFast = iMA(Symbol(), 0, FastEma, 0, MODE_EMA, PRICE_CLOSE, 2);
double CurrentFast = iMA(Symbol(), 0, FastEma, 0, MODE_EMA, PRICE_CLOSE, 1);
double PreviousSlow = iMA(Symbol(), 0, SlowEma, 0, MODE_EMA, PRICE_CLOSE, 2);
double CurrentSlow = iMA(Symbol(), 0, SlowEma, 0, MODE_EMA, PRICE_CLOSE, 1);
if(PreviousFast<PreviousSlow && CurrentFast>CurrentSlow)
   if(OrdersTotal()== 0)
      ticket=OrderSend("NZDUSD",OP_BUY,LotSize,Ask,10,Ask-(StopLoss*pips),Ask+(TakeProfit*pips),"Myorder",12345,0,Green);
      Print("stoploss-BuyOrder: ",Ask-(StopLoss*pips));
      Print("Ask in BuyOrder: ",Ask);
      if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("SELL order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening BUY order : ",GetLastError());
        
        
if(PreviousFast>PreviousSlow && CurrentFast<CurrentSlow)
   if(OrdersTotal()== 0)
      ticket=OrderSend("NZDUSD",OP_SELL,LotSize,Bid,10,Bid+(StopLoss*pips),Bid-(TakeProfit*pips),"Mysorder",12345,0,Red);
      Print("stoploss-SellOrder: ",Bid+(StopLoss*pips));
      Print("Bid in SellOrder: ",Bid);
      if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("SELL order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening SELL order : ",GetLastError());
  }
//+------------------------------------------------------------------+
 
//---double PreviousFast = iMA(Symbol(), 0, FastEma, 0, MODE_EMA, PRICE_CLOSE, 2);
   double CurrentFast = iMA(Symbol(), 0, FastEma, 0, MODE_EMA, PRICE_CLOSE, 1);
   double PreviousSlow = iMA(Symbol(), 0, SlowEma, 0, MODE_EMA, PRICE_CLOSE, 2);
   double CurrentSlow = iMA(Symbol(), 0, SlowEma, 0, MODE_EMA, PRICE_CLOSE, 1);
   if(PreviousFast<PreviousSlow && CurrentFast>CurrentSlow)
      if(OrdersTotal()== 0)
        {
         ticket=OrderSend("NZDUSD",OP_BUY,LotSize,Ask,10,Ask-(StopLoss*pips),Ask+(TakeProfit*pips),"Myorder",12345,0,Green);
         Print("stoploss-BuyOrder: ",Ask-(StopLoss*pips));
         Print("Ask in BuyOrder: ",Ask);
         if(ticket>0)
           {
            if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
               Print("SELL order opened : ",OrderOpenPrice());
           }
         else
            Print("Error opening BUY order : ",GetLastError());
        }

First the obvious stuff, you are missing {} (I have put them in and highlighted them). This means that you will get the error reports even when there was no attempt to open an order. That is why last error is 0.

Also you are trying to open a buy and then reporting that a sell has opened

Reason: