4108 error

 

I don't know why this is happening and how to over come it but it's getting me nuts.

The same code works properly if i don't include the calculatelotsize() and the if(){lots/2} condition. But when i include these the EA fails to close the orders...

I tried assigning indivdual tickets to each trade but even then it does the same thing. Please point out my mistakes and the way to avoid them. SLB,TPB,SLS,TPS are stoploss and take profit for buy(B) and sell(S).

void ADXMACDMARSI()
{
      int ticket=0;
      int ticket1=0;
       ADX=iADX(Symbol(),0,per_ADX,PRICE_OPEN,MODE_MAIN,0);
      nowpdi=iADX(Symbol(),0,per_ADX,PRICE_OPEN,MODE_PLUSDI,0);
          nowmdi=iADX(Symbol(),0,per_ADX,PRICE_OPEN,MODE_MINUSDI,0);
        
   MacdCurrent=iMACD(NULL,0, FastEMA, SlowEMA,SignalSMA,PRICE_CLOSE,MODE_MAIN,0);
   SignalCurrent=iMACD(NULL,0, FastEMA, SlowEMA,SignalSMA,PRICE_OPEN,MODE_SIGNAL,0);
   
    FMA=iMA(NULL,0,MPeriod1,0,MODE_SMA,PRICE_OPEN,0);
   SMA=iMA(NULL,0,MPeriod2,0,MODE_SMA,PRICE_OPEN,0);
   
    SLB=NormalizeDouble(Ask-Stoploss*Point,4);
   TPB=NormalizeDouble(Ask+takeprofit*Point,4);

   SLS=NormalizeDouble(Bid+Stoploss*Point,4);
   TPS=NormalizeDouble(Bid-takeprofit*Point,4);
   
    rsi=iRSI(Symbol(),0,14,PRICE_CLOSE,0);
      
             if(rsi<=40 && FMA>SMA && MacdCurrent>SignalCurrent  && nowpdi>nowmdi && buycond==true && ADX>=30 && ADX>nowpdi && ADX>nowmdi)
                        {
                       checkcloseADXMACDMARSI();
                        ticket=OrderSend(Symbol(),OP_BUY,CalculateLotSize(),Ask,3,SLB,TPB,"",1986,0,Red); // open new BUY Order for ADX
                         if(ticket>0)
                            {
                             if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY order opened : ",OrderOpenPrice());
                               Alert("BUY MACDMA");
                            }
                        else
                           {
                              Print("Error opening BUY order : ",GetLastError());      
                               RefreshRates();
                              ticket=OrderSend(Symbol(),OP_BUY,CalculateLotSize(),Ask,3,SLB,TPB,"",1986,0,Red); // open new BUY Order for ADX
                           }
                         buycond=false;
                        sellcond=true;
                       }
                       
                       if(rsi>=70 && FMA<SMA && MacdCurrent<SignalCurrent && nowpdi<nowmdi  && sellcond==true && ADX>=30 && ADX>nowpdi && ADX>nowmdi) 
                       {
                       checkcloseADXMACDMARSI();
                       ticket1=OrderSend(Symbol(),OP_SELL,CalculateLotSize(),Bid,3,SLS,TPS,"",1986,0,Blue);//open new Sell Order for MACD
                          if(ticket>0)
                            {
                             if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL order opened : ",OrderOpenPrice());
                             Alert("SELL MACDMA");
                            }
                          else 
                          {
                          Print("Error opening SELL order : ",GetLastError());  
                          RefreshRates();
                          ticket1=OrderSend(Symbol(),OP_SELL,CalculateLotSize(),Bid,3,SLS,TPS,"",1986,0,Blue);//open new Sell Order for MACD
                          }
                       buycond=true;
                       sellcond=false;
                       }
                       
                       
     if(buycond==false && Bid<OrderOpenPrice())
      {
          OrderClose(OrderTicket(),OrderLots()/2,Bid,3,Snow);      
      }
      
      if(sellcond==false && Ask>OrderOpenPrice())
      {
         OrderClose(OrderTicket(),OrderLots()/2,Ask,3,Gold);         
      }
      
}
void checkcloseADXMACDMARSI()
{
for(int e=OrdersTotal()-1;e>=0;e--)
     {
      if(OrderSelect(e,SELECT_BY_POS,MODE_TRADES)==false)        break;
      if(OrderMagicNumber()!=1986 || OrderSymbol()!=Symbol()) continue;
      if(OrderType()==OP_BUY)
      {
     if(rsi>=40 && FMA<SMA && MacdCurrent<SignalCurrent && nowpdi<nowmdi)
      {
     // if(OrderProfit()>=0)
      OrderClose(OrderTicket(),OrderLots(),Ask,3,Gold);
      OrderClose(OrderTicket(),OrderLots(),Bid,3,Snow);
      Print("Buy order closed");
      }
      break;
      }
      if(OrderType()==OP_SELL)
      {
   if(rsi<=70 && FMA>SMA && MacdCurrent>SignalCurrent  && nowpdi>nowmdi)
      {
      //if(OrderProfit()>=0)
      OrderClose(OrderTicket(),OrderLots(),Bid,3,Snow);     
      OrderClose(OrderTicket(),OrderLots(),Ask,3,Gold);
      Print("SELL order closed");
      }
      break;
      }

    }//close bracket for for loop
}// close bracket for checkclose
//-----------------------------------------------------------------------------------------------


//-------------------------------------------+
double CalculateLotSize()
{


    if(FixedLots > 0.0)
        return (FixedLots);

    double pipValue = MarketInfo(Symbol(), MODE_TICKVALUE);
    double lots = AccountFreeMargin()*Risk/ (StopLoss * pipValue);
    
    double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
    int digits = 0;
    if(lotStep <= 0.01)
        digits = 2;
    else if(lotStep <= 0.1)
        digits = 1;
    lots = NormalizeDouble(lots, digits);
      
      double minLots = MarketInfo(Symbol(), MODE_MINLOT);
      if(lots < minLots)
          lots = minLots;
      
      double maxLots = MarketInfo(Symbol(), MODE_MAXLOT);
      if(lots > maxLots)
          lots = maxLots;
      
      return (lots);
}

U can try to modify the values if required....

Thanks and Regards,

Rohit

 

I see the probable reason.

.

It is the construction:

"for(int e=OrdersTotal()-1;e>=0;e--)"

Inside this construction there are:

1. one function "OrderSelect()"
2. many functions "OrderClose()"

After first succesful "OrderClose()" using valid "OrderTicket()" of selected order all others "OrderClose()" will use invalid "OrderTicket()", that is ticket of another order, "error code 4108 = invalid ticket" !

Solution:

1. Instead of "for(int e=OrdersTotal()-1;e>=0;e--)" use

"

int N = OrdersTotal()-1;

for(int e=N;e>=0;e--)

"

2. For single "OrderSelect()" use single "OrderClose()".

.

And advice: use "OrderClosePrice()" instead of any other price in function "OrderClose()", for example, "OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Gold);".

.

Good Luck !

 

Thank you Sir, :)

 

ksrohit2712:

The same code works properly if i don't include the calculatelotsize() and the if(){lots/2} condition.

  1. double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
        int digits = 0;
        if(lotStep <= 0.01)
            digits = 2;
        else if(lotStep <= 0.1)
            digits = 1;
        lots = NormalizeDouble(lots, digits);
    
    Lots must be a multiple of LotStep. but there is no reason why it must be 0.1 or 0.01. Lots/2 also will not be correct.
        double  minLot  = MarketInfo(Symbol(), MODE_MINLOT),
                LotStep = MarketInfo(Symbol(), MODE_LOTSTEP),
            size = MathFloor(size/LotStep)*LotStep;
            if (size < minLot){ ...

  2. Always count down when modifying orders. Must for delete/close or when other EAs or human can add, change, or delete
 
Thank you Sir
Reason: