Please help me on understanding mql4 indicator that draws arrows

 
I'm trying to make an indicator that draws arrows on certain bars at their close prices. What I don't understand is the array buffers in mql4 are only to do with price instead of price and datetime. My logic is to find the bars which satisfies the requirements then store their datetime and close price to two arrays so that the program can understand where to draw in x and y axis which represent date and price. But the example mql4 has nothing to do with time. So what is the secret behind it? And if I want to transform the indicator to an expert advisor with no demand to draw anything but just store the bar's time and price for usage of looking for entry opportunity. How should I do this?
 
John Voidman:
I'm trying to make an indicator that draws arrows on certain bars at their close prices. What I don't understand is the array buffers in mql4 are only to do with price instead of price and datetime. My logic is to find the bars which satisfies the requirements then store their datetime and close price to two arrays so that the program can understand where to draw in x and y axis which represent date and price. But the example mql4 has nothing to do with time. So what is the secret behind it? And if I want to transform the indicator to an expert advisor with no demand to draw anything but just store the bar's time and price for usage of looking for entry opportunity. How should I do this?

First it should be understood that the date-time for each bar is stored in the time[] array passed on by the OnCalculate() event handler.

Also without your code, it is difficult to understand exactly what you want to do, and there may be a much simpler approach than what you are describing.

However, maintaining true to your request, I see two ways to approach this problem. In both cases you will need an extra calculation buffer that is hidden and does not plot.

  1. The first approach is the most common and instead of saving the date-time for the bar, save in the calculated hidden buffer, the index offset or shift in reference to the current bar.
  2. The second is to store the date-time of the bar directly to the buffer array by making use of a union structure. Since buffers are "double" and occupy 8 bytes, and "datetime" is also 8 bytes, just create a union of a "double" and a "datetime" variable in order to write and read date-times from a buffer array.
EDIT: Please note that the second solution may seem more elegant, but it will actually be much more complex because when using the data to point back to the bar in question, you will then need to do a "search" for the bar by date, equivalent to iBarShift which will be computationally more expensive. The first solution is much more direct not requiring any kind of search for the bar and is the preferred method.

    If you provide your more code to explain you requirements, then I can go into more specific solutions.

    Structures, Classes and Interfaces - Data Types - Language Basics - MQL4 Reference
    Structures, Classes and Interfaces - Data Types - Language Basics - MQL4 Reference
    • docs.mql4.com
    Structures, Classes and Interfaces - Data Types - Language Basics - MQL4 Reference
     
    Fernando Carreiro:

    First it should be understood that the date-time for each bar is stored in the time[] array passed on by the OnCalculate() even handler.

    Also without your code, it is difficult to understand exactly what you want to do, and there may be a much simpler approach than what you are describing.

    However, maintaining true to your request, I see two ways to approach this problem. In both cases you will need an extra calculation buffer that is hidden and does not plot.

    1. The first approach is the most common and instead of saving the date-time for the bar, save in the calculated hidden buffer, the index offset or shift in reference to the current bar.
    2. The second is to store the date-time of the bar directly to the buffer array by making use of a union structure. Since buffers are "double" and occupy 8 bytes, and "datetime" is also 8 bytes, just create a union of a "double" and a "datetime" variable in order to write and read date-times from a buffer array.
    EDIT: Please note that the second solution may seem more elegant, but it will actually be much more complex because when using the data to point back to the bar in question, you will then need to do a "search" for the bar by date, equivalent to iBarShift which will be computationally more expensive. The first solution is much more direct not requiring any kind of search for the bar and is the preferred method.

      If you provide your more code to explain you requirements, then I can go into more specific solutions.

      Thanks you for your answer. The first approach is automatically done by the MT4, right? Cause I don't see any explicit codes that store the index offset to the buffer. I'll put my code below. The simple explanation is it tries to get lowest and highest price of every small period. I try not to worry about time and it worked. Now I'm trying to make it into a function of EA or a library that can be used for understanding potential resistance and support prices.
       
      //+------------------------------------------------------------------+
      //|                                             RelativeHighnLow.mq4 |
      //|                                                          voidman |
      //|                                             https://www.mql5.com |
      //+------------------------------------------------------------------+
      #property copyright "voidman"
      #property link      "https://www.mql5.com"
      #property version   "1.00"
      #property strict
      #property indicator_chart_window
      #property indicator_buffers 2
      #property indicator_plots   2
      //--- plot High
      #property indicator_label1  "high"
      #property indicator_type1   DRAW_ARROW
      #property indicator_color1  clrBlue
      #property indicator_style1  STYLE_SOLID
      #property indicator_width1  1
      //--- plot Low
      #property indicator_label2  "low"
      #property indicator_type2   DRAW_ARROW
      #property indicator_color2  clrRed
      #property indicator_style2  STYLE_SOLID
      #property indicator_width2  1
      
      input int      halfWidth = 5;
      
      
      //--- indicator buffers
      double         highBuffer[];
      double         lowBuffer[];
      
      //+------------------------------------------------------------------+
      //| Custom indicator initialization function                         |
      //+------------------------------------------------------------------+
      int OnInit()
        {
      //--- indicator buffers mapping
         SetIndexBuffer(0, highBuffer);
         SetIndexBuffer(1, lowBuffer);
      //--- setting a code from the Wingdings charset as the property of PLOT_ARROW
      //   PlotIndexSetInteger(0,PLOT_ARROW,234); 
      //   PlotIndexSetInteger(1,PLOT_ARROW,233); these are the default lines generated by mql4 but I find them not working so I replace with the lines below
         SetIndexArrow(0, 226);
         SetIndexArrow(1, 225);
      //---
         return(INIT_SUCCEEDED);
        }
      //+------------------------------------------------------------------+
      //| 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[])
        {
      //---
         if(rates_total < halfWidth*2 + 1) return(0);
        
         int      uncalculated;
         double   priceWindow = ChartGetDouble(0,CHART_FIXED_MAX,0) - ChartGetDouble(0,CHART_FIXED_MIN,0);
         
         uncalculated = rates_total - prev_calculated;
         for(int i=halfWidth; i<uncalculated+halfWidth; i++)
         {   
            
            int m = 0;
            int n = 0;
            for(int j=1; j<=halfWidth; j++)
            {   
               if(close[i]==MathMax(close[i],close[i+j]) && close[i]==MathMax(close[i],close[i-j]))
               {
                  m++;
                  if(m==halfWidth) 
                     highBuffer[i] = close[i] + priceWindow*0.04;
               }
               if(close[i]==MathMin(close[i],close[i+j]) && close[i]==MathMin(close[i],close[i-j]))
               {
                  n++;
                  if(n==halfWidth) 
                     lowBuffer[i] = close[i] - priceWindow*0.04;  
               }
            }
         }
         
      //--- return value of prev_calculated for next call
         return(rates_total);
        }
      //+------------------------------------------------------------------+
      //| Timer function                                                   |
      //+------------------------------------------------------------------+
      void OnTimer()
        {
      //---
         
        }
      //+---------------------   --------------------------------------------+
      
       
      John Voidman: The first approach is automatically done by the MT4, right? Cause I don't see any explicit codes that store the index offset to the buffer.

      No! The array index is just that, an array Index. it is not stored in any buffer automatically.

       
      John Voidman: The simple explanation is it tries to get lowest and highest price of every small period. I try not to worry about time and it worked. Now I'm trying to make it into a function of EA or a library that can be used for understanding potential resistance and support prices.

      I don't see in your indicator code anything that has to do with your original question.

      However, if you are looking for a way in the EA, to identify the time for a the relevant shift when searching the high or low buffer values via the iCustom(), then you can simply use the Time[] series array to obtain the time for that specific index shift used in the iCustom() call.

      Show your EA code where you obtain the values with iCustom() and carry out the high/low search so that we can offer you suggestions.

       
      John Voidman:

      Just a renamed 5 period super signals. You can find out what "super signals" does on the newt

       
      Mladen Rakic:

      Just a renamed 5 period super signals. You can find out what "super signals" does on the newt

      Thanks, They look quite the same.
       
      John Voidman #:
      This is very helpful, since i've always had the issue being discussed.
      Reason: