Download MetaTrader 5
To add comments, please log in or register
One billion tasks have already been executed with MQL5 Cloud Network. Test trading robots even faster!
dennisj2
153
dennisj2 2014.09.08 11:49 

I've written a large number of indicators and they are fairly robust. I have always followed a pattern to display all but one of the buffers in the main chart window and reserving 1 buffer not to plot but to store measures that are calculated for and retrieved by a given EA. These measures aren't prices and would not look good if applied to a chart.

This has worked well for me until now. I have a need to put an indicator in a separate window and even though I set the indicator_style property to DRAW_NONE - the indicator still draws the buffer. Since all of my values are either near 0 or greater than 100, I get an indicator that basically shows a solid line down the middle.

 I've tried using the indicator_plots property = indicator_buffers-1, I've tried to set SetIndexDrawBegin(2,0) - but, nothing seems to work and I have not been able to find a workaround anywhere. Worst case, I'll have to put the indicator code into my EA - but, wow.

Does anyone know of a way of having a separate window indicator not draw a plot?

Alain Verleyen
Moderator
28658
Alain Verleyen 2014.09.08 12:11  
dennisj2:

I've written a large number of indicators and they are fairly robust. I have always followed a pattern to display all but one of the buffers in the main chart window and reserving 1 buffer not to plot but to store measures that are calculated for and retrieved by a given EA. These measures aren't prices and would not look good if applied to a chart.

This has worked well for me until now. I have a need to put an indicator in a separate window and even though I set the indicator_style property to DRAW_NONE - the indicator still draws the buffer. Since all of my values are either near 0 or greater than 100, I get an indicator that basically shows a solid line down the middle.

 I've tried using the indicator_plots property = indicator_buffers-1, I've tried to set SetIndexDrawBegin(2,0) - but, nothing seems to work and I have not been able to find a workaround anywhere. Worst case, I'll have to put the indicator code into my EA - but, wow.

Does anyone know of a way of having a separate window indicator not draw a plot?

If set to DRAW_NONE it should not draw anything. Please show the relevant code.

dennisj2
153
dennisj2 2014.09.08 12:19  
angevoyageur:

If set to DRAW_NONE it should not draw anything. Please show the relevant code.


//+------------------------------------------------------------------+
//|                                                  pipMA-ST-v1.mq4 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   2

//--- plot indPipValue
#property indicator_label1  "indPipValue"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrSeaGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

//--- plot indTLine
#property indicator_label2  "indTLine"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrGoldenrod
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

//--- plot indPLine
#property indicator_label3  "indData"
#property indicator_type3   DRAW_NONE

#include <std_utility.mqh>

#define   dataMeasures    15
#define   dataTLine        0  //--- current trend line value
#define   dataFOCCur       1  //--- current factor of change
#define   dataFOCMin       2  //--- absolute retrace factor of change
#define   dataFOCMax       3  //--- highest factor of change this direction
#define   dataFOCDev       4  //--- current factor of change deviation
#define   dataFOCDir       5  //--- current direction from last deviation
#define   dataFOCTrend     6  //--- overall trend (based on FOC max)
#define   dataRngSize      7  //--- pip history range
#define   dataRngLow       8  //--- pip history range low
#define   dataRngMid       9  //--- pip history range bisector
#define   dataRngHigh     10  //--- pip history range high
#define   dataRngStr      11  //--- range strength based on composite range directions
#define   dataRngLowDir   12  //--- direction of low range
#define   dataRngMidDir   13  //--- direction of range bisector
#define   dataRngHighDir  14  //--- direction of range high

//--- input parameters
input int inpPeriod=200;  //--- pip MA range

//--- indicator buffers
double    indPipBuffer[];
double    indTLineBuffer[];
double    indDataBuffer[];

//--- operational variables
double    data[dataMeasures];

double    pipHistory[5000];
int       pipIndex = inpPeriod;

//+------------------------------------------------------------------+
//| pipChange - manages pip history                                  |
//+------------------------------------------------------------------+
bool pipChange()
  {
    int idx=pipIndex;

    if (fabs(pip(pipHistory[pipIndex]-Close[0]))>=1.0)
    {
      if (pipIndex == 0)
        for (pipIndex=inpPeriod-1; pipIndex>0; pipIndex--)
          pipHistory[pipIndex]=pipHistory[pipIndex-1];
      else
        pipIndex--;
  
      pipHistory[pipIndex]=Close[0];
       

      while (idx<inpPeriod)
      {
        indPipBuffer[idx-pipIndex]=pipHistory[idx];
        idx++;
      }
        
      return(true);
    }

    return(false);
  }

//+------------------------------------------------------------------+
//| pipChange - manages pip history                                  |
//+------------------------------------------------------------------+
void CalculateTLineRegression()
  {
    //--- Linear regression line
    double m[5] = {0.00,0.00,0.00,0.00,0.00};  //--- slope
    double b    = 0.00;                        //--- y-intercept
    
    double sumx = 0.00;
    double sumy = 0.00;
    
    for (int idx=0; idx<inpPeriod; idx++)
    {
      sumx += idx+1;
      sumy += pipHistory[idx];
      
      m[1] += (idx+1)*pipHistory[idx];
      m[3] += pow(idx+1,2);
    }
    
    m[1]   *= inpPeriod;
    m[2]    = sumx*sumy;
    m[3]   *= inpPeriod;
    m[4]    = pow(sumx,2);
    
    m[0]    = (m[1]-m[2])/(m[3]-m[4]);
    b       = (sumy - m[0]*sumx)/inpPeriod;
    
    for (int idx=0; idx<inpPeriod; idx++)
      //--- y=mx+b
      indTLineBuffer[inpPeriod-idx-1] = (m[0]*(inpPeriod-idx-1))+b;
      
    indPipBuffer[inpPeriod]=0.00;
    indTLineBuffer[inpPeriod]=0.00;
  }

//+------------------------------------------------------------------+
//| CalculateMeasures - calculates pipMA metrics and loads buffer    |
//+------------------------------------------------------------------+
void CalculateMeasures()
  {
    double dataLast[dataMeasures];
    
    ArrayCopy(dataLast,data);
    
    //--- range metrics
    data[dataRngLow]    = pipHistory[0];
    data[dataRngHigh]   = pipHistory[0];
    
    for (int idx=0; idx<inpPeriod; idx++)
    {
      data[dataRngLow]  = fmin(data[dataRngLow],pipHistory[idx]);
      data[dataRngHigh] = fmax(data[dataRngHigh],pipHistory[idx]);
    }

    data[dataRngSize]   = pip(data[dataRngHigh] - data[dataRngLow]);
    data[dataRngMid]    = (data[dataRngHigh] + data[dataRngLow]) / 2;

    if (dataLast[dataRngLow]!=data[dataRngLow])
      data[dataRngLowDir]   = dir(data[dataRngLow]-dataLast[dataRngLow]);

    if (dataLast[dataRngMid]!=data[dataRngMid])
      data[dataRngMidDir]   = dir(data[dataRngMid]-dataLast[dataRngMid]);

    if (dataLast[dataRngHigh]!=data[dataRngHigh])
      data[dataRngHighDir]  = dir(data[dataRngHigh]-dataLast[dataRngHigh]);
    
    data[dataRngStr]    = data[dataRngLowDir]+data[dataRngMidDir]+data[dataRngHighDir];

    if (fabs(data[dataRngStr])>2)
      data[dataRngStr]  = 2*dir(data[dataRngStr]);
      
    for (int idx=0; idx<dataMeasures; idx++)
      indDataBuffer[idx]= data[idx];
      
    //--- factor of change metrics
    data[dataFOCCur]    = (atan(pip(indTLineBuffer[0]-indTLineBuffer[inpPeriod-1])/inpPeriod)*180)/M_PI;
    data[dataTLine]     = (indTLineBuffer[0]);
    
    if (dir(data[dataFOCCur]) == data[dataFOCTrend])
    {
    Print("in the area: "+NormalizeDouble(data[dataFOCCur],1)+":"+NormalizeDouble(data[dataFOCMax],1));
    
      if (NormalizeDouble(data[dataFOCCur],1) == NormalizeDouble(data[dataFOCMax],1))
        data[dataFOCMin]= 0.00;
      else
      if (data[dataFOCMin]  == 0.00)
        data[dataFOCMin]= fabs(data[dataFOCCur]);
      else
        data[dataFOCMin]= fmin(fabs(data[dataFOCCur]),fabs(data[dataFOCMin]));

      data[dataFOCMax]  = fmax(fabs(data[dataFOCCur]),fabs(data[dataFOCMax]))*data[dataFOCTrend];
    }
    else
    {
      data[dataFOCMin]  = 0.00;
      data[dataFOCMax]  = data[dataFOCCur];
    }

    data[dataFOCDev]    = fabs(fabs(data[dataFOCMax]-data[dataFOCCur]));
    data[dataFOCTrend]  = dir(data[dataFOCMax]);
    
    if (data[dataFOCDev]!= dataLast[dataFOCDev])
      data[dataFOCDir]  = dir(dataLast[dataFOCDev]-data[dataFOCDev])*data[dataFOCTrend];
  }
  
//+------------------------------------------------------------------+
//| CalculateMeasures - calculates pipMA metrics and loads buffer    |
//+------------------------------------------------------------------+
void RefreshScreen()
  {
    if (pipIndex == 0)
    {  
      SetLevelValue(1,data[dataRngMid]);
    
      UpdateLabel("lrFOCCur",DoubleToStr(data[dataFOCCur],1),dirColor(dir(data[dataFOCTrend])),15);
      UpdateLabel("lrFOCMax",DoubleToStr(data[dataFOCMax],1),dirColor(dir(data[dataFOCTrend])),15);
      UpdateLabel("lrFOCDev",DoubleToStr(data[dataFOCDev],1),dirColor(dir(data[dataFOCDir])),8);
      UpdateLabel("lrFOCMin",DoubleToStr(data[dataFOCMin],1),dirColor(dir(data[dataFOCDir])),8);

      UpdateDirection("lrFOCDir",(int)data[dataFOCDir],12);
      UpdateDirection("lrFOCTrend",(int)data[dataFOCTrend],12);
    }
    else
      UpdateLabel("lrFOCCur","Initializing "+DoubleToStr(((inpPeriod-pipIndex)/inpPeriod)*100,1)+"%");

  }

//+------------------------------------------------------------------+
//| 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 (pipChange())
      if (pipIndex == 0)
      {
        CalculateTLineRegression();
        CalculateMeasures();
      }
   
    RefreshScreen();
    
    //--- return value of prev_calculated for next call
    return(rates_total);
  }

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
    //--- indicator buffers mapping
    SetIndexBuffer(0,indPipBuffer);
    SetIndexBuffer(1,indTLineBuffer);
    SetIndexBuffer(2,indDataBuffer);
 
    SetIndexEmptyValue(0, 0.00);
    SetIndexEmptyValue(1, 0.00);
    SetIndexEmptyValue(2, 0.00);
   
    ArrayInitialize(indPipBuffer,    0.00);
    ArrayInitialize(indTLineBuffer,  0.00);
    ArrayInitialize(indDataBuffer,   0.00);

    ArrayInitialize(pipHistory,      0.00);
    
    NewLabel("lrFOCCur","Initializing",5,15,clrWhite,SCREEN_UL,1);
    NewLabel("lrFOCMax","",65,15,clrNONE,SCREEN_UL,1);
    NewLabel("lrFOCDev","",30,40,clrNONE,SCREEN_UL,1);
    NewLabel("lrFOCMin","",90,40,clrNONE,SCREEN_UL,1);
    
    NewLabel("lrFOCDir","",10,40,clrNONE,SCREEN_UL,1);
    NewLabel("lrFOCTrend","",70,40,clrNONE,SCREEN_UL,1);
    
    return(INIT_SUCCEEDED);
  }
  
Alain Verleyen
Moderator
28658
Alain Verleyen 2014.09.08 12:38  

You are using statement that doesn't work with mql4. Try this :

#property indicator_buffers 2
#property indicator_plots   2

//--- plot indPipValue
#property indicator_label1  "indPipValue"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrSeaGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

//--- plot indTLine
#property indicator_label2  "indTLine"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrGoldenrod
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1

//--- plot indPLine
#property indicator_label3  "indData"
#property indicator_type3   DRAW_NONE

and add this line at the top of OnInit()

   IndicatorBuffers(3);
dennisj2
153
dennisj2 2014.09.08 12:50  
wow, magic! Thanks a bunch!
Alain Verleyen
Moderator
28658
Alain Verleyen 2014.09.08 13:03  
dennisj2:
wow, magic! Thanks a bunch!
You are welcome.
Alberto Jorge Cushnir
228
Alberto Jorge Cushnir 2015.12.23 02:09  

Hi mate!

Sorry for asking, but, could be possible you share your std_utility.mqh file?

Thanks in advance 

/
To add comments, please log in or register