Download MetaTrader 5

Bars() call strange behaviour

To add comments, please log in or register
Laurentiu Sorin Tene
703
Laurentiu Sorin Tene  

Hello,

I have an EA that I run on a Demo account.

code is like this:

 if(Bars(_Symbol,_Period)>100)
   some code;
  else
    Print("Ai luat teapa;Bars= ",Bars(_Symbol,_Period));   

In Experts tab very rare; something like 1/100 times, I can see this: 

2014.02.13 09:33:59.459 EA_29ian14_best (EURUSD,M1) Ai luat teapa;Bars= 50573 

So what is the explanation that if statement execute the "else" branch ?

Does anyone have meet with this problem ? 

Laurentiu Sorin Tene
703
Laurentiu Sorin Tene  

Meanwhile I found the mystery. This is my EA:

//+------------------------------------------------------------------+
//|                                                         TEST.mq5 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2013, Forex-Experts"
#property link      "http://www.forex-experts.com"
#property version   "1.04"

#include <Trade\Trade.mqh>

input double Lots               = 0.5;
input bool   UseMM              = false;
input double MaximumRisk        = 0.02;    // Maximum Risk in percentage
input double DecreaseFactor     = 3;       // Descrease factor
input double StopLoss           = 15;
input double TakeProfit         = 0;
input double TrailingStop       = 15;
//If you set UseMM=true, MaximumRisk determine the risk of equity to trade.
//If DecreaseFactor>0 then 2 or more consecutive losses the lot size will decrease
// the based on number of losses and Decrease factor using this number lot=lot-lot*losses/DecreaseFactor
//---
int MA_handle=0;
int PozitieDes=0;
double Price=0;
double StLs=0;
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
  {
   if (!UseMM) return(Lots);
   double price=0.0;
   double margin=0.0;
//--- select lot size
   if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
      return(0.0);
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
      return(0.0);
   if(margin<=0.0)
      return(0.0);

   double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_FREEMARGIN)*MaximumRisk/margin,2);
//--- calculate number of losses orders without a break
   if(DecreaseFactor>0)
     {
      //--- select history for access
      HistorySelect(0,TimeCurrent());
      //---
      int    orders=HistoryDealsTotal();  // total history deals
      int    losses=0;                    // number of losses orders without a break

      for(int i=orders-1;i>=0;i--)
        {
         ulong ticket=HistoryDealGetTicket(i);
         if(ticket==0)
           {
            Print("HistoryDealGetTicket failed, no trade history");
            break;
           }
         //--- check symbol
         if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol)
            continue;
         //--- check profit
         double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
         if(profit>0.0)
            break;
         if(profit<0.0)
            losses++;
        }
      //---
      if(losses>1)
         lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
     }
//--- normalize and check limits
   double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   lot=stepvol*NormalizeDouble(lot/stepvol,0);

   double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   if(lot<minvol)
      lot=minvol;

   double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   if(lot>maxvol)
      lot=maxvol;
//--- return trading volume
   return(lot);
  }
//+------------------------------------------------------------------+
//| Check for open position conditions                               |
//+------------------------------------------------------------------+
void CheckForOpen(void)
  {
   double PretPozDes=0;
   if(PositionSelect(_Symbol)==true) // we have an opened position
      PretPozDes=PositionGetDouble(POSITION_PRICE_OPEN);

double MyStopLoss=0,MyTakeProfit=0;  
//--- Define some MQL5 Structures we will use for our trade
   MqlTick latest_price;      // To be used for getting recent/latest price quotes
   MqlRates rt[2];            // To be used to store the prices, volumes and spread of each bar

//--- Get the last price quote using the MQL5 MqlTick Structure
   if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Error getting the latest price quote - error:",GetLastError(),"!!");
      return;
     }

//--- go trading only for first ticks of new bar
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
   double MA[1];
   if(CopyBuffer(MA_handle,0,0,1,MA)<0)
     {
      Alert("Error copying iMA indicator Buffers - error:",GetLastError(),"!!");
      ResetLastError();
      return;
     }     

//--- check signals
   ENUM_ORDER_TYPE signal=WRONG_VALUE;
       if((latest_price.bid < MA[0] && PozitieDes==0) || (latest_price.bid < PretPozDes - 0.00035 && PozitieDes>0 && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL))
        {
         signal=ORDER_TYPE_SELL;    // sell conditions
        }
       if ((latest_price.bid > MA[0] && PozitieDes==0) || (latest_price.ask > PretPozDes + 0.00035 && PozitieDes>0 && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY))
        { 
         signal=ORDER_TYPE_BUY;     // buy conditions
        }
//--------------------------------------------------------------------------------------------
//--- additional checking
   if(signal!=WRONG_VALUE)
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
         if(Bars(_Symbol,_Period)>100)
            {
            CTrade trade;
                       
            if (signal==ORDER_TYPE_SELL) {
               if (TakeProfit==0) MyTakeProfit=0; else MyTakeProfit=SymbolInfoDouble(_Symbol,SYMBOL_BID)-TakeProfit*_Point;
               if (StopLoss==0) MyStopLoss = NormalizeDouble(MA[0],_Digits)+(SymbolInfoDouble(_Symbol,SYMBOL_ASK)-SymbolInfoDouble(_Symbol,SYMBOL_BID)); else MyStopLoss=SymbolInfoDouble(_Symbol,SYMBOL_BID)+StopLoss*_Point;
               Print("SELL MyStopLoss = ",MyStopLoss);
            }
            if (signal==ORDER_TYPE_BUY) {
               if (TakeProfit==0) MyTakeProfit=0; else MyTakeProfit=SymbolInfoDouble(_Symbol,SYMBOL_ASK)+TakeProfit*_Point;
               if (StopLoss==0) MyStopLoss = NormalizeDouble(MA[0],_Digits); else MyStopLoss=SymbolInfoDouble(_Symbol,SYMBOL_ASK)-StopLoss*_Point;            
               Print("BUY MyStopLoss = ",MyStopLoss);
            }
            trade.PositionOpen(_Symbol,signal,TradeSizeOptimized(),
                               SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
                               MyStopLoss,MyTakeProfit);

      if(PositionSelect(_Symbol)==true)
       {
        if (signal==ORDER_TYPE_SELL) {
//               SendNotification(" " + Symbol() + DoubleToString(Period(),0) + " : short signal @ " + DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_BID), Digits()));
         if (PozitieDes==0)
           {
            Print ("Open SELL 1 @ ",latest_price.bid," SL=",PositionGetDouble(POSITION_SL));
            Print ("  BID= ",latest_price.bid, " < MA[0]= ",MA[0]);
           }
          else
           {
            Print ("Open SELL 2 @ ",latest_price.bid," SL=",PositionGetDouble(POSITION_SL));
            Print ("  BID= ",latest_price.bid, " < PretPozDes-0.00035= ",PretPozDes-0.00035);
           }
        }
         if (signal==ORDER_TYPE_BUY) {
//               SendNotification(" " + Symbol() + DoubleToString(Period(),0) + " : long signal @ " + DoubleToString(SymbolInfoDouble(_Symbol,SYMBOL_ASK), Digits()));
          if (PozitieDes==0)
            {
             Print("Open BUY 1 @ ",latest_price.ask," SL=",PositionGetDouble(POSITION_SL));
             Print("  BID= ",latest_price.bid, " > MA[0]",MA[0]);
            }
           else
            {
             Print("Open BUY 2 @ ",latest_price.ask," SL=",PositionGetDouble(POSITION_SL));
             Print("  ASK= ",latest_price.ask," > PretPozDes+0.00035= ",PretPozDes + 0.00035);
            }
         }
//---------------------------------------------------------------------------------------------------------------------------------
HistorySelect(0, TimeCurrent());
Print("Last deal type = "+EnumToString((ENUM_DEAL_TYPE)HistoryDealGetInteger(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_TYPE))); 
Print("Last deal price M = "+DoubleToString(HistoryDealGetDouble(HistoryDealGetTicket(HistoryDealsTotal()-1),DEAL_PRICE),_Digits));
Print("Last deal price J = ",precioCierrePosicAnt(_Symbol));

//---------------------------------------------------------------------------------------------------------------------------------
        PozitieDes=PozitieDes+1;
       }
       else
        Print("Ai luat teapa;Bars= ",Bars(_Symbol,_Period));    
           }
//---
  }
//+------------------------------------------------------------------+
//| Check for close position conditions                              |
//+------------------------------------------------------------------+
void CheckForClose(void)
  {
//--- Define some MQL5 Structures we will use for our trade
   MqlTick latest_price;      // To be used for getting recent/latest price quotes
   MqlRates rt[2];            // To be used to store the prices, volumes and spread of each bar

//--- Get the last price quote using the MQL5 MqlTick Structure
   if(!SymbolInfoTick(_Symbol,latest_price))
     {
      Alert("Error getting the latest price quote - error:",GetLastError(),"!!");
      return;
     }
//--- go trading only for first ticks of new bar
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      return;
     }
   double MA[1];
   if(CopyBuffer(MA_handle,0,0,1,MA)<0)
     {
      Alert("Error copying iMA indicator Buffers - error:",GetLastError(),"!!");
      ResetLastError();
      return;
     }  
//--- positions already selected before
   double PricePosOpen  = PositionGetDouble(POSITION_PRICE_OPEN);

   bool signal=false;
   long type=PositionGetInteger(POSITION_TYPE);
//-------------------------------------------------------------------------------------------------------
   if(type==(long)POSITION_TYPE_BUY)
    if(latest_price.bid < MA[0] && latest_price.bid > PricePosOpen)
     {
      signal=true;
      Print ("Close BUY win BID=",latest_price.bid," > PricePosOpen=",PricePosOpen);
     }
   if(type==(long)POSITION_TYPE_SELL)
    if(latest_price.bid > MA[0] && latest_price.ask < PricePosOpen)
     {
      signal=true;
      Print ("Close SELL win ASK=",latest_price.ask," < PricePosOpen=",PricePosOpen); 
     } 
//-----------------------------------------------------------------------------------------------------

     
//--- additional checking
   if(signal)
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED))
         if(Bars(_Symbol,_Period)>100)
           {
            CTrade trade;
            trade.PositionClose(_Symbol,3);
            if (type==(long)POSITION_TYPE_BUY ) {
              Print("  : long(BUY) exit signal @ BID= ",SymbolInfoDouble(_Symbol,SYMBOL_BID)," Sym_ASK=",SymbolInfoDouble(_Symbol,SYMBOL_ASK)," Sym_LAST=",SymbolInfoDouble(_Symbol,SYMBOL_LAST),"l_p.ask=",latest_price.ask," MA[0]=",MA[0]);
             }
            if (type==(long)POSITION_TYPE_SELL) {
              Print("  : short(SELL) exit signal @ ASK= ",SymbolInfoDouble(_Symbol,SYMBOL_ASK)," Sym_BID=",SymbolInfoDouble(_Symbol,SYMBOL_BID)," Sym_LAST=",SymbolInfoDouble(_Symbol,SYMBOL_LAST),"l_p.bid=",latest_price.bid," MA[0]=",MA[0]);
             }
           }
//---
  }
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(void)
  {
   Print("START EA");
//---
  //--- creation of the indicator iMA
   MA_handle=iMA(NULL,0,3,0,MODE_SMA,PRICE_CLOSE);
  //--- report if there was an error in object creation
   if(MA_handle<0)
      {
      Print("The creation of iMA has failed: MA_handle=",INVALID_HANDLE);
      Print("Runtime error = ",GetLastError());
      //--- forced program termination
      return(-1);
      }
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
  {
//---
   if(!PositionSelect(_Symbol) || (PositionSelect(_Symbol) && PozitieDes == 1)) 
     {
      if(!PositionSelect(_Symbol))
       {
        PozitieDes=0;
       }
      CheckForOpen();
     }
    else  
     {
      CheckForClose();
     }
   if(TrailingStop>0 && PositionSelect(Symbol()))
     {
      int type=(int)PositionGetInteger(POSITION_TYPE);
      StLs=PositionGetDouble(POSITION_SL);
      double PRopen=PositionGetDouble(POSITION_PRICE_OPEN);
      if(type==0) // avem BUY deschis
        {
         double bid=SymbolInfoDouble(Symbol(),SYMBOL_BID);
         Price=bid-TrailingStop*_Point;
         if((PRopen < Price && StLs < Price && StLs>0) || StLs==0) Modifi_Position(Price);
        }
    //---
      if(type==1) // avem SELL deschis
        {
         double ask=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
         Price=ask+TrailingStop*_Point;
      if((PRopen > Price && StLs > Price && StLs>0) || StLs==0) Modifi_Position(Price);
        }
     }

//---
  }

void Modifi_Position(double _trail)
  {
   if(!PositionSelect(Symbol())) return;
   double prof_prv=PositionGetDouble(POSITION_TP);
   double sl_prv=PositionGetDouble(POSITION_SL);
   double VolPozDes=PositionGetDouble(POSITION_VOLUME);
   
   MqlTradeRequest prequest; MqlTradeResult presult; ZeroMemory(prequest);

   prequest.action = TRADE_ACTION_SLTP;
   prequest.symbol = Symbol();
   prequest.sl     = NormalizeDouble(_trail,Digits());
   prequest.tp     = prof_prv;
   prequest.volume = VolPozDes;
   if (MathAbs(sl_prv-NormalizeDouble(_trail,Digits()))>=_Point) {
//---
   if(!OrderSend(prequest,presult))
      Print("error modify SL = ",__FUNCTION__,": ",presult.comment," answer code ",presult.retcode);
     else
      if(PositionGetInteger(POSITION_TYPE)==0)
       Print("StLs= ",StLs," POS_SL= ",PositionGetDouble(POSITION_SL)," Pret=BID-TS= ",SymbolInfoDouble(Symbol(),SYMBOL_BID)-TrailingStop*_Point);
      if(PositionGetInteger(POSITION_TYPE)==1) 
       Print("StLs= ",StLs," POS_SL= ",PositionGetDouble(POSITION_SL)," Pret=ASK+TS= ",SymbolInfoDouble(Symbol(),SYMBOL_ASK)+TrailingStop*_Point);
   }
  
  }
//------------------------------------------------------------------------------
double precioCierrePosicAnt(string simb= NULL)
{
   int      i, nTrans= 0;
   ulong    ticket= 0;
   ENUM_DEAL_ENTRY tipoTrans= DEAL_ENTRY_IN;
   string   simbPosic= "";
   double   precioTrans = 0;
   datetime horaApertAct= PositionSelect(simb)? (datetime)PositionGetInteger(POSITION_TIME): TimeCurrent();
   if(HistorySelect(0, horaApertAct-1))
   {
      nTrans= HistoryDealsTotal();
      for(i= nTrans-1; i>=0; i--)
      {
         ticket= HistoryDealGetTicket(i);
         simbPosic= HistoryDealGetString(ticket, DEAL_SYMBOL);
         precioTrans= HistoryDealGetDouble(ticket, DEAL_PRICE);
         tipoTrans= (ENUM_DEAL_ENTRY)HistoryDealGetInteger(ticket, DEAL_ENTRY);
         if(simbPosic==simb && tipoTrans==DEAL_ENTRY_OUT) break;
      }
   }
   return(precioTrans);
}



If I comment the line that call the precioCierrePosicAnt() function the problem disappear. So the only explanation I have is that the problem is on synchronization with the trade server. But according to Docs about Bars() 

Note

If data for the timeseries with specified parameters are not formed in the terminal by the time of the Bars() function call, or data of the timeseries are not synchronized with a trade server by the moment of the function call, the function returns a zero value.

 

So, arise another question. In my EA Bars=50573, as you see on my previous post. Are Docs wrong ? Is my thinking wrong ?

I wait your opinions ! 

Laurentiu Sorin Tene
703
Laurentiu Sorin Tene  

Sorry to inform everybody that my conclusion was wrong. I let the EA to run more time and I notice the problem arise again. So not the call of precioCierrePosicAnt() is the problem.

Anyway this is a random (or I can not determine the cause) problem.

Please test the code in your terminal, account and give some opinions 

Rogerio Figurelli
Moderator
43045
Rogerio Figurelli  
tenlau:

Sorry to inform everybody that my conclusion was wrong. I let the EA to run more time and I notice the problem arise again. So not the call of precioCierrePosicAnt() is the problem.

Anyway this is a random (or I can not determine the cause) problem.

Please test the code in your terminal, account and give some opinions 

tenlau, not necessary test the code in the terminal, since the problem looks simple.

Note that Bars() is a dynamic return function, so, to avoid the value change while debugging, you must use a variable to save it, instead of calling Bars() again in your Print().

For instance:

int bars=Bars(_Symbol,_Period);
if (bars>100) {
   ...
}
else {
   ...
}

This also explain the factor 1/100, that is exactly the situations where the second read of Bars() is getting the real/expected value.

Laurentiu Sorin Tene
703
Laurentiu Sorin Tene  
figurelli:

tenlau, not necessary test the code in the terminal, since the problem looks simple.

Note that Bars() is a dynamic return function, so, to avoid the value change while debugging, you must use a variable to save it, instead of calling Bars() again in your Print().

For instance:

This also explain the factor 1/100, that is exactly the situations where the second read of Bars() is getting the real/expected value.

Ok I changed the code as in your post. Problem remains. I mean bars=50000 (which is the maximum bars set on chart). So what is the explanation for execution of else (false) branch, because 50000 is greater than 100, so the true branch of if statement should be executed ?
Rogerio Figurelli
Moderator
43045
Rogerio Figurelli  
tenlau:
Ok I changed the code as in your post. Problem remains. I mean bars=50000 (which is the maximum bars set on chart). So what is the explanation for execution of else (false) branch, because 50000 is greater than 100, so the true branch of if statement should be executed ?

You are printing Bars() or variable bars?

If you print bars, and 50000>100 is sometime false, then probably we have a leak problem, but I don't think so.

Laurentiu Sorin Tene
703
Laurentiu Sorin Tene  
figurelli:

You are printing Bars() or variable bars?

If you print bars, and 50000>100 is sometime false, then probably we have a leak problem, but I don't think so.

You got the point, I print variable bars. I am stuck I don't know how to fix this !
Laurentiu Sorin Tene
703
Laurentiu Sorin Tene  
OK got it. Was a coding problem. The else branch that print variable bar is not from if (bars>100 statement !
Rogerio Figurelli
Moderator
43045
Rogerio Figurelli  
tenlau:
OK got it. Was a coding problem. The else branch that print variable bar is not from if (bars>100 statement !
Very good, I suggest you revise the source code indentation to avoid similar future problems.
Alain Verleyen
Moderator
33236
Alain Verleyen  
tenlau:
OK got it. Was a coding problem. The else branch that print variable bar is not from if (bars>100 statement !

I suggest you to use the styler to avoid such waste of time.

Rogerio Figurelli
Moderator
43045
Rogerio Figurelli  
angevoyageur:

I suggest you to use the styler to avoid such waste of time.

Indeed, well remembered.
12
To add comments, please log in or register