Indicator help

 

Hello,

At times, the attached indicator does not change color according to the MA cross. For the correct color to appear, I have to change the time frame of the chart and bring it back to the relevant time frame. Appreciate it if someone could have a look at it and make the necessary correction/changes for the indicator to work properly.

Thanks in anticipation.

Files:
 

Try this.

if(MA_Fast_Current > MA_Slow_Current && MA_Fast_Previous < MA_Slow_Previous) Up[i]   = 1;
if(MA_Fast_Current < MA_Slow_Current && MA_Fast_Previous > MA_Slow_Previous) Down[i] = 1;

It appears you need another variable, named MA_Fast_Previous, to detect a moving average cross.


 

Thanks for your response. I think that adding your codes will determine the specific bar at which the cross occurred, however as we move to the next bar, the code that I have very well determines (or does it?) whether there is an up or down signal. This fact is not reflected unless I change the time frame and then come back to the relevant time frame.


TF

 
How hard can it be to declare a variable named MA_Fast_Previous and revise the code as follows?

MA_Fast_Current  = iMA(NULL,0,mA_Period_Fast,0,mA_Method_Fast,mA_AppliedPrice_Fast,i+0);
MA_Fast_Previous = iMA(NULL,0,mA_Period_Fast,0,mA_Method_Fast,mA_AppliedPrice_Fast,i+1);
MA_Slow_Current  = iMA(NULL,0,mA_Period_Slow,0,mA_Method_Slow,mA_AppliedPrice_Slow,i+0);
MA_Slow_Previous = iMA(NULL,0,mA_Period_Slow,0,mA_Method_Slow,mA_AppliedPrice_Slow,i+1);

if(MA_Fast_Current > MA_Slow_Current && MA_Fast_Previous < MA_Slow_Previous) Up[i]   = 1;
if(MA_Fast_Current < MA_Slow_Current && MA_Fast_Previous > MA_Slow_Previous) Down[i] = 1;

If the previous fast MA was below the previous slow MA, and the current fast MA is above the current slow MA, you have a cross. 

The logic you have now, 

if(MA_Fast_Current > MA_Slow_Current && MA_Fast_Current > MA_Slow_Previous)

evaluates to TRUE if the current fast MA is above the current and previous values of the slow MA. If the previous fast MA was below the previous slow MA, your logic has no way of detecting that.


If you want the indicator simply to indicate whether the fast MA is above or below the slow MA, the logic becomes simple:

MA_Fast_Current  = iMA(NULL,0,mA_Period_Fast,0,mA_Method_Fast,mA_AppliedPrice_Fast,i+0);
MA_Slow_Current  = iMA(NULL,0,mA_Period_Slow,0,mA_Method_Slow,mA_AppliedPrice_Slow,i+0);

if(MA_Fast_Current > MA_Slow_Current) Up[i]   = 1;
if(MA_Fast_Current < MA_Slow_Current) Down[i] = 1;



 
TradeForexFx:

Hello,

At times, the attached indicator does not change color according to the MA cross. For the correct color to appear, I have to change the time frame of the chart and bring it back to the relevant time frame. Appreciate it if someone could have a look at it and make the necessary correction/changes for the indicator to work properly.

Thanks in anticipation.

This indicator is a dumbed-down version of MACD. MACD not only tells you the direction of the cross but also the magnitude. You could just as easily use MACD for this indicator, but I'm not sure why you'd want/need to... (unless of course you needed to use MAs that weren't EMAs 😮)

e.g.  

if(macd.Main(i) >= 0.0) 
   UpBuffer[i] = 1.0;
 

Steve, I will work on your suggestion (not at all hard).

nicoli, I like to observe various indicators in histo format. A properly working template can be used for any other indicator. As such I am looking for a properly working template which would update itself automatically rather than a need to change time frames to get it synced.


TF

 
TradeForexFx:

Steve, I will work on your suggestion (not at all hard).

nicoli, I like to observe various indicators in histo format. A properly working template can be used for any other indicator. As such I am looking for a properly working template which would update itself automatically rather than a need to change time frames to get it synced.


TF

Then this should do the trick. 

//+------------------------------------------------------------------+
//|                                                   MaCrossNew.mq4 |
//|                                                      nicholishen |
//|                         https://www.forexfactory.com/nicholishen |
//+------------------------------------------------------------------+
#property copyright "nicholishen"
#property link      "https://www.forexfactory.com/nicholishen"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 1
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Up
#property indicator_label1  "Up"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrDodgerBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  3
//--- plot Dn
#property indicator_label2  "Dn"
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  3
//--- input parameters
input int      InpFastMa=10;
input int      InpSlowMa=34;
//--- indicator buffers
double         UpBuffer[];
double         DnBuffer[];

#include <Indicators\Indicators.mqh>
CiMACD macd;
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0,UpBuffer);
   SetIndexBuffer(1,DnBuffer);
   if(!macd.Create(_Symbol, PERIOD_CURRENT, InpFastMa, InpSlowMa, 9, PRICE_CLOSE))
      return INIT_FAILED;
   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[])
{
   int limit = rates_total - prev_calculated;
   if(limit < 1)
      limit = 1;
   for(int i=limit-1; i>=0; i--){
      if(macd.Main(i) >= 0.0){
         UpBuffer[i] = 1.0;
         DnBuffer[i] = EMPTY_VALUE;
      }else{
         UpBuffer[i] = EMPTY_VALUE;
         DnBuffer[i] = 1.0;
      }
   }
   return(rates_total);
}
 
Thanks Nicholi.
 

Thanks once again Nicholi. The codes provided by you seems to be working well as far as Moving averages are concerned. I am sure that this template will work as well for introducing inputs such as input for MA method/applied price, as well as template to introduce other indicators to achieve a histo presentations.


The problem however is that this form of coding is quite beyond my understanding, such as use of include/mqh files. I cannot understand how the Moving Average has been called to get their values. I am  unable to use this somewhat advanced form of coding. I can handle coding that simply uses iMA(NULL,....,...) format of calling indicators


As such, I would appreciate if the coding format provided by me is reviewed for necessary corrections/improvement, so that it will be able to sync constantly rather than sync when I change time frames. 


As for the solution provided by Steven, it does not address my problem of syncing.


Thanks once again.

 
TradeForexFx:

Thanks once again Nicholi. The codes provided by you seems to be working well as far as Moving averages are concerned. I am sure that this template will work as well for introducing inputs such as input for MA method/applied price, as well as template to introduce other indicators to achieve a histo presentations.


The problem however is that this form of coding is quite beyond my understanding, such as use of include/mqh files. I cannot understand how the Moving Average has been called to get their values. I am  unable to use this somewhat advanced form of coding. I can handle coding that simply uses iMA(NULL,....,...) format of calling indicators


As such, I would appreciate if the coding format provided by me is reviewed for necessary corrections/improvement, so that it will be able to sync constantly rather than sync when I change time frames. 


As for the solution provided by Steven, it does not address my problem of syncing.


Thanks once again.

I am in the habit of using the class wrappers for simplicity. In this case it is equally simple to make a wrapper function... This you should understand. 

//+------------------------------------------------------------------+
//|                                                   MaCrossNew.mq4 |
//|                                                      nicholishen |
//|                         https://www.forexfactory.com/nicholishen |
//+------------------------------------------------------------------+
#property copyright "nicholishen"
#property link      "https://www.forexfactory.com/nicholishen"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 1
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Up
#property indicator_label1  "Up"
#property indicator_type1   DRAW_HISTOGRAM
#property indicator_color1  clrDodgerBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  3
//--- plot Dn
#property indicator_label2  "Dn"
#property indicator_type2   DRAW_HISTOGRAM
#property indicator_color2  clrRed
#property indicator_style2  STYLE_SOLID
#property indicator_width2  3
//--- input parameters
input int      InpFastMa=10;
input int      InpSlowMa=34;
//--- indicator buffers
double         UpBuffer[];
double         DnBuffer[];

double macd(int i)
{
   return iMACD(_Symbol, PERIOD_CURRENT, InpFastMa, InpSlowMa, 9, PRICE_CLOSE, 0, i);
}
//+------------------------------------------------------------------+
int OnInit()
{
   SetIndexBuffer(0,UpBuffer);
   SetIndexBuffer(1,DnBuffer);
   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[])
{
   int limit = rates_total - prev_calculated;
   if(limit < 1)
      limit = 1;
   for(int i=limit-1; i>=0; i--){
      if(macd(i) >= 0.0){
         UpBuffer[i] = 1.0;
         DnBuffer[i] = EMPTY_VALUE;
      }else{
         UpBuffer[i] = EMPTY_VALUE;
         DnBuffer[i] = 1.0;
      }
   }
   return(rates_total);
}

 

Yes, I understand this better now. I was able to make desired changes using Moving average rather than the Macd used in the above template. 


Thanks!!

Reason: