iHighest error 4807

 

Making my first EA by editting the example moving average EA that comes with MT5. 

Running this on historical data outputs

"2022.05.07 14:45:33.566 2022.01.03 00:05:00   iHighest() call error. Error code=4807"


I imagine this is very obvious to an expert. This is literally my first day using MT5 so please be kind.

//+------------------------------------------------------------------+
//|                                              Moving Averages.mq5 |
//|                   Copyright 2009-2017, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2009-2017, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"

#include <Trade\Trade.mqh>

input double MaximumRisk        = 0.02;    // Maximum Risk in percentage
input double DecreaseFactor     = 3;       // Descrease factor
input int    LookBackEnter = 20;
input int    LookBackExit = 10;




//---
int    HighSlowHandle=0;
int    HighFastHandle=0;
int    LowSlowHandle=0;
int    LowFastHandle=0;
bool   ExtHedging=false;
CTrade ExtTrade;

#define MA_MAGIC 1234502
//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
  {
   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_MARGIN_FREE)*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 Expert Magic number
         if(HistoryDealGetInteger(ticket,DEAL_MAGIC)!=MA_MAGIC)
            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)
  {
   MqlRates rt[2];
//--- go trading only for first ticks of new bar
   if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
     {
      Print("CopyRates of ",_Symbol," failed, no history");
      PrintFormat("iHighest() call error. Error code=%d",GetLastError());
      return;
     }
   if(rt[1].tick_volume>1)
      return;

     
//--- get highest price in n (long period) days
   double highSlow[1];
   if(CopyBuffer(HighSlowHandle,0,0,1,highSlow)!=1)
     {
      Print("CopyBuffer from iHighest slow failed, no data");
      PrintFormat("iHighest() call error. Error code=%d",GetLastError());
      return;
     }
     
   double lowSlow[1];
   if(CopyBuffer(LowSlowHandle,0,0,1,lowSlow)!=1)
     {
      Print("CopyBuffer from iLowest slow failed, no data");
      return;
     }
 
     
//--- check signals
   ENUM_ORDER_TYPE signal=WRONG_VALUE;

   if(rt[0].close<=lowSlow[0])
      signal=ORDER_TYPE_SELL;    // sell conditions
   else
     {
      if(rt[0].close>=highSlow[0])
         signal=ORDER_TYPE_BUY;  // buy conditions
     }
//--- additional checking
   if(signal!=WRONG_VALUE)
     {
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
         ExtTrade.PositionOpen(_Symbol,signal,TradeSizeOptimized(),
                               SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
                               0,0);
     }
//---
  }
//+------------------------------------------------------------------+
//| Check for close position conditions                              |
//+------------------------------------------------------------------+
void CheckForClose(void)
  {
   MqlRates rt[2];
//--- 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;
     }
   if(rt[1].tick_volume>1)
      return;
//--- get current Moving Average 

     
   double highFast[1];
   if(CopyBuffer(HighFastHandle,0,0,1,highFast)!=1)
     {
      Print("CopyBuffer from iHighest fast failed, no data");
      return;
     }
     
   double lowFast[1];
   if(CopyBuffer(LowFastHandle,0,0,1,lowFast)!=1)
     {
      Print("CopyBuffer from iLowestFast failed, no data");
      return;
     }
     
     
//--- positions already selected before
   bool signal=false;
   long type=PositionGetInteger(POSITION_TYPE);

   if(type==(long)POSITION_TYPE_BUY && rt[0].open<=lowFast[0])
      signal=true;
   if(type==(long)POSITION_TYPE_SELL && rt[0].open>=highFast[0])
      signal=true;
//--- additional checking
   if(signal)
     {
      if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
         ExtTrade.PositionClose(_Symbol,3);
     }
//---
  }
//+------------------------------------------------------------------+
//| Position select depending on netting or hedging                  |
//+------------------------------------------------------------------+
bool SelectPosition()
  {
   bool res=false;
//--- check position in Hedging mode
   if(ExtHedging)
     {
      uint total=PositionsTotal();
      for(uint i=0; i<total; i++)
        {
         string position_symbol=PositionGetSymbol(i);
         if(_Symbol==position_symbol && MA_MAGIC==PositionGetInteger(POSITION_MAGIC))
           {
            res=true;
            break;
           }
        }
     }
//--- check position in Netting mode
   else
     {
      if(!PositionSelect(_Symbol))
         return(false);
      else
         return(PositionGetInteger(POSITION_MAGIC)==MA_MAGIC); //---check Magic number
     }
//--- result for Hedging mode
   return(res);
  }
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit(void)
  {
//--- prepare trade class to control positions if hedging mode is active
   ExtHedging=((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
   ExtTrade.SetExpertMagicNumber(MA_MAGIC);
   ExtTrade.SetMarginMode();
   ExtTrade.SetTypeFillingBySymbol(Symbol());
//--- Moving Average indicator
 //  ExtHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
  // if(ExtHandle==INVALID_HANDLE)
   //  {
    //  printf("Error creating MA indicator");
   //  return(INIT_FAILED);
    //}
    HighSlowHandle = iHighest(_Symbol,_Period,MODE_CLOSE,LookBackEnter,0);
    if(HighSlowHandle==INVALID_HANDLE)
    {
     printf("Error creating HighSlow indicator");
     return(INIT_FAILED);
    }
    
    LowSlowHandle = iLowest(_Symbol,_Period,MODE_CLOSE,LookBackEnter,0);
    if(LowSlowHandle==INVALID_HANDLE)
    {
     printf("Error creating lowSlow indicator");
     return(INIT_FAILED);
    }
    
    HighFastHandle = iHighest(_Symbol,_Period,MODE_CLOSE,LookBackExit,0);
    if(HighFastHandle==INVALID_HANDLE)
    {
     printf("Error creating HighFast indicator");
     return(INIT_FAILED);
    }
    
    LowFastHandle = iLowest(_Symbol,_Period,MODE_CLOSE,LookBackExit,0);
    if(LowFastHandle==INVALID_HANDLE)
    {
     printf("Error creating lowFast indicator");
     return(INIT_FAILED);
    }
     
//--- ok
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick(void)
  {
//---
   if(SelectPosition())
      CheckForClose();
   else
      CheckForOpen();
//---
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
  }
//+------------------------------------------------------------------+
 
HighFastHandle = iHighest(_Symbol,_Period,MODE_CLOSE,LookBackExit,0);

iHighest doesnt give you a indicator handle.

https://www.mql5.com/de/docs/series/ihighest


and btw, you can check what error 4807 means. https://www.mql5.com/en/docs/constants/errorswarnings/errorcodes

Dokumentation zu MQL5: Zugang zu Zeitreihen und Indikatoren / iHighest
Dokumentation zu MQL5: Zugang zu Zeitreihen und Indikatoren / iHighest
  • www.mql5.com
iHighest - Zugang zu Zeitreihen und Indikatoren - Nachschlagewerk MQL5 - Nachschlagewerk über die Sprache des algothitmischen/automatischen Handels für MetaTrader 5
 
   if(rt[1].tick_volume>1)

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.
          MT4: New candle - MQL4 programming forum #3 (2014)
          MT5: Accessing variables - MQL4 programming forum #3 (2022)

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

Reason: