Working on an Indicator that shows the Prof/Loss for the MACD 9MA cross.

 

Hi All,

I am working on an Indicator that shows the Prof/Loss on the chart as a line, as well as, the highest value of the PL going back to the beginning of the chart.

I wrote it in Metastock and have pasted a pick of the chart example. I'm not very good at MQL4, but have included the code that I've written.

If you put the code on a M1 chart, you'll see that the value on the chart jumps around....and I don't understand why.

If you could please also give me some hints for creating the HIGHEST PL Value...I can't seem to get my head around where I'm going wrong. 

Please have a look and give me some ideas

Thanks people. :)

Have a GREAT WEEKEND!!!!!

Prof Loss Indicator


#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Silver
//---- buffers
double ExtMapBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicator
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMapBuffer1);
   IndicatorShortName("MACD PL");
   SetIndexLabel(0,"MACD PL");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//----
   double PL = 0;
   int limit= Bars-counted_bars-1;
   for(int i=limit; i>= 0; i--)
   
      {

      if(iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2)>iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,2))
        {
         PL = (Close[i+1]-Close[i+2])+PL;
        } 
        else {
            PL=(Close[i+2]-Close[i+1])+PL;
     
           }
      ExtMapBuffer1[i]=PL;
    
     }

//----
   return(0);
  }
//+------------------------------------------------------------------+
 
Timbo618:

I am working on an Indicator that shows the Prof/Loss on the chart as a line, as well as, the highest value of the PL going back to the beginning of the chart.

It's not entirely clear to me what you are trying to do, but there are at least two problems in the code.

Firstly:

iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2)

This will always get the MACD value as-at two bars ago from now, not two bars previous to the historic bar i. I am not sure exactly what you are trying to do here, but it seems as though you must intend something like:

iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN, i + 2)

Secondly, consider what happens when counted_bars > 0. For example, if limit=0, then the following happens:

  • You initialise the variable PL to zero
  • The for loop gets run once, and PL is set to the latest difference in close prices - without any reference to previous values
  • You then put this single latest difference in close prices into the indicator buffer, without taking into account any previous values. So, the value jumps.

It looks as though you must want to do something more like:

if (...MACD condition...) {
  ExtMapBuffer1[i] = (Close[i+1]-Close[i+2]) + ExtMapBuffer1[i + 1];
} else {
  ExtMapBuffer1[i] = (Close[i+2]-Close[i+1]) + ExtMapBuffer1[i + 1];
}

 In other words, you use the indicator buffer as the running total, because, unlike the variable PL, the values in the buffer get preserved between different ticks and calculations of the indicator.

 
jjc:

It's not entirely clear to me what you are trying to do, but there are at least two problems in the code.

Firstly:

This will always get the MACD value as-at two bars ago from now, not two bars previous to the historic bar i. I am not sure exactly what you are trying to do here, but it seems as though you must intend something like:

Secondly, consider what happens when counted_bars > 0. For example, if limit=0, then the following happens:

  • You initialise the variable PL to zero
  • The for loop gets run once, and PL is set to the latest difference in close prices - without any reference to previous values
  • You then put this single latest difference in close prices into the indicator buffer, without taking into account any previous values. So, the value jumps.

It looks as though you must want to do something more like:

 In other words, you use the indicator buffer as the running total, because, unlike the variable PL, the values in the buffer get preserved between different ticks and calculations of the indicator.

YOU..My Friend....Are a GENIUS!!!!....That's exactly what I'm looking for... :)

It works perfectly....I don't know why I was using a 2 instead of (Now minus 2)....Of course it was only using bar no.2....I'm a freaking idiot....I'ts been a long week.

The reason why I'm looking at this and wanting the highest value of the PL Indicator is in my EA, I want it to not trade when the virtual drawdown of a particular EA (eg MACD 9 MA) reaches a certain level (i.e. HighPL-MACDPL>300....If you know what I mean.

I will try and code the Highest High value of the MACD PL on the weekend...I don't think I should be too hard...But you never know with me...The Accidental Coder... :)

Thanks again jjc.

Have a great weekend.

 
jjc:

It's not entirely clear to me what you are trying to do, but there are at least two problems in the code.

Firstly:

This will always get the MACD value as-at two bars ago from now, not two bars previous to the historic bar i. I am not sure exactly what you are trying to do here, but it seems as though you must intend something like:

Secondly, consider what happens when counted_bars > 0. For example, if limit=0, then the following happens:

  • You initialise the variable PL to zero
  • The for loop gets run once, and PL is set to the latest difference in close prices - without any reference to previous values
  • You then put this single latest difference in close prices into the indicator buffer, without taking into account any previous values. So, the value jumps.

It looks as though you must want to do something more like:

 In other words, you use the indicator buffer as the running total, because, unlike the variable PL, the values in the buffer get preserved between different ticks and calculations of the indicator.

Hi jjc...I tried adding a buffer with ExtHiBuffer for the high....but my brain is Friday fried...

Am I on the right track?


Thanks again for everything.

Cheers.


 double PL = 0;
   int limit= Bars-counted_bars-1;
   for(int i=limit; i>= 0; i--)
   
      {

      if(iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,i+2)>iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,i+2))
        {
         PL = (Close[i+1]-Close[i+2])+ExtMapBuffer1[i+1];
        } 
      if(iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,i+2)<iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,i+2))
        {
         PL = (Close[i+2]-Close[i+1])+ExtMapBuffer1[i+1];
        } 
        else {
            PL=PL;
     
           }
           if(ExtMapBuffer1[i]>ExtMapBuffer1[i+1])
        {
         ExtHiBuffer1[i] = ExtMapBuffer1[i];
        } 
      
        else {
            ExtHiBuffer1[i]=ExtHiBuffer1[i+1];
     
           }
      ExtMapBuffer1[i]=PL;
    
     }

//----
   return(0);
  }
//+------------------------------------------------------------------+
 
Timbo618:

Hi jjc...I tried adding a buffer with ExtHiBuffer for the high....but my brain is Friday fried...

Am I on the right track?

You again have the problem that the value of the variable PL does not persist, and is reset to zero, on each call to start(). Therefore, again, when counted_bars > 0 you are setting PL just to the most recent changes, and ignoring the cumulative history.

The simplest answer is to use two buffers: one for the cumulative PL, and one for the increasing peaks in that cumulative value. (If you only want to display one of the values, then you can use SetIndexStyle(..., DRAW_NONE) on the other.)

I am not sure if the following is exactly what you are trying to do, but it should demonstrate the general principle (using the new-style OnCalculate() rather than the old-style start() function).

#property strict
#property indicator_separate_window

#property indicator_color1    Red
#property indicator_color2    Blue

// Use two buffers: one for the cumulative PL, and one for the 
// high of that cumulative value
#property indicator_buffers 2
double CumulativePL[];
double HighestPL[];


int OnInit()
{
   // Set up indicator buffers
   SetIndexBuffer(0, CumulativePL);
   SetIndexBuffer(1, HighestPL);

   // Set the empty-value to zero rather than the default.
   // Otherwise, we can be adding to indicator buffer values which 
   // contain the special value 2147483647 (EMPTY_VALUE) rather than zero
   SetIndexEmptyValue(0, 0);
   SetIndexEmptyValue(1, 0);
   
   return(INIT_SUCCEEDED);
}

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[])
{
   // Work out which bars need (re-)calculating.
   // The fact that we are using a 26-bar EMA in the MACD, and then 9-bar smoothing of the 
   // MACD, plus going back 2 bars prior, means that there's no point looking at the first 
   // 37 bars of the history; the values will be meaningless. For simplicity, we'll
   // round this up to 40
   int iStartAt = MathMin(rates_total - prev_calculated, rates_total - 40);

   // Do the running totals using the indicator buffers, whose values are preserved between
   // calls to OnCalculate(), rather than variables such as the original PL whose 
   // value is lost and reset on each call/tick
   for (int i = iStartAt; i >= 0; i--) {
      if (iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,i+2) >iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,i+2)) {
         CumulativePL[i] = CumulativePL[i + 1] + Close[i+1] - Close[i+2];
      } else {
         CumulativePL[i] = CumulativePL[i + 1] + Close[i+2] - Close[i+1];
      }
      HighestPL[i] = MathMax(HighestPL[i + 1], CumulativePL[i]);
   }
   return(rates_total);
}