MQL4 - arithmetic error from MQL4

 

Hi everyone.


I am trying to program a new trading system (very simple one) which consists of 1 MMA crossover with 2 type of exits. One stop loss based on volatility and another one which is a kind of trailing stop based on the breakout. I.e. if I have a long position, it will be closed when the price breaks out the lowest of the previous 10 days and reversely if it is a short position, position is closed when price beraks out the highest of the last 10 days.

I could program all of that but I am experiencing a problem with the 10 days exist. For some reason MQL4 is telling me that the Ask price is always > the highest 10 days (condition for closing a short position) even when it is not (for example Ask 1.29200, Highest 10 d 1.29500; I will keep having Bid > highest 10 days as true.

Same problem for the Bid < Lowest 10days  (exit condition for a long position)


Anyon who could have an idea of how I could solve this problem?


here is my code


//+------------------------------------------------------------------+

//| Global Variables                                                 |

//+------------------------------------------------------------------+

extern int  Period_MA_1=50;                                              // Periode 1er MA

extern int  Period_MA_2=100;                                             // Periode 2eme MA

extern double Risk=0.02;                                                 // % Capital a risque par trade

extern int N=3;                                                          // Variable N

extern int MagicNumberAchat=123;                                         // Magic Number to use for the BUY orders

extern int MagicNumberVente=456;                                         // Magic Number to use for the SELL orders



bool Work=true;                                                          // EA will work

bool Cond_Stop_Achat;                                              // Condition to close the BUY order

bool Cond_Stop_Vente;                                              // Condition to close the SELL order



//+------------------------------------------------------------------+

//| Start function                                                   |

//+------------------------------------------------------------------+

int start()

  { 

//+------------------------------------------------------------------+

//| Local Variables                                                  |

//+------------------------------------------------------------------+





double val_highest20=High[iHighest(NULL,0,MODE_HIGH,20,1)];                   // Highest value in the last 20 days

double val_highest10=High[iHighest(NULL,0,MODE_HIGH,10,1)];                   // Highest value in the last 10 days

double val_lowest20=Low[iLowest(NULL,0,MODE_LOW,20,1)];                     // Lowest value in the last 20 days

double val_lowest10=Low[iLowest(NULL,0,MODE_LOW,10,1)];                     // Lowest value in the last 10 days



double MA_1_c=iMA(NULL,0,Period_MA_1,0,MODE_SMA,PRICE_CLOSE,0);          // Current value of MA_1

double MA_2_c=iMA(NULL,0,Period_MA_2,0,MODE_SMA,PRICE_CLOSE,0);          // Current value of MA_2

double MA_1_p=iMA(NULL,0,Period_MA_1,0,MODE_SMA,PRICE_CLOSE,1);          // Previous close value of MA_1

double MA_2_p=iMA(NULL,0,Period_MA_2,0,MODE_SMA,PRICE_CLOSE,1);          // Previous close value of MA_2



double StopATR = NormalizeDouble(iATR(NULL,0,20,0)*N,5);                 // Stop base sur ATR 20d



if (Bid < val_lowest10)

   Cond_Stop_Achat=true;



if (Ask > val_highest10)

   Cond_Stop_Vente=true;



Comment("Highest20: ",val_highest20,"\n","Highest10: ",val_highest10,"\n","Lowest20: ",val_lowest20,"\n","Lowest10: ",val_lowest10,"\n","Close :",iClose(NULL,0,1),"\n","Ask: ",Ask," , ",Cond_Stop_Vente,"\n","Bid: ",Bid," , ",Cond_Stop_Achat,"\n");

        

//--------------------------------------------------------------------

//Preliminary check

   if(Bars < Period_MA_2)                                               // Not enough bars

     {

      Alert("Not enough bars in the window. EA doesn't work.");         // Exit start()

     }

   if(Work==false)                                                      // Critical error

     {

      Alert("Critical error. EA doesn't work.");                        // Exit start()   

   }

   

//+------------------------------------------------------------------+

//| OPENING ORDERS - BUYING CONDITIONS                               |

//+------------------------------------------------------------------+



         if (MA_1_p <= MA_2_p && MA_1_c > MA_2_c)                       // Condition if crossover MM50>MM100

         {

         OrderSend(Symbol(),OP_BUY,0.1,Ask,0,Bid-StopATR,0,"Achat",MagicNumberAchat,0,clrGreen);

         }

//+------------------------------------------------------------------+

//| PYRAMIDAGE - BUYING CONDITIONS                                   |

//+------------------------------------------------------------------+



   

//+------------------------------------------------------------------+

//| OPENING ORDERS - SELLING CONDITIONS                              |

//+------------------------------------------------------------------+



      if (MA_1_p >= MA_2_p && MA_1_c < MA_2_c)  // Condition if crossover MM50<MM100

         {

         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,Ask+StopATR,0,"Vente",MagicNumberVente,0,clrRed);

         }

//+------------------------------------------------------------------+

//| PYRAMIDAGE - SELLING CONDITIONS                                  |

//+------------------------------------------------------------------+



   

//+------------------------------------------------------------------+

//| CLOSING ORDERS - BUYING CONDITIONS                                |

//+-------------------------------------------------------------------+

      

if (Bid < val_lowest10)                                             // Condition if price dips below lowest 10d

   {

     for(int i = OrdersTotal()-1; i >= 0; i--) 

     {

         OrderSelect(i,SELECT_BY_POS,MODE_TRADES);         

         {

         Print("ERROR - Unable to select the Buy order - ",GetLastError());

         break;

         }

         if(OrderMagicNumber()==MagicNumberAchat)

         {

         OrderClose(OrderTicket(),OrderLots(),Bid,3,clrPurple);                      // Close the orders

         Print("Ordre Achat ferme par ATR");

         }

     }

     }

//+------------------------------------------------------------------+

//| CLOSING ORDERS - SELLING CONDITIONS                              |

//+------------------------------------------------------------------+



if (Ask > val_highest10)                                            // Condition if price breaks above highest 10d

   {    

     for(int i = OrdersTotal()-1; i >= 0; i--) 

     {

         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false);         

         {

         Print("ERROR - Unable to select the Sell order - ",GetLastError());

         break;

         }

         if(OrderMagicNumber()==MagicNumberVente)

         {

         if(OrderClose(OrderTicket(),OrderLots(),Ask,3,clrPurple)==false)                      // Close the orders

         {

         Print("ERROR - Unable to close the Sell order - ",GetLastError());

         break;

         }

         else OrderClose(OrderTicket(),OrderLots(),Ask,3,clrPurple);

         Alert("Ordre Achat ferme par ATR");

         }

     }

     }

    return(0);

   }
 
Xav243: For some reason MQL4 is telling me that the Ask price is always > the highest 10 days (condition for closing a short position) even when it is not (for example Ask 1.29200, Highest 10 d 1.29500; I will keep having Bid > highest 10 days as true.
  1. When you post code please use the CODE button (Alt-S)! (For large amounts of code, attach it.) Please edit your (original) post.
              General rules and best pratices of the Forum. - General - MQL5 programming forum
              Messages Editor

  2. if (Bid < val_lowest10)   Cond_Stop_Achat=true;
    
    if (Ask > val_highest10)   Cond_Stop_Vente=true;
    Once you set those static variables to true they will always (until you restart the terminal) be true.
       Cond_Stop_Achat= Bid < val_lowest10;
    
       Cond_Stop_Vente=Ask > val_highest10;
    

  3. Charts are bid chart. A breakout is when price moves above the previous high. Ask will be above the previous high before there is a breakout.

  4.          OrderSend(Symbol(),OP_SELL,0.1,Bid,0,Ask+StopATR,0,"Vente",MagicNumberVente,0,clrRed);
    
             OrderSelect(i,SELECT_BY_POS,MODE_TRADES);         
    
             OrderClose(OrderTicket(),OrderLots(),Bid,3,clrPurple);                      // Close the orders
    Check your return codes for errors, report them and you would know why. Don't just silence the compiler, it is trying to help you.
              What are Function return values ? How do I use them ? - MQL4 and MetaTrader 4 - MQL4 programming forum
              Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
    Only those functions that return a value (e.g. iClose, MarketInfo, etc.) must you call ResetLastError before in order to check after.

  5. Your close uses Bid, invalid for sell orders. Use OrderClosePrice, see #6.3

  6. In the presence of multiple orders (one EA multiple charts, multiple EAs, manual trading,) while you are waiting for the current operation (closing, deleting, modifying) to complete, any number of other operations on other orders could have concurrently happened and changed the position indexing:
    1. For non-FIFO (US brokers,) (or the EA only opens one order per symbol,) you can simply count down in a position loop, and you won't miss orders. Get in the habit of always counting down.
                Loops and Closing or Deleting Orders - MQL4 and MetaTrader 4 - MQL4 programming forum
      For FIFO (US brokers,) and you (potentially) process multiple orders per symbol, you must count up and on a successful operation, reprocess all positions (set index to -1 before continuing.)
    2. and check OrderSelect in case earlier positions were deleted.
                What are Function return values ? How do I use them ? - MQL4 and MetaTrader 4 - MQL4 programming forum
                Common Errors in MQL4 Programs and How to Avoid Them - MQL4 Articles
    3. and if you (potentially) process multiple orders, must call RefreshRates() after server calls if you want to use the Predefined Variables (Bid/Ask) or OrderClosePrice() instead, on the next order/server call.
 

Hi Whroeder1,


I have edited the message accordingly.


> 3. Charts are bid chart. A breakout is when price moves above the previous high. Ask will be above the previous high before there is a breakout.

Yes I agree. That is why in my code the 10days range is shifted 1 bar just before the actual bar, so the Ask price is not part of it.


Thanks for your quick and clear answer. I will dive into it, work on my code and will let you know how it goes.


Xavier

 

I have updated my code accordingly and conditions are now dynamic. Thanks.


My EA is now returning me 2 errors when trying to close orders: error 4018 and "unknown ticket x for OrderClose function" even though I am using the Magic Number function.

Also when putting a sell order, it is closed immediatly by the EA...


//+------------------------------------------------------------------+
//| Global Variables                                                 |
//+------------------------------------------------------------------+
extern int  Period_MA_1=50;                                              // Periode 1er MA
extern int  Period_MA_2=100;                                             // Periode 2eme MA
extern double Risk=0.02;                                                 // % Capital a risque par trade
extern int N=3;                                                          // Variable N
extern int MagicNumberAchat=123;                                         // Magic Number to use for the BUY orders
extern int MagicNumberVente=456;                                         // Magic Number to use for the SELL orders

bool Work=true;                                                          // EA will work
bool Cond_Stop_Achat;                                              // Condition to close the BUY order
bool Cond_Stop_Vente;                                              // Condition to close the SELL order

//+------------------------------------------------------------------+
//| Start function                                                   |
//+------------------------------------------------------------------+
int start()
  { 
//+------------------------------------------------------------------+
//| Local Variables                                                  |
//+------------------------------------------------------------------+


double val_highest20=High[iHighest(NULL,0,MODE_HIGH,20,1)];                   // Highest value in the last 20 days
double val_highest10=High[iHighest(NULL,0,MODE_HIGH,10,1)];                   // Highest value in the last 10 days
double val_lowest20=Low[iLowest(NULL,0,MODE_LOW,20,1)];                       // Lowest value in the last 20 days
double val_lowest10=Low[iLowest(NULL,0,MODE_LOW,10,1)];                       // Lowest value in the last 10 days

double MA_1_c=iMA(NULL,0,Period_MA_1,0,MODE_SMA,PRICE_CLOSE,0);                // Current value of MA_1
double MA_2_c=iMA(NULL,0,Period_MA_2,0,MODE_SMA,PRICE_CLOSE,0);               // Current value of MA_2
double MA_1_p=iMA(NULL,0,Period_MA_1,0,MODE_SMA,PRICE_CLOSE,1);               // Previous close value of MA_1
double MA_2_p=iMA(NULL,0,Period_MA_2,0,MODE_SMA,PRICE_CLOSE,1);               // Previous close value of MA_2

double StopATR = NormalizeDouble(iATR(NULL,0,20,0)*N,5);                      // Stop based on ATR 20d

if (Bid < val_lowest10)
   Cond_Stop_Achat=true;
   else Cond_Stop_Achat=false;

if (Ask > val_highest10)
   Cond_Stop_Vente=true;
   else Cond_Stop_Vente=false;

Comment("Highest20: ",val_highest20,"\n","Highest10: ",val_highest10,"\n","Lowest20: ",val_lowest20,"\n","Lowest10: ",val_lowest10,"\n","Close :",iClose(NULL,0,1),"\n","Ask: ",Ask," , ",Cond_Stop_Vente,"\n","Bid: ",Bid," , ",Cond_Stop_Achat,"\n");
        
//--------------------------------------------------------------------
//Preliminary check
   if(Bars < Period_MA_2)                                               // Not enough bars
     {
      Alert("Not enough bars in the window. EA doesn't work.");         // Exit start()
     }
   if(Work==false)                                                      // Critical error
     {
      Alert("Critical error. EA doesn't work.");                        // Exit start()   
   }
   
//+------------------------------------------------------------------+
//| OPENING ORDERS - BUYING CONDITIONS                               |
//+------------------------------------------------------------------+

         if (MA_1_p <= MA_2_p && MA_1_c > MA_2_c)                                                           // Condition if crossover MM50>MM100
         {
            if(OrderSend(Symbol(),OP_BUY,0.1,Ask,0,Bid-StopATR,0,"Achat",MagicNumberAchat,0,clrGreen)<0)   // Check OrderSend (return is a value of -1)
            {
            Print("Order Send BUY failed, error #", GetLastError());                                        // Print into the terminal the error
            }
         }
//+------------------------------------------------------------------+
//| PYRAMIDAGE - BUYING CONDITIONS                                   |
//+------------------------------------------------------------------+

   
//+------------------------------------------------------------------+
//| OPENING ORDERS - SELLING CONDITIONS                              |
//+------------------------------------------------------------------+

      if (MA_1_p >= MA_2_p && MA_1_c < MA_2_c)  // Condition if crossover MM50<MM100
         {
            if(OrderSend(Symbol(),OP_SELL,0.1,Bid,0,Ask+StopATR,0,"Vente",MagicNumberVente,0,clrRed)<0)  // Check OrderSend (return is a value of -1)
            {
            Print("Order Send SELL failed, error #", GetLastError());                                    // Print into the terminal the error
            }
         }
//+------------------------------------------------------------------+
//| PYRAMIDAGE - SELLING CONDITIONS                                  |
//+------------------------------------------------------------------+

   
//+------------------------------------------------------------------+
//| CLOSING ORDERS - BUYING CONDITIONS                                |
//+-------------------------------------------------------------------+
      
if (Cond_Stop_Achat=true)                                                                                // Condition if price dips below lowest 10d
   {
     for(int i = OrdersTotal()-1; i >= 0; i--) 
     {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)         
         {
         Print("ERROR - Unable to select the Buy order - ",GetLastError());
         break;
         }
         if(OrderMagicNumber()==MagicNumberAchat)
         {
         if(OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3,clrPurple)==false)                 // Close the order
         {
         Print("ERROR - Unable to close the Sell order - ",GetLastError());
         break;
         }
         else Alert("Ordre Achat ferme par ATR");
         }
     }
     }
//+------------------------------------------------------------------+
//| CLOSING ORDERS - SELLING CONDITIONS                              |
//+------------------------------------------------------------------+

if (Cond_Stop_Vente=true)                                                                               // Condition if price breaks above highest 10d
   {    
     for(int i = OrdersTotal()-1; i >= 0; i--) 
     {
         if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)         
         {
         Print("ERROR - Unable to select the Sell order - ",GetLastError());
         break;
         }
         if(OrderMagicNumber()==MagicNumberVente)
         {
         if(OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3,clrPurple)==false)                  // Close the order
         {
         Print("ERROR - Unable to close the Sell order - ",GetLastError());
         break;
         }
         else Alert("Ordre Vente ferme par ATR");
         }
     }
     }
    return(0);
   }
 
Xav243: My EA is now returning me 2 errors when trying to close orders: error 4018 and "unknown ticket x for OrderClose function" even though I am using the Magic Number function.
         if(  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3,clrPurple)==false){…}
         else OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),3,clrPurple);

MN is irrelevant. Why does that surprise you? Your code tries to close an order. If it succeeds it again tries the close the same order.

 

Oh I see! I did not realize that.


I changed but I still have the same problem, i.e. my order is immediately closed

 
Previously answered #1.2
 
whroeder1 2018.07.16 09:24     FR
Previously answered #1.2


→I thought I had already addressed this issue by updating 

if (Bid < val_lowest10)   Cond_Stop_Achat=true;

if (Ask > val_highest10)   Cond_Stop_Vente=true;

to this

if (Bid < val_lowest10)
   Cond_Stop_Achat=true;
   else Cond_Stop_Achat=false;

if (Ask > val_highest10)
   Cond_Stop_Vente=true;
   else Cond_Stop_Vente=false;

Now the conditions switch from true to false depending on the result which is what I wanted.

But even after changing this, and putting OrderClosePrice as sugested, my orders are closed immediatly by the 10d stop.


I apologize in advance for not being able to spot something that might be obvious, I am learning to code in MQL4 and really appreciate your time for helping me.

 
Use the debugger or print out your variables, including _LastError and prices and find out why.