HTF Open line indicator: learn what I'm doing wrong

 

Hi, I'm learning mql4 and I coded an indicator that plots a line equal to the current open price of any higher timeframe. This is the code:


// Setup
   #property copyright "Ironhak"
   #property description "Indicate current candle open"
   #property strict
   #property show_inputs
   #property indicator_chart_window

   // Define number of buffers
      #property indicator_buffers 1     


      

//--- Indicator Settings

   input string   none_1            = "------------------------";       //Indicator Parameters
   input   ENUM_TIMEFRAMES i_tf1_open    = 60;   // TimeFrame 1 Open 
   
//--- Global variable declarations

   // Indicator buffers
      double buff_tf1_open[];

//--- Event handling functions

   // Initialisation event handler
      int OnInit(void)
      {
         // Set number of significant digits (precision)
            IndicatorSetInteger( INDICATOR_DIGITS, _Digits );

         // Set Indicator buffers
            SetIndexBuffer( 0, buff_tf1_open, INDICATOR_DATA );
   
         // Set indicator labels
            SetIndexLabel(0,IntegerToString(i_tf1_open)+" open"); 
          
         //Set indicator style   
            SetIndexStyle(0,DRAW_LINE);

         
         return INIT_SUCCEEDED;  // Successful initialisation of indicator
      };

   // Calculation event handler
      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[]
         )
      {
         // Define maximum index for the buffer array
            int iMaxIndex = rates_total - 1;
         
         // Main loop — fill in the arrays with data values
            for( int i = rates_total - ( prev_calculated < 1 ? 1 : prev_calculated ); i >= 0; i-- )
            {
               
               double
                  tf_1;
                  
               if( i < iMaxIndex )
               {  
                  tf_1=iOpen (0,i_tf1_open,0);
                 
               }

               buff_tf1_open[i]   = tf_1;
              
            };
      
         // Return value of prev_calculated for next call
            return rates_total;
      };
      

      void OnDeinit(const int reason)
        {
         ObjectDelete(0,st_Status);
        }

   

The indicator will plot current open line extended to all chart and previous open are not plotted, here's the indicator set to plot the 1h open on a 1m chart:

And this is what it should plot instead:


I would really appreciate if someone is kind enough to point me out what I'm doing wrong. Thank's. 

 
ironhak:

Hi, I'm learning mql4 and I coded an indicator that plots a line equal to the current open price of any higher timeframe. This is the code:


The indicator will plot current open line extended to all chart and previous open are not plotted, here's the indicator set to plot the 1h open on a 1m chart:

And this is what it should plot instead:


I would really appreciate if someone is kind enough to point me out what I'm doing wrong. Thank's. 

Check and learn

Daily Open Line
Daily Open Line
  • www.mql5.com
An simple Indicator displaying daily opening line.
 
Navdeep Singh #:

Check and learn

Hi, thank's, but please note that you linked an mql5 indicator. Instead I'm working on mql4, thanks. 

 
ironhak #:

Hi, thank's, but please note that you linked an mql5 indicator. Instead I'm working on mql4, thanks. 

Logically it will be same for MT4, only buffer indexing is opposite.
 
Navdeep Singh #:
Logically it will be same for MT4, only buffer indexing is opposite.

Thank's for replying but sincerly I don't understand what you mean by "buffer indexing is opposite". 

I would like to understand what and why the indicator I wrote by myself is wrong and not working as inteded, thank you. 

Edit: by the way the indicator you posted is only about daily open while I'm referring to HTF open. 
 
  1.                if( i < iMaxIndex )
                   {  
                      tf_1=iOpen (0,i_tf1_open,0);
                     
                   }
    
                   buff_tf1_open[i]   = tf_1;

    The if is unnecessary when your loop is correct.
              How to do your lookbacks correctly #9#14 & #19 (2016)

  2. You are mixing apples and oranges.

  3. You are reading the same value repeatedly.

  4. You just can't process bar zero, you must process bar zero of the other timeframe.
              How to do your lookbacks correctly #13 (2016)


  5. ironhak #: I don't understand what you mean by "buffer indexing is opposite".

    In MT4, buffers and the predefined arrays are all ordered AsSeries. There is a difference between the arrays passed to OnCalculate (e.g. low[]) and the MT4 predefined variables (e.g. Low[].) The passed arrays have no default direction, just like MT5.

    To determine the indexing direction of time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[], call ArrayGetAsSeries(). In order not to depend on default values, you should unconditionally call the ArraySetAsSeries() function for those arrays, which are expected to work with.
              Event Handling Functions - Functions - Language Basics - MQL4 Reference

  6. In MT5, you must set the direction.

    To define the indexing direction in the time[], open[], high[], low[], close[], tick_volume[], volume[] and spread[] arrays, call the ArrayGetAsSeries() function. In order not to depend on defaults, call the ArraySetAsSeries() function for the arrays to work with.
              Event Handling / OnCalculate - Reference on algorithmic/automated trading language for MetaTrader 5
 
William Roeder #:
  1. The if is unnecessary when your loop is correct.
              How to do your lookbacks correctly #9#14 & #19 (2016)

  2. You are mixing apples and oranges.

  3. You are reading the same value repeatedly.

  4. You just can't process bar zero, you must process bar zero of the other timeframe.
              How to do your lookbacks correctly #13 (2016)


  5. In MT4, buffers and the predefined arrays are all ordered AsSeries. There is a difference between the arrays passed to OnCalculate (e.g. low[]) and the MT4 predefined variables (e.g. Low[].) The passed arrays have no default direction, just like MT5.

  6. In MT5, you must set the direction.

Thank's for your kind reply. I tried to understand it as much as I could and I came up with this:

// Setup
#property copyright "Eddy"
#property description "Indicate current candle open"
#property strict
#property show_inputs
#property indicator_chart_window

// Define number of buffers
#property indicator_buffers 1

// Allow user to change indicator style


//--- Indicator Settings
//Enum indicator mode

//Enum line witdht
enum ENUM_LINE_WIDTH
  {
   _1=1,  //1
   _2=2,  //2
   _3=3,  //3
   _4=4,  //4
   _5=5,  //5
  };

input string   none_1            = "------------------------";       //Indicator Parameters
input   ENUM_TIMEFRAMES i_tf1_open    = 60;   // TimeFrame 1 Open


//--- Global variable declarations

// Indicator buffers
double buff_tf1_open[];

string st_Status;
//--- Event handling functions

// Initialisation event handler
int OnInit(void)
  {
// Set number of significant digits (precision)
   IndicatorSetInteger(INDICATOR_DIGITS, _Digits);

// Set Indicator buffers
   SetIndexBuffer(0, buff_tf1_open, INDICATOR_DATA);

//Set indicator style
   SetIndexStyle(0,DRAW_LINE);


   return INIT_SUCCEEDED;  // Successful initialisation of indicator
  };

// Calculation event handler
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[]
)
  {
// Define maximum index for the buffer array

   int lookback = 100; //trying to display 1D open on last 100 1h candles
// Replacing loop function with the one you pointed out
   for(int iBar = Bars-1-MathMax(lookback, prev_calculated); iBar >= 0; --iBar)
     {
      // Timeseries and Indicators Access uses index=iBar


      int index_tf1 =  iBarShift(0,i_tf1_open,Time[iBar],false);

      double tf_1 = iOpen(0,i_tf1_open,index_tf1+1);

      buff_tf1_open[iBar]   = tf_1;
     };

   return rates_total-1; // Recalculate current bar next tick.


// Return value of prev_calculated for next call
   return rates_total;
  };


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

  }

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

Now it works but it display previous candle open (i.e. if attached on a 1h chart and i_tf1_open =1440 it will display previous day open). I don't understand why, maybe it's caused by this?


double tf_1 = iOpen(0,i_tf1_open,index_tf1+1);

I did not understood why on the expample you provided there's that "+1" so I assume that could be the problem, but most likely it's something else. If not bother you could you please point me out why it's painting previous candle instead of current one? 


Thank's again for your time. 




Edit: additional question

So, if I understood correctly, assume I attach this "indicator" to a 1H chart:

   int lookback = 100; //trying to display 1D open on last 100 1h candles
// Replacing loop function with the one you pointed out
   for(int iBar = Bars-1-MathMax(lookback, prev_calculated); iBar >= 0; --iBar)
     {
      // Timeseries and Indicators Access uses index=iBar


      double dailyATR = iATR(0,1440,period,iBar);

      buff_dailyATR[iBar]   = tf_1;
     };

   return rates_total-1; // Recalculate current bar next tick.

Where period = 24. Actually it's not calculating the atr of previous 24 daily candles, but it's calculating the atr of the daily candle relative to the 1h chart, so actually this code is calculating the average atr of ~current/previous daily candle if attached to a 1H chart, right? Thank's

 
ironhak #:

Thank's for your kind reply. I tried to understand it as much as I could and I came up with this:

Now it works but it display previous candle open (i.e. if attached on a 1h chart and i_tf1_open =1440 it will display previous day open). I don't understand why, maybe it's caused by this?

I did not understood why on the expample you provided there's that "+1" so I assume that could be the problem, but most likely it's something else. If not bother you could you please point me out why it's painting previous candle instead of current one? 


Thank's again for your time. 




Edit: additional question

So, if I understood correctly, assume I attach this "indicator" to a 1H chart:

Where period = 24. Actually it's not calculating the atr of previous 24 daily candles, but it's calculating the atr of the daily candle relative to the 1h chart, so actually this code is calculating the average atr of ~current/previous daily candle if attached to a 1H chart, right? Thank's

Ok I actually found out it was the "+1", by removing it I was able to get actual candle open price. I've one last question, how can I remove indicator "stairs"? I mean these increments:

They are too distracting if I'm going to add more instances of this indicator. Thank's. 

 
ironhak #:

Ok I actually found out it was the "+1", by removing it I was able to get actual candle open price. I've one last question, how can I remove indicator "stairs"? I mean these increments:

They are too distracting if I'm going to add more instances of this indicator. Thank's. 

Either use dot style for the line

Or 

Set an empty value for the index where line steps thereby breaking the line.

Styles of Indicator Lines - Appendixes - MQL4 Tutorial
Styles of Indicator Lines - Appendixes - MQL4 Tutorial
  • book.mql4.com
Styles of Indicator Lines - Appendixes - MQL4 Tutorial
 
Navdeep Singh #:

Either use dot style for the line

Or 

Set an empty value for the index where line steps thereby breaking the line.

Is this also ok?

  for(int iBar = Bars-1-MathMax(lookback, prev_calculated); iBar >= 0; --iBar)
     {
      // Timeseries and Indicators Access uses index=iBar


      int index_tf1 =  iBarShift(0,i_tf1_open,Time[iBar],false);

      double tf_1 = iOpen(0,i_tf1_open,index_tf1);
      
      if( iBarShift(0,i_tf1_open,Time[iBar],false)!= iBarShift(0,i_tf1_open,Time[iBar+1],false)){ 
         buff_tf1_open[iBar] = tf_1;
         buff_tf1_open[iBar+1]   = EMPTY_VALUE;
         } else{ 
            buff_tf1_open[iBar]   = tf_1 ;
      }
     };

   return rates_total-1;
Edit: by the way using dotted line style does not hide the "scales"...