INVALIDE VOLUMES error on backtest

 

Hi guys, I wanna know if anyone cand help me to fix this problem. I try to put my EA on the market but  every time I try to validate it I recieve a message about the invalid volumes error when trading EURUSD for 1H. I read the article about fixing EA's  problems but I can't find the error in my code. Thus I decided to search for help in traders community.

here's the code:

#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>

CPositionInfo a_position;
CTrade        a_trade;
CSymbolInfo   a_symbol;


input double          Multiplier = 1;
input ushort          Step       = 100;

int rsiHandle;
int handleMACD;
input double eaLots = 0.01; 
input int TP_points = 20; 
input int FAST_MACD = 12;
input int SLOW_MACD = 26;
input int MACD_SMA = 9;
input int RSI_period = 18;
input int BollingerBands_period = 23;
input int RSIhigh = 50;
input int RSIlow = 50;
double last_price    = 0;
int    last_pos_type = -1;
double last_lots     = 0;
double points;
input ulong           MagicNumber = 123;
input ulong           Slippage    = 10;
double eStep;

void setChartColorBackground(color BackgroundColor)
{
ChartSetInteger(_Symbol, CHART_COLOR_BACKGROUND, BackgroundColor);
}  
void setChartCandleBull(color BackgroundColor)
{
ChartSetInteger(_Symbol, CHART_COLOR_CANDLE_BULL, BackgroundColor);
}  
void setChartCandleBear(color BackgroundColor)
{
ChartSetInteger(_Symbol, CHART_COLOR_CANDLE_BEAR, BackgroundColor);
}  
void setChartColorForeground(color ForegroundColor)
{
ChartSetInteger(_Symbol, CHART_COLOR_BID, ForegroundColor);
}  
void setChartGridColor(color GridColor)
{
ChartSetInteger(_Symbol, CHART_COLOR_GRID, GridColor);
}  

  
int OnInit()
  {
//---
setChartColorBackground(clrMaroon);
setChartCandleBull(clrWhiteSmoke);
setChartCandleBear(clrBlack);
setChartColorForeground(clrBlack);
setChartGridColor(clrMaroon);

    if (!a_symbol.Name(Symbol()))
      return(INIT_FAILED);
      
   a_trade.SetExpertMagicNumber(MagicNumber);
   a_trade.SetMarginMode();
   a_trade.SetTypeFillingBySymbol(a_symbol.Name());
   a_trade.SetDeviationInPoints(Slippage);
   
   int digits = 1;
   
   if (a_symbol.Digits() == 3 || a_symbol.Digits() == 5)
      digits = 10;
      
   points = a_symbol.Point() * digits;
   eStep  = Step * points;
   
   rsiHandle = iRSI(_Symbol,PERIOD_CURRENT,RSI_period,PRICE_CLOSE);
   handleMACD = iMACD(_Symbol,_Period,FAST_MACD,SLOW_MACD,MACD_SMA,PRICE_CLOSE);
 
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   double MiddleBandArray[];
   double UpperBandArray[];
   double LowerBandArray[];
   
   //sort the price array from the cuurent candle downwards
   ArraySetAsSeries(MiddleBandArray,true);
   ArraySetAsSeries(UpperBandArray,true);
   ArraySetAsSeries(LowerBandArray,true);
   
   //define Bollinger Bands
   int BollingerBands = iBands(_Symbol,_Period,BollingerBands_period,0,2,PRICE_CLOSE);
   
   //copy price info into the array
   CopyBuffer(BollingerBands,0,0,3,MiddleBandArray);
   CopyBuffer(BollingerBands,1,0,3,UpperBandArray);
   CopyBuffer(BollingerBands,2,0,3,LowerBandArray);
   
   //calcualte EA for the cuurent candle
   double MiddleBandValue=MiddleBandArray[0];
   double UpperBandValue=UpperBandArray[0];
   double LowerBandValue=LowerBandArray[0];
      double posPrice = PositionGetDouble(POSITION_PRICE_OPEN);        
      double tp = MiddleBandArray[0];
      double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
   if (!RefreshRates())
      return;
      
   if (CalcProfit(POSITION_TYPE_BUY) >= tp)
       CloseAll(POSITION_TYPE_BUY);
          
   if (CalcProfit(POSITION_TYPE_SELL) >= tp)
       CloseAll(POSITION_TYPE_SELL);
          
   int count = PosCount();
   
   if (count < 1)
   {
   //Bollinger Bands indicator
   //create an array for several prices
   
   
   //RSI indicator
  double rsi[];
  CopyBuffer(rsiHandle,0,1,1,rsi);
  double macd[];
  CopyBuffer(handleMACD,0,1,1,macd);
  
  if (rsi[0]<=RSIlow && bid<=LowerBandValue && macd[0] > 0){
  OpenBuy(eaLots);
           return;}
  if (rsi[0]>=RSIhigh && ask >= UpperBandValue && macd[0] < 0)
       {
  OpenSell(eaLots);
           return;
        }
     }
  if (last_price != 0 && last_pos_type >= 0 && last_lots != 0)
   {
       if (last_pos_type == POSITION_TYPE_BUY)
       {
           if (a_symbol.Ask() <= last_price - eStep)
           {
               double next_lots = CalcLots(last_lots * Multiplier);
               
               if (next_lots != 0)
               {
                  OpenBuy(next_lots);
                  return;
               }
           }
       }
   }
   
   if (last_price != 0 && last_pos_type >= 0 && last_lots != 0)
   {
       if (last_pos_type == POSITION_TYPE_SELL)
       {
           if (a_symbol.Ask() >= last_price + eStep)
           {
               double next_lots = CalcLots(last_lots * Multiplier);
               
               if (next_lots != 0)
               {
                  OpenSell(next_lots);
                  return;
               }
           }
       }
   }
   
}
//+------------------------------------------------------------------+
bool OpenBuy(double alot)
{
    if (alot == 0)
    {
        Print("Ошибка объёма для открытия позиции на покупку!");
        return(false);
    }
    
    if (a_trade.Buy(alot, a_symbol.Name(), a_symbol.Ask(), 0, 0))
    {
        if (a_trade.ResultDeal() == 0)
        {
            Print("Ошибка открытия позиции на покупку!");
            return(false);
        }
    }
    
    return(true);
}
//+------------------------------------------------------------------+
bool OpenSell(double alot)
{
    if (alot == 0)
    {
        Print("Ошибка объёма для открытия позиции на продажу!");
        return(false);
    }
    
    if (a_trade.Sell(alot, a_symbol.Name(), a_symbol.Bid(), 0, 0))
    {
        if (a_trade.ResultDeal() == 0)
        {
            Print("Ошибка открытия позиции на продажу!");
            return(false);
        }
    }
    
    return(true);
}
//+------------------------------------------------------------------+
void CloseAll(ENUM_POSITION_TYPE pos_type)
{
    for(int i=PositionsTotal() - 1; i>=0; i--)
    {
       if (a_position.SelectByIndex(i))
       {
           if (a_position.PositionType() == pos_type && a_position.Magic() == MagicNumber && a_position.Symbol() == a_symbol.Name())
              a_trade.PositionClose(a_position.Ticket());
       }
    }
}
//+------------------------------------------------------------------+
double CalcProfit(ENUM_POSITION_TYPE pos_type)
{
    double profit = 0;
    
    for(int i=PositionsTotal() - 1; i>=0; i--)
    {
       if (a_position.SelectByIndex(i))
       {
           if (a_position.PositionType() == pos_type && a_position.Magic() == MagicNumber && a_position.Symbol() == a_symbol.Name())
              profit += a_position.Profit();
       }
    }
    
    return(profit);
}
//+------------------------------------------------------------------+
double CalcLots(double lots)
{
    double new_lots  = NormalizeDouble(lots, 2);
    double step_lots = a_symbol.LotsStep();
    
    if (step_lots > 0)
       new_lots = step_lots * MathFloor(new_lots / step_lots);
       
    double minlot = a_symbol.LotsMin();
    
    if (new_lots < minlot)
        new_lots = minlot;
        
    double maxlot = a_symbol.LotsMax();
    
    if (new_lots > maxlot)
       new_lots = maxlot;
       
    return(new_lots);
}
//+------------------------------------------------------------------+

int PosCount()
{
   int count = 0;
   for (int i = PositionsTotal()-1; i>=0; i--)
   {
       if (a_position.SelectByIndex(i))
       {
           if (a_position.Symbol() == a_symbol.Name() && a_position.Magic() == MagicNumber)
              count++;
       }
   }
   
   return(count);
}

//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
{
    if (trans.type == TRADE_TRANSACTION_DEAL_ADD)
    {
        long deal_type = -1;
        long deal_entry = -1;
        long deal_magic = 0;
        
        double deal_volume = 0;
        double deal_price  = 0;
        string deal_symbol = "";
        
        if (HistoryDealSelect(trans.deal))
        {
            deal_type    = HistoryDealGetInteger(trans.deal, DEAL_TYPE);
            deal_entry   = HistoryDealGetInteger(trans.deal, DEAL_ENTRY);
            deal_magic   = HistoryDealGetInteger(trans.deal, DEAL_MAGIC);
            
            deal_volume  = HistoryDealGetDouble(trans.deal, DEAL_VOLUME);
            deal_price   = HistoryDealGetDouble(trans.deal, DEAL_PRICE);
            deal_symbol  = HistoryDealGetString(trans.deal, DEAL_SYMBOL);
        }
        else return;
    
       if (deal_symbol == a_symbol.Name() && deal_magic == MagicNumber)
       {
          if (deal_entry == DEAL_ENTRY_IN && (deal_type == DEAL_TYPE_BUY || deal_type == DEAL_TYPE_SELL))
          {
              last_price    = deal_price;
              last_pos_type = (deal_type == DEAL_TYPE_BUY) ? POSITION_TYPE_BUY : POSITION_TYPE_SELL;
              last_lots     = deal_volume;
          }
          else if (deal_entry == DEAL_ENTRY_OUT)
          {
             last_lots     = 0;
             last_pos_type = -1;
             last_price    = 0;
          }
       }
    }
}


//+------------------------------------------------------------------+
bool RefreshRates()
{
   if (!a_symbol.RefreshRates())
   {
      Print("не удалось обновить котировки валютной пары!");
      return(false);
   } 
   
   if (a_symbol.Ask() == 0 || a_symbol.Bid() == 0)
      return(false);
      
   return(true);   
}
//+------------------------------------------------------------------+

Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Trade Transaction Structure
Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Trade Transaction Structure
  • www.mql5.com
Trade Transaction Structure - Data Structures - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 

If you post your code here please use the code button in the menu line </>

Have you gone through your code with the debugger or placed a print if the volume is too low or too high?

 
Carl Schreiber #:

If you post your code here please use the code button in the menu line </>

Have you gone through your code with the debugger or placed a print if the volume is too low or too high?

yeah, of course. but when I do backtesting myself the EA work pretty well