Indicators Used
Miscellaneous
0
Views
0
Downloads
0
Favorites
RSI_Divergence
#property copyright "RSI Divergence"
#property link "RSI Divergence"
//---- defines
#define DodgerBlue2 0xaa6014
#define Crimson2 0x280d93
//---- indicator settings
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_buffers 8
#property indicator_color1 SlateBlue // 0: Rsi line
#property indicator_color2 MediumOrchid // 1: Rsi smoothed line(T3)
#property indicator_color3 Aqua // 2: Long signal, cross
#property indicator_color4 Magenta // 3: Short signal, cross
#property indicator_color5 DodgerBlue // 4: Long signal, divergence
#property indicator_color6 Crimson // 5: Short signal, divergence
#property indicator_color7 Crimson2 // 6: Top peak
#property indicator_color8 DodgerBlue2 // 7: Bottom peak
#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 bool bCheckDiv = true; // show divergence
extern bool bShowAllDiv = false; // show all divergence or above/below level_hi/lo
extern bool bCheckCross = false; // show cross signal
extern bool bCheckLineMan = true; // show LineMan
extern bool bAlertCross = false; // PlaySound() on signal cross
extern bool bAlertDiv = false; // PlaySound() on divergence
extern bool bAlertLineMan = false; // PlaySound() on divergence
extern bool bDrawOnChart = true; // draw lines on chart/window
extern int div_mode = MODE_MAIN; // 0/MODE_MAIN:RSI value 1/MODE_SIGNAL:smoothed value(T3)
extern int nCheckBars = 120; // number of bars to check divergence
extern int rsi_period = 8; // RSI period
extern int t3_period = 8; // RSI period
extern double level_lo = 30; // when bShowAllDiv is true, show divergence only below this level
extern double level_hi = 70; // when bShowAllDiv is true, show divergence only above this level
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 int window = 0; // specify indicator window explicitly, 0: auto
extern int nMaxBars = 2000; // maximum number of bars to calculate, 0: no limit
//---- indicator buffers
double BufferMain[]; // 0: Rsi main line
double BufferSignal[]; // 1: Rsi smoothed line
double BufferLongCross[]; // 2: Long signal, cross
double BufferShortCross[]; // 3: Short signal, cross
double BufferLongDiv[]; // 4: Long signal, divergence
double BufferShortDiv[]; // 5: Short signal, divergence
double BufferTop[]; // 6: top peak
double BufferBottom[]; // 7: bottom peak
//---- vars
string sIndicatorName;
string sIndSelf = "00-RsiDiv_v104";
string sPrefix;
int g_window;
int markLong = 233;
int markShort = 234;
int markDot = 167;
color colRegularLong = DodgerBlue; // ( 30, 144, 255)= 0x1e90ff
color colRegularShort = Crimson; // (220, 20, 60)= 0xdc143c
color colHiddenLong = DodgerBlue2;
color colHiddenShort = Crimson2;
color colLineManUpper = Aqua;
color colLineManLower = Magenta;
int wRegular = 1;
int wHidden = 1;
double t3_curvature = 0.6180;
double t3_e1, t3_e2, t3_e3, t3_e4, t3_e5, t3_e6;
double t3_c1, t3_c2, t3_c3, t3_c4;
double t3_w1, t3_w2, t3_b2, t3_b3;
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 + "," + rsi_period + "," + t3_period + ")";
sPrefix = sIndicatorName;
IndicatorShortName(sIndicatorName);
SetIndexBuffer(0, BufferMain);
SetIndexBuffer(1, BufferSignal);
SetIndexBuffer(2, BufferLongCross);
SetIndexBuffer(3, BufferShortCross);
SetIndexBuffer(4, BufferLongDiv);
SetIndexBuffer(5, BufferShortDiv);
SetIndexBuffer(6, BufferTop);
SetIndexBuffer(7, BufferBottom);
SetIndexLabel(0, "Rsi main");
SetIndexLabel(1, "Rsi signal");
SetIndexLabel(2, "Long signal, cross");
SetIndexLabel(3, "Short signal, cross");
SetIndexLabel(4, "Long signal, divergence");
SetIndexLabel(5, "Short signal, divergence");
SetIndexLabel(6, "Top peak");
SetIndexLabel(7, "Bottom peak");
SetIndexStyle(0, DRAW_LINE);
SetIndexStyle(1, DRAW_LINE);
SetIndexStyle(2, DRAW_ARROW);
SetIndexStyle(3, DRAW_ARROW);
SetIndexStyle(4, DRAW_ARROW);
SetIndexStyle(5, DRAW_ARROW);
SetIndexStyle(6, DRAW_ARROW);
SetIndexStyle(7, DRAW_ARROW);
SetIndexArrow(2, markLong);
SetIndexArrow(3, markShort);
SetIndexArrow(4, markLong);
SetIndexArrow(5, markShort);
SetIndexArrow(6, markDot);
SetIndexArrow(7, markDot);
int n = rsi_period;
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, level_lo);
SetLevelValue(1, level_hi);
// setup for T3
t3_e1 = 0;
t3_e2 = 0;
t3_e3 = 0;
t3_e4 = 0;
t3_e5 = 0;
t3_e6 = 0;
t3_c1 = 0;
t3_c2 = 0;
t3_c3 = 0;
t3_c4 = 0;
t3_w1 = 0;
t3_w2 = 0;
t3_b2 = 0;
t3_b3 = 0;
t3_b2 = t3_curvature * t3_curvature;
t3_b3 = t3_b2 * t3_curvature;
t3_c1 = -t3_b3;
t3_c2 = (3.0 * (t3_b2 + t3_b3));
t3_c3 = -3.0 * (2.0 * t3_b2 + t3_curvature + t3_b3);
t3_c4 = (1.0 + 3 * t3_curvature + t3_b3 + 3.0 * t3_b2);
double x = MathMax(t3_period, 1);
x = 1.0 + 0.5 * (x - 1.0);
t3_w1 = 2.0 / (x + 1.0);
t3_w2 = 1.0 - t3_w1;
}
//----------------------------------------------------------------------
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 = true, bool bRay = false)
{
sName = sPrefix + sName + " w" + win;
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)
{
sName = sPrefix + sName + " w" + win;
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);
}
//----------------------------------------------------------------------
double getVal(int i)
{
if (div_mode == MODE_MAIN) {
return(BufferMain[i]);
}
return(BufferSignal[i]);
}
//----------------------------------------------------------------------
double getLowerPrice(int i)
{
double hi, lo;
if (div_mode == MODE_MAIN) {
hi = High[i];
lo = Low[i];
} else {
hi = iMA(NULL, 0, t3_period, 0, MODE_LWMA, PRICE_HIGH, i);
lo = iMA(NULL, 0, t3_period, 0, MODE_LWMA, PRICE_LOW, i);
}
return(MathMin(hi, lo));
}
//----------------------------------------------------------------------
double getHigherPrice(int i)
{
double hi, lo;
if (div_mode == MODE_MAIN) {
hi = High[i];
lo = Low[i];
} else {
hi = iMA(NULL, 0, t3_period, 0, MODE_LWMA, PRICE_HIGH, i);
lo = iMA(NULL, 0, t3_period, 0, MODE_LWMA, PRICE_LOW, i);
}
return(MathMax(hi, lo));
}
//----------------------------------------------------------------------
void intersect(double &x0, double &y0, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
{
x0 = 0;
y0 = 0;
double a1, a2, b1, b2;
if (x1 == x2){
if (x3 != x4) {
a1 = (y4 - y3) / (x4 - x3);
b1 = y3 - a1 * x3;
x0 = x2;
y0 = a1 * x0 + b1;
} else {
if (x1 == x3) {
x0 = x1;
y0 = y1;
}
}
return;
}
if (x3 == x4){
a1 = (y2 - y1) / (x2 - x1);
b1 = y2 - a1 * x2;
x0 = x3;
y0 = a1 * x0 + b1;
return;
}
a1 = 0;
b1 = 0;
a2 = 0;
b2 = 0;
a1 = (y2 - y1) / (x2 - x1);
b1 = y2 - a1 * x2;
a2 = (y4 - y3) / (x4 - x3);
b2 = y3 - a2 * x3;
if (a1 != a2) {
x0 = (b1 - b2) / (a2 - a1);
y0 = a1 * x0 + b1;
} else {
if (b1 == b2) {
x0 = x1;
y0 = y1;
}
}
}
//----------------------------------------------------------------------
bool checkAlert()
{
bool bPlayed = false;
if ((bCheckCross && bAlertCross) || (bCheckDiv && bAlertDiv) || (bCheckLineMan && bAlertLineMan)) {
bool bFireCross = (BufferLongCross[0] != EMPTY_VALUE || BufferShortCross[0] != EMPTY_VALUE);
bool bFireDiv = (BufferLongDiv[0] != EMPTY_VALUE || BufferShortDiv[0] != EMPTY_VALUE);
bool bFire = ((bAlertCross && bFireCross) || (bAlertDiv && bFireDiv));
if (bFire && tAlertLast != Time[0]) {
PlaySound("alert.wav");
bPlayed = true;
}
}
return(bPlayed);
}
//----------------------------------------------------------------------
void start()
{
bool bRedraw = false;
if (window > 0) {
g_window = window;
} else {
g_window = WindowOnDropped();
if (g_window <= 0) {
g_window = WindowFind(sIndicatorName);
}
}
int limit = Bars;
if (nMaxBars > 0) {
limit = MathMin(limit, nMaxBars);
}
if (timeFrame != Period()) {
// MTF
limit = MathMax(limit, timeFrame / Period());
for (int i = limit - 1; i >= 0; i--) {
int x = iBarShift(NULL, timeFrame, Time[i]);
BufferMain[i] = iCustom(NULL, timeFrame, sIndSelf, 0, bCheckDiv, bShowAllDiv, bCheckCross, bCheckLineMan,
false, false, false, bDrawOnChart, div_mode, nCheckBars, rsi_period, t3_period,
level_lo, level_hi, div_oscErr, div_priceErr, window, nMaxBars, 0, x);
BufferSignal[i] = iCustom(NULL, timeFrame, sIndSelf, 0, bCheckDiv, bShowAllDiv, bCheckCross, bCheckLineMan,
false, false, false, false, div_mode, nCheckBars, rsi_period, t3_period,
level_lo, level_hi, div_oscErr, div_priceErr, window, nMaxBars, 1, x);
BufferLongCross[i] = iCustom(NULL, timeFrame, sIndSelf, 0, bCheckDiv, bShowAllDiv, bCheckCross, bCheckLineMan,
false, false, false, false, div_mode, nCheckBars, rsi_period, t3_period,
level_lo, level_hi, div_oscErr, div_priceErr, window, nMaxBars, 2, x);
BufferShortCross[i] = iCustom(NULL, timeFrame, sIndSelf, 0, bCheckDiv, bShowAllDiv, bCheckCross, bCheckLineMan,
false, false, false, false, div_mode, nCheckBars, rsi_period, t3_period,
level_lo, level_hi, div_oscErr, div_priceErr, window, nMaxBars, 3, x);
BufferLongDiv[i] = iCustom(NULL, timeFrame, sIndSelf, 0, bCheckDiv, bShowAllDiv, bCheckCross, bCheckLineMan,
false, false, false, false, div_mode, nCheckBars, rsi_period, t3_period,
level_lo, level_hi, div_oscErr, div_priceErr, window, nMaxBars, 4, x);
BufferShortDiv[i] = iCustom(NULL, timeFrame, sIndSelf, 0, bCheckDiv, bShowAllDiv, bCheckCross, bCheckLineMan,
false, false, false, false, div_mode, nCheckBars, rsi_period, t3_period,
level_lo, level_hi, div_oscErr, div_priceErr, window, nMaxBars, 5, x);
BufferTop[i] = iCustom(NULL, timeFrame, sIndSelf, 0, bCheckDiv, bShowAllDiv, bCheckCross, bCheckLineMan,
false, false, false, false, div_mode, nCheckBars, rsi_period, t3_period,
level_lo, level_hi, div_oscErr, div_priceErr, window, nMaxBars, 6, x);
BufferBottom[i] = iCustom(NULL, timeFrame, sIndSelf, 0, bCheckDiv, bShowAllDiv, bCheckCross, bCheckLineMan,
false, false, false, false, div_mode, nCheckBars, rsi_period, t3_period,
level_lo, level_hi, div_oscErr, div_priceErr, window, nMaxBars, 7, x);
}
// check alert
if (checkAlert()) {
tAlertLast = Time[0];
}
return;
}
// timeFrame == Period()
double val1, val2, val3, val4;
for (i = limit - 1; i >= 0; i--) {
double rsi = iRSI(NULL, 0, rsi_period, PRICE_CLOSE, i);
t3_e1 = t3_w1 * rsi + t3_w2 * t3_e1;
t3_e2 = t3_w1 * t3_e1 + t3_w2 * t3_e2;
t3_e3 = t3_w1 * t3_e2 + t3_w2 * t3_e3;
t3_e4 = t3_w1 * t3_e3 + t3_w2 * t3_e4;
t3_e5 = t3_w1 * t3_e4 + t3_w2 * t3_e5;
t3_e6 = t3_w1 * t3_e5 + t3_w2 * t3_e6;
BufferMain[i] = rsi;
BufferSignal[i] = t3_c1 * t3_e6 + t3_c2 * t3_e5 + t3_c3 * t3_e4 + t3_c4 * t3_e3;
BufferLongCross[i] = EMPTY_VALUE;
BufferShortCross[i] = EMPTY_VALUE;
BufferTop[i] = EMPTY_VALUE;
BufferBottom[i] = EMPTY_VALUE;
// check cross
if (bCheckCross) {
double main2 = BufferMain[i + 2];
double main1 = BufferMain[i + 1];
double sig2 = BufferSignal[i + 2];
double sig1 = BufferSignal[i + 1];
datetime t2 = Time[i + 2];
datetime t1 = Time[i + 1];
double cx, cy;
intersect(cx, cy, t2, main2, t1, main1, t2, sig2, t1, sig1);
if (cx > t2 && cx <= t1) {
if (cy <= level_lo) {
BufferLongCross[i] = cy;
}
if (cy >= level_hi) {
BufferShortCross[i] = cy;
}
}
}
if (bCheckDiv || bCheckLineMan) {
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
if (bCheckDiv) {
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) {
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 (bShowAllDiv || (os <= level_lo || oe <= level_lo)) {
objLine("line bo" + ts, g_window, ts, os, te, oe, colLine, w);
if (bDrawOnChart) {
objLine("line bp" + ts, 0, ts, ps, te, pe, colLine, w);
objArrow("arrow bp" + tsSig, 0, tsSig, psSig - Point, markLong, colArrow);
}
BufferLongDiv[i1 - 2] = os;
bRedraw = true;
}
}
}
}
// 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) {
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 (bShowAllDiv || (os >= level_hi || oe >= level_hi)) {
objLine("line to" + ts, g_window, ts, os, te, oe, colLine, w);
if (bDrawOnChart) {
objLine("line tp" + ts, 0, ts, ps, te, pe, colLine, w);
objArrow("arrow tp" + tsSig, 0, tsSig, psSig + Point, markShort, colArrow);
}
BufferShortDiv[i1 - 2] = os;
bRedraw = true;
}
}
}
}
}
// LineMan
if (bCheckLineMan) {
// lower line
int b0 = -1;
int b1 = -1;
for (i = 0; i < limit; i++) {
bool bBottom = (BufferBottom[i] != EMPTY_VALUE);
if (bBottom) {
if (b0 == -1) {
b0 = i;
} else if (b1 == -1) {
b1 = i;
break;
}
}
}
int style;
if (b0 >= 0 && b1 >= 0) {
ts = Time[b1];
ps = BufferBottom[b1];
te = Time[b0];
pe = BufferBottom[b0];
if (pe > ps) {
style = STYLE_SOLID;
} else {
style = STYLE_DOT;
}
objLine("LineManUp", g_window, ts, ps, te, pe, colLineManLower, 1, style, true, true);
bRedraw = true;
}
// upper line
int u0 = -1;
int u1 = -1;
for (i = 0; i < limit; i++) {
bool bTop = (BufferTop[i] != EMPTY_VALUE);
if (bTop) {
if (u0 == -1) {
u0 = i;
} else if (u1 == -1) {
u1 = i;
break;
}
}
}
if (u0 >= 0 && u1 >= 0) {
ts = Time[u1];
ps = BufferTop[u1];
te = Time[u0];
pe = BufferTop[u0];
if (pe < ps) {
style = STYLE_SOLID;
} else {
style = STYLE_DOT;
}
objLine("LineManDown", g_window, ts, ps, te, pe, colLineManUpper, 1, style, true, true);
bRedraw = true;
}
}
// check alert
if (checkAlert()) {
tAlertLast = Time[0];
}
if (bRedraw) {
WindowRedraw();
}
}
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
---