Volume_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
// This indicator is intended to be used on the Daily Timeframe
// By changing the overlay to false just below, the divergence lines, etc. will
// be drawn on the PVT instead of the price chart
//@version=4
study("Volume Divergence+", overlay = true)
barsback = input(title = "Price Lookback", type = input.integer, defval = 15, minval = 1)
lookback = input(title = "PVT Lookback", type = input.integer, defval = 15, 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)
pvtTolerance = input(title = "PVT Epsilon (%)", type = input.float, defval = 1.0, minval = 0.0)
displayHighLows = input(title = "Display High/Low Pivots", type=input.bool, defval = false)
overlayMode = input(title = "Overlay Price Chart", type = input.bool, defval = true)
displayBullCon = input(title = "Bullish Confirmations",type = input.bool, defval = true)
displayBearCon = input(title = "Bearish Confirmations",type = input.bool, defval = true)
shortRange = 1
if shortRangeString == "Med"
shortRange := 2
else if shortRangeString == "Long"
shortRange := 3
netVolume = sign(change(close)) * volume
volumeColor = color.new(netVolume < 0 ? color.purple : color.blue, transp = not overlayMode ? 50 : 100)
plot(pvt, "PVT", color=color.new(color.orange, transp= not overlayMode ? 0 : 100), linewidth=3)
// plot(volume, "Volume", style=plot.style_histogram, linewidth=5, color=volumeColor)
var bool priceHighSet = na
var bool priceLowSet = na
var bool pvtHighSet = na
var bool pvtLowSet = na
currHigh = pivothigh(pvt, lookback, lookback)
currLow = pivotlow(pvt, lookback, lookback)
lastHighShort = valuewhen(not na(currHigh), currHigh, shortRange)
lastLowShort = valuewhen(not na(currLow), currLow, shortRange)
lowerHighShort = not na(currHigh) ? lastHighShort > (currHigh * (1 + (pvtTolerance / 100))) : false
higherHighShort = not na(currHigh) ? lastHighShort < (currHigh * (1 - (pvtTolerance / 100))) : false
lowerLowShort = not na(currLow) ? lastLowShort > (currLow * (1 + (pvtTolerance / 100))) : false
higherLowShort = not na(currLow) ? lastLowShort < (currLow * (1 - (pvtTolerance / 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
bullishConHigh = higherPriceHighRecent and higherHighRecent
bullishConLow = higherPriceLowRecent and higherLowRecent
bullishDiv = lowerPriceHighRecent and higherHighRecent
bearishConHigh = lowerPriceHighRecent and lowerHighRecent
bearishConLow = lowerPriceLowRecent and lowerLowRecent
bearishDiv = higherPriceHighRecent and lowerHighRecent
priceHighIndex = barssince(not na(priceHighSet))
priceLowIndex = barssince(not na(priceLowSet))
pvtHighIndex = barssince(not na(pvtHighSet))
pvtLowIndex = barssince(not na(pvtLowSet))
priceHighSet := not na(currPriceHigh) ? true : na
priceLowSet := not na(currPriceLow) ? true : na
pvtHighSet := not na(currHigh) ? true : na
pvtLowSet := 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 = pvtLowIndex
newIndexLow2 = bar_index - lookback
if pvtLowIndex < lookback
for i = 0 to lookback
if pvtLowIndex[i] == 0
newIndexLow := pvtLowIndex[i + 1] + (i + 1)
newIndexLow2 -= i + 1
break
newIndexHigh = pvtHighIndex
newIndexHigh2 = bar_index - lookback
if pvtHighIndex < lookback
for i = 0 to lookback
if pvtHighIndex[i] == 0
newIndexHigh := pvtHighIndex[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(pvtLowIndex, 500)
max_bars_back(pvtHighIndex, 500)
max_bars_back(priceLowIndex, 500)
max_bars_back(priceHighIndex, 500)
if shortRange <= 1
prevPivot = 0
else
newIndexLow += pvtLowIndex[newIndexLow + 1] + 1
newIndexHigh += pvtHighIndex[newIndexHigh + 1] + 1
newIndexPriceLow += priceLowIndex[newIndexPriceLow + 1] + 1
newIndexPriceHigh += priceHighIndex[newIndexPriceHigh + 1] + 1
if shortRange == 3
newIndexLow += pvtLowIndex[newIndexLow + 1] + 1
newIndexHigh += pvtHighIndex[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 highPvtLine = na
var line lowPriceLine = na
var line lowPvtLine = na
if (bullishDiv and not bullishDiv[1]) or (bearishDiv and not bearishDiv[1])
if not overlayMode // PVT
highPvtLine := line.new(0, 0, 0, 0)
line.set_x1(highPvtLine, x_high)
line.set_y1(highPvtLine, lastHighShort)
line.set_x2(highPvtLine, newIndexHigh2)
line.set_y2(highPvtLine, currHigh)
line.set_style(highPvtLine, line.style_dotted)
line.set_width(highPvtLine, 2)
line.set_color(highPvtLine, color=bullishDiv and not bearishDiv ? color.green : color.red)
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=bullishDiv and not bearishDiv ? color.green : color.red)
if (bullishConHigh and not bullishConHigh[1] and displayBullCon) or (bearishConHigh and not bearishConHigh[1] and displayBearCon)
if not overlayMode // PVT
highPvtLine := line.new(0, 0, 0, 0)
line.set_x1(highPvtLine, x_high)
line.set_y1(highPvtLine, lastHighShort)
line.set_x2(highPvtLine, newIndexHigh2)
line.set_y2(highPvtLine, currHigh)
line.set_style(highPvtLine, line.style_dotted)
line.set_width(highPvtLine, 2)
line.set_color(highPvtLine, color=bullishConHigh and not bearishConHigh ? color.blue : 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=bullishConHigh and not bearishConHigh ? color.blue : color.yellow)
if (bullishConLow and not bullishConLow[1] and displayBullCon) or (bearishConLow and not bearishConLow[1] and displayBearCon)
if not overlayMode // PVT
lowPvtLine := line.new(0, 0, 0, 0)
line.set_x1(lowPvtLine, x_low)
line.set_y1(lowPvtLine, lastLowShort)
line.set_x2(lowPvtLine, newIndexLow2)
line.set_y2(lowPvtLine, currLow)
line.set_style(lowPvtLine, line.style_dotted)
line.set_width(lowPvtLine, 2)
line.set_color(lowPvtLine, color=bullishConLow and not bearishConLow ? color.blue : color.yellow)
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=bullishConLow and not bearishConLow ? color.blue : color.yellow)
if not overlayMode and displayHighLows // PVT
if lowerHighShort
label.new(bar_index - lookback, currHigh + 10000, style=label.style_triangledown, color=color.new(color.yellow, transp=75), size=size.tiny)
if higherHighShort
label.new(bar_index - lookback, currHigh + 10000, style=label.style_triangledown, color=color.new(color.green, transp=75), size=size.tiny)
if lowerLowShort
label.new(bar_index - lookback, currLow - 10000, style=label.style_triangleup, color=color.new(color.red, transp=75), size=size.tiny)
if higherLowShort
label.new(bar_index - lookback, currLow - 10000, 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)
// Bullish Divergence - trend reversal
// Price makes lower high while volume makes higher high
if bullishDiv and not bullishDiv[1]
if not overlayMode // PVT
label.new(x_high_mid, (currHigh + lastHighShort) / 2, "Bull Div", color=labelColor1, style=label.style_label_down, textcolor=color.green, size=size.small)
else
label.new(x_price_high_mid, (currPriceHigh + lastPriceHighShort) / 2, "Vol Bullish Divergence", color=labelColor1, style=label.style_label_down, textcolor=color.green, size=size.normal)
// Bullish Confirmation - trend continuation
// Price makes higher high while volume makes higher high
// Price makes higher low while volume makes higher low
if bullishConHigh and not bullishConHigh[1] and displayBullCon
if not overlayMode // PVT
label.new(x_high_mid, (currHigh + lastHighShort) / 2, "Bull Con", color=labelColor1, style=label.style_label_down, textcolor=color.blue, size=size.small)
else
label.new(x_price_high_mid, (currPriceHigh + lastPriceHighShort) / 2, "Vol Bullish Confirm", color=labelColor1, style=label.style_label_down, textcolor=color.blue, size=size.normal)
if bullishConLow and not bullishConLow[1] and displayBullCon
if not overlayMode // PVT
label.new(x_low_mid, (currLow + lastLowShort) / 2, "Bull Con", color=labelColor1, style=label.style_label_up, textcolor=color.blue, size=size.small)
else
label.new(x_price_low_mid, (currPriceLow + lastPriceLowShort) / 2, "Vol Bullish Confirm", color=labelColor1, style=label.style_label_up, textcolor=color.blue, size=size.normal)
// Bearish Divergence - trend reversal
// Price makes higher high while volume makes lower high
if bearishDiv and not bearishDiv[1]
if not overlayMode // PVT
label.new(x_high_mid, (currHigh + lastHighShort) / 2, "Bear Div", color=labelColor1, textcolor=color.red, size=size.small)
else
label.new(x_price_high_mid, (currPriceHigh + lastPriceHighShort) / 2, "Vol Bearish Divergence", color=labelColor1, textcolor=color.red, size=size.normal)
// Bearish Confirmation - trend continuation
// Price makes lower high while volume makes lower high
// Price makes lower low while volume makes lower low
if bearishConHigh and not bearishConHigh[1] and displayBearCon
if not overlayMode // PVT
label.new(x_high_mid, (currHigh + lastHighShort) / 2, "Bear Con", color=labelColor1, style=label.style_label_down, textcolor=color.yellow, size=size.small)
else
label.new(x_price_high_mid, (currPriceHigh + lastPriceHighShort) / 2, "Vol Bearish Confirm", color=labelColor1, style=label.style_label_down, textcolor=color.yellow, size=size.normal)
if bearishConLow and not bearishConLow[1] and displayBearCon
if not overlayMode // PVT
label.new(x_low_mid, (currLow + lastLowShort) / 2, "Bear Con", color=labelColor1, style=label.style_label_up, textcolor=color.yellow, size=size.small)
else
label.new(x_price_low_mid, (currPriceLow + lastPriceLowShort) / 2, "Vol Bearish Confirm", color=labelColor1, style=label.style_label_up, textcolor=color.yellow, size=size.normal)
Show all 285 lines