Using time driven custom indicator for debug in an EA

 

I have created a custom indicator, DebugIncludeSignal.mq5, for EA debug purposes. The indicator has one buffer which are controlled by a set of two arrays, one time array and one signal array. DebugIncludeSignal.mql5 customer indicator works fine when I attach it to a chart.

In order to see how that the custom indicator can be used from an EA I created a driver EA, DebugIncludeSignal_EA.mq5. When I debug it through the Strategy Tester, the GetData method fetch data from the buffer of the indicator, however the indicator buffer and plot is not changing values to the values setup according to the time array and signal array as coded in the DebugIncludeSignal.mq5.

Would appreciate any help to resolve this issue.

Custom Indicator DebugIncludeSignal.mq5:

//+------------------------------------------------------------------+
//|                                           DebugIncludeSignal.mq5 |
//|                                                       karlk      |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, karlk."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "DebugFileSignal"
#property indicator_separate_window
#property indicator_minimum -1
#property indicator_maximum 3
#property indicator_buffers 1
#property indicator_plots   1

//--- plot dbg_bool1
#property indicator_label1    "dbg_signal"
#property indicator_type1     DRAW_LINE
#property indicator_color1    clrRed
#property indicator_style1    STYLE_SOLID
#property indicator_width1    2


enum ENUM_CMD_DEBUG
{
   CMD_VOID=-1,
   CMD_NEUTRAL,
   CMD_LONG,
   CMD_SHORT
};

//--- external variables
int      lasterror;

string    dbg_timearr[] =
   {
       "2019.08.27 15:00:00"
      ,"2019.08.28 15:15:00"
      ,"2019.08.29 18:15:00"
      ,"2019.08.30 18:15:00"
   };

ENUM_CMD_DEBUG      dbg_signalarr[] =
   {
       CMD_LONG
      ,CMD_SHORT
      ,CMD_NEUTRAL
      ,CMD_VOID
   };


//--- indicator buffers
double         dbg_signalBuffer[];

//--- name of the indicator on a chart 
string         short_name = "DebugIncludeSignal";


//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
   SetIndexBuffer(0,dbg_signalBuffer,INDICATOR_DATA);

//--- show the symbol/timeframe the Debug bool is calculated for 
   IndicatorSetString(INDICATOR_SHORTNAME, short_name); 
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, 0);
   PlotIndexSetInteger(0,PLOT_DRAW_TYPE,DRAW_LINE); 
   PlotIndexSetInteger(0,PLOT_LINE_STYLE,STYLE_SOLID); 
   PlotIndexSetInteger(0,PLOT_LINE_COLOR,clrRed); 
   PlotIndexSetInteger(0,PLOT_LINE_WIDTH,2); 
   
   
//--- normal initialization of the indicator     
   return(INIT_SUCCEEDED); 

}

void OnDeinit(const int reason)
{
}

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(
                const int rates_total,
                const int prev_calculated, 
                const datetime &time[], 
                const double &open[], 
                const double &high[], 
                const double &low[], 
                const double &close[], 
                const long &tick_volume[], 
                const long &volume[], 
                const int &spread[])
{

   static bool       f_siggen=false;
   int               first, bar;
   datetime          t=(datetime)(0), ts=(datetime)(0);
   ENUM_CMD_DEBUG    cmd=CMD_VOID, next_cmd=CMD_VOID;
   
   if (rates_total < 1)
      return(0);
    
   if (prev_calculated == 0) {
      first = 0;
      f_siggen = SignalGenerator(ts, next_cmd);
      cmd = CMD_VOID;
   }
   else 
      first = prev_calculated - 1;

   for(bar = first; bar < rates_total; bar++) {
      if(f_siggen && (time[bar]>=ts)) {
         cmd = next_cmd;
         f_siggen = SignalGenerator(ts, next_cmd);
      }
      dbg_signalBuffer[bar] = double(cmd);
   }
     
   return(rates_total);
}

//+------------------------------------------------------------------+


bool SignalGenerator(datetime& timestamp, ENUM_CMD_DEBUG& cmd)
{
   string            s, cmdstr;
   static int        idx=0;   
   
   if(idx < ArraySize(dbg_timearr)) {
      timestamp = StringToTime(dbg_timearr[idx]);
      cmd = dbg_signalarr[idx];   
      idx++;
      return true;
   }
   else {
      timestamp = datetime(0);
      cmd = CMD_NEUTRAL;   
      return false;
   }         
}


Works fine when attached to a chart:

Chart with DebugIncludeSignal.mq5 Custom indicator


The driver EA, DebugIncludeSignal_EA.mq5:

//+------------------------------------------------------------------+
//|                                        DebugIncludeSignal_EA.mq5 |
//|                                                       Karlk      |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "karlk"
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <Indicators\Custom.mqh>

enum ENUM_CMD_DEBUG
{
   CMD_VOID=-1,
   CMD_NEUTRAL,
   CMD_LONG,
   CMD_SHORT
};

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CiDebugIncludeSignal : public CiCustom
{
protected:

public:
                     CiDebugIncludeSignal(void);
                    ~CiDebugIncludeSignal(void);
   bool              Create(const string symbol, const ENUM_TIMEFRAMES period,
                            const ENUM_INDICATOR type, const int num_params, const MqlParam &params[], const int buffers);
   double            GetData(const int buffer_num,const int index) const;
   
};
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CiDebugIncludeSignal::CiDebugIncludeSignal(void)
{
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
CiDebugIncludeSignal::~CiDebugIncludeSignal(void)
{
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CiDebugIncludeSignal::Create(const string symbol,const ENUM_TIMEFRAMES period,const ENUM_INDICATOR type,const int num_params,const MqlParam &params[],const int buffers)
{
   NumBuffers(buffers);
   if(CIndicator::Create(symbol,period,type,num_params,params))
      return Initialize(symbol,period,num_params,params);
   return false;
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double CiDebugIncludeSignal::GetData(const int buffer_num,const int index) const
{
   return CiCustom::GetData(buffer_num,index);
}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+

CiDebugIncludeSignal   *dfs_handle;

int OnInit()
{
   
   MqlParam params[1];
   
   params[0].type=TYPE_STRING;
   params[0].string_value="_myIndicators\\DebugIncludeSignal";
   
   dfs_handle = new CiDebugIncludeSignal();
   dfs_handle.Create(Symbol(), PERIOD_CURRENT, IND_CUSTOM, 1, params, 1);

   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   double            DebugSignal;
   ENUM_CMD_DEBUG    DebugSignal_cmd;
   datetime          current_bar_opentime;
   static datetime   prev_bar_opentime;

   current_bar_opentime = iTime(Symbol(), PERIOD_CURRENT, 0);
   if(current_bar_opentime != prev_bar_opentime) {
      prev_bar_opentime = current_bar_opentime;
      dfs_handle.Refresh();
      DebugSignal = dfs_handle.GetData(0, 1);
      DebugSignal_cmd = ENUM_CMD_DEBUG(DebugSignal);
   }
   switch(DebugSignal_cmd) {
      case CMD_VOID:
      // signal void actions
      break;
      
      case CMD_NEUTRAL:
      // signal neutral actions
      break;
      
      case CMD_LONG:
      // signal long actions
      break;
      
      case CMD_SHORT:
      // signal short actions
      break;
      
      default:
      break;
   }
      
      
}
//+------------------------------------------------------------------+
//| Trade function                                                   |
//+------------------------------------------------------------------+
void OnTrade()
  {
//---
   
  }
//+------------------------------------------------------------------+


Here is the output in the Strategy Tester. The indicator shows only a -1.0 value for the whole test period.

Strategy tester chart


BR/

Karl

Reason: