Indicators Used
Miscellaneous
0
Views
0
Downloads
0
Favorites
MACD_Divergence_v2
//+------------------------------------------------------------------+
//| ProjectName |
//| Copyright 2012, CompanyName |
//| http://www.companyname.net |
//+------------------------------------------------------------------+
#property copyright "MACD Divergence"
#property link "MACD Divergence"
//---- defines
#define DodgerBlue2 0xaa6014
#define Crimson2 0x280d93
//---- indicator settings
#property indicator_separate_window
#property indicator_buffers 8
#property indicator_color1 Yellow // 0: Macd main line
#property indicator_color2 Orange // 1: Macd signal line
#property indicator_color3 Gray // 2: Macd OsMA line
#property indicator_color4 DodgerBlue // 3: Long signal
#property indicator_color5 Crimson // 4: Short signal
#property indicator_color6 Crimson2 // 5: Top peak
#property indicator_color7 DodgerBlue2 // 6: Bottom peak
#property indicator_color8 White // 7: Macd signal (main/signal cross)
#property indicator_width1 1
#property indicator_width2 1
#property indicator_width3 1
#property indicator_width4 1
#property indicator_width5 1
#property indicator_width6 1
#property indicator_width7 1
#property indicator_width8 1
#property indicator_style1 STYLE_SOLID
#property indicator_style2 STYLE_DOT
#property indicator_style3 STYLE_SOLID
#property indicator_style4 STYLE_SOLID
#property indicator_style5 STYLE_SOLID
#property indicator_style6 STYLE_SOLID
#property indicator_style7 STYLE_SOLID
#property indicator_style8 STYLE_SOLID
//---- indicator parameters
extern int timeFrame = 0; // time frame
extern int nCheckBars = 120; // number of bars to check divergence
extern int macd_fast = 12; // fast EMA
extern int macd_slow = 26; // slow EMA
extern int macd_signal = 9; // signal SMA
extern int div_mode = 2; // 0:MODE_MAIN 1:MODE_SIGNAL 2:OsMA
extern double div_oscErr = 4.0; // allowable error along divergence line (oscilator)
extern double div_priceErr = 0.4; // allowable error along divergence line (PPS), iATR(nCheckBars)*err
extern bool bAlertDiv = false; // PlaySound() on divergence
extern bool bAlertCross = false; // PlaySound() on Macd main/signal cross
extern bool bAlertDialog = false; // display dialog on alert
extern bool bDrawObj = true; // draw lines on chart/window
extern int window = 0; // specify indicator window explicitly, 0: auto
extern int nMaxBars = 20000; // maximum number of bars to calculate, 0: no limit
//---- indicator buffers
double BufferMacdMain[]; // 0: Macd main line
double BufferMacdSignal[]; // 1: Macd signal line
double BufferMacdOsMA[]; // 2: Macd signal line
double BufferLongDiv[]; // 3: Long signal
double BufferShortDiv[]; // 4: Short signal
double BufferTop[]; // 5: top peak
double BufferBottom[]; // 6: bottom peak
double BufferCross[]; // 7: Macd main/signal cross
//---- vars
string sIndicatorName;
string sIndSelf="00-MacdDiv_v104";
string sPrefix;
int g_window;
int markLong = 233;
int markShort = 234;
int markDot = 167;
int markCross = 167;
color colRegularLong = DodgerBlue; // ( 30, 144, 255)= 0x1e90ff
color colRegularShort = Crimson; // (220, 20, 60)= 0xdc143c
color colHiddenLong = DodgerBlue2;
color colHiddenShort = Crimson2;
int wRegular = 1;
int wHidden = 1;
datetime tAlertLast = 0;
//----------------------------------------------------------------------
string TimeFrameToStr(int timeFrame)
{
switch(timeFrame)
{
case 1: return("M1");
case 5: return("M5");
case 15: return("M15");
case 30: return("M30");
case 60: return("H1");
case 240: return("H4");
case 1440: return("D1");
case 10080: return("W1");
case 43200: return("MN");
}
return("??");
}
//----------------------------------------------------------------------
void init()
{
if(timeFrame==0)
{
timeFrame=Period();
}
string tf=TimeFrameToStr(timeFrame);
sIndicatorName=sIndSelf+"("+tf+","+div_mode+","+macd_fast+","+macd_slow+","+macd_signal+")";
sPrefix=sIndicatorName;
IndicatorShortName(sIndicatorName);
SetIndexBuffer(0,BufferMacdMain);
SetIndexBuffer(1,BufferMacdSignal);
SetIndexBuffer(2,BufferMacdOsMA);
SetIndexBuffer(3,BufferLongDiv);
SetIndexBuffer(4,BufferShortDiv);
SetIndexBuffer(5,BufferTop);
SetIndexBuffer(6,BufferBottom);
SetIndexBuffer(7,BufferCross);
SetIndexLabel(0,"Macd main");
SetIndexLabel(1,"Macd signal");
SetIndexLabel(2,"Macd OsMA");
SetIndexLabel(3,"Long signal, divergence");
SetIndexLabel(4,"Short signal, divergence");
SetIndexLabel(5,"Top peak");
SetIndexLabel(6,"Bottom peak");
SetIndexLabel(7,"Macd main/signal cross");
SetIndexStyle(0,DRAW_LINE);
SetIndexStyle(1,DRAW_LINE);
SetIndexStyle(2,DRAW_HISTOGRAM);
SetIndexStyle(3,DRAW_ARROW);
SetIndexStyle(4,DRAW_ARROW);
SetIndexStyle(5,DRAW_ARROW);
SetIndexStyle(6,DRAW_ARROW);
SetIndexStyle(7,DRAW_ARROW);
SetIndexArrow(3,markLong);
SetIndexArrow(4,markShort);
SetIndexArrow(5,markDot);
SetIndexArrow(6,markDot);
SetIndexArrow(7,markCross);
int n=MathMax(macd_fast,macd_slow)+macd_signal;
SetIndexDrawBegin(0,n);
SetIndexDrawBegin(1,n);
SetIndexDrawBegin(2,n);
SetIndexDrawBegin(3,n);
SetIndexDrawBegin(4,n);
SetIndexDrawBegin(5,n);
SetIndexDrawBegin(6,n);
SetIndexDrawBegin(7,n);
SetLevelValue(0,0.0);
}
//----------------------------------------------------------------------
void deinit()
{
int n=ObjectsTotal();
for(int i=n-1; i>=0; i--)
{
string sName=ObjectName(i);
if(StringFind(sName,sPrefix)==0)
{
ObjectDelete(sName);
}
}
}
//----------------------------------------------------------------------
void objLine(string sName,int win,datetime ts,double ps,datetime te,double pe,color col,
int width=1,int style=STYLE_SOLID,bool bBack=false,bool bRay=false)
{
ObjectCreate(sName,OBJ_TREND,win,0,0);
ObjectSet(sName,OBJPROP_TIME1,ts);
ObjectSet(sName,OBJPROP_PRICE1,ps);
ObjectSet(sName,OBJPROP_TIME2,te);
ObjectSet(sName,OBJPROP_PRICE2,pe);
ObjectSet(sName,OBJPROP_COLOR,col);
ObjectSet(sName,OBJPROP_WIDTH,width);
ObjectSet(sName,OBJPROP_STYLE,style);
ObjectSet(sName,OBJPROP_BACK,bBack);
ObjectSet(sName,OBJPROP_RAY,bRay);
}
//----------------------------------------------------------------------
void objArrow(string sName,int win,datetime t,double p,int arrow,color col,int width=1)
{
ObjectCreate(sName,OBJ_ARROW,win,0,0);
ObjectSet(sName,OBJPROP_TIME1,t);
ObjectSet(sName,OBJPROP_PRICE1,p);
ObjectSet(sName,OBJPROP_ARROWCODE,arrow);
ObjectSet(sName,OBJPROP_COLOR,col);
ObjectSet(sName,OBJPROP_WIDTH,width);
}
//----------------------------------------------------------------------
string divModeToStr(int divMode)
{
switch(div_mode)
{
case MODE_MAIN:
return("MAIN");
case MODE_SIGNAL:
return("SIGNAL");
}
return("OsMA");
}
//----------------------------------------------------------------------
double getVal(int i)
{
switch(div_mode)
{
case MODE_MAIN:
return(BufferMacdMain[i]);
case MODE_SIGNAL:
return(BufferMacdSignal[i]);
}
return(BufferMacdOsMA[i]);
}
//----------------------------------------------------------------------
double getLowerPrice(int i)
{
double hi = High[i];
double lo = Low[i];
return(MathMin(hi,lo));
}
//----------------------------------------------------------------------
double getHigherPrice(int i)
{
double hi = High[i];
double lo = Low[i];
return(MathMax(hi,lo));
}
//----------------------------------------------------------------------
double macdDiv(bool bDrawObj,int mode,int x)
{
double v=iCustom(NULL,timeFrame,sIndSelf,
0,
nCheckBars,
macd_fast,
macd_slow,
macd_signal,
div_mode,
div_oscErr,
div_priceErr,
false,
false,
false,
bDrawObj,
window,
nMaxBars,
mode,x);
return(v);
}
//----------------------------------------------------------------------
void checkAlert()
{
if(bAlertDiv || bAlertCross)
{
bool bLongDiv=(BufferLongDiv[0]!=EMPTY_VALUE);
bool bShortDiv=(BufferShortDiv[0] != EMPTY_VALUE);
bool bFireDiv =(bLongDiv|| bShortDiv);
bool bFireCross=(BufferCross[0]!=EMPTY_VALUE);
bool bFire=((bAlertDiv && bFireDiv) ||
(bAlertCross && bFireCross));
if(bFire && tAlertLast!=Time[0])
{
if(!bAlertDialog)
{
PlaySound("alert.wav");
} else {
string s="";
if(bFireDiv)
{
string sMode=divModeToStr(div_mode);
if(bLongDiv)
{
s=s+"MACD("+sMode+") divergence, Long";
} else if(bShortDiv) {
s=s+"MACD("+sMode+") divergence, Short";
}
}
if(bFireCross)
{
if(s !="")
{
s=s+", ";
}
if(BufferMacdMain[1]>=BufferMacdSignal[1])
{
s=s+"MACD Golden Cross";
} else {
s=s+"MACD Dead Cross";
}
}
Alert("["+sIndSelf+"] "+s);
}
tAlertLast=Time[0];
}
}
}
//----------------------------------------------------------------------
void start()
{
if(window>0)
{
g_window=window;
} else {
g_window=WindowFind(sIndicatorName);
}
int counted_bars=IndicatorCounted();
if(counted_bars<0) return(-1);
if(counted_bars>0) counted_bars--;
int limit=Bars-counted_bars;
if(counted_bars==0) limit-=1+MathMax(nCheckBars,3);
int limit0=limit;
// clear beyond limits
for(int i=limit0-1; i>=limit; i--)
{
BufferMacdMain[i] = 0;
BufferMacdSignal[i] = 0;
BufferMacdOsMA[i] = 0;
BufferLongDiv[i] = EMPTY_VALUE;
BufferShortDiv[i] = EMPTY_VALUE;
BufferTop[i] = EMPTY_VALUE;
BufferBottom[i] = EMPTY_VALUE;
BufferCross[i] = 0;
}
if(timeFrame!=Period())
{
// MTF
limit =MathMax(limit, timeFrame / Period());
for(i=limit-1; i>=0; i--)
{
int x=iBarShift(NULL,timeFrame,Time[i]);
BufferMacdMain[i] = macdDiv(bDrawObj, 0, x);
BufferMacdSignal[i] = macdDiv(false, 1, x);
BufferMacdOsMA[i] = macdDiv(false, 2, x);
BufferLongDiv[i] = macdDiv(false, 3, x);
BufferShortDiv[i] = macdDiv(false, 4, x);
BufferTop[i] = macdDiv(false, 5, x);
BufferBottom[i] = macdDiv(false, 6, x);
BufferCross[i] = macdDiv(false, 7, x);
}
checkAlert();
return;
}
// timeFrame == Period()
double val1,val2,val3,val4;
for(i=limit-1; i>=0; i--)
{
BufferMacdMain[i] = iMACD(NULL, 0, macd_fast, macd_slow, macd_signal, PRICE_CLOSE, MODE_MAIN, i);
BufferMacdSignal[i] = iMACD(NULL, 0, macd_fast, macd_slow, macd_signal, PRICE_CLOSE, MODE_SIGNAL, i);
BufferMacdOsMA[i] = BufferMacdMain[i] - BufferMacdSignal[i];
BufferTop[i] = EMPTY_VALUE;
BufferBottom[i] = EMPTY_VALUE;
BufferCross[i] = EMPTY_VALUE;
double main2 = BufferMacdMain[i + 2];
double main1 = BufferMacdMain[i + 1];
double sig2 = BufferMacdSignal[i + 2];
double sig1 = BufferMacdSignal[i + 1];
if((main1>=sig1 && main2<sig2) ||
(main1<sig1 && main2>=sig2))
{
BufferCross[i]=(main1+main2+sig1+sig2) * 0.25;
}
// check top/bottom peak
val4 = getVal(i + 4);
val3 = getVal(i + 3);
val2 = getVal(i + 2);
val1 = getVal(i + 1);
// top peak
if(val4<=val3 && val3<=val2 && val2>val1)
{
BufferTop[i+2]=val2;
}
// bottom peak
if(val4>val3 && val3>val2 && val2<=val1)
{
BufferBottom[i+2]=val2;
}
}
// search divergence on bottom
for(int i1= limit-1; i1>= 0; i1--)
{
if(BufferBottom[i1] == EMPTY_VALUE)
{
continue;
}
for(int hidden=0; hidden<=1; hidden++)
{
val1=getVal(i1);
double p1=Close[i1];
int i2=-1;
for(int j=1; j<=nCheckBars; j++)
{
x=i1+j;
if(BufferBottom[x]==EMPTY_VALUE)
{
continue;
}
val2=getVal(x);
double p2=Close[x];
if((!hidden && (val2>val1 || p2<p1)) ||
(hidden && (val2<val1 || p2>p1)))
{
continue;
}
bool bExceed=false;
// check div_oscErr
for(int k=i1+1; k<x; k++)
{
double s=getVal(k);
double pred=val1 +(val2 -val1) *(k -i1)/(x -i1);
if(pred-s>=div_oscErr*Point)
{
bExceed=true;
break;
}
}
// check div_priceErr
for(k=i1+1; k<x; k++)
{
s= getLowerPrice(k);
pred=p1+(p2-p1) *(k-i1)/(x-i1);
if(pred-s>=iATR(NULL,0,nCheckBars,k)*div_priceErr)
{
bExceed=true;
break;
}
}
if(!bExceed)
{
i2=x;
}
}
if(i2>=0)
{
val1 = getVal(i1);
val2 = getVal(i2);
datetime ts=Time[i1];
datetime tsSig=Time[i1-2];
datetime te=Time[i2];
double os = getVal(i1);
double oe = getVal(i2);
double ps = Close[i1];
double psSig=Open[i1-2];
double pe=Close[i2];
color colLine,colArrow;
int w;
if(!hidden)
{
colLine=colRegularLong;
colArrow=colRegularLong;
w=wRegular;
} else {
colLine=colHiddenLong;
colArrow=colRegularLong;
w=wHidden;
}
if(bDrawObj)
{
objLine(sPrefix+"line bo"+ts,g_window,ts,os,te,oe,colLine,w);
objLine(sPrefix+"line bp"+ts,0,ts,ps,te,pe,colLine,w);
objArrow(sPrefix+"arrow bp"+tsSig,0,tsSig,psSig-Point,markLong,colArrow);
}
BufferLongDiv[i1-2]=os;
}
}
}
// search divergence on top
for(i1 = limit-1; i1>= 0; i1--)
{
if(BufferTop[i1] == EMPTY_VALUE)
{
continue;
}
for(hidden=0; hidden<=1; hidden++)
{
val1=getVal(i1);
p1 = Close[i1];
i2 = -1;
for(j=1; j<=nCheckBars; j++)
{
x=i1+j;
if(BufferTop[x]==EMPTY_VALUE)
{
continue;
}
val2=getVal(x);
p2=Close[x];
if((!hidden && (val2>val1 || p2<p1)) ||
(hidden && (val2<val1 || p2>p1)))
{
continue;
}
bExceed=false;
// check div_oscErr
for(k=i1+1; k<x; k++)
{
s= getVal(k);
pred=val1+(val2-val1) *(k-i1)/(x-i1);
if(s-pred>=div_oscErr*Point)
{
bExceed=true;
break;
}
}
// check div_priceErr
for(k=i1+1; k<x; k++)
{
s= getHigherPrice(k);
pred=p1+(p2-p1) *(k-i1)/(x-i1);
if(s-pred>=iATR(NULL,0,nCheckBars,k)*div_priceErr)
{
bExceed=true;
break;
}
}
if(!bExceed)
{
i2=x;
}
}
if(i2>=0)
{
val1 = getVal(i1);
val2 = getVal(i2);
ts=Time[i1];
tsSig=Time[i1-2];
te = Time[i2];
os = getVal(i1);
oe = getVal(i2);
ps = Close[i1];
psSig=Open[i1-2];
pe=Close[i2];
if(!hidden)
{
colLine=colRegularShort;
colArrow=colRegularShort;
w=wRegular;
} else {
colLine=colHiddenShort;
colArrow=colRegularShort;
w=wHidden;
}
if(bDrawObj)
{
objLine(sPrefix+"line to"+ts,g_window,ts,os,te,oe,colLine,w);
objLine(sPrefix+"line tp"+ts,0,ts,ps,te,pe,colLine,w);
objArrow(sPrefix+"arrow tp"+tsSig,0,tsSig,psSig+Point,markShort,colArrow);
}
BufferShortDiv[i1-2]=os;
}
}
}
checkAlert();
}
//+------------------------------------------------------------------+
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---