Anna Coulling Volume Price Analysis For ThinkOrSwim

I'm not sure exactly how to enter it in but what I'm looking for is basically:

if any other color than green do not display else green

When you get a chance could you let me know exactly how I would enter that into the code? All your time is appreciated.

@Cwparker23 I'm trying to add a vertical line for every "UP" , color.green candle but it keeps giving me errors. Any idea why?

addverticalline("UP" , color.green);
Vol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Vol.SetLineWeight(3);
Vol.DefineColor("Up", Color.green);

Ok. I've messed around and got a vertical line to show up...just still not giving me the end results that I'm looking for. After trying several different changes and thinking all day it just seems easier if I can just add whatever coding is needed to place an up arrow below all green candles. I don't need arrows under the "light green" candles...just the "green" candles. Any help would be appreciated.
 
Last edited by a moderator:

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Ok. I've messed around and got a vertical line to show up...just still not giving me the end results that I'm looking for. After trying several different changes and thinking all day it just seems easier if I can just add whatever coding is needed to place an up arrow below all green candles. I don't need arrows under the "light green" candles...just the "green" candles. Any help would be appreciated.
Ruby:
plot GreenCandleArrow =  if close > open and Vol >VolAvgis then low else double.NaN ;
     GreenCandleArrow.SetPaintingStrategy(PaintingStrategy.ARROW_up);
     GreenCandleArrow.SetDefaultColor(color.blue) ;
     GreenCandleArrow.SetLineWeight(3);
No guarantee it will work on mobile.
 
Last edited:
Hi all,

I was interested in converting this code for MTF analysis for swing trading. So I went ahead and restructured the code a bit to incorporate these changes. This will add labels to the chart plot, which will help us understand what is happening in each timeframe.

To get multiple time frame labels, please include the study multiple times in the studies and strategies, and change the aggregation period according to your needs. Note: This works only on the TF higher than the current TF. For example, if you are looking at 1 HR TF, only labels above 1 HR TF are displayed, and nothing below 1HR will be displayed.

Enjoy!


Code:
# Original script by Cwparker23
# Mods/additions by Tidan
# Updates:
#    Further reduced redundancy
#    Reconfigured reversal signals to include magenta bars and set default mode to reversal
#    Restructured how bull/bear volume bars are recognized
#    Added option to use original buy/sell volume calculation or new method
#    Removed bull/bear option and signals
# v3
# Mods/additions by Shreyas Kamath
# Restructured the code to incorporate Aggregation period and plot labels on the charts for MTF analysis.

#hint: The indicator finds irregular bodies based on candle size and volume, it colors price to indicate irregular bodies below volume average (blue bullish and plum bearish) and indicate irregular bodies above-average volume (cyan bullish and magenta bearish). Also colors price with above-average volume (green bullish and red bearish) and below-average volume (light green bullish and orange bearish).

input volAvgLength = 12; #default 12
input volAvgType = AverageType.EXPONENTIAL; #default exponential
input useOriginalVolCalc = no;
input period = AggregationPeriod.DAY;

DefineGlobalColor("CAM_UP", Color.GREEN);
DefineGlobalColor("CAM_UP2", Color.LIGHT_GREEN);
DefineGlobalColor("CAM_UP3", Color.CYAN);
DefineGlobalColor("CAM_UP4", Color.BLUE);
DefineGlobalColor("CAM_DN", Color.RED);
DefineGlobalColor("CAM_DN2", Color.DARK_ORANGE );
DefineGlobalColor("CAM_DN3", Color.MAGENTA );
DefineGlobalColor("CAM_DN4", Color.PLUM );

script Volume_ {
    input agg = AggregationPeriod.DAY;
    input volAvgLength = 12; #default 12
    input volAvgType = AverageType.EXPONENTIAL; #default exponential
    input useOriginalVolCalc = no;

      # According to aggregation
    def close_agg =  close(period = agg);
    def open_agg =  open(period = agg);
    def low_agg =  low(period = agg);
    def high_agg =  high(period = agg);
    def volume_agg =  volume(period = agg);


      ####
      # new method to determine buying/selling volume
      #def buying = Round(volume_agg  * (close_agg - low_agg ) / (high_agg  - low_agg ), 0);
      #def selling = Round(volume_agg  * (high_agg  - close) / (high_agg  - low_agg ), 0);


    def buying;
    def selling;
    if useOriginalVolCalc
    {
        buying = if close_agg > open_agg then 1 else 0;
        selling = if close_agg < open_agg then 1 else 0;
    }
    else
    {
        buying = Round(volume_agg  * (close_agg - low_agg ) / (high_agg  - low_agg ), 0);
        selling = Round(volume_agg  * (high_agg  - close_agg) / (high_agg  - low_agg ), 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 lower;
    declare zerobase;
    def VolAvg = MovingAverage(volAvgType, volume_agg , volAvgLength);
    def BODY_RANGE = Max(open_agg , close_agg) - Min(open_agg , close_agg);
    def IR_BODY = if (BODY_RANGE < BODY_RANGE[1]) and (volume_agg  > volume_agg [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 up3 = if IR_BODYG and (volume_agg > VolAvg) then 1 else 0;
    def up4 = if IR_BODYG then 1 else 0;
    def down3 = if IR_BODYR and (volume_agg > VolAvg) then 1 else 0;
    def down4 = if IR_BODYR then 1 else 0;
    def up = if (buying > selling) and (volume_agg > VolAvg)  then 1 else 0;
    def down = if (buying < selling) and (volume_agg > VolAvg) then 1 else 0;
    def up2 = if (buying > selling) then 1 else 0;
    def down2 = if (buying < selling) then 1 else 0;
    ####

    plot Volume_feedback =  if up4 then 4 else
                            if up3 then 3 else
                            if up2 then 2 else
                            if up then 1 else
                            if down4 then -4 else
                            if down3 then -3 else
                            if down2 then -2 else
                            if down then -1 else
                             0;
}

def currentPeriod = GetAggregationPeriod();
def returned_Vol;

if period >= currentPeriod {
    returned_Vol  = Volume_(agg = period,
                        volAvgLength = volAvgLength,
                        volAvgType = volAvgType,
                        useOriginalVolCalc = useOriginalVolCalc);

} else {
    returned_Vol = Double.NaN;

}

AddLabel(!IsNaN(returned_Vol), if period == AggregationPeriod.MONTH then "M"
else if period == AggregationPeriod.WEEK then "W"
else if period == AggregationPeriod.FOUR_DAYS then "4D"
else if period == AggregationPeriod.THREE_DAYS then "3D"
else if period == AggregationPeriod.TWO_DAYS then "2D"
else if period == AggregationPeriod.DAY then "D"
else if period == AggregationPeriod.FOUR_HOURS then "4H"
else if period == AggregationPeriod.TWO_HOURS then "2H"
else if period == AggregationPeriod.HOUR then "60m"
else if period == AggregationPeriod.THIRTY_MIN then "30m"
else if period == AggregationPeriod.TWENTY_MIN then "20m"
else if period == AggregationPeriod.FIFTEEN_MIN then "15m"
else if period == AggregationPeriod.TEN_MIN then "10m"
else if period == AggregationPeriod.FIVE_MIN then "5m"
else if period == AggregationPeriod.FOUR_MIN then "4m"
else if period == AggregationPeriod.THREE_MIN then "3m"
else if period == AggregationPeriod.TWO_MIN then "2m"
else if period == AggregationPeriod.MIN then "1m"
else "", if returned_Vol == 3 then GlobalColor("CAM_UP3")
    else if  returned_Vol == -3 then GlobalColor("CAM_DN3")
    else if  returned_Vol == 4 then GlobalColor("CAM_UP4")
    else if  returned_Vol == -4 then GlobalColor("CAM_DN4")
    else if  returned_Vol == 1 then GlobalColor("CAM_UP")
    else if  returned_Vol == -1 then GlobalColor("CAM_DN")
    else if  returned_Vol == 2 then GlobalColor("CAM_UP2")
    else if  returned_Vol == -2 then GlobalColor("CAM_DN2")
    else Color.GRAY);
 
So this is basically Tidans code from CW parkers code that I put my little arrow code on the end. Need help figuring out how to get the arrows to plot on the upper chart and to get the arrows to plot exactly corresponding to Tidans vertical light green and dark orange dotted lines. I'm getting alerts every time one of my arrows triggers but my arrows are not 100% corresponding to Tidans vertical indicator lines.

# Original script by Cwparker23
# Mods/additions by Tidan
# Updates:
# Further reduced redundancy
# Reconfigured reversal signals to include magenta bars and set default mode to reversal
# Restructured how bull/bear volume bars are recognized
# Added option to use original buy/sell volume calculation or new method
# Removed bull/bear option and signals
# v3


#hint: The indicator finds irregular bodies based on candle size and volume, it colors price to indicate irregular bodies below volume average (blue bullish and plum bearish) and indicate irregular bodies above-average volume (cyan bullish and magenta bearish). Also colors price with above-average volume (green bullish and red bearish) and below-average volume (light green bullish and orange bearish). \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 paintBars = no;
input volAvgLength = 12; #default 12
input volAvgType = AverageType.EXPONENTIAL; #default exponential
input useOriginalVolCalc = no;

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 lower;
declare zerobase;

plot Vol = volume;
plot VolAvg = MovingAverage(volAvgType, volume, volAvgLength);
VolAvg .SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);
VolAvg .SetDefaultColor(Color.GRAY);
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 up3 = if IR_BODYG and (Vol > VolAvg) then 1 else 0;
def up4 = if IR_BODYG then 1 else 0;
def down3 = if IR_BODYR and (Vol > VolAvg) then 1 else 0;
def down4 = if IR_BODYR then 1 else 0;
def up = if (buying > selling) and (Vol > VolAvg) then 1 else 0;
def down = if (buying < selling) and (Vol > VolAvg) then 1 else 0;
def up2 = if (buying > selling) then 1 else 0;
def down2 = if (buying < selling) then 1 else 0;
####

Vol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Vol.SetLineWeight(3);
Vol.DefineColor("Up", Color.GREEN);
Vol.DefineColor("Down", Color.RED);
Vol.DefineColor("Up2", Color.LIGHT_GREEN);
Vol.DefineColor("Down2", Color.DARK_ORANGE );
Vol.DefineColor("Up3", Color.CYAN);
Vol.DefineColor("Up4", Color.BLUE);
Vol.DefineColor("Down3", Color.MAGENTA );
Vol.DefineColor("Down4", Color.PLUM );

Vol.AssignValueColor(
if up3 then Vol.Color("Up3")
else if up4 then Vol.Color("Up4")
else if down3 then Vol.Color("Down3")
else if down4 then Vol.Color("Down4")
else if up then Vol.Color("Up")
else if down then Vol.Color("Down")
else if up2 then Vol.Color("Up2")
else if down2 then Vol.Color("Down2")
else Color.WHITE);




DefineGlobalColor("CAM_UP", Color.GREEN);
DefineGlobalColor("CAM_UP2", Color.LIGHT_GREEN);
DefineGlobalColor("CAM_UP3", Color.CYAN);
DefineGlobalColor("CAM_UP4", Color.BLUE);
DefineGlobalColor("CAM_DN", Color.RED);
DefineGlobalColor("CAM_DN2", Color.DARK_ORANGE );
DefineGlobalColor("CAM_DN3", Color.MAGENTA );
DefineGlobalColor("CAM_DN4", Color.PLUM );

AssignPriceColor(
if !paintBars then Color.CURRENT
else if up3 then GlobalColor("CAM_UP3")
else if down3 then GlobalColor("CAM_DN3")
else if up4 then GlobalColor("CAM_UP4")
else if down4 then GlobalColor("CAM_DN4")
else if up then GlobalColor("CAM_UP")
else if down then GlobalColor("CAM_DN")
else if up2 then GlobalColor("CAM_UP2")
else if down2 then GlobalColor("CAM_DN2")
else Color.CURRENT);



# reversal signal set up
def pastUp = if up[2] or up2[2] or up3[2] or up4[2] then 1 else 0;
def pastDn = if down[2] or down2[2] or down3[2] or down4[2] then 1 else 0;
def currUp = if up or up2 or up3 or up4 then 1 else 0;
def currDn = if down or down2 or down3 or down4 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 up3[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 up3[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 down3[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 down3[1], "", if (currUp) then Color.LIGHT_GREEN else if (currDn) then Color.DARK_ORANGE else Color.GRAY, Curve.SHORT_DASH);

plot buyarrow = revSig and revFil and up3[1] and trigger ;
buyarrow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
buyarrow.SetDefaultColor(Color.CYAN);
plot sellarrow = revSig and revFil and down3[1] and trigger ;
sellarrow.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
sellarrow.SetDefaultColor(Color.MAGENTA);



# end of script
 
Last edited by a moderator:
So this is basically Tidans code from CW parkers code that I put my little arrow code on the end. Need help figuring out how to get the arrows to plot on the upper chart and to get the arrows to plot exactly corresponding to Tidans vertical light green and dark orange dotted lines. I'm getting alerts every time one of my arrows triggers but my arrows are not 100% corresponding to Tidans vertical indicator lines.
So you are saying that you want arrows on the upper chart where there are vertical lines on the lower chart.

There are 4 sets of defined vertical lines statements, each with 3 defined conditions.
This means that you have 12 defined arrows.
xYIspIx.png

Ruby:
# Original script by Cwparker23  ############  UPPER CHART ARROWS   ####################
# Mods/additions by Tidan
# Updates:
#    Further reduced redundancy
#    Reconfigured reversal signals to include magenta bars and set default mode to reversal
#    Restructured how bull/bear volume bars are recognized
#    Added option to use original buy/sell volume calculation or new method
#    Removed bull/bear option and signals
# v3


#hint: The indicator finds irregular bodies based on candle size and volume, it colors price to indicate irregular bodies below volume average (blue bullish and plum bearish) and indicate irregular bodies above-average volume (cyan bullish and magenta bearish). Also colors price with above-average volume (green bullish and red bearish) and below-average volume (light green bullish and orange bearish). \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 paintBars = no;
input volAvgLength = 12; #default 12
input volAvgType = averageType.exponential; #default exponential
input useOriginalVolCalc = no;

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);

def Vol = volume;
def VolAvg = movingAverage(volAvgType,volume,volAvgLength);
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 up3 = if IR_BODYG and (Vol > VolAvg) then 1 else 0;
def up4 = if IR_BODYG then 1 else 0;
def down3 = if IR_BODYR and (Vol > VolAvg) then 1 else 0;
def down4 = if IR_BODYR then 1 else 0;
def up = if (buying > selling) and (Vol > VolAvg)  then 1 else 0;
def down = if (buying < selling) and (Vol > VolAvg) then 1 else 0;
def up2 = if (buying > selling) then 1 else 0;
def down2 = if (buying < selling) then 1 else 0;
####

DefineGlobalColor("CAM_UP", Color.GREEN);
DefineGlobalColor("CAM_UP2", Color.liGHT_GREEN);
DefineGlobalColor("CAM_UP3", Color.cyan);
DefineGlobalColor("CAM_UP4", Color.blue);
DefineGlobalColor("CAM_DN", Color.RED);
DefineGlobalColor("CAM_DN2", Color.darK_ORANGE );
DefineGlobalColor("CAM_DN3", Color.mAGENTA );
DefineGlobalColor("CAM_DN4", Color.plum );

AssignPriceColor(
    if !paintBars then Color.CURRENT
    else if up3 then GlobalColor("CAM_UP3")
    else if down3 then GlobalColor("CAM_DN3")
    else if up4 then GlobalColor("CAM_UP4")
    else if down4 then GlobalColor("CAM_DN4")
    else if up then GlobalColor("CAM_UP")
    else if down then GlobalColor("CAM_DN")
    else if up2 then GlobalColor("CAM_UP2")
    else if down2 then GlobalColor("CAM_DN2")
    else Color.CURRENT);



# reversal signal set up
def pastUp = if up[2] or up2[2] or up3[2] or up4[2] then 1 else 0;
def pastDn = if down[2] or down2[2] or down3[2] or down4[2] then 1 else 0;
def currUp = if up or up2 or up3 or up4 then 1 else 0;
def currDn = if down or down2 or down3 or down4 then 1 else 0;
def trigger = if (pastUp and currUp) or (pastDn and currDn) then 0 else 1;


# cyan reversal
plot signal1 =  revFil and up3[1] and trigger ;
     signal1.assignValueColor(if(currUp) then color.light_green else if (currDn) then color.dark_orange else color.gray);
     signal1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
plot signal2 =  revSig and !revFil and up3[1] ;
     signal2.assignValueColor(if(currUp) then color.lime else if (currDn) then color.pink else color.gray);
     signal2.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_up);
# magenta reversal
plot signal3 = revSig and revFil and down3[1] and trigger;
     signal3.assignValueColor(if(currUp) then color.green else if (currDn) then color.red else color.gray);
     signal3.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
plot signal4 = revSig and !revFil and down3[1];
     signal4.assignValueColor(if(currUp) then color.dark_green else if (currDn) then color.dark_red else color.gray);
     signal4.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
# end of script
 
Last edited:
UPDATED 1/29/23

I made a modified version of this that sits in the volume area and colors price with above-average volume bright green/red, below-average volume darker green/red, Low Volume Irregular Bodies a very light red/green (and an option to turn these off), while the High Volume Irregular reversal-signaling bodies are still Cyan/Magenta. I also added an RSI option to help filter out the noise in the middle of the price action that doesn't indicate a reversal.

Code below.

Note: I made the useOriginalVolCalc set to Yes by default because I think others (including myself) would be putt-off by some candles being painted bullish/bearish incorrectly. The option is still there to use the new Calc if preferred.

But I also made a completely different study (not based on this code at all) that also looks for volume anomalies. Interestingly, it finds anomalies that this one does not, and this one finds ones that mine does not. You can check it out here. I've also made a combined one of both that I might share later.

6qYDbuJ.png

veIAGNY.png



Code:
# 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
 
Last edited:
UPDATED 1/21/23

I made a modified version of this that sits in the volume area and colors price with above-average volume bright green/red, below-average volume darker green/red, Low Volume Irregular Bodies a very light red/green (and an option to run theses off), while the High Volume Irregular reversal-signaling bodies are still Cyan/Magenta. I also added an RSI option to help filter out the noise in the middle of the price action that doesn't indicate a reversal.

Hi, Do you know why mine doesnt show the volume bars like your screenshot ? Thanks


UPDATE:
It didnt work initially but I got it working by tinkering around

Beside the Equities -> Show volume subgraph, it also need to

1) General -> Layout -> Show price subgraph (need to check this option)
1) Appearance -> Volume bars -> Color as symbol ticks (need to check this option)
 
Last edited by a moderator:
UPDATED 1/21/23

I made a modified version of this that sits in the volume area and colors price with above-average volume bright green/red, below-average volume darker green/red, Low Volume Irregular Bodies a very light red/green (and an option to run theses off), while the High Volume Irregular reversal-signaling bodies are still Cyan/Magenta. I also added an RSI option to help filter out the noise in the middle of the price action that doesn't indicate a reversal.

Code below.

Note: I made the useOriginalVolCalc set to Yes by default because I think others (including myself) would be putt-off by some candles being painted bullish/bearish incorrectly. The option is still there to use the new Calc if preferred.

But I also made a completely different study (not based on this code at all) that also looks for volume anomalies. Interestingly, it finds anomalies that this one does not, and this one finds ones that mine does not. You can check it out here. I've also made a combined one of both that I might share later.

6qYDbuJ.png

veIAGNY.png



Code:
# 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 = yes;
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 and (if Use_RSI then (RSIType >= RSIHi or RSIType <= RSILo) else RSI())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 and (if Use_RSI then (RSIType >= RSIHi or RSIType <= RSILo) else RSI()) 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(102,255,102)); #up4
Vol.DefineColor("IBDownHV", Color.mAGENTA); #down3
Vol.DefineColor("IBDownLV", CreateColor(255,153,153)); #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
UPDATED 1/21/23

I made a modified version of this that sits in the volume area and colors price with above-average volume bright green/red, below-average volume darker green/red, Low Volume Irregular Bodies a very light red/green (and an option to run theses off), while the High Volume Irregular reversal-signaling bodies are still Cyan/Magenta. I also added an RSI option to help filter out the noise in the middle of the price action that doesn't indicate a reversal.

Code below.

Note: I made the useOriginalVolCalc set to Yes by default because I think others (including myself) would be putt-off by some candles being painted bullish/bearish incorrectly. The option is still there to use the new Calc if preferred.

But I also made a completely different study (not based on this code at all) that also looks for volume anomalies. Interestingly, it finds anomalies that this one does not, and this one finds ones that mine does not. You can check it out here. I've also made a combined one of both that I might share later.

6qYDbuJ.png

veIAGNY.png



Code:
# 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 = yes;
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 and (if Use_RSI then (RSIType >= RSIHi or RSIType <= RSILo) else RSI())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 and (if Use_RSI then (RSIType >= RSIHi or RSIType <= RSILo) else RSI()) 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(102,255,102)); #up4
Vol.DefineColor("IBDownHV", Color.mAGENTA); #down3
Vol.DefineColor("IBDownLV", CreateColor(255,153,153)); #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

How to determine long or short based on the candles?
 
Last edited by a moderator:

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
346 Online
Create Post

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top