Backtesting interpretation

pasquale87  

Hi, I'm new to mql. I wrote simple EA based on stochastic oscillator. I don't understand backtesting:

Why are there more arrows in red circle on the same bar? Maybe I open a position without before close another position? I tried checking if PositionsTotal()<1 before orderSend, but it seems not working. Thanks in advance for your helping.

backtestingChart


I add code for better explanation:

void OnTick()
  {
        string signal = "";

        double karray[], darray[];

        ArraySetAsSeries(karray,true);
        ArraySetAsSeries(darray, true);

        int stocasticDefinition = iStochastic(_Symbol, _Period, 5, 3, 3, MODE_SMA, STO_LOWHIGH);

        CopyBuffer(stocasticDefinition,0,0,3,karray);
        CopyBuffer(stocasticDefinition,1,0,3,darray);

        double kvalue0 = karray[0];
        double dvalue0 = darray[0];

        double kvalue1 = karray[1];
        double dvalue1 = darray[1];  
        
        if (kvalue0 < 20 && dvalue0 < 20) {
                if ((kvalue0 > dvalue0) && (kvalue1 < dvalue1)) {
                        signal = "buy"; 
                        openOrder(signal);                              
                }
        }

        if (kvalue0 > 80 && dvalue0 > 80) {
                if ((kvalue0 < dvalue0) && (kvalue1 > dvalue1)) {
                        signal = "sell";        
                        openOrder(signal);
                }
        }       
   
  }

void openOrder(string signal) {
        
        MqlTradeRequest request={0};
        MqlTradeResult response={0};
        
        double tp = 0.0;
        double sl = 0.0;
        if (signal == "sell") {
                double prezzo_corrente = SymbolInfoDouble(_Symbol,SYMBOL_BID);
                tp = prezzo_corrente - 0.002;
                sl = prezzo_corrente + 0.001;
                request.type = ORDER_TYPE_SELL;
        }
        if (signal == "buy") {  
                double prezzo_corrente = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
                tp = prezzo_corrente + 0.002;
                sl = prezzo_corrente - 0.001;   
                request.type = ORDER_TYPE_BUY;
        }
 
        request.action = TRADE_ACTION_DEAL;
        request.symbol =_Symbol;
        request.volume = 0.01;
        request.type_filling = ORDER_FILLING_FOK;
        
        request.tp = tp;
        request.sl = sl;
        request.deviation = 5;
        

        if (PositionsTotal()<1)) {
                bool risp = OrderSend(request, response);
                if(!risp) {
                        PrintFormat("OrderSend error: %d", response.retcode);
                } else {
                        PrintFormat("DONE: DEAL=%I64u  ORDER=%I64u", response.deal,response.order);
                        Print("ACCOUNT PROFIT = ", AccountInfoDouble(ACCOUNT_PROFIT), "; ACCOUNT BALANCE", AccountInfoDouble(ACCOUNT_BALANCE));
                }
        }
}
Keith Watford  

Why have you posted in the MQL4 section??

I will move your topic to the EA section.

Khuman Bakhramirad  

it had a bug and also i think it was triggering your TP or SL and opening another order in same Candle so i added a NewBAr function which will only open order if its a new bar

so basically one order in one candle

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   string signal = "";

   double karray[], darray[];

   ArraySetAsSeries(karray,true);
   ArraySetAsSeries(darray, true);

   int stocasticDefinition = iStochastic(_Symbol, _Period, 5, 3, 3, MODE_SMA, STO_LOWHIGH);

   CopyBuffer(stocasticDefinition,0,0,3,karray);
   CopyBuffer(stocasticDefinition,1,0,3,darray);

   double kvalue0 = karray[0];
   double dvalue0 = darray[0];

   double kvalue1 = karray[1];
   double dvalue1 = darray[1];

   if(kvalue0 < 20 && dvalue0 < 20)
     {
      if((kvalue0 > dvalue0) && (kvalue1 < dvalue1))
        {
         signal = "buy";
         openOrder(signal);
        }
     }

   if(kvalue0 > 80 && dvalue0 > 80)
     {
      if((kvalue0 < dvalue0) && (kvalue1 > dvalue1))
        {
         signal = "sell";
         openOrder(signal);
        }
     }

  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void openOrder(string signal)
  {

   MqlTradeRequest request= {0};
   MqlTradeResult response= {0};

   double tp = 0.0;
   double sl = 0.0;
   if(signal == "sell")
     {
      double prezzo_corrente = SymbolInfoDouble(_Symbol,SYMBOL_BID);
      tp = prezzo_corrente - 0.002;
      sl = prezzo_corrente + 0.001;
      request.type = ORDER_TYPE_SELL;
      request.price=prezzo_corrente;
     }
   if(signal == "buy")
     {
      double prezzo_corrente = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
      tp = prezzo_corrente + 0.002;
      sl = prezzo_corrente - 0.001;
      request.type = ORDER_TYPE_BUY;
      request.price=prezzo_corrente;
     }

   request.action = TRADE_ACTION_DEAL;
   request.symbol =_Symbol;
   request.volume = 0.01;
   request.type_filling = ORDER_FILLING_FOK;
   
   request.tp = tp;
   request.sl = sl;
   request.deviation = 5;


   if(PositionsTotal()<1 && isNewBar())
     {
      bool risp = OrderSend(request, response);
      if(!risp)
        {
         PrintFormat("OrderSend error: %d", response.retcode);
        }
      else
        {
         PrintFormat("DONE: DEAL=%I64u  ORDER=%I64u", response.deal,response.order);
         Print("ACCOUNT PROFIT = ", AccountInfoDouble(ACCOUNT_PROFIT), "; ACCOUNT BALANCE", AccountInfoDouble(ACCOUNT_BALANCE));
        }
     }
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//|         check if new bar has appeard                                                         |
//+------------------------------------------------------------------+
static int BARS;

bool isNewBar()
  {
   if(BARS!=Bars(_Symbol,_Period))
     {
      BARS=Bars(_Symbol,_Period);
      return(true);
     }
   return(false);
  }
pasquale87  
Keith Watford:

Why have you posted in the MQL4 section??

I will move your topic to the EA section.

Sorry, I'm wrong
pasquale87  
Khuman Bakhramirad:

it had a bug and also i think it was triggering your TP or SL and opening another order in same Candle so i added a NewBAr function which will only open order if its a new bar

so basically one order in one candle

Thanks a lot, now it works! Sorry, another question: when i try to show
AccountInfoDouble(ACCOUNT_PROFIT)
I visualize the same profit for all trades, also if the balance is changed. What I'm wrong?
William Roeder  
   if(BARS!=Bars(_Symbol,_Period))

For a new bar test, Bars is unreliable (a refresh/reconnect can change number of bars on chart), volume is unreliable (miss ticks), Price is unreliable (duplicate prices and The == operand. - MQL4 programming forum.) Always use time.
          New candle - MQL4 programming forum #3 2014.04.04

I disagree with making a new bar function, because it can only be called once per tick. A variable can be tested multiple times.
          Running EA once at the start of each bar - MQL4 programming forum 2011.05.06

Reason: