OrderClose Error 4051 - Invalid Ticket

 

Hey Guys,

my skills in MQL4 aren't that sophisticated so I have no idea why I get the Error 4051 all the time. It would be also very helpful I one could explain in more detail to me what an invalid ticket is, maybe I'll figure it out by my own then.

Thanks in advance!

This should the relevant part of the code:

// BUY Order 
    if(Trend == 1 && OrdersTotal() == 0 && OpenPosition == false && Trade == true) // GreenLock
      {
      RefreshRates();
      
      TicketBUY = OrderSend(Symbol(),OP_BUY,1,Ask,3,0,0,"BUY",16384,0,Green);
      //Print ("1   " + TicketBUY);
      BarsAtTrade = Bars;
      TRStop = ArrayAverage - Volatility ;
      OpenPosition = true;
      
      }
      
    // Close BUY Order
    
    if ((Trend == 0 || Trend == -1) && OpenPosition == true)
      {
      if(OrderSelect(TicketBUY, SELECT_BY_TICKET) == true)
         {
         TicketBUY=OrderTicket();
         Print("T " + TicketBUY);
         OrderClose(TicketBUY,1,Bid,0,Red);
         OpenPosition = false;
         }
 
luedman:

Hey Guys,

my skills in MQL4 aren't that sophisticated so I have no idea why I get the Error 4051 all the time. It would be also very helpful I one could explain in more detail to me what an invalid ticket is, maybe I'll figure it out by my own then.

Thanks in advance!

This should the relevant part of the code:

Did your OrderSend() work ? if it didn't what is the value of TicketBUY ? and what happens when you try to do an OrderSelect() with that ticket number ?


You really need to read, understand and implement this: What are Function return values ? How do I use them ?

 

Error 4051 is not Invalid Ticket.

Maybe you need to look elsewhere in your code to find the problem

ERR_INVALID_FUNCTION_PARAMVALUE 4051 Invalid function parameter value.
 

@GumRai

In this case it is an invalid Ticket:

2013.10.14 11:54:18 1999.12.28 00:00 Moving Average EURUSD,H4: OrderClose error 4051

2013.10.14 11:54:18 1999.12.28 00:00 Moving Average EURUSD,H4: invalid ticket for OrderClose function

@RaptorUK

The OrderSend() did work. When I Print TicketBUY, I get the value of 1.

Thats why I'm wondering. It opens a long position (with TicketBUY = 1) and then it does not close it afterwards. And I get the Error.

 
luedman:

@GumRai

In this case it is an invalid Ticket:

2013.10.14 11:54:18 1999.12.28 00:00 Moving Average EURUSD,H4: OrderClose error 4051

2013.10.14 11:54:18 1999.12.28 00:00 Moving Average EURUSD,H4: invalid ticket for OrderClose function

@RaptorUK

The OrderSend() did work. When I Print TicketBUY, I get the value of 1.

Thats why I'm wondering. It opens a long position (with TicketBUY = 1) and then it does not close it afterwards. And I get the Error.

So what is the value of TicketBUY when OrderClose() is called ? is TicketBUY a static variable ? are you reporting the error when the OrderClose() fails as well as the relevant variables, i.e. TicketBuy, Bid, Ask, Freezlevel, etc ?


Did you read, understand and implement this: What are Function return values ? How do I use them ?
 

Use Edit/Find and check all instances of TicketBUY in your code.

Assuming that TicketBUY has to be a global scope variable, make sure that a different ticket number is not assigned to it or that you don't re-declare it

 

Thanks for your Input!

Well TicketBUY is global variable. I actually don't know what static exactly means is that context.

TicketBUY is only used in the small part of the code I've posted above.

@Raptor: Yes I did read your article and I thought that I had undestood it. My EA buys something, that works fine. TicketBUY gets the value of 1 then. But when the conditions for closing the order are fullfilled it fails and produces the error. At that time, there is only one long position and no other positions else (I'm focusing on the long side first here, before I change the short side).

That target of this EA should be, to be invested long when the trend is going up (then the EA draws green dots), short when the trend goes down (red) and there should be no position when there is no trend (grey dots).

So if you guys could show me, how to write the following code, than I might just rewrite it and maybe it'll work then:

if ( Bunying conditions)

-> BUY

if (closing long position conditions)

-> Close that one order from above

Since I just want to have ONE position at the same time only, that should be that hard, right? I have no idea why I can't get this simple task done...

I posted the whole code below, maybe that helps.

//+------------------------------------------------------------------+
//|                                                 Multi MAs .mq4   |
//|                                   Copyright 2013, Lukas Schreiner|
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, Lukas Schreiner."

   int n;
   int i;
   int BarLock;
   
   double ArraySum;
   double ArrayAverage;
   double ArrayAverage1;
   double ValueLastDot;
   double ValueLastDot1;
   double Sum;
   double Average;
   double DotGrowth;
   int Trend;
   
   
   string ObjNameDot;
   string ObjNameTR;
   int TimeLastBar;
   
   int TicketBUY;
   int TicketSELL;
   int BarsAtTrade;
   double TRStop;
   bool OpenPosition;
   bool Trade;
   
   
   int init()
   {
   i = 1;
   OpenPosition = false;
   return(0);
   }
   
   
   int start()
   {
   
   if (BarLock != Bars) // Bar Lock Start
   
      {     //BarLockStart - Things in Brackest will only calculated once per bar
      ObjNameDot = StringConcatenate("Dot",Bars);
      ObjNameTR = StringConcatenate("TRStop",Bars);
      
      ObjectCreate(ObjNameDot,OBJ_ARROW,0,TimeCurrent(),ArrayAverage);
      ObjectCreate(ObjNameTR,OBJ_ARROW,0,TimeCurrent(),TRStop);
      
      TRStop = ArrayAverage * (1 + (Bars - BarsAtTrade)*0.0005); // Faktor def!
      
      
      if (ValueLastDot1 != 0 && ValueLastDot != 0)
         {
         DotGrowth = 100*((ValueLastDot - ValueLastDot1)/ValueLastDot1);
         
         Sum = Sum + MathSqrt(DotGrowth*DotGrowth);
         
         Average = Sum/i;
         i++;
         //Print (Average  + "    " +  MathSqrt(DotGrowth*DotGrowth));
         
         if (i > 1000000) //Reset
            {
            i = 1;
            Sum = 0;
            }
         }
         
      if (ArrayAverage > ValueLastDot)
         {
         ObjectSet(ObjNameDot,OBJPROP_COLOR,Green);
         Trend = 1;
         }
    
      if (ArrayAverage < ValueLastDot)
        {
         ObjectSet(ObjNameDot,OBJPROP_COLOR,Red);
         Trend = -1;
        }
    
      if (MathSqrt(DotGrowth*DotGrowth) <  (Average)) // Factor before Average? 
         {
         ObjectSet(ObjNameDot,OBJPROP_COLOR,Gray);
         Trend = 0;
         }
      
         ValueLastDot1 = ValueLastDot; 
         ValueLastDot  = ArrayAverage;
         
      
      }     
    
    BarLock = Bars; //BarLockEnd 
   
   // General Info
   
   double Price = iMA(NULL,0,1,0,MODE_SMA,PRICE_CLOSE,0);
   
   double Volatility = (iMA(NULL,0,50,0,MODE_SMA,PRICE_HIGH,0)) - (iMA(NULL,0,50,0,MODE_SMA,PRICE_LOW,0));
   
   // Getting Average of MAs 
   
   while (n < 50)
      {
      double MA[50]; 
      MA[n] = iMA(NULL,0,n,0,MODE_SMA,PRICE_CLOSE,0);
      //Print ("Check  " + MA[n]);
      
      ArraySum = ArraySum + MA[n];
      ArrayAverage = ArraySum/49;
      n++;
      }
    
    if (n == 50)
      {
      n = 1;
      }
    
    //Drawing Dots
    
    ObjectSet(ObjNameDot,OBJPROP_ARROWCODE,119);
    ObjectMove(ObjNameDot,0,TimeCurrent(),ArrayAverage);
    
    // TR Stop Object
   
    ObjectSet(ObjNameTR,OBJPROP_ARROWCODE,119);
    ObjectSet(ObjNameTR,OBJPROP_COLOR,Blue);
    ObjectMove(ObjNameTR,0,TimeCurrent(),TRStop);
    
    // BUY Order 
    if(Trend == 1 && OrdersTotal() == 0 && OpenPosition == false) // GreenLock
      {
      RefreshRates();
      
      TicketBUY = OrderSend(Symbol(),OP_BUY,1,Ask,3,0,0,"BUY",16384,0,Green);
      //Print ("1   " + TicketBUY);
      BarsAtTrade = Bars;
      TRStop = ArrayAverage - Volatility ;
      OpenPosition = true;
      
      }
      
    
    // Close BUY Order
    if ((Trend == 0 || Trend == -1) && OpenPosition == true)
      {
      Print(TicketBUY);
      if(OrderSelect(TicketBUY, SELECT_BY_TICKET) == true)
         {
         
         Print("T " + TicketBUY);
         OrderClose(TicketBUY,1,Bid,0,Red);
         OpenPosition = false;
         }
      }
      
      
     
    // SELL Order 
    if(Trend == -1 && OrdersTotal() == 0 && OpenPosition == false && Trade == true) // GreenLock
      {
      RefreshRates();
      TicketSELL = OrderSend(Symbol(),OP_SELL,1,Bid,3,0,0,"SELL",16384,0,Red);
      
      
      if (OrderSelect(TicketSELL,SELECT_BY_TICKET) == true)
         {
         BarsAtTrade = Bars;
         TRStop = ArrayAverage - Volatility ;
         OpenPosition = true;
         }
      }
      
    // Close SELL Order
    if (Trend > -1  && OpenPosition == true)
      {
      OrderClose(TicketSELL,1,Ask,0,Green);
      OpenPosition = false;
      }
    
    // RESET
    ArrayAverage1 = ArrayAverage;
    ArraySum = 0;
    Trade = false;
    HideTestIndicators(true);
    
   return(0);
   }
 
luedman:

Thanks for your Input!

Well TicketBUY is global variable. I actually don't know what static exactly means is that context.

TicketBUY is only used in the small part of the code I've posted above.

@Raptor: Yes I did read your article and I thought that I had undestood it.

And you chose to ignore it . . . you don't check the return value from your OrderSend() you don't check the return value from your OrderClose() . . . had you done so and printed the relevant variables in the case of an error you probably could have fixed your code by now . . . I guess you want someone else to do it for you.
 
RaptorUK:
. I guess you want someone else to do it for you.

Here is your error . . .

2013.10.14 22:19:18 2007.10.01 01:00 MultiMAs EURUSD,H1: OrderClose failed. TicketSELL: 0 Ask 1.42692 Bid 1.42690 Error: 4051

2013.10.14 22:19:18 2007.10.01 01:00 MultiMAs EURUSD,H1: OrderClose error 4051

2013.10.14 22:19:18 2007.10.01 01:00 MultiMAs EURUSD,H1: invalid ticket for OrderClose function

2013.10.14 22:19:18 2007.10.01 01:00 MultiMAs EURUSD,H1: open #1 buy 1.00 EURUSD at 1.42692 ok

. . . your code opens a BUY and then tries to close a SELL with a ticket number of 0, why ? there isn't a SELL open so why do you try to close one ?

10 minutes of coding and testing.

 

I did that in former versions of the code. But it doesn't help me to understand the problem better.

If I use Print() functions like shown below, the journal shows only ouputs of the first and second Print() functions ( ->Print("2: " + TicketBUY); ) But why doesn't it get to the third one? The third one is even before the OrderClose()

Thats the journal:

2013.10.14 23:28:33 2013.10.11 04:03 Moving Average USDJPY,M1: OrderClose error 4051

2013.10.14 23:28:33 2013.10.11 04:03 Moving Average USDJPY,M1: invalid ticket for OrderClose function

2013.10.14 23:28:33 2013.10.11 04:03 Moving Average USDJPY,M1: 2: 1

2013.10.14 23:28:33 2013.10.11 04:03 Moving Average USDJPY,M1: 1: 1

// BUY Order 
    if(Trend == 1 && OrdersTotal() == 0 && OpenPosition == false) // GreenLock
      {
      RefreshRates();
      
      TicketBUY = OrderSend(Symbol(),OP_BUY,1,Ask,3,0,0,"BUY",16384,0,Green);
      //Print ("1   " + TicketBUY);
      Print("1: " + TicketBUY);
      BarsAtTrade = Bars;
      TRStop = ArrayAverage - Volatility ;
      OpenPosition = true;
      return(0);
      }
      
    Print("2: " + TicketBUY);
    // Close BUY Order
    if ((Trend == 0 || Trend == -1) && OpenPosition == true)
      {
      Print("3: " + TicketBUY);
      if(OrderSelect(TicketBUY, SELECT_BY_TICKET) == true)
         {
         Print("4: " + TicketBUY);
         OrderClose(TicketBUY,1,Bid,0,Red);
         
         OpenPosition = false;
         }
      }
 
luedman:

I did that in former versions of the code. But it doesn't help me to understand the problem better.

If I use Print() functions like shown below, the journal shows only ouputs of the first and second Print() functions ( ->Print("2: " + TicketBUY); ) But why doesn't it get to the third one? The third one is even before the OrderClose()


Because Trend is not 0 and is not -1 . . . what is the value of Trend ? why aren't you Printing it ? and why are you showing the code for the Buy OrderClose() when the error is coming from the Sell OrderClose() ? did you read my post above ?

    // Close SELL Order
    if (Trend > -1  && OpenPosition == true)
      {
      if(!OrderClose(TicketSELL,1,Ask,0,Green) )
         {
         Print("OrderClose failed. TicketSELL: ", TicketSELL, " Ask ", DoubleToStr(Ask, Digits), " Bid ", DoubleToStr(Bid, Digits), " Error: ", GetLastError() );
         }
         
      OpenPosition = false;
      }

If Trend is greater than -1 and you have any open position then you try to close a SELL, you don't even try to OrderSelect() it as you do with the Buy OrderClose() code . . .

Reason: