Using Indicator Data from other timeframes

 

Hi,

I am building an indicator to display several visual objects on the graph. I have a problem getting the high and low defined by ZigZag from a higher timeframe.

My indicator will not use a buffer to save data, I want it to plot objects on the chart and will do the object plotting on initialization and on each new candle only.

I know it is not a usual thing for indicators, but please bear with me to explain the issue I am facing.

When loading the indicator on the screen, nothing happens, and when debugging, I have all the buffers returned as zero. Same issue when changing timeframes.

However leaving it on the chart for one new candle, everything seems to work right and I have the object plotted.

Anything I am doing wrong? The same function is called in both initialization and new bar, so it is kind of weird. Would it be a problem handling buffers on initialization? 

Thanks for the help

//+------------------------------------------------------------------+
//|                                                      ProjectName |
//|                                      Copyright 2020, CompanyName |
//|                                       http://www.companyname.net |
//+------------------------------------------------------------------+
#property version   "1.00"
#property indicator_chart_window

input int               InpZigZagDepth          = 4;           //ZigZag dDepth
input ENUM_TIMEFRAMES   InpTF1                  = PERIOD_M15;  //First TimeFrame
input color             InpTF1Color             = clrRed;      //Color

int   mHandle;
double mBuffer[];

//--- On Init
int OnInit()
  {
   mHandle = iCustom(Symbol(),InpTF1,"Examples/ZigZag",InpZigZagDepth,5,3);
   ArraySetAsSeries(mBuffer,true);
   DrawFractals();
   return (INIT_SUCCEEDED);
  }

//
bool DeleteDrawings(string text)
  {
   for(int i =ObjectsTotal(ChartID(),0)-1; i>=0; i--)
     {
      string tempname  = ObjectName(ChartID(),i,0);
      if(StringFind(tempname,text,0) >=0)
         ObjectDelete(ChartID(),tempname);
     }
   return true;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   DeleteDrawings("Fractal");
   IndicatorRelease(mHandle);
   ChartRedraw(ChartID());

  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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[])

  {
   if(IsNewBar())
      DrawFractals();

   return(rates_total);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void plotFractal(string name, datetime time,double price,int anchor,color clr)
  {
   ObjectCreate(ChartID(),"Fractal_"+name,OBJ_ARROW,0,time,price);
   ObjectSetInteger(ChartID(),"Fractal_"+name,OBJPROP_ARROWCODE,119);
   ObjectSetInteger(ChartID(),"Fractal_"+name,OBJPROP_ANCHOR,anchor);
   ObjectSetInteger(ChartID(),"Fractal_"+name,OBJPROP_COLOR,clr);
   ChartRedraw(0);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DrawFractals()
  {
   DeleteDrawings("Fractal");

   int HTloopBack = 200;
   double fractal = 0;
   int  startIndex = 0;
   int endIndex = 0;
   int plotIndex = 0;

   for(int i=1; i<=HTloopBack ; i++)
     {
      int result = CopyBuffer(mHandle, 0, i, 1, mBuffer);
      if(result == 1 ) fractal = mBuffer[0];
      if(fractal !=0 && fractal != EMPTY_VALUE)
        {
         if(fractal == iHigh(Symbol(),InpTF1,i))
           {
            startIndex = iBarShift(Symbol(),Period(),iTime(Symbol(),InpTF1,i-1),false);
            endIndex = iBarShift(Symbol(),Period(),iTime(Symbol(),InpTF1,i),false);
            for(int x=startIndex+1; x<=endIndex; x++)
              {
               plotFractal("TF1_"+x+"_"+i,iTime(Symbol(),Period(),x),fractal,ANCHOR_BOTTOM,InpTF1Color);
              }
           }
         else
           {
            startIndex = iBarShift(Symbol(),Period(),iTime(Symbol(),InpTF1,i-1),false);
            endIndex = iBarShift(Symbol(),Period(),iTime(Symbol(),InpTF1,i),false);
            for(int x=startIndex+1; x<=endIndex; x++)
              {
               plotFractal("TF1_"+x+"_"+i,iTime(Symbol(),Period(),x),fractal,ANCHOR_TOP,InpTF1Color);
              }
           }

        }
     }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsNewBar()
  {
   static bool result = false;

   static datetime previous_time = 0;
   datetime        current_time  =iTime(Symbol(),PERIOD_CURRENT, 0);
   result                       = false;
   if(previous_time != current_time)
     {
      previous_time = current_time;
      result        = true;
     }
   return (result);
  }
//+------------------------------------------------------------------+
 

If your program (EA or indicator) doesn't do what it should use the debugger (in case of an indicator make sure it is not running on a different chart of the terminal):

Code debugging:  https://www.metatrader5.com/en/metaeditor/help/development/debug
Error Handling and Logging in MQL5:  https://www.mql5.com/en/articles/2041
Tracing, Debugging and Structural Analysis of Source Code, scroll down to: "Launching and Debuggin": https://www.mql5.com/en/articles/272

Code debugging - Developing programs - MetaEditor Help
  • www.metatrader5.com
MetaEditor has a built-in debugger allowing you to check a program execution step by step (by individual functions). Place breakpoints in the code...
 
Carl Schreiber #:

If your program (EA or indicator) doesn't do what it should use the debugger (in case of an indicator make sure it is not running on a different chart of the terminal):

Code debugging:  https://www.metatrader5.com/en/metaeditor/help/development/debug
Error Handling and Logging in MQL5:  https://www.mql5.com/en/articles/2041
Tracing, Debugging and Structural Analysis of Source Code, scroll down to: "Launching and Debuggin": https://www.mql5.com/en/articles/272

Hey Carl, 

Thanks for the reply.

I already used the debugger, as mentioned in my initial message. The indicator buffer is not returned on initialization and on timeframe change (re-initialization) -->  4806 Requested data not found. 

However, leaving it there for the next candle it is being copied with no problem. This conclusion was made from buffer reading and behavior on charts. 

Both cases above are using the same exact function. I am wondering if it is a kind of limitation where the indicator buffer is not loaded correctly when the timeframe used is different than the chart timeframe. As I am using standard MT5 calls to initiate the indicator and call its buffers.

I adjusted this part of my code just to throw errors in the journal, just to make my analysis more readable - check the gif attached simulating the scenarios.

if(result == 1 ) {fractal = mBuffer[0]; Print(i,":",fractal);} else Print(i,":",GetLastError());


What I suspect is there is something in MQL5 libraries, not allowing the buffer to correctly being initialized .

 

Risk a look in other indicators in the code base.

Nothing happens in OnCalculate() until the 1st new bar appears - where is the calculation of the history of the chart?

Check the orientation of all your buffers (oldest and most recent values). See the doc. of CopyBuffer().

Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
Documentation on MQL5: Timeseries and Indicators Access / CopyBuffer
  • www.mql5.com
CopyBuffer - Timeseries and Indicators Access - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
Your topic has been moved to the section: Technical Indicators
Please consider which section is most appropriate — https://www.mql5.com/en/forum/172166/page6#comment_49114893
Reason: