MACD_Divergence+.txt
Copy
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © krosenfeld7
//@version=4
study(title="MACD Divergence+", shorttitle="MACD Divergence+", overlay = true)
barsback = input(title = "Price Lookback", type = input.integer, defval = 10, minval = 1)
lookback = input(title = "MACD Lookback", type = input.integer, defval = 10, minval = 1)
shortRangeString = input(title = "Divergence Range", type = input.string, defval = "Short", options = ["Short", "Med", "Long"])
priceTolerance = input(title = "Price Epsilon (%)",type = input.float, defval = 1.0, minval = 0.0)
macdTolerance = input(title = "MACD Epsilon (%)", type = input.float, defval = 1.0, minval = 0.0)
// Getting inputs
fast_length = input(title="MACD Fast Length", type=input.integer, defval=12)
slow_length = input(title="MACD Slow Length", type=input.integer, defval=26)
src = input(title="MACD Source", type=input.source, defval=close)
signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9)
sma_source = input(title="Simple MA (Oscillator)", type=input.bool, defval=false)
sma_signal = input(title="Simple MA (Signal Line)", type=input.bool, defval=false)
displayHighLows = input(title = "Display High/Low Pivots", type=input.bool, defval = false)
overlayMode = input(title = "Overlay Price Chart", type = input.bool, defval = true)
// Calculating
fast_ma = sma_source ? sma(src, fast_length) : ema(src, fast_length)
slow_ma = sma_source ? sma(src, slow_length) : ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal ? sma(macd, signal_length) : ema(macd, signal_length)
hist = macd - signal
shortRange = 1
if shortRangeString == "Med"
shortRange := 2
else if shortRangeString == "Long"
shortRange := 3
overlayModeOrange = color.new(color.orange, transp = not overlayMode ? 0 : 100)
overlayModeBlue = color.new(color.blue, transp = not overlayMode ? 0 : 100)
overlayModeWhite = color.new(color.white, transp = not overlayMode ? 0 : 100)
overlayModeWhite90 = color.new(color.white, transp = not overlayMode ? 90 : 100)
overlayModeWhite85 = color.new(color.white, transp = not overlayMode ? 85 : 100)
overlayModeWhite80 = color.new(color.white, transp = not overlayMode ? 80 : 100)
plot(macd, title="MACD", color=overlayModeBlue, linewidth = 2)
plot(signal, title="Signal", color=overlayModeOrange, linewidth = 2)
// plot(hist, title="Histogram", style=plot.style_columns, color=(hist>=0 ? (hist[1] < hist ? col_grow_above : col_fall_above) : (hist[1] < hist ? col_grow_below : col_fall_below) ), transp=0 )
bandUp = hline(7500, "Upper Band", color = (not overlayMode ? color.white : na), linewidth = 1, linestyle = hline.style_dashed)
bandMid = hline(0, "Middle Band", color = (not overlayMode ? color.blue : na), linewidth = 2, linestyle = hline.style_solid)
bandLow = hline(-7500, "Lower Band", color = (not overlayMode ? color.white : na), linewidth = 1, linestyle = hline.style_dashed)
fill(bandLow, bandUp, color = overlayModeWhite80)
var bool priceHighSet = na
var bool priceLowSet = na
var bool macdHighSet = na
var bool macdLowSet = na
currHigh = pivothigh(macd, lookback, lookback)
currLow = pivotlow(macd, lookback, lookback)
lastHighShort = valuewhen(not na(currHigh), currHigh, shortRange)
lastLowShort = valuewhen(not na(currLow), currLow, shortRange)
lowerHighShort = not na(currHigh) ? lastHighShort > (currHigh * (1 + (macdTolerance / 100))) : false
higherHighShort = not na(currHigh) ? lastHighShort < (currHigh * (1 - (macdTolerance / 100))) : false
lowerLowShort = not na(currLow) ? lastLowShort > (currLow * (1 + (macdTolerance / 100))) : false
higherLowShort = not na(currLow) ? lastLowShort < (currLow * (1 - (macdTolerance / 100))) : false
currPriceHigh = pivothigh(high, barsback, barsback)
currPriceLow = pivotlow(low, barsback, barsback)
lastPriceHighShort = valuewhen(not na(currPriceHigh), currPriceHigh, shortRange)
lastPriceLowShort = valuewhen(not na(currPriceLow), currPriceLow, shortRange)
lowerPriceHighShort = not na(currPriceHigh) ? lastPriceHighShort > (currPriceHigh * (1 + (priceTolerance / 100))) : false
higherPriceHighShort = not na(currPriceHigh) ? lastPriceHighShort < (currPriceHigh * (1 - (priceTolerance / 100))) : false
lowerPriceLowShort = not na(currPriceLow) ? lastPriceLowShort > (currPriceLow * (1 + (priceTolerance / 100))) : false
higherPriceLowShort = not na(currPriceLow) ? lastPriceLowShort < (currPriceLow * (1 - (priceTolerance / 100))) : false
lowerLowRecent = barssince(lowerLowShort) < lookback
lowerHighRecent = barssince(lowerHighShort) < lookback
higherLowRecent = barssince(higherLowShort) < lookback
higherHighRecent = barssince(higherHighShort) < lookback
lowerPriceLowRecent = barssince(lowerPriceLowShort) < barsback
lowerPriceHighRecent = barssince(lowerPriceHighShort) < barsback
higherPriceLowRecent = barssince(higherPriceLowShort) < barsback
higherPriceHighRecent = barssince(higherPriceHighShort) < barsback
regShortBullish = lowerPriceLowRecent and higherLowRecent
hidShortBullish = higherPriceLowRecent and lowerLowRecent
regShortBearish = higherPriceHighRecent and lowerHighRecent
hidShortBearish = lowerPriceHighRecent and higherHighRecent
priceHighIndex = barssince(not na(priceHighSet))
priceLowIndex = barssince(not na(priceLowSet))
macdHighIndex = barssince(not na(macdHighSet))
macdLowIndex = barssince(not na(macdLowSet))
priceHighSet := not na(currPriceHigh) ? true : na
priceLowSet := not na(currPriceLow) ? true : na
macdHighSet := not na(currHigh) ? true : na
macdLowSet := not na(currLow) ? true : na
currPriceHigh := na(currPriceHigh) ? currPriceHigh[1] : currPriceHigh
currPriceLow := na(currPriceLow) ? currPriceLow[1] : currPriceLow
currHigh := na(currHigh) ? currHigh[1] : currHigh
currLow := na(currLow) ? currLow[1] : currLow
newIndexLow = macdLowIndex
newIndexLow2 = bar_index - lookback
if macdLowIndex < lookback
for i = 0 to lookback
if macdLowIndex[i] == 0
newIndexLow := macdLowIndex[i + 1] + (i + 1)
newIndexLow2 -= i + 1
break
newIndexHigh = macdHighIndex
newIndexHigh2 = bar_index - lookback
if macdHighIndex < lookback
for i = 0 to lookback
if macdHighIndex[i] == 0
newIndexHigh := macdHighIndex[i + 1] + (i + 1)
newIndexHigh2 -= i + 1
break
newIndexPriceLow = priceLowIndex
newIndexPriceLow2 = bar_index - barsback
if priceLowIndex < barsback
for i = 0 to barsback
if priceLowIndex[i] == 0
newIndexPriceLow := priceLowIndex[i + 1] + (i + 1)
newIndexPriceLow2 -= i + 1
break
newIndexPriceHigh = priceHighIndex
newIndexPriceHigh2 = bar_index - barsback
if priceHighIndex < barsback
for i = 0 to barsback
if priceHighIndex[i] == 0
newIndexPriceHigh += priceHighIndex[i + 1] + 1
newIndexPriceHigh2 -= i + 1
break
max_bars_back(macdLowIndex, 500)
max_bars_back(macdHighIndex, 500)
max_bars_back(priceLowIndex, 500)
max_bars_back(priceHighIndex, 500)
if shortRange <= 1
prevPivot = 0
else
newIndexLow += macdLowIndex[newIndexLow + 1] + 1
newIndexHigh += macdHighIndex[newIndexHigh + 1] + 1
newIndexPriceLow += priceLowIndex[newIndexPriceLow + 1] + 1
newIndexPriceHigh += priceHighIndex[newIndexPriceHigh + 1] + 1
if shortRange == 3
newIndexLow += macdLowIndex[newIndexLow + 1] + 1
newIndexHigh += macdHighIndex[newIndexHigh + 1] + 1
newIndexPriceLow += priceLowIndex[newIndexPriceLow + 1] + 1
newIndexPriceHigh += priceHighIndex[newIndexPriceHigh + 1] + 1
x_low = bar_index - lookback - newIndexLow - 1
x_low_mid = bar_index - lookback - (newIndexLow / 2)
x_high = bar_index - lookback - newIndexHigh - 1
x_high_mid = bar_index - lookback - (newIndexHigh / 2)
x_price_low = bar_index - barsback - newIndexPriceLow - 1
x_price_low_mid = bar_index - barsback - (newIndexPriceLow / 2)
x_price_high = bar_index - barsback - newIndexPriceHigh - 1
x_price_high_mid = bar_index - barsback - (newIndexPriceHigh / 2)
var line highPriceLine = na
var line lowPriceLine = na
var line lowMacdLine = na
var line highMacdLine = na
if (regShortBearish and not regShortBearish[1]) or (hidShortBearish and not hidShortBearish[1])
if not overlayMode // MACD
highMacdLine := line.new(0, 0, 0, 0)
line.set_x1(highMacdLine, x_high)
line.set_y1(highMacdLine, lastHighShort)
line.set_x2(highMacdLine, newIndexHigh2)
line.set_y2(highMacdLine, currHigh)
line.set_style(highMacdLine, line.style_dotted)
line.set_width(highMacdLine, 2)
line.set_color(highMacdLine, color=regShortBearish ? color.red : color.yellow)
else
highPriceLine := line.new(0, 0, 0, 0)
line.set_x1(highPriceLine, x_price_high)
line.set_y1(highPriceLine, lastPriceHighShort)
line.set_x2(highPriceLine, newIndexPriceHigh2)
line.set_y2(highPriceLine, currPriceHigh)
line.set_style(highPriceLine, line.style_dotted)
line.set_width(highPriceLine, 3)
line.set_color(highPriceLine, color=regShortBearish ? color.red : color.yellow)
if (regShortBullish and not regShortBullish[1]) or (hidShortBullish and not hidShortBullish[1])
if not overlayMode // MACD
lowMacdLine := line.new(0, 0, 0, 0)
line.set_x1(lowMacdLine, x_low)
line.set_y1(lowMacdLine, lastLowShort)
line.set_x2(lowMacdLine, newIndexLow2)
line.set_y2(lowMacdLine, currLow)
line.set_style(lowMacdLine, line.style_dotted)
line.set_width(lowMacdLine, 2)
line.set_color(lowMacdLine, color=regShortBullish ? color.green : color.blue)
else
lowPriceLine := line.new(0, 0, 0, 0)
line.set_x1(lowPriceLine, x_price_low)
line.set_y1(lowPriceLine, lastPriceLowShort)
line.set_x2(lowPriceLine, newIndexPriceLow2)
line.set_y2(lowPriceLine, currPriceLow)
line.set_style(lowPriceLine, line.style_dotted)
line.set_width(lowPriceLine, 3)
line.set_color(lowPriceLine, color=regShortBullish ? color.green : color.blue)
if not overlayMode and displayHighLows // MACD
posCurrHigh = currHigh < 1000 ? (currHigh + 1000) * 1.25 : currHigh * 1.25
posCurrLow = currLow < 0 ? currLow * 1.25 : (currLow - 1000) * 0.75
if lowerHighShort
label.new(bar_index - lookback, posCurrHigh, style=label.style_triangledown, color=color.new(color.yellow, transp=75), size=size.tiny)
if higherHighShort
label.new(bar_index - lookback, posCurrHigh, style=label.style_triangledown, color=color.new(color.green, transp=75), size=size.tiny)
if lowerLowShort
label.new(bar_index - lookback, posCurrLow, style=label.style_triangleup, color=color.new(color.red, transp=75), size=size.tiny)
if higherLowShort
label.new(bar_index - lookback, posCurrLow, style=label.style_triangleup, color=color.new(color.blue, transp=75), size=size.tiny)
else if displayHighLows
if lowerPriceHighShort
label.new(bar_index - barsback, currPriceHigh * 1.05, style=label.style_triangledown, color=color.new(color.yellow, transp=75), size=size.tiny)
if higherPriceHighShort
label.new(bar_index - barsback, currPriceHigh * 1.05, style=label.style_triangledown, color=color.new(color.green, transp=75), size=size.tiny)
if lowerPriceLowShort
label.new(bar_index - barsback, currPriceLow * 0.95, style=label.style_triangleup, color=color.new(color.red, transp=75), size=size.tiny)
if higherPriceLowShort
label.new(bar_index - barsback, currPriceLow * 0.95, style=label.style_triangleup, color=color.new(color.blue, transp=75), size=size.tiny)
labelColor1 = color.new(color.black, transp=25)
// Short Regular Bullish Divergence - trend reversal
// Price makes lower lows while MACD makes higher lows
if regShortBullish and not regShortBullish[1]
if not overlayMode // MACD
label.new(x_low_mid, (currLow + lastLowShort) / 2, "Reg Bull Div", color=labelColor1, style=label.style_label_up, textcolor=color.green, size=size.small)
else
label.new(x_price_low_mid, (currPriceLow + lastPriceLowShort) / 2, "Reg MACD Bull Div", color=labelColor1, style=label.style_label_up, textcolor=color.green, size=size.normal)
// Short Hidden Bullish Divergence - trend continuation
// Price makes higher lows while MACD makes lower lows
if hidShortBullish and not hidShortBullish[1]
if not overlayMode // MACD
label.new(x_low_mid, (currLow + lastLowShort) / 2, "Hid Bull Div", color=labelColor1, style=label.style_label_up, textcolor=color.blue, size=size.small)
else
label.new(x_price_low_mid, (currPriceLow + lastPriceLowShort) / 2, "Hid MACD Bull Div", color=labelColor1, style=label.style_label_up, textcolor=color.blue, size=size.normal)
// Short Regular Bearish Divergence - trend reversal
// Price makes higher highs while MACD makes lower highs
if regShortBearish and not regShortBearish[1]
if not overlayMode // MACD
label.new(x_high_mid, (currHigh + lastHighShort) / 2, " Reg Bear Div", color=labelColor1, textcolor=color.red, size=size.small)
else
label.new(x_price_high_mid, (currPriceHigh + lastPriceHighShort) / 2, "Reg MACD Bear Div", color=labelColor1, textcolor=color.red, size=size.normal)
// Short Hidden Bearish Divergence - trend continuation
// Price makes lower highs while MACD makes higher highs
if hidShortBearish and not hidShortBearish[1]
if not overlayMode // MACD
label.new(x_high_mid, (currHigh + lastHighShort) / 2, "Hid Bear Div", color=labelColor1, textcolor=color.yellow, size=size.small)
else
label.new(x_price_high_mid, (currPriceHigh + lastPriceHighShort) / 2, "Hid MACD Bear Div", color=labelColor1, textcolor=color.yellow, size=size.normal)
Show all 273 lines