MetaTrader 4 BUG when drawing arrow and trendline with OrderDelete() function

 

Hi there,

I just found a bug in drawing an arrow by using the "OrderDelete()" function. Maybe somebody can check if it is a bug or a feature :).

First the system specs:
- Windows 10 PRO 64
- MetaTrader 4 v1090

What happens?

First I place pending orders - fine!
Then I delete them with OrderDelete() - fine also (for the order), BUT...

1. in visual backtest mode an arrow (and trendline) is drawn even when color is set to CLR_NONE
2. in live trading "no" arrow (and trendline) is drawn - "no" means that ONE arrow and ONE trendline is drawn but all parameters (price, time, ID, ...) are set to 0!
-> same parameters for every deleted order so no new objects after the first delete

So it looks like that there is an internal bug when sending the arrow and trendline parameters from the order to the objects.

Build a workaround for me by searching for the object with "no" parameters and draw manually a new one but what the heck is going wrong in the MT4?
Just my PC affected? Can somebody fix that please!


Regards

Michael

 

If you want someone to check, you should provide a test code to reproduce the issue.

Anyway, even if it's an MT4 bug, which I doubt, it will not be fixed as MT4 development and support is completely stopped.

 
Alain Verleyen:

If you want someone to check, you should provide a test code to reproduce the issue.

Anyway, even if it's an MT4 bug, which I doubt, it will not be fixed as MT4 development and support is completely stopped.

//+------------------------------------------------------------------+
//|                                                      Arrow Tester|
//+------------------------------------------------------------------+
#property strict

input int MagicNumber = 444;
string Name = "Arrow Tester";
string Version = "Aliens out there";

input int Verfall = 4;

input double Entry_long = 20;
extern double Long_Lots = 2;
input double TP_long = 20;
input double SL_long = 6.0;
input double TG_long = 2.8;
extern double TG_long_Lots = 1;

input double Entry_short = 20;
extern double Short_Lots = 2;
input double TP_short = 20;
input double SL_short = 6.0;
input double TG_short = 2.8;
extern double TG_short_Lots = 1;

input color LongColor = Lime;
input color ShortColor = FireBrick;
input color DeleteColor = Blue;
input color TGColor = Yellow;

int Slippage = 10;

double PointSet;
bool CloseTicket, DeleteTicket;
int Ticket, LastRunning;

bool PendingLong, PendingShort;
bool RunningLong, RunningShort;

datetime LongTime, ShortTime, TradeTimeLong, TradeTimeShort;
double LastHigh, LastLow;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init() {
   LastRunning = 0;
   return(0);
}

//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit() {
   return(0);
}

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start() {
  
   if (Digits <= 3) PointSet = 0.01; else PointSet = 0.0001;
   if (Digits <= 1) PointSet = 1;
   double Spread = Ask-Bid;
   
//+------------------------------------------------------------------+
//| expert begin                                                     |
//+------------------------------------------------------------------+

//Get Indicator Buffers
   int Status = 0;
   if (iOpen(Symbol(),0,1)>iClose(Symbol(), 0, 1) && iOpen(Symbol(),0,2)>iClose(Symbol(), 0, 2) && iOpen(Symbol(),0,3)>iClose(Symbol(), 0, 3) ) Status = -1;
   if (iOpen(Symbol(),0,1)<iClose(Symbol(), 0, 1) && iOpen(Symbol(),0,2)<iClose(Symbol(), 0, 2) && iOpen(Symbol(),0,3)<iClose(Symbol(), 0, 3) ) Status =  1;
   if (Status == 1) { LongTime  = iTime(Symbol(), 0, 1); LastHigh = iHigh(Symbol(), 0, 1); }
   if (Status == -1) { ShortTime = iTime(Symbol(), 0, 1); LastLow  = iLow(Symbol(), 0, 1); }   

//Check Position        
   RunningLong = false;
   RunningShort = false;
   PendingLong = false;
   PendingShort = false;
   
      for (int t = OrdersTotal()-1; t >= 0; t--) {
         if (OrderSelect(t, SELECT_BY_POS, MODE_TRADES)==true) {
            if(OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol()) {
               if(OrderType()==OP_BUYSTOP)   PendingLong = true;
               if(OrderType()==OP_SELLSTOP)  PendingShort = true;
               if(OrderType()==OP_BUY)       { RunningLong = true;  LastRunning =  1; TradeTimeLong = OrderOpenTime();  }
               if(OrderType()==OP_SELL)      { RunningShort = true; LastRunning = -1; TradeTimeShort = OrderOpenTime(); }
            }
         }
       }

//Reset Swing Mode
      if(LastRunning == 1 && RunningLong==false  && (PendingShort==true || Status==-1)) LastRunning = 0;
      if(LastRunning ==-1 && RunningShort==false && (PendingLong==true  || Status==1))  LastRunning = 0;

//Place Orders
     
            double LE = NormalizeDouble(Spread + LastHigh + Entry_long*PointSet, Digits);
            double SE = NormalizeDouble(LastLow - Entry_short*PointSet, Digits);
            double TPL = NormalizeDouble(LE + (TP_long-Entry_long)*PointSet, Digits);
            double SLL = NormalizeDouble(LE - (Entry_long+SL_long)*PointSet, Digits);
            double TPS = NormalizeDouble(SE - (TP_short-Entry_short)*PointSet, Digits);
            double SLS = NormalizeDouble(SE + (Entry_short+SL_short)*PointSet, Digits);
            
            if (!PendingLong  && !RunningLong  && LastRunning<=0 && Status==1 && LE-Ask>=MarketInfo(NULL, MODE_STOPLEVEL) && iHigh(Symbol(), 0, 0)<LE) {
               OpenTrade(Symbol(), OP_BUYSTOP, Long_Lots, LE, Slippage, SLL, TPL, Name + " " + Symbol() + " Buy(#" + IntegerToString(MagicNumber) + ")", MagicNumber, 0, LongColor);
            }
            
            if (!PendingShort && !RunningShort && LastRunning>=0 && Status==-1 && Bid-SE>=MarketInfo(NULL, MODE_STOPLEVEL) && iLow(Symbol(), 0, 0)>SE) {
               OpenTrade(Symbol(), OP_SELLSTOP, Short_Lots, SE, Slippage, SLS, TPS,  Name + " " + Symbol() + " Sell(#" + IntegerToString(MagicNumber) + ")", MagicNumber, 0, ShortColor);
            }  
            //Modify SL
            for (int t = OrdersTotal()-1; t >= 0; t--) {
               if (OrderSelect(t, SELECT_BY_POS, MODE_TRADES)==true) {
                  if(OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol()) {         
                     if(OrderType()==OP_BUY  && SE>0 && Status==-1)
                        ModifyTrade(OrderTicket(), OrderOpenPrice(), SE, OrderTakeProfit(), 0, CLR_NONE);
                     if(OrderType()==OP_SELL && LE>0 && Status==1)
                        ModifyTrade(OrderTicket(), OrderOpenPrice(), LE, OrderTakeProfit(), 0, CLR_NONE);
                  }
               }
            }    
               

//Delete Pending
      for (int t = OrdersTotal()-1; t >= 0; t--) {
         if (OrderSelect(t, SELECT_BY_POS, MODE_TRADES)==true) {
            if(OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol()) {                        
               DeleteTicket = false;
               //New Signals or Trades
               if(OrderType()==OP_BUYSTOP && (OrderOpenTime()<TradeTimeShort || OrderOpenTime()<=LongTime))
                  DeleteTrade(OrderTicket(), DeleteColor);
               if(OrderType()==OP_SELLSTOP && (OrderOpenTime()<TradeTimeLong  || OrderOpenTime()<=ShortTime))
                  DeleteTrade(OrderTicket(), DeleteColor);
               //Expiration   
               if(OrderType()==OP_BUYSTOP && (iTime(Symbol(), 0, 0)>=OrderOpenTime()+Verfall*PeriodSeconds()))
                  DeleteTrade(OrderTicket(), DeleteColor);
               if(OrderType()==OP_SELLSTOP && (iTime(Symbol(), 0, 0)>=OrderOpenTime()+Verfall*PeriodSeconds()))
                  DeleteTrade(OrderTicket(), DeleteColor);                  
            }
         }
       }   

//TG
      for (int t = OrdersTotal()-1; t >= 0; t--) {
         if (OrderSelect(t, SELECT_BY_POS, MODE_TRADES)==true) {
            if(OrderMagicNumber()==MagicNumber && OrderSymbol()==Symbol()) {
            
               if(OrderType()==OP_BUY && OrderLots()>=TG_long_Lots && OrderLots()>(Long_Lots-TG_long_Lots) && Bid>=OrderOpenPrice()+(TG_long-Entry_long)*PointSet)
                  CloseTrade(OrderType(), OrderTicket(), TG_long_Lots, MarketInfo(OrderSymbol(),MODE_BID), Slippage, TGColor);
               
               if(OrderType()==OP_SELL && OrderLots()>=TG_short_Lots && OrderLots()>(Short_Lots-TG_short_Lots) && Ask<=OrderOpenPrice()-(TG_short-Entry_short)*PointSet) 
                  CloseTrade(OrderType(), OrderTicket(), TG_short_Lots, MarketInfo(OrderSymbol(),MODE_ASK), Slippage, TGColor);
               
            }
         }
       } 

//     
 return(0);
 
}

//+------------------------------------------------------------------+
//Open Trade
int OpenTrade(string symbol, int cmd, double volume, double price, int slippage, double stoploss, double takeprofit, string comment, int magic, datetime expiration, color arrow_color)
{
   int loopcount=0;
   Ticket=OrderSend(symbol,cmd,volume,price,slippage,0,0,comment,magic,expiration,arrow_color);
   Print (Name + " Open Order Ticket: " + IntegerToString(Ticket));
   while(Ticket == -1)
   {
      Sleep(2400);
      loopcount++;
      if(loopcount > 4) break;
      RefreshRates();
      if(cmd == OP_BUY)  price= Ask;
      if(cmd == OP_SELL) price= Bid;
      Ticket=OrderSend(symbol,cmd,volume,price,slippage,0,0,comment,magic,expiration,arrow_color);
   }
   
   if(Ticket<0) Print(Name + " Error opening order: ", GetLastError());

   if(Ticket>0)
   {
      if (OrderSelect(Ticket, SELECT_BY_TICKET, MODE_TRADES))
      {
        if (stoploss>0 || takeprofit>0) ModifyTrade(OrderTicket(), OrderOpenPrice(), stoploss, takeprofit, 0, CLR_NONE);
        if(cmd == OP_BUY) Print(Name + " BUY order opened: ", OrderOpenPrice());
                  if(cmd == OP_SELL) Print(Name + " SELL order opened: ", OrderOpenPrice());
      }
   }        

   return(Ticket);
}
//+------------------------------------------------------------------+

//Close Trade
bool CloseTrade(int ordertype, int ticket, double lots, double price, int slippage, color arrow_color) 
{
   int loopcount=0;
   CloseTicket=OrderClose(ticket, lots, price, slippage, arrow_color);
   while (CloseTicket==false)
   {
      Sleep(600);
      loopcount++;
      if(loopcount > 4) break;
      RefreshRates();
      if(ordertype == OP_BUY) price = Bid;
      if(ordertype == OP_SELL) price = Ask;      
      CloseTicket=OrderClose(ticket, lots, price, slippage, arrow_color);
   } 

   if (CloseTicket==true)
   {
      //
    } else {
                Print(Name + " Error closing order: ", GetLastError());
   }

   return (CloseTicket);
}

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

//Close Trade
bool DeleteTrade(int ticket, color arrow_color) 
{
   int loopcount=0;
   DeleteTicket=OrderDelete(ticket, arrow_color);
   while (DeleteTicket==false)
   {
      Sleep(600);
      loopcount++;
      if(loopcount > 4) break;  
      DeleteTicket=OrderDelete(ticket, arrow_color);
   } 

   if (DeleteTicket==true)
   {
      Print(Name + " Order deleted");
    } else {
                Print(Name + " Error deleting order: ", GetLastError());
   }

   return (DeleteTicket);
}

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

//Modify Trade
bool ModifyTrade(int ticket, double openprice, double stoploss, double takeprofit, datetime expiration, color arrow_color) 
{
   int loopcount=0;
   bool ModifyTicket=OrderModify(ticket, openprice, stoploss, takeprofit, expiration, arrow_color);
   while (ModifyTicket==false)
   {
      Sleep(600);
      loopcount++;
      if(loopcount > 10) break;
      RefreshRates();   
      ModifyTicket=OrderModify(ticket, openprice, stoploss, takeprofit, expiration, arrow_color);
   } 

   if (ModifyTicket==true)
   {
      Print(Name + " Order successfully modified.");
    } else {
                Print(Name + " Error modifying Order: " + IntegerToString(GetLastError()) + " " + DoubleToString(takeprofit) + " " + DoubleToString(stoploss));
   }
   
   return (ModifyTicket);
}

There you go :)!

 
Anyone tried?
Reason: