# Original script by Cwparker23 with mods/additions by Tidan
# Modified by Wiinii - Whole new color scheme + RSI option to cut down the noise.
# https://usethinkscript.com/threads/anna-coulling-volume-price-analysis-for-thinkorswim.8882/post-115196
#hint: The indicator finds irregular bodies based on candle size and volume, it colors price to indicate irregular bodies below volume average (very light green bullish and very light red bearish) and indicate irregular bodies above-average volume (cyan bullish and magenta bearish). Also colors price with above-average volume (bright green/red) and below-average volume (dark green/red). \n As confirmation watch TMO(trueMomentumOsc), it should be above zero for entering short and below zero for entering long.\n\n<b>Note: </b>To view aggregations higher than daily comment out the two "AddLabel" lines by prefixing them with a "#" sign.
input showReversalSignals = yes;
input reversalFilter = yes;
input showLabels = no;
input volAvgLength = 10; #default 10
input volAvgType = averageType.exponential; #default exponential
input useOriginalVolCalc = yes;
input Use_RSI = no;
def RSIType = RSI(averageType = "EXPONENTIAL");
input RSIHi = 67;
input RSILo = 33;
def revSig = showReversalSignals;
def revFil = reversalFilter;
####
# new method to determine buying/selling volume
#def buying = Round(volume * (close - low) / (high - low), 0);
#def selling = Round(volume * (high - close) / (high - low), 0);
def buying;
def selling;
if useOriginalVolCalc
{
buying = if close > open then 1 else 0;
selling = if close < open then 1 else 0;
}
else
{
buying = Round(volume * (close - low) / (high - low), 0);
selling = Round(volume * (high - close) / (high - low), 0);
}
####
# Note: to view on time frames higher than Daily comment out these two AddLabel lines
AddLabel(showLabels, "Day_volume: " + volume (period = "DAY" ), Color.LIGHT_GRAY);
AddLabel(showLabels, "volume: " + volume, Color.white);
declare on_volume;
declare zerobase;
plot Vol = volume;
Vol.SetHiding(1 == 1);
plot VolAvg = movingAverage(volAvgType,volume,volAvgLength);
VolAvg .SetPaintingStrategy(PaintingStrategy.line);
VolAvg .SetDefaultColor(Color.Cyan);
def BODY_RANGE = max(open,close) - min(open,close);
def IR_BODY = if (BODY_RANGE < BODY_RANGE[1]) and (volume > volume[1]) then 1 else 0 ;
def IR_BODYG = if IR_BODY and buying > selling then 1 else 0;
def IR_BODYR = if IR_BODY and buying < selling then 1 else 0;
####
# new method to determine vol bar properties
def IBUpHV= if IR_BODYG and (Vol > VolAvg) and (if Use_RSI then (RSIType >= RSIHi or RSIType <= RSILo) else RSI()) then 1 else 0; #up3
def IBUpLV = if IR_BODYG then 1 else 0; #up4
def IBDownHV = if IR_BODYR and (Vol > VolAvg) and (if Use_RSI then (RSIType >= RSIHi or RSIType <= RSILo) else RSI()) then 1 else 0; #down3
def IBDownLV = if IR_BODYR then 1 else 0; #down4
def UpHV = if (buying > selling) and (Vol > VolAvg) then 1 else 0; #up
def DownHV = if (buying < selling) and (Vol > VolAvg) then 1 else 0; #down
def UpLV = if (buying > selling) then 1 else 0; #up2
def DownLV = if (buying < selling) then 1 else 0; #down2
Vol.DefineColor("UpHV", CreateColor(0,255,0)); #up
Vol.DefineColor("DownHV", CreateColor(255,0,0)); #down
Vol.DefineColor("UpLV", CreateColor(0,175,0)); #up2
Vol.DefineColor("DownLV", CreateColor(175,0,0)); #down2
Vol.DefineColor("IBUpHV", Color.cyan); #up3
Vol.DefineColor("IBUpLV", CreateColor(153,255,153)); #up4
Vol.DefineColor("IBDownHV", Color.magenta); #down3
Vol.DefineColor("IBDownLV", CreateColor(255,225,255)); #down4
#NOTE: Order on this one matters!
AssignPriceColor(
if IBUpHV then vol.Color("IBUpHV") #up3
else if IBDownHV then vol.Color("IBDownHV") #down3
else if IBUpLV then vol.Color("IBUpLV") #up4
else if IBDownLV then vol.Color("IBDownLV") #down4
else if UpHV then vol.Color("UpHV") #up
else if DownHV then vol.Color("DownHV") #down
else if UpLV then vol.Color("UpLV") #up2
else if DownLV then vol.Color("DownLV") #down2
else Color.CURRENT);
# reversal signal set up
def pastUp = if UpHV[2] or UpLV[2] or IBUpHV[2] or IBUpLV[2] then 1 else 0;
def pastDn = if DownHV[2] or IBDownLV[2] or IBDownHV[2] or DownLV[2] then 1 else 0;
def currUp = if UpHV or UpLV or IBUpHV or IBUpLV then 1 else 0;
def currDn = if DownHV or IBDownLV or IBDownHV or DownLV then 1 else 0;
def trigger = if (pastUp and currUp) or (pastDn and currDn) then 0 else 1;
# cyan reversal
addVerticalLine(revSig and revFil and IBUpHV[1] and trigger,"",if(currUp) then color.light_green else if (currDn) then color.dark_orange else color.gray,curve.short_dash);
addVerticalLine(revSig and !revFil and IBUpHV[1],"",if(currUp) then color.light_green else if (currDn) then color.dark_orange else color.gray,curve.short_dash);
# magenta reversal
addVerticalLine(revSig and revFil and IBDownHV[1] and trigger,"",if(currUp) then color.light_green else if (currDn) then color.dark_orange else color.gray,curve.short_dash);
addVerticalLine(revSig and !revFil and IBDownHV[1],"",if(currUp) then color.light_green else if (currDn) then color.dark_orange else color.gray,curve.short_dash);
# end of script