## VPA CANDLE COLORS
## By richard_the_red
## This script will make candles with more relative volume brighter
# and with less relative volume less visually important.
# It also colors candles based on selling vs buying volume percentage rather than open/close.
# This means you can have orange or yellow candles
# if the volume is a more even mix of buying and selling.
## Yellow dots in the candle body mean that it is significant volume for that candle,
# rvsd is greater than Standard_Deviations.
## NOTE: if you change your appearance settings for volume bars
# to color them using candle color then they will also show the VPA colors,
# this saves on performance so you don't have to use the old VPA Volume Colors script as well.
declare upper; # only applies to candles in the main chart
declare once_per_bar; # reduces computation time dramatically at the expense of not calculating current bar color, just uses default
## The length of our MA for volume, here defaults to the last 20 candles
input only_show_below = AggregationPeriod.FIFTEEN_MIN;
input SMA_Length = 20; # how many bars to calculate RVSD
input Standard_Deviations = 1.0; # default number of SD threshold, 1 is 65% 2 is 95%
input max_transparency_percent = 50; # so you can turn off volume-based opacity if you want, make it 100
def opacity = (max_transparency_percent / 100) * 255;
DefineGlobalColor("dot", color.mAGENTA);
def L = low;
def C = close;
def O = open;
def H = high;
def V = volume;
# See if this is the current candle so we can skip coloring it for performance reasons
def isLatestBar = !IsNaN(close) && IsNaN(close[-1]);
## Originally Developed by Melvin E. Dickover, the Relative Volume Standard Deviation is calculated over the SMA_Length kind of like a moving average but more complicated. RCB uses this in his enhanced volume script.
def rvsd = RelativeVolumeStDev(length = SMA_Length);
def isRvsd = rvsd >= Standard_Deviations;
def rvsdhigh = Highest(rvsd, SMA_Length);
def base_opacity = ((rvsd / rvsdhigh) * (255 - opacity)) + opacity; # completely transparent candles are useless
def cvalcur = if isRvsd then 255 else if isNaN(base_opacity) then opacity else base_opacity; # significant bars are always brighter
## Color candles on a gradient from green if buying volume is greater than selling, to red if selling volume is greater than buying.
## Note that the opacity of the candle is based on Relative Volume Standard Deviation (SMA_Length price vs volume)
def Buying = v * ((c - l) / (h - l));
def Selling = v * ((h - c) / (h - l));
def Percent = AbsValue(Buying - Selling) / v;
def Percent_Buying = Buying / v;
def pctgreen = Percent_Buying * cvalcur;
def Percent_Selling = Selling / v;
def pctred = Percent_Selling * cvalcur;
def Red =
if ( # if candle is flat then check last for color else use pct
(h == l),
if (c < c[1], 255, 120),
if ( pctred > 255, 255, if (pctred < 0, 0, pctred) )
);
def Green =
if ( # if candle is flat then check last for color else use pct
(h == l),
if (c > c[1], 255, 120),
if ( pctgreen > 255, 255, if (pctgreen < 0, 0, pctgreen) )
);
def Blue = if (isRvsd, 40, 30); # Make slight blue tint to soften the color
## Now color the candle. Modifying the green value slightly as it doesn't show up as well as red
AssignPriceColor(if isLatestBar OR only_show_below <= GetAggregationPeriod() then color.current else CreateColor(Red, Green, Blue));
plot rvsd_dot = if (isRVSD, Max(o, c) - (BodyHeight() / 2), double.NaN);
rvsd_dot.setPaintingStrategy(paintingStrategy.POINTS);
rvsd_dot.assignValueColor(GlobalColor("dot"));