Cumulative Volume Delta For ThinkOrSwim

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

I'm not sure what you mean by "(as candles)" above, but I created this a while back. It uses the time relative volume for the last X days (default is 21) to create an average volume for that specific candle during the day. Then is plots the diff from the volume for the current candle. The result is an oscillator showing you when volume is abnormal for the selected timeframe.

Pros: It can show you when current volume for the selected timeframe is significantly greater than it has been recently during that same period.
Con 1: Because it uses fold to loop back on the chart looking for the same candle as the current one for prior days, it can be a bit slow to load up.
Con 2: Folding to look back for the same candle on previous days may not be 100% accurate but seems good enough.

You'll notice the term "Zombie" referring to a period of time. It is the time between 10:30am and 2pm. That is the slower time during the day when a dead stock can inexplicably come back to life, hence the name.

Ruby:
#Delta V
#Author: TradeArcher2020
#Version: 0.1
#Date Created: 09/18/2021

#hint: Calculates the difference (aka Delta) between the current volume and the average historic volume.
#hint PeriodLookBack: The number of days to use to calculate the average for the current candle. (Recommended using 21 or less for performance reasons)
#hint NormalizeOutlierVolumeDiffs: If yes, this will attempt to prevent wildly large volume spikes (that can often be data glitches in the chart) from skewing the oscillator layout.
#hint VolumeDiffMethod: Defaults to "daily".  This determines how the oscilator values are calculated.  Daily uses the total daily volume.  Current uses just the current candle.  Period uses the total volume for the current period (Premarket, Open, Zombie, Reversal and After Hours). "dc2" is the Daily + the current divided by 2. And "dpc3" is the daily + the period + the current divided by 3.
#hint ShowBubbles: Turned off by default.  When turned on, bubbles will show up at the end of every key time period (End of Day, Premarkt, Open, Zombie, Reversal, After Hours) showing the total percent difference in volume for the period compared to the average.  Useful for research purposes looking back at historical volume trends.

input PeriodLookBack = 21; #hint PeriodLookBack: The number of days back used to calculate the average.
#input PercentAboveAverageForSignal = 300;
input ShowOscillator = yes;
input ShowZeroLine = yes;
input PercentUp1 = 50;
input PercentUp2 = 100;
input PercentUp3 = 200;
input PercentUp4 = 1000;
input PercentDown1 = 50;
input PercentDown2 = 100;
input ShowBubbles = no;
input ShowSignals = yes;
input NormalizeOutlierVolumeDiffs = yes;
input VolumeDiffMethod = {"dpc3", "dc2", default "daily", "period", "current"};
input ShortEMALength = 3;
input LongEMALength = 60;

declare hide_on_daily;
declare lower;
declare real_size;

def dayStart = 0000;
def dayEnd = 2359;
def openStart = 0930;
def zombieStart = 1030;
def reversalStart = 1400;
def ahStart = 1600;

def dayRollover = GetYYYYMMDD();
def isNewDay = CompoundValue(1, dayRollover != dayRollover[1], yes);
def isPremarket = SecondsFromTime(dayStart) >= 0 and SecondsTillTime(openStart) > 0;
def isOpen = SecondsFromTime(openStart) >= 0 and SecondsTillTime(zombieStart) > 0;
def isZombie = SecondsFromTime(zombieStart) >= 0 and SecondsTillTime(reversalStart) > 0;
def isReversal = SecondsFromTime(reversalStart) >= 0 and SecondsTillTime(ahStart) > 0;
def isAfterHours = SecondsFromTime(ahStart) >= 0 and SecondsTillTime(dayEnd) >= 0;

def day = GetDay();
def lastDay = GetLastDay();
def isToday = If(day == lastDay, 1, 0);
def hasPremarketStartedToday = if(isToday, yes, no);
def hasOpenStartedToday = CompoundValue(1, isToday and SecondsFromTime(openStart) >= 0, yes);
def hasZombieStartedToday = CompoundValue(1, isToday and SecondsFromTime(zombieStart) >= 0, yes);
def hasReversalStartedToday = CompoundValue(1, isToday and SecondsFromTime(reversalStart) >= 0, yes);
def hasAfterHoursStartedToday = CompoundValue(1, isToday and SecondsFromTime(ahStart) >= 0, yes);

def runningVolumeForDay = if(isNewDay, volume, runningVolumeForDay[1] + volume);
def runningVolumeForPremarket = if(isNewDay, volume, if(isPremarket, runningVolumeForPremarket[1] + volume, runningVolumeForPremarket[1]));
def runningVolumeForOpen = if(isOpen and !isOpen[1], volume, if(isOpen, runningVolumeForOpen[1] + volume, RunningVolumeForOpen[1]));
def runningVolumeForZombie = if(isZombie and !isZombie[1], volume, if(isZombie, runningVolumeForZombie[1] + volume, runningVolumeForZombie[1]));
def runningVolumeForReversal = if(isReversal and !isReversal[1], volume, if(isReversal, runningVolumeForReversal[1] + volume, runningVolumeForReversal[1]));
def runningVolumeForAfterHours = if(isAfterHours and !isAfterHours[1], volume, if(isAfterHours, runningVolumeForAfterHours[1] + volume, runningVolumeForAfterHours[1]));


def currentAggregationPeriod = GetAggregationPeriod();

def barsPerDay = 86400000 / currentAggregationPeriod;

def foldLength = PeriodLookBack * barsPerDay;

def barTime = Floor((SecondsFromTime(dayStart) * 1000) / currentAggregationPeriod);

def volumeAtTimeSum =
(fold ix = 0 to PeriodLookBack with vSum do vSum +
    (fold ixx = 0 to barsPerDay with subVSum do
         subVSum + (if(GetValue(barTime, ((ix+1)*(ixx+1))-1) == barTime, GetValue(volume, ((ix+1)*(ixx+1)-1)), 0))));


#def avgVolumeAtTime = volumeAtTimeSum / PeriodLookBack;
def avgVolumeAtTime = if(IsNaN(volumeAtTimeSum / PeriodLookBack), 0.001, volumeAtTimeSum / PeriodLookBack);

def runningAvgVolumeForDay = if(isNewDay, avgVolumeAtTime, runningVolumeForDay[1] + avgVolumeAtTime);
def runningAvgVolumeForPremarket = if(isNewDay, avgVolumeAtTime, if(isPremarket, runningAvgVolumeForPremarket[1] + avgVolumeAtTime, runningAvgVolumeForPremarket[1]));
def runningAvgVolumeForOpen = if(isOpen and !isOpen[1], avgVolumeAtTime, if(isOpen, runningAvgVolumeForOpen[1] + avgVolumeAtTime, runningAvgVolumeForOpen[1]));
def runningAvgVolumeForZombie = if(isZombie and !isZombie[1], avgVolumeAtTime, if(isZombie, runningAvgVolumeForZombie[1] + avgVolumeAtTime, runningAvgVolumeForZombie[1]));
def runningAvgVolumeForReversal = if(isReversal and !isReversal[1], avgVolumeAtTime, if(isReversal, runningAvgVolumeForReversal[1] + avgVolumeAtTime, runningAvgVolumeForReversal[1]));
def runningAvgVolumeForAfterHours = if(isAfterHours and !isAfterHours[1], avgVolumeAtTime, if(isAfterHours, runningAvgVolumeForAfterHours[1] + avgVolumeAtTime, runningAvgVolumeForAfterHours[1]));


def dpc3 = (runningVolumeForDay + (if isPremarket then runningVolumeForPremarket else if isOpen then runningVolumeForOpen else if isZombie then runningVolumeForZombie else if isReversal then runningVolumeForReversal else runningVolumeForAfterHours) + volume) / 3;
def dc2 = (runningVolumeForDay + volume) / 2;
def dailyVolume = runningVolumeForDay;
def p = (if isPremarket then runningVolumeForPremarket else if isOpen then runningVolumeForOpen else if isZombie then runningVolumeForZombie else if isReversal then runningVolumeForReversal else runningVolumeForAfterHours);
def currentVolume = volume;

def avgDpc3 = (runningAvgVolumeForDay + (if isPremarket then runningAvgVolumeForPremarket else if isOpen then runningAvgVolumeForOpen else if isZombie then runningAvgVolumeForZombie else if isReversal then runningAvgVolumeForReversal else runningAvgVolumeForAfterHours) + avgVolumeAtTime) / 3;
def avgDc2 = (runningAvgVolumeForDay + avgVolumeAtTime) / 2;
def avgDailyVolume = runningAvgVolumeForDay;
def avgPeriodVolume = (if isPremarket then runningAvgVolumeForPremarket else if isOpen then runningAvgVolumeForOpen else if isZombie then runningAvgVolumeForZombie else if isReversal then runningAvgVolumeForReversal else runningAvgVolumeForAfterHours);
def avgCurrentVolume = avgVolumeAtTime;
def volVal;
def avgVolVal;

switch (VolumeDiffMethod) {
    case "current":
        volVal = currentVolume;
        avgVolVal = avgCurrentVolume;
    case "daily":
        volVal = dailyVolume;
        avgVolVal = avgDailyVolume;
    case "dc2":
        volVal = dc2;
        avgVolVal = avgDc2;
    case "dpc3":
        volVal = dpc3;
        avgVolVal = avgDc2;
    case "period":
        volVal = p;
        avgVolVal = avgPeriodVolume;
}

plot ZeroLine = 0;
ZeroLine.SetDefaultColor(Color.WHITE);
ZeroLine.SetHiding(!ShowZeroLine);

def tmpDiffAvg = if(IsNaN(volVal) or IsNaN(avgVolVal) or volVal == 0 or avgVolVal == 0, 0.0, ((volVal - avgVolVal) / avgVolVal) * 100);
def diffAvg = Round(tmpDiffAvg, 0);

def oscillatorValue = if(NormalizeOutlierVolumeDiffs and AbsValue(tmpDiffAvg)/10 > AbsValue(tmpDiffAvg[1]), if(IsNaN(tmpDiffAvg[1]), 0.001, tmpDiffAvg[1]*2), tmpDiffAvg);

DefineGlobalColor("DiffEmaLongUp", Color.GREEN);
DefineGlobalColor("DiffEmaLongDown", Color.PINK);
DefineGlobalColor("DiffEmaLongNeutral", Color.WHITE);

DefineGlobalColor("DiffEmaShortUp", Color.LIME);
DefineGlobalColor("DiffEmaShortDown", Color.RED);
DefineGlobalColor("DiffEmaShortNeutral", Color.WHITE);

DefineGlobalColor("DiffEmaPivotTop", Color.LIGHT_RED);
DefineGlobalColor("DiffEmaPivotBottom", Color.LIME);

plot DiffEmaLong = MovAvgExponential(oscillatorValue, LongEMALength);
plot DiffEmaLongDirection = if DiffEmaLong[1] < DiffEmaLong then 1 else if DiffEmaLong[1] > DiffEmaLong then -1 else 0;
DiffEmaLongDirection.Hide();
DiffEmaLong.AssignValueColor(if DiffEmaLongDirection > 0 then GlobalColor("DiffEmaLongUp") else if DiffEmaLongDirection < 0 then GlobalColor("DiffEmaLongDown") else GlobalColor("DiffEmaLongNeutral"));

plot DiffEmaLongPivot = if(DiffEmaLongDirection != DiffEmaLongDirection[-1], DiffEmaLong, Double.NaN);
DiffEmaLongPivot.SetPaintingStrategy(paintingStrategy = PaintingStrategy.TRIANGLES);
DiffEmaLongPivot.SetLineWeight(3);
DiffEmaLongPivot.AssignValueColor(if DiffEmaLongDirection == 1 then GlobalColor("DiffEmaPivotTop") else if DiffEmaLongDirection == -1 then GlobalColor("DiffEmaPivotBottom") else Color.CURRENT);

plot DiffEmaShort = MovAvgExponential(oscillatorValue, ShortEMALength);
plot DiffEmaShortDirection = if DiffEmaShort[1] < DiffEmaShort then 1 else if DiffEmaShort[1] > DiffEmaShort then -1 else 0;
DiffEmaShortDirection.Hide();
DiffEmaShort.AssignValueColor(if DiffEmaShortDirection > 0 then GlobalColor("DiffEmaShortUp") else if DiffEmaShortDirection < 0 then GlobalColor("DiffEmaShortDown") else GlobalColor("DiffEmaShortNeutral"));

plot DiffEmaShortPivot = if(DiffEmaShortDirection != DiffEmaShortDirection[-1], DiffEmaShort, Double.NaN);
DiffEmaShortPivot.SetPaintingStrategy(paintingStrategy = PaintingStrategy.TRIANGLES);
DiffEmaShortPivot.SetLineWeight(3);
DiffEmaShortPivot.AssignValueColor(if DiffEmaShortDirection == 1 then GlobalColor("DiffEmaPivotTop") else if DiffEmaShortDirection == -1 then GlobalColor("DiffEmaPivotBottom") else Color.CURRENT);

#AddChartBubble(NormalizeOutlierVolumeDiffs and AbsValue(diffAvg)/10 > AbsValue(diffAvg[1]), 0, diffAvg + "\n" + diffAvg[1]);
plot VolumeDiffOscillator = oscillatorValue;
VolumeDiffOscillator.DefineColor("Up", CreateColor(0, 255, 255));
VolumeDiffOscillator.DefineColor("UpDecreasing", CreateColor(0, 0, 255));
VolumeDiffOscillator.DefineColor("Down", CreateColor(255, 0, 0));
VolumeDiffOscillator.DefineColor("DownDecreasing",  CreateColor(255, 255, 0));
VolumeDiffOscillator.AssignValueColor(
if VolumeDiffOscillator[1] < VolumeDiffOscillator then if VolumeDiffOscillator[0] >= 0
then VolumeDiffOscillator.Color("Up")
else VolumeDiffOscillator.Color("DownDecreasing")
else if VolumeDiffOscillator >= 0
then VolumeDiffOscillator.Color("UpDecreasing")
else VolumeDiffOscillator.Color("Down") );
VolumeDiffOscillator.SetPaintingStrategy(if !ShowOscillator then PaintingStrategy.POINTS else PaintingStrategy.HISTOGRAM);
VolumeDiffOscillator.SetLineWeight(5);
#VolumeForcastOscillator.SetHiding(!ShowOscillator);

def percentOfAvg = Round(((volume - avgVolumeAtTime)/ avgVolumeAtTime) * 100, 0);

def dayPctDiff = Round(((runningVolumeForDay - runningAvgVolumeForDay) / runningAvgVolumeForDay) * 100, 0);
def premarketPctDiff = Round(((runningVolumeForPremarket - runningAvgVolumeForPremarket) / runningAvgVolumeForPremarket) * 100, 0);
def openPctDiff = Round(((runningVolumeForOpen - runningAvgVolumeForOpen) / runningAvgVolumeForOpen) * 100, 0);
def zombiePctDiff = Round(((runningVolumeForZombie - runningAvgVolumeForZombie) / runningAvgVolumeForZombie) * 100, 0);
def reversalPctDiff = Round(((runningVolumeForReversal - runningAvgVolumeForReversal) / runningAvgVolumeForReversal) * 100, 0);
def afterHoursPctDiff = Round(((runningVolumeForAfterHours - runningAvgVolumeForAfterHours) / runningAvgVolumeForAfterHours) * 100, 0);

def dpd = Round(if(isNewDay, dayPctDiff, dpd[1]), 0);
plot DayPercentDiffTotal = dpd;
DayPercentDiffTotal.Hide();

def pmpd = Round(if(isOpen and !isOpen[1], premarketPctDiff[1], pmpd[1]), 0);
plot PremarketPercentDiffTotal = pmpd;
PremarketPercentDiffTotal.Hide();

def opd = Round(if(isZombie  and !isZombie[1], openPctDiff[1], opd[1]), 0);
plot OpenPercentDiffTotal = opd;
OpenPercentDiffTotal.Hide();

def zpd = Round(if(isReversal  and !isReversal[1], zombiePctDiff[1], zpd[1]), 0);
plot ZombiePercentDiffTotal = zpd;
ZombiePercentDiffTotal.Hide();

def rpd = Round(if(isAfterHours  and !isAfterHours[1], reversalPctDiff[1], rpd[1]), 0);
plot ReversalPercentDiffTotal = rpd;
ReversalPercentDiffTotal.Hide();

def ahpd = Round(if(isNewDay, zombiePctDiff[1], ahpd[1]), 0);
plot AfterHoursPercentDiffTotal = ahpd;
AfterHoursPercentDiffTotal.Hide();

AddChartBubble(ShowBubbles and isNewDay, 0, "Today:\n" + DayPercentDiffTotal + "%", color = if DayPercentDiffTotal > 1000 then Color.LIME else Color.WHITE);
AddChartBubble(ShowBubbles and PremarketPercentDiffTotal != PremarketPercentDiffTotal[1], 0, "PM:\n" + PremarketPercentDiffTotal + "%", color = if PremarketPercentDiffTotal > 1000 then Color.LIME else Color.WHITE);
AddChartBubble(ShowBubbles and OpenPercentDiffTotal != OpenPercentDiffTotal[1], 0, "Open:\n" + OpenPercentDiffTotal + "%", color = if OpenPercentDiffTotal > 1000 then Color.LIME else Color.WHITE);
AddChartBubble(ShowBubbles and ZombiePercentDiffTotal != ZombiePercentDiffTotal[1], 0, "Zombie:\n" + ZombiePercentDiffTotal + "%", color = if ZombiePercentDiffTotal > 1000 then Color.LIME else Color.WHITE);
AddChartBubble(ShowBubbles and ReversalPercentDiffTotal != ReversalPercentDiffTotal[1], 0, "Reversal:\n" + ReversalPercentDiffTotal + "%", color = if ReversalPercentDiffTotal > 1000 then Color.LIME else Color.WHITE);
AddChartBubble(ShowBubbles and AfterHoursPercentDiffTotal != AfterHoursPercentDiffTotal[1], 0, "AH:\n" + AfterHoursPercentDiffTotal + "%", color = if AfterHoursPercentDiffTotal > 1000 then Color.LIME else Color.WHITE);

DefineGlobalColor("PercentUp1", Color.DARK_GREEN);
DefineGlobalColor("PercentUp2", Color.LIGHT_GREEN);
DefineGlobalColor("PercentUp3", Color.GREEN);
DefineGlobalColor("PercentUp4", Color.LIME);
DefineGlobalColor("PercentDown1", Color.LIGHT_ORANGE);
DefineGlobalColor("PercentDown2", Color.RED);

AddLabel(yes, "Vol/Avg % Differences", Color.WHITE);
AddLabel(yes, "Daily Avg: " + runningAvgVolumeForDay, Color.WHITE);
AddLabel(yes, "Today: " + runningVolumeForDay, if runningVolumeForDay > runningAvgVolumeForDay then Color.GREEN else Color.WHITE);

AddLabel(dayPctDiff >= PercentUp4, "Day: " + dayPctDiff + "%", GlobalColor("PercentUp4"));
AddLabel(dayPctDiff >= PercentUp3 and dayPctDiff < PercentUp4, "Day: " + dayPctDiff + "%", GlobalColor("PercentUp3"));
AddLabel(dayPctDiff >= PercentUp2 and dayPctDiff < PercentUp3, "Day: " + dayPctDiff + "%", GlobalColor("PercentUp2"));
AddLabel(dayPctDiff >= PercentUp1 and dayPctDiff < PercentUp2, "Day: " + dayPctDiff + "%", GlobalColor("PercentUp1"));
AddLabel(dayPctDiff <= -PercentDown1 and dayPctDiff > -PercentDown2, "Day: " + dayPctDiff + "%", GlobalColor("PercentDown1"));
AddLabel(dayPctDiff <= -PercentDown2, "Day: " + dayPctDiff + "%", GlobalColor("PercentDown2"));
AddLabel(dayPctDiff < PercentUp1 and dayPctDiff > -PercentDown1, "Day: " + dayPctDiff + "%", Color.WHITE);

AddLabel(hasPremarketStartedToday and premarketPctDiff >= PercentUp4, "Premarket: " + premarketPctDiff + "%", GlobalColor("PercentUp4"));
AddLabel(hasPremarketStartedToday and premarketPctDiff >= PercentUp3 and premarketPctDiff < PercentUp4, "Premarket: " + premarketPctDiff + "%", GlobalColor("PercentUp3"));
AddLabel(hasPremarketStartedToday and premarketPctDiff >= PercentUp2 and premarketPctDiff < PercentUp3, "Premarket: " + premarketPctDiff + "%", GlobalColor("PercentUp2"));
AddLabel(hasPremarketStartedToday and premarketPctDiff >= PercentUp1 and premarketPctDiff < PercentUp2, "Premarket: " + premarketPctDiff + "%", GlobalColor("PercentUp1"));
AddLabel(hasPremarketStartedToday and premarketPctDiff <= -PercentDown2, "Premarket: " + premarketPctDiff + "%", GlobalColor("PercentDown2"));
AddLabel(hasPremarketStartedToday and premarketPctDiff <= -PercentDown1 and premarketPctDiff > -PercentDown2, "Premarket: " + premarketPctDiff + "%", GlobalColor("PercentDown1"));
AddLabel(hasPremarketStartedToday and premarketPctDiff < PercentUp1 and premarketPctDiff > -PercentDown1, "Premarket: " + premarketPctDiff + "%", Color.WHITE);

AddLabel(hasOpenStartedToday and openPctDiff >= PercentUp4, "Open: " + openPctDiff + "%", GlobalColor("PercentUp4"));
AddLabel(hasOpenStartedToday and openPctDiff >= PercentUp3 and openPctDiff < PercentUp4, "Open: " + openPctDiff + "%", GlobalColor("PercentUp3"));
AddLabel(hasOpenStartedToday and openPctDiff >= PercentUp2 and openPctDiff < PercentUp3, "Open: " + openPctDiff + "%", GlobalColor("PercentUp2"));
AddLabel(hasOpenStartedToday and openPctDiff >= PercentUp1 and openPctDiff < PercentUp2, "Open: " + openPctDiff + "%", GlobalColor("PercentUp1"));
AddLabel(hasOpenStartedToday and openPctDiff <= -PercentDown2, "Open: " + openPctDiff + "%", GlobalColor("PercentDown2"));
AddLabel(hasOpenStartedToday and openPctDiff <= -PercentDown1 and openPctDiff > -PercentDown2, "Open: " + openPctDiff + "%", GlobalColor("PercentDown1"));
AddLabel(hasOpenStartedToday and openPctDiff < PercentUp1 and openPctDiff > -PercentDown1, "Open: " + openPctDiff + "%", Color.WHITE);

AddLabel(hasZombieStartedToday and zombiePctDiff >= PercentUp4, "Zombie: " + zombiePctDiff + "%", GlobalColor("PercentUp4"));
AddLabel(hasZombieStartedToday and zombiePctDiff >= PercentUp3 and zombiePctDiff < PercentUp4, "Zombie: " + zombiePctDiff + "%", GlobalColor("PercentUp3"));
AddLabel(hasZombieStartedToday and zombiePctDiff >= PercentUp2 and zombiePctDiff < PercentUp3, "Zombie: " + zombiePctDiff + "%", GlobalColor("PercentUp2"));
AddLabel(hasZombieStartedToday and zombiePctDiff >= PercentUp1 and zombiePctDiff < PercentUp2, "Zombie: " + zombiePctDiff + "%", GlobalColor("PercentUp1"));
AddLabel(hasZombieStartedToday and zombiePctDiff <= -PercentDown2, "Zombie: " + zombiePctDiff + "%", GlobalColor("PercentDown2"));
AddLabel(hasZombieStartedToday and zombiePctDiff <= -PercentDown1 and zombiePctDiff > -PercentDown2, "Zombie: " + zombiePctDiff + "%", GlobalColor("PercentDown1"));
AddLabel(hasZombieStartedToday and zombiePctDiff < PercentUp1 and zombiePctDiff > -PercentDown1, "Zombie: " + zombiePctDiff + "%", Color.WHITE);

AddLabel(hasReversalStartedToday and reversalPctDiff >= PercentUp4, "Reversal: " + reversalPctDiff + "%", GlobalColor("PercentUp4"));
AddLabel(hasReversalStartedToday and reversalPctDiff >= PercentUp3 and reversalPctDiff < PercentUp4, "Reversal: " + reversalPctDiff + "%", GlobalColor("PercentUp3"));
AddLabel(hasReversalStartedToday and reversalPctDiff >= PercentUp2 and reversalPctDiff < PercentUp3, "Reversal: " + reversalPctDiff + "%", GlobalColor("PercentUp2"));
AddLabel(hasReversalStartedToday and reversalPctDiff >= PercentUp1 and reversalPctDiff < PercentUp2, "Reversal: " + reversalPctDiff + "%", GlobalColor("PercentUp1"));
AddLabel(hasReversalStartedToday and reversalPctDiff <= -PercentDown2, "Reversal: " + reversalPctDiff + "%", GlobalColor("PercentDown2"));
AddLabel(hasReversalStartedToday and reversalPctDiff <= -PercentDown1 and reversalPctDiff > -PercentDown2, "Reversal: " + reversalPctDiff + "%", GlobalColor("PercentDown1"));
AddLabel(hasReversalStartedToday and reversalPctDiff < PercentUp1 and reversalPctDiff > -PercentDown1, "Reversal: " + reversalPctDiff + "%", Color.WHITE);

AddLabel(hasAfterHoursStartedToday and afterHoursPctDiff >= PercentUp4, "After Hours: " + afterHoursPctDiff + "%", GlobalColor("PercentUp4"));
AddLabel(hasAfterHoursStartedToday and afterHoursPctDiff >= PercentUp3 and afterHoursPctDiff < PercentUp4, "After Hours: " + afterHoursPctDiff + "%", GlobalColor("PercentUp3"));
AddLabel(hasAfterHoursStartedToday and afterHoursPctDiff >= PercentUp2 and afterHoursPctDiff < PercentUp3, "After Hours: " + afterHoursPctDiff + "%", GlobalColor("PercentUp2"));
AddLabel(hasAfterHoursStartedToday and afterHoursPctDiff >= PercentUp1 and afterHoursPctDiff < PercentUp2, "After Hours: " + afterHoursPctDiff + "%", GlobalColor("PercentUp1"));
AddLabel(hasAfterHoursStartedToday and afterHoursPctDiff <= -PercentDown2, "After Hours: " + afterHoursPctDiff + "%", GlobalColor("PercentDown2"));
AddLabel(hasAfterHoursStartedToday and afterHoursPctDiff <= -PercentDown1 and afterHoursPctDiff > -PercentDown2, "After Hours: " + afterHoursPctDiff + "%", GlobalColor("PercentDown1"));
AddLabel(hasAfterHoursStartedToday and afterHoursPctDiff < PercentUp1 and afterHoursPctDiff > -PercentDown1, "After Hours: " + afterHoursPctDiff + "%", Color.WHITE);


AddVerticalLine(isPremarket and !isPremarket[1], text = "Begin Premarket", color = Color.WHITE);

AddVerticalLine(isOpen and !isOpen[1], text = "Begin Open", color = Color.WHITE);

AddVerticalLine(isZombie and !isZombie[1], text = "Begin Zombie", color = Color.WHITE);

AddVerticalLine(isReversal and !isReversal[1], text = "Begin Reversal", color = Color.WHITE);

AddVerticalLine(isAfterHours and !isAfterHours[1], text = "Begin After Hours", color = Color.WHITE);

plot spikeUpSignal = if(ShowSignals and VolumeDiffOscillator >= 0 and VolumeDiffOscillator crosses above DiffEmaLong, DiffEmaLong, Double.NaN);
spikeUpSignal.SetDefaultColor(Color.LIME);
spikeUpSignal.SetPaintingStrategy(paintingStrategy = PaintingStrategy.TRIANGLES);

plot spikeDownSignal = if(ShowSignals and VolumeDiffOscillator < 0 and VolumeDiffOscillator crosses below DiffEmaLong, DiffEmaLong, Double.NaN);
spikeDownSignal.SetDefaultColor(Color.MAGENTA);
spikeDownSignal.SetPaintingStrategy(paintingStrategy = PaintingStrategy.TRIANGLES);

plot crossUpSignal = if(ShowSignals and DiffEmaShort crosses above DiffEmaLong, DiffEmaShort, Double.NaN);
crossUpSignal.SetDefaultColor(Color.LIME);
crossUpSignal.SetPaintingStrategy(paintingStrategy = PaintingStrategy.ARROW_UP);
crossUpSignal.SetLineWeight(3);

plot crossDownSignal =  if(ShowSignals and DiffEmaShort crosses below DiffEmaLong, DiffEmaShort, Double.NaN);
crossDownSignal.SetDefaultColor(Color.MAGENTA);
crossDownSignal.SetPaintingStrategy(paintingStrategy = PaintingStrategy.ARROW_DOWN);
crossDownSignal.SetLineWeight(3);

plot crossMidlineUpSignal = if(ShowSignals and DiffEmaShort crosses above ZeroLine, ZeroLine, Double.NaN);
crossMidlineUpSignal.SetDefaultColor(Color.GREEN);
crossMidlineUpSignal.SetPaintingStrategy(paintingStrategy = PaintingStrategy.ARROW_UP);
crossMidlineUpSignal.SetLineWeight(3);

plot crossMidlineDownSignal =  if(ShowSignals and DiffEmaShort crosses below ZeroLine, ZeroLine, Double.NaN);
crossMidlineDownSignal.SetDefaultColor(Color.RED);
crossMidlineDownSignal.SetPaintingStrategy(paintingStrategy = PaintingStrategy.ARROW_DOWN);
crossMidlineDownSignal.SetLineWeight(3);

Bullish Example:
DeltaV_NLSP_Bullish_Example.png


Bearish Example:
DeltaV_SYTA_Bearish_Example.png


The histogram bar colors:
Light Blue == Above avg volume for time period and higher than previous candle
Dark Blue == Above avg volume for time period and lower than previous candle
Red = Below avg volume for time period and lower than previous candle
Yellow = Below avg volume for time period and higher than previous candle

There are also volume avg and relative volume average lines that are used to signal when volume exceeds those lines to help you see that volume is coming in to the ticker.

The basic idea/usage of this indicator is, when there are blue histogram bars and they are increasing, that means volume is growing and so momentum should continue. But when the bars are red/yellow, the volume is below the recent averages and thus it is off a lot of people's radars. This can mean a stock that was hot yesterday may fade off today if the bars are red/yellow.

This indicator is sort of like training wheels for learning to spot volume changes. I think over time you'll find you don't need it because you'll see the diff instinctively. But I hope this helps someone.
 
Last edited by a moderator:

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
437 Online
Create Post

Similar threads

Similar threads

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