I am trying to create indicator which displays up arrow when MACD histogram changes direction to go up, and down arrow when change to down. I run with no errors but it giving incorrect arrows on chart and missing out many changes...
Any help much appreciated! :)
Post the code ...
Sorry I dont know why it didnt insert properly the first time...
//| 19151.mq4 |
//| |
//| |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 LawnGreen
#property indicator_color2 Red
//MACD Settings
extern int Fast_EMA = 12;
extern int Slow_EMA = 26;
extern int Signal_Period = 9;
extern int price = PRICE_CLOSE;
//MACD for calculations
double MACD1;
double MACD2;
double MACD3;
double CrossUp[];
double CrossDown[];
//plot state can be 1 of: UP,DOWN
#define PLOTUP 1
#define PLOTDOWN -1
int iWaitFor = PLOTUP; //initial value
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators/ Arrows
SetIndexBuffer(0, CrossUp);
SetIndexStyle(0, DRAW_ARROW, EMPTY);
SetIndexArrow(0, 225);
SetIndexBuffer(1, CrossDown);
SetIndexStyle(1, DRAW_ARROW, EMPTY);
SetIndexArrow(1, 226);
return(0);
}
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
MACD1 =0;
MACD2 =0;
MACD3 =0;
int counted_bars = IndicatorCounted();
int i;
int limit;
if(counted_bars < 0)
return(-1);
if(counted_bars > 0)
counted_bars--;
limit = Bars - counted_bars;
for(i=0; i<=limit; i++)
{
MACD1 = iMACD(NULL,0,Fast_EMA,Slow_EMA,Signal_Period,price,MODE_MAIN,i);
MACD2 = iMACD(NULL,0,Fast_EMA,Slow_EMA,Signal_Period,price,MODE_MAIN,i + 1);
MACD3 = iMACD(NULL,0,Fast_EMA,Slow_EMA,Signal_Period,price,MODE_MAIN,i + 2);
if ((MACD1<MACD2 && MACD2>MACD3) && iWaitFor==PLOTUP) //
{
iWaitFor = PLOTDOWN;
CrossUp[i]=Low[i] - 0.0005;
}
if ((MACD1>MACD2 && MACD2<MACD3) && iWaitFor==PLOTDOWN)
{
iWaitFor = PLOTUP;
CrossDown[i]=High[i] + 0.0005;
}
}
return(0);
}
Sorry I dont know why it didnt insert properly the first time...
//| 19151.mq4 |
//| |
//| |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 LawnGreen
#property indicator_color2 Red
//MACD Settings
extern int Fast_EMA = 12;
extern int Slow_EMA = 26;
extern int Signal_Period = 9;
extern int price = PRICE_CLOSE;
//MACD for calculations
double MACD1;
double MACD2;
double MACD3;
double CrossUp[];
double CrossDown[];
//plot state can be 1 of: UP,DOWN
#define PLOTUP 1
#define PLOTDOWN -1
int iWaitFor = PLOTUP; //initial value
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators/ Arrows
SetIndexBuffer(0, CrossUp);
SetIndexStyle(0, DRAW_ARROW, EMPTY);
SetIndexArrow(0, 225);
SetIndexBuffer(1, CrossDown);
SetIndexStyle(1, DRAW_ARROW, EMPTY);
SetIndexArrow(1, 226);
return(0);
}
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
MACD1 =0;
MACD2 =0;
MACD3 =0;
int counted_bars = IndicatorCounted();
int i;
int limit;
if(counted_bars < 0)
return(-1);
if(counted_bars > 0)
counted_bars--;
limit = Bars - counted_bars;
for(i=0; i<=limit; i++)
{
MACD1 = iMACD(NULL,0,Fast_EMA,Slow_EMA,Signal_Period,price,MODE_MAIN,i);
MACD2 = iMACD(NULL,0,Fast_EMA,Slow_EMA,Signal_Period,price,MODE_MAIN,i + 1);
MACD3 = iMACD(NULL,0,Fast_EMA,Slow_EMA,Signal_Period,price,MODE_MAIN,i + 2);
if ((MACD1<MACD2 && MACD2>MACD3) && iWaitFor==PLOTUP) //
{
iWaitFor = PLOTDOWN;
CrossUp[i]=Low[i] - 0.0005;
}
if ((MACD1>MACD2 && MACD2<MACD3) && iWaitFor==PLOTDOWN)
{
iWaitFor = PLOTUP;
CrossDown[i]=High[i] + 0.0005;
}
}
return(0);
}
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 clrLawnGreen
#property indicator_color2 clrRed
#property strict
//------------------------------------------------------------------
extern int Fast_EMA = 12; // Fast ema period
extern int Slow_EMA = 26; // Slow ema period
extern ENUM_APPLIED_PRICE price = PRICE_CLOSE; // Price
double CrossUp[],CrossDown[],direction[],macd[];
int OnInit()
{
IndicatorBuffers(4);
SetIndexBuffer(0, CrossUp); SetIndexStyle(0, DRAW_ARROW); SetIndexArrow(0, 225);
SetIndexBuffer(1, CrossDown); SetIndexStyle(1, DRAW_ARROW); SetIndexArrow(1, 226);
SetIndexBuffer(2, direction);
SetIndexBuffer(3, macd);
return(0);
}
int OnCalculate (const int rates_total,
const int prev_calculated,
const datetime& btime[],
const double& open[],
const double& high[],
const double& low[],
const double& close[],
const long& tick_volume[],
const long& volume[],
const int& spread[] )
{
int counted_bars = prev_calculated;
if(counted_bars < 0) return(-1);
if(counted_bars > 0) counted_bars--;
int limit=MathMin(rates_total-counted_bars,rates_total-1);
for(int i=limit; i>-0; i--)
{
macd[i] = iMA(NULL,0,Fast_EMA,0,MODE_EMA,price,i)-iMA(NULL,0,Slow_EMA,0,MODE_EMA,price,i);
direction[i] = (i<Bars-1) ? (macd[i]>macd[i+1]) ? 1 : (macd[i]<macd[i+1]) ? -1 : 0 : 0;
CrossUp[i] = EMPTY_VALUE;
CrossDown[i] = EMPTY_VALUE;
if (i<Bars-1 && direction[i]!=direction[i+1])
{
if (direction[i]== 1) CrossUp[i] = Low[i] - iATR(NULL,0,10,i);
if (direction[i]==-1) CrossDown[i] = High[i] + iATR(NULL,0,10,i);
}
}
return(rates_total);
}
Use this (it plots an arrow on a bar where the macd slope changes up or down). Since you did not use the signal line for anything, in this version there is no signal calculated (or parameter used for that)
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 clrLawnGreen
#property indicator_color2 clrRed
#property strict
//------------------------------------------------------------------
extern int Fast_EMA = 12; // Fast ema period
extern int Slow_EMA = 26; // Slow ema period
extern ENUM_APPLIED_PRICE price = PRICE_CLOSE; // Price
double CrossUp[],CrossDown[],direction[],macd[];
int OnInit()
{
IndicatorBuffers(4);
SetIndexBuffer(0, CrossUp); SetIndexStyle(0, DRAW_ARROW); SetIndexArrow(0, 225);
SetIndexBuffer(1, CrossDown); SetIndexStyle(1, DRAW_ARROW); SetIndexArrow(1, 226);
SetIndexBuffer(2, direction);
SetIndexBuffer(3, macd);
return(0);
}
int OnCalculate (const int rates_total,
const int prev_calculated,
const datetime& btime[],
const double& open[],
const double& high[],
const double& low[],
const double& close[],
const long& tick_volume[],
const long& volume[],
const int& spread[] )
{
int counted_bars = prev_calculated;
if(counted_bars < 0) return(-1);
if(counted_bars > 0) counted_bars--;
int limit=MathMin(rates_total-counted_bars,rates_total-1);
for(int i=limit; i>-0; i--)
{
macd[i] = iMA(NULL,0,Fast_EMA,0,MODE_EMA,price,i)-iMA(NULL,0,Slow_EMA,0,MODE_EMA,price,i);
direction[i] = (i<Bars-1) ? (macd[i]>macd[i+1]) ? 1 : (macd[i]<macd[i+1]) ? -1 : 0 : 0;
CrossUp[i] = EMPTY_VALUE;
CrossDown[i] = EMPTY_VALUE;
if (i<Bars-1 && direction[i]!=direction[i+1])
{
if (direction[i]== 1) CrossUp[i] = Low[i] - iATR(NULL,0,10,i);
if (direction[i]==-1) CrossDown[i] = High[i] + iATR(NULL,0,10,i);
}
}
return(rates_total);
}
Wow thank you so much Rakic, very much appreciated!!! :)
Out of interest do you know what was wrong with the approach I used to code this and why it didnt work, as opposed to what you have done?
Wow thank you so much Rakic, very much appreciated!!! :)
Out of interest do you know what was wrong with the approach I used to code this and why it didnt work, as opposed to what you have done?
- you were checking conditions (and "inheriting" previous state) from right to left - from future to past. That is a bad practice and should be avoided (that is one of the most common causes for repainting - not necessarily, but coupled with variables values "inheriting", that directly leads to repainting)
- conditions were not clear (you were looking for places where the macd made an extreme on previous bar, not on current, and then marked it a if it was the current)
- your arrow buffers were not cleaned - that was another cause for repainting that needed to be solved
A couple of things :
- you were checking conditions (and "inheriting" previous state) from right to left - from future to past. That is a bad practice and should be avoided (that is one of the most common causes for repainting - not necessarily, but coupled with variables values "inheriting", that directly leads to repainting)
- conditions were not clear (you were looking for places where the macd made an extreme on previous bar, not on current, and then marked it a if it was the current)
- your arrow buffers were not cleaned - that was another cause for repainting that needed to be solved
Thankyou again Rakic very helpful!
I am trying to understand your code so I can work with it but I am struggling with a few parts, specifically the use of 0:0:, EmptyValue, and the if statement (below only).. any guidance on this I would be very greatful for!
Also I am trying to get the arrow to display on the current candle '0', ( so after close of previous rather than on it) - I have tried changing CrossUp[i] to CrossUp[i-1] but had no luck... any thoughts on how I could do this...
Many Thanks!
CrossUp[i] = EMPTY_VALUE;
CrossDown[i] = EMPTY_VALUE;
if (i<Bars-1 && direction[i]!=direction[i+1])
...
...
This line is equivalent to :
{
if(macd[i]>macd[i+1])
{
direction[i]=1;
}
else if(macd[i]<macd[i+1])
{
direction[i]=-1;
}
else
{
direction[i]=0;
}
}
else
{
direction[i]=0;
}
Thankyou again Rakic very helpful!
I am trying to understand your code so I can work with it but I am struggling with a few parts, specifically the use of 0:0:, EmptyValue, and the if statement (below only).. any guidance on this I would be very greatful for!
Also I am trying to get the arrow to display on the current candle '0', ( so after close of previous rather than on it) - I have tried changing CrossUp[i] to CrossUp[i-1] but had no luck... any thoughts on how I could do this...
Many Thanks!
CrossUp[i] = EMPTY_VALUE;
CrossDown[i] = EMPTY_VALUE;
if (i<Bars-1 && direction[i]!=direction[i+1])
Hi Radic,
Do you know how I can get arrow to display on current candle - I have tried changing "for(int i=limit; i>-0; i--)" to "for(int i=limit; i>=0; i--)" but this did not work... any thoughts please...? :)
Thanks
![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I am trying to create indicator which displays up arrow when MACD histogram changes direction to go up, and down arrow when change to down. I run with no errors but it giving incorrect arrows on chart and missing out many changes...
Any help much appreciated! :)
//| 19151.mq4 |
//| |
//| |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 LawnGreen
#property indicator_color2 Red
//MACD Settings
extern int Fast_EMA = 12;
extern int Slow_EMA = 26;
extern int Signal_Period = 9;
extern int price = PRICE_CLOSE;
//MACD for calculations
double MACD1;
double MACD2;
double MACD3;
double CrossUp[];
double CrossDown[];
//plot state can be 1 of: UP,DOWN
#define PLOTUP 1
#define PLOTDOWN -1
int iWaitFor = PLOTUP; //initial value
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators/ Arrows
SetIndexBuffer(0, CrossUp);
SetIndexStyle(0, DRAW_ARROW, EMPTY);
SetIndexArrow(0, 225);
SetIndexBuffer(1, CrossDown);
SetIndexStyle(1, DRAW_ARROW, EMPTY);
SetIndexArrow(1, 226);
return(0);
}
//+------------------------------------------------------------------+
//| script program start function |
//+------------------------------------------------------------------+
int start()
{
MACD1 =0;
MACD2 =0;
MACD3 =0;
int counted_bars = IndicatorCounted();
int i;
int limit;
if(counted_bars < 0)
return(-1);
if(counted_bars > 0)
counted_bars--;
limit = Bars - counted_bars;
for(i=0; i<=limit; i++)
{
MACD1 = iMACD(NULL,0,Fast_EMA,Slow_EMA,Signal_Period,price,MODE_MAIN,i);
MACD2 = iMACD(NULL,0,Fast_EMA,Slow_EMA,Signal_Period,price,MODE_MAIN,i + 1);
MACD3 = iMACD(NULL,0,Fast_EMA,Slow_EMA,Signal_Period,price,MODE_MAIN,i + 2);
if ((MACD1<MACD2 && MACD2>MACD3) && iWaitFor==PLOTUP) //
{
iWaitFor = PLOTDOWN;
CrossUp[i]=Low[i] - 0.0005;
}
if ((MACD1>MACD2 && MACD2<MACD3) && iWaitFor==PLOTDOWN)
{
iWaitFor = PLOTUP;
CrossDown[i]=High[i] + 0.0005;
}
}
return(0);
}