Accessing Seconds from 1min Chart ThinkOrSwim

evanevans

Active member
I'm trying to create a label to show projected number of shares traded (volume) by close of the current bar. Technically all I want to do is color a CurrentBarVolume label according to whether the projected volume of the current bar will be above or below the average of the last 30 bars.

The problem is, I can't get the number of seconds that have passed in the current minute (GetTime) so that I can do a calculated projection.

For example, if in the first 10 seconds of the current minute 100,000 shares have traded, than at that point you can project that 600,000 shares might trade by the close of the current bar.

So for my script, if that 600,000 number (for example) is above the average bar volume of the last 30 bars, I want to color the label green, otherwise light_gray.

Any help?

Many thanks
 
@Welkin it went great today. The colors indicating up/down direction multiplied the usefulness massively. I think it's a really great momentum style indicator at this point. I did set the smoothing to 0, but interestingly I did not notice a visual difference between 0 and the default of 5.

What were some of your other thoughts for it?

I still would love to see it auto-adapt to the amount of tick volume that is coming in. I think a user posted an example of how that could be approached earlier in this thread? I find myself frequently going in and changing the tick-frame to 1 premarket and midday, and to 5 or 10 during market open and end of day and during strong rally moments. You have to constantly be changing it. Is there no way to not plot each tick and instead plot the value of a cumulative tick counted value each passing second?

This is how it looks on my setup:
swceGpm.png
the 5% is for elapsed time, so 5% of 60 secs would be 3, 10% would be 6 seconds, etc... the input
elapsedProjectionDivisor is what would control how the projection is reduced during those seconds, so if the indicator is set to 60 secs and its set to 10% the first 6 secs of the projection would be divided in half. Adjust it until you find a sweet spot that works for you. Sorry if that was confusing, I should probably change the input names to something else or create some hints. I might scrap the percentage part and change it back to seconds instead, I just thought it might offer a little more flexability because when adjusting the seconds input you wouldn't have to enter new values as often.

What was posted by MattATM would not automatically adjust the chart's tick aggregation, it could be used to dynamically set the seconds input, which I've been considering trying, but not sure how valuable that'll be because generally you want it set to the same aggregation your upper chart is set to (1 min, 5 min, etc..) so that you have insight into whats happening inside those candles. I don't think you'd want it automatically cycling through to 1 min, 3 min 5 min, 20 min cycles and so on...
I might also try and use it in adjusting the projection spikes at the start of a new cycle, but need to consider the criteria that needs to be met for auto adjustment and what values it should use in place of those adjustments as well. It will not auto adjust the aggregation of the chart itself, you're gonna still experience large bursts of tick movement on the x axis, followed by less volatile periods of time. So you would still be adjusting from 1 tick, 5 tick, and 10 tick chart aggregations regardless.... I'm currently not aware of a way around this, if you ever find a way let me know.

The tick sentiment that I implimented is working OK, but just that, I find it to be a little better when set to 5 min vs 1 min. I plan on adding some other options that the user can choose from, like basing tick sentiment on moving averages, heiken ashi trend, volume profile, inertia, ADL, etc...
 
And another thought I had, was you could adapt some of the math in this work, to display a "ghost" volume bar projection above or overlayed on current volume, on the 1min. The typical lower volume indicator that people are familiar with. It could show the volume candle already completed (ex: at 50% opacity). Not even sure if that's possible, but just throwing it out there, into the think tank! (y) Great work @Welkin!
 
@Welkin, I noticed today, at many turns, that the tick coloring was many times green whilst the stock was tanking. I rarely see vice versa but I'm sure that happens too right? If you want to try your hand at some other coloring methods as you described, I can report back my observations across many stocks. I watch dozens, and trade them, all day long, using price action, volume, and this indicator as a momentum predictor.
 
@Welkin it went great today. The colors indicating up/down direction multiplied the usefulness massively. I think it's a really great momentum style indicator at this point. I did set the smoothing to 0, but interestingly I did not notice a visual difference between 0 and the default of 5.

What were some of your other thoughts for it?

I still would love to see it auto-adapt to the amount of tick volume that is coming in. I think a user posted an example of how that could be approached earlier in this thread? I find myself frequently going in and changing the tick-frame to 1 premarket and midday, and to 5 or 10 during market open and end of day and during strong rally moments. You have to constantly be changing it. Is there no way to not plot each tick and instead plot the value of a cumulative tick counted value each passing second?

This is how it looks on my setup:
swceGpm.png
how do you get the lower tick chart without candles/price like in this posts pic. I can get it as a lower tick chart but I don't also want the candle plot because it takes up to much room.
 
@Welkin, I noticed today, at many turns, that the tick coloring was many times green whilst the stock was tanking. I rarely see vice versa but I'm sure that happens too right? If you want to try your hand at some other coloring methods as you described, I can report back my observations across many stocks. I watch dozens, and trade them, all day long, using price action, volume, and this indicator as a momentum predictor.
yes, I'll work on it some more this week end, probably sat/sunday night. Didn't have time to do much scripting these past 2 days.

I was playing around with the volume profile aspect but I've concluded it'll probably have to remain a separate upper indicator because it plots at the price level, which can't be controlled and messes with how the projection indicator looks. So far I've made 2 versions, one which is triggered when volume has reached 2 and/or 3 standard deviations, and and the other option volume profile will plot based on the specified time in seconds like the current projection indicator. So you can see volume profile on a tick chart in a 1 min, 5 min, etc... time frame and see what is going on inside those candles before they close.

Here is the script for it if you guys want to play around with it, and like I said they should be used as upper indicator, couldn't combine them with the projection indicator unless I do something where the plots remain hidden...
In the indicator's settings you can choose how volume profile will plot by changing the VolumeProfileTrigger input :
rU8K7Fp.png

Code:
#[email protected]
#Seconds based Volume Profile indicator for TICK charts. + Volume Deviations
#v8.26.2020
declare upper;

def NA = Double.NaN;
input aggregationInSeconds = 300;
input VolumeProfileTrigger = {default TimeBased, VolumeDeviations};
def start = 0000;
def end = 1600;
def c = close;
def v = volume;
def min = Floor(SecondsFromTime(start) / aggregationInSeconds);
def test = min != min[1];
############################################
#Deviations in Volume
input avgVolLength = 20;
input volAverageType = AverageType.SIMPLE;
def VolAvg = MovingAverage(volAverageType, V, avgVolLength);
#2Sigma and 3Sigma Vol Filter
input Sigma2Deviation = 2.0;
input Sigma3Deviation = 3.0;
def averageType = AverageType.SIMPLE;
def sDev = StDev(data = V, length = avgVolLength);
def VolSigma2 = VolAvg + Sigma2Deviation * sDev;
def VolSigma3 = VolAvg + Sigma3Deviation * sDev;
############################################
#Volume Profile Start
input onExpansion = no;
input profiles = 1000;
input showPointOfControl = yes;
input showValueArea = no;
input valueAreaPercent = 70;
input opacity = 50;
input height = .25;
def vcond;
switch(VolumeProfileTrigger){
case TimeBased:
vcond = if test then 1 else 0;
case VolumeDeviations:
vcond = if v > VolSigma2 or v > VolSigma3 then 1 else 0;
};
profile vol = VolumeProfile("startNewProfile" = vcond, "onExpansion" = onExpansion, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def con = CompoundValue(1, onExpansion, no);
def pc = if IsNaN(vol.GetPointOfControl()) and con then pc[1] else vol.GetPointOfControl();
def hVA = if IsNaN(vol.GetHighestValueArea()) and con then hVA[1] else vol.GetHighestValueArea();
def lVA = if IsNaN(vol.GetLowestValueArea()) and con then lVA[1] else vol.GetLowestValueArea();

def hProfile = if IsNaN(vol.GetHighest()) and con then hProfile[1] else vol.GetHighest();
def lProfile = if IsNaN(vol.GetLowest()) and con then lProfile[1] else vol.GetLowest();
def plotsDomain = IsNaN(c) == onExpansion;

plot POC = if plotsDomain then pc else Double.NaN;
plot ProfileHigh = if plotsDomain then hProfile else Double.NaN;
plot ProfileLow = if plotsDomain then lProfile else Double.NaN;
plot VAHigh = if plotsDomain then hVA else Double.NaN;
plot VALow = if plotsDomain then lVA else Double.NaN;


DefineGlobalColor("Profile", Color.DARK_GRAY);
DefineGlobalColor("Point Of Control", Color.DARK_ORANGE);
DefineGlobalColor("Value Area", Color.GRAY);

vol.Show(GlobalColor("Profile"), if showPointOfControl then GlobalColor("Point Of Control") else Color.CURRENT, if showValueArea then GlobalColor("Value Area") else Color.CURRENT, opacity);
POC.SetDefaultColor(GlobalColor("Point Of Control"));
POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VALow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetDefaultColor(GlobalColor("Value Area"));
VALow.SetDefaultColor(GlobalColor("Value Area"));
ProfileHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileHigh.SetDefaultColor(Color.GRAY);
ProfileLow.SetDefaultColor(Color.GRAY);
ProfileHigh.Hide();
ProfileLow.Hide();
 
Last edited:
@Welkin Really cool stuff, interested to see what you can do with the vol profile. Would it be possible to do a volume profile for a 4h chart that starts a new profile every "x" amount of bars. I could find that very useful. I'm not a day trader myself but these cool indicators your making also have useful applications on higher timeframe.
 
Last edited by a moderator:
@Welkin Really cool stuff, interested to see what you can do with the vol profile. Would it be possible to do a volume profile for a 4h chart that starts a new profile every "x" amount of bars. I could find that very useful. I'm not a day trader myself but these cool indicators your making also have useful applications on higher timeframe.
here you go, I also added a couple of other extras
Code:
#[email protected]
#Volume Profile All-In-One
##########################
#Seconds based for TICK charts
#High Volume Deviations
#Regular Trading Hours
#Extended Trading Hours
#Every X Number of Bars
#Anchored at Date/Time
#Moving Average Crossover
#RSI OverBought/OverSold
#CCI OverBought/OverSold
#v8.30.2020
declare upper;

def NA = Double.NaN;
input VolumeProfileTrigger = {SecondsBasedForTick, VolumeDeviations, default RegularTradingHours, ExtendedTradingHours, EveryXNumberOfBars, AnchorAtDateTime, MovingAverageCross, RSI_OBOS, CCI_OBOS};
input aggregationInSeconds = 300;
input start = 0930;
input end = 1600;
def YYYYMMDD = GetYYYYMMDD();
def RTH = SecondsFromTime(start) >=0 and SecondsFromTime(end) <=0;

def o = open;
def h = high;
def c = close;
def l = low;
def v = volume;
def min = Floor(SecondsFromTime(start) / aggregationInSeconds);
def test = min != min[1];
############################################
#Deviations in Volume
input avgVolLength = 20;
input volAverageType = AverageType.SIMPLE;
def VolAvg = MovingAverage(volAverageType, V, avgVolLength);
#2Sigma and 3Sigma Vol Filter
input Sigma2Deviation = 2.0;
input Sigma3Deviation = 3.0;
def averageType = AverageType.SIMPLE;
def sDev = StDev(data = V, length = avgVolLength);
def VolSigma2 = VolAvg + Sigma2Deviation * sDev;
def VolSigma3 = VolAvg + Sigma3Deviation * sDev;

############################################
#Every X Number of Bars
input everyXNumberBars = 40;
def bn = barNumber();
def cnt = if isnan(cnt[1]) then 1 else if cnt[1] <= everyXNumberBars then cnt[1]+ 1 else 1;
def xcnttest = if cnt[1] == everyXNumberBars then 1 else 0;

############################################
#Anchored Date/Time
input dateAnchor = 20200827;
input timeAnchor = 0930;
def dateTest = if YYYYMMDD == dateAnchor then 1 else 0;
def timeTest = if SecondsTillTime(timeAnchor) ==0 then 1 else 0;

############################################
#Moving Average Crosses
input movAvg1Price = close;
input movAvg2Price = close;
input movAvg1Type = AverageType.SIMPLE;
input movAvg2Type = AverageType.SIMPLE;
input movAvg1Length = 18;
input movAvg2Length = 50;
def movAvg1 = MovingAverage(movAvg1Type, movAvg1Price, movAvg1Length);
def movAvg2 = MovingAverage(movAvg2Type, movAvg2Price, movAvg2Length);
def MAtest = if (movAvg1 crosses below movAvg2) or (movAvg1 crosses above movAvg2) then 1 else 0;

############################################
#RSI
input rsiLength = 14;
input rsiOverBought = 75;
input rsiOverSold = 25;
input rsiPrice = close;
input rsiAvgType = AverageType.WILDERS;
def NetChgAvg = MovingAverage(averageType, rsiPrice - rsiPrice[1], rsiLength);
def TotChgAvg = MovingAverage(averageType, AbsValue(rsiPrice - rsiPrice[1]), rsiLength);
def ChgRatio = if TotChgAvg != 0 then NetChgAvg / TotChgAvg else 0;
def RSI = 50 * (ChgRatio + 1);
def RSIOBtest = RSI >= rsiOverBought;
def RSIOStest = RSI <= rsiOverSold;

############################################
#CCI
input CCIlength = 14;
input cciOverBought = 140;
input cciOverSold = -140;
def cciPrice = c + l + h;
def linDev = lindev(cciPrice, CCIlength);
def CCI = if linDev == 0 then 0 else (cciPrice - Average(cciPrice, CCIlength)) / linDev / 0.015;
def cciOBtest = CCI >= cciOverBought;
def cciOStest = CCI <= cciOverSold;

############################################
#Volume Profile
input onExpansion = no;
input profiles = 1000;
input showPointOfControl = yes;
input showValueArea = no;
input valueAreaPercent = 70;
input opacity = 50;
input height = .25;
def vcond;
switch(VolumeProfileTrigger){
case SecondsBasedForTick:
vcond = if test then 1 else 0;
case VolumeDeviations:
vcond = if v > VolSigma2 or v > VolSigma3 then 1 else 0;
case RegularTradingHours:
vcond = if !RTH and RTH[1] then 1 else if !RTH then 1 else 0;
case ExtendedTradingHours:
vcond = if RTH and !RTH[1] then 1 else if RTH then 1 else 0;
case EveryXNumberOfBars:
vcond = if xcnttest then 1 else 0;
case AnchorAtDateTime:
vcond = if dateTest and timeTest then 1 else 0;
case MovingAverageCross:
vcond = if MAtest then 1 else 0;
case RSI_OBOS:
vcond = if RSIOBtest or RSIOStest then 1 else 0;
case CCI_OBOS:
vcond = if cciOBtest or cciOStest then 1 else 0;
};
profile vol = VolumeProfile("startNewProfile" = vcond, "onExpansion" = onExpansion, "numberOfProfiles" = profiles, "pricePerRow" = height, "value area percent" = valueAreaPercent);
def con = CompoundValue(1, onExpansion, no);
def pc = if IsNaN(vol.GetPointOfControl()) and con then pc[1] else vol.GetPointOfControl();
def hVA = if IsNaN(vol.GetHighestValueArea()) and con then hVA[1] else vol.GetHighestValueArea();
def lVA = if IsNaN(vol.GetLowestValueArea()) and con then lVA[1] else vol.GetLowestValueArea();

def hProfile = if IsNaN(vol.GetHighest()) and con then hProfile[1] else vol.GetHighest();
def lProfile = if IsNaN(vol.GetLowest()) and con then lProfile[1] else vol.GetLowest();
def plotsDomain = IsNaN(c) == onExpansion;

plot POC = if plotsDomain then pc else Double.NaN;
plot ProfileHigh = if plotsDomain then hProfile else Double.NaN;
plot ProfileLow = if plotsDomain then lProfile else Double.NaN;
plot VAHigh = if plotsDomain then hVA else Double.NaN;
plot VALow = if plotsDomain then lVA else Double.NaN;


DefineGlobalColor("Profile", Color.DARK_GRAY);
DefineGlobalColor("Point Of Control", Color.DARK_ORANGE);
DefineGlobalColor("Value Area", Color.GRAY);

vol.Show(GlobalColor("Profile"), if showPointOfControl then GlobalColor("Point Of Control") else Color.CURRENT, if showValueArea then GlobalColor("Value Area") else Color.CURRENT, opacity);
POC.SetDefaultColor(GlobalColor("Point Of Control"));
POC.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VALow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
VAHigh.SetDefaultColor(GlobalColor("Value Area"));
VALow.SetDefaultColor(GlobalColor("Value Area"));
ProfileHigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileLow.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
ProfileHigh.SetDefaultColor(Color.GRAY);
ProfileLow.SetDefaultColor(Color.GRAY);
ProfileHigh.Hide();
ProfileLow.Hide();
 
Last edited:
Added a few new options for gauging sentiment, give them a try.
Code:
#[email protected]
#Attempt at Volume Projection on low TICK charts
#Thanks to YungTraderFromMontana and evanevans for the ideas
#v8.30.2020
declare lower;

def NA = Double.NaN;
input Sentiment = {ContinuousCloseAboveBelowRatio, Inertia, SummativeStrength, HeikenAshiTrend, default AboveBelowMovAvg, AboveBelowHighVolTriggeredVWAP};
input aggregationInSeconds = 60;
input elapsedPercentSmoothValue = 5;
input elapsedProjectionDivisor = 2;
input showVerticalExceedPrevCvol = yes;
input showVerticalCycleEndCvol = yes;
def start = 0000;
def end = 1600;
def o = open;
def h = high;
def l = low;
def c = close;
def v = volume;
def bull = c > c[1];
def bear = c < c[1];
def neutral = c == o;
def min = Floor(SecondsFromTime(start) / aggregationInSeconds);
def till = SecondsTillTime(end) / aggregationInSeconds;
def test = min != min[1];
def vc = if test and !test[1] then v else if !test then vc[1] + v else vc[1];
def secondselapsed = (AbsValue(till - Ceil(till)) * aggregationInSeconds);
def secondsleft = aggregationInSeconds - secondselapsed;
def multipliertest = aggregationInSeconds / secondselapsed;
def multiplier  = if IsInfinite(multipliertest) then NA else multipliertest;
def percntelapsed = Round(((secondselapsed / aggregationInSeconds) * 100), 0);
def cl = if test then 1 else cl[1] + 1;
def ch = if test then cl[1] else ch[1];
def prevcumulativehigh = if test and !test[1] then vc[1] else prevcumulativehigh[1];
def cvolpassprev = vc >= prevcumulativehigh and vc[1] < prevcumulativehigh;
def highestprevchigh = HighestAll(prevcumulativehigh);
def projectioncalc = vc * multiplier;

######################
#Continuous Close Above/Below Previous Ratio
def upval = if test and !test[1] and bull then 1 else if !test and bull then upval[1] + 1 else if test and bear then 0 else upval[1];
def downval = if test and !test[1] and bear then 1 else if !test and bear then downval[1] + 1 else if test and bull then 0 else downval[1];
def ContinuousCloseRatio = upval / downval;

######################
#Inertia
input inertiaLength = 20;
input inertiaPrice = close;
def inertia = inertia(inertiaPrice,inertiaLength);

######################
#Summative Volume Strength based on close position
input summativeLength = 5;
def bvolsum = Sum(((c - l) / (h - l)) * v, summativeLength);
def svolsum = Sum(((h - c) / (h - l)) * v, summativeLength);

######################
#Heiken Ashi
def HAopen;
def HAhigh;
def HAlow;
def HAclose;
HAopen = CompoundValue(1, (HAopen[1] + HAclose[1]) / 2, (o[1] + c[1]) / 2);
HAhigh = Max(Max(h, HAopen), HAclose[1]);
HAlow = Min(Min(l, HAopen), HAclose[1]);
HAclose = ohlc4;

######################
#Above Below Moving Average
input movAvgPrice = close;
input movAvgType = AverageType.SIMPLE;
input movAvgLength = 50;
def MA = MovingAverage(movAvgType, movAvgPrice, movAvgLength);

######################
#Sigma Vol Filters
input avgVolLength = 20;
input volAverageType = AverageType.SIMPLE;
input Sigma2 = 2.0;
input Sigma3 = 3.0;
def VolAvg = MovingAverage(volAverageType, v, avgVolLength);
def sDev = StDev(data = v, length = avgVolLength);
def VolSigma2 = VolAvg + Sigma2 * sDev;
def VolSigma3 = VolAvg + Sigma3 * sDev;

######################
#VWAP
def vconf =if v > volsigma3 then 1 else if v > volsigma2 then 1 else 0;
def VolumeSum = if vconf then v else CompoundValue(1, VolumeSum[1] + v, v);
def VolumeVwapSum = if vconf then v * vwap else CompoundValue(1, VolumeVwapSum[1] + v * vwap, v * vwap);
def volumeVwap2Sum = if vconf then v * Sqr(vwap) else CompoundValue(1, volumeVwap2Sum[1] + v * Sqr(vwap), v * Sqr(vwap));
def VW = if !IsNaN(c) then VolumeVwapSum / VolumeSum else VW[1];

plot cvolpassprevsig = if cvolpassprev then vc else NA;
plot CVol = vc;
plot prevchigh = prevcumulativehigh;
plot cycleavg = Round(TotalSum(if test then ch[1] else 0) / min, 1);
plot cyclehigh = ch;
plot cyclelength = cl;
plot projection = if (projectioncalc >= highestprevchigh) and (percntelapsed < elapsedPercentSmoothValue) then projectioncalc / elapsedProjectionDivisor else projectioncalc;

cycleavg.Hide();
cyclehigh.Hide();
cyclelength.Hide();

AddVerticalLine(showVerticalExceedPrevCvol and !IsNaN(cvolpassprevsig), "                 " + secondselapsed + "s / " + aggregationInSeconds + " | " + percntelapsed + "%", Color.CYAN);
AddVerticalLine(showVerticalCycleEndCvol and test, " Length " + cyclelength[1] + "       CVol " + prevcumulativehigh, Color.GRAY, Curve.FIRM);

def Pos;
def Neg;
switch (Sentiment){
case ContinuousCloseAboveBelowRatio:
    Pos = !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio > 1;
    Neg = !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio < 1;
case Inertia:
    Pos = inertia > inertia[1];
    Neg = !Pos;
case SummativeStrength:
    Pos = bvolsum > svolsum;
    Neg = svolsum > bvolsum;
case HeikenAshiTrend:
    Pos = HAclose > HAopen;
    Neg = !Pos;
case AboveBelowMovAvg:
    Pos = close > MA;
    Neg = !Pos;
case AboveBelowHighVolTriggeredVWAP:
    Pos = close > VW;
    Neg = !Pos;
}

#Labels
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, upval, Color.GREEN);
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, downval, Color.RED);
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, "Cycle Sentiment: " + Round(ContinuousCloseRatio, 2), if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio > 1 then Color.GREEN else if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio < 1 then Color.RED else  Color.GRAY);
AddLabel(1, "Cycle Length: " + cyclelength[1], Color.GRAY);
AddLabel(1, "Prev Cycle Length: " + cyclehigh, Color.GRAY);
AddLabel(1, "Cycle Avg: " + cycleavg, Color.GRAY);
AddLabel(1, "Cycles Since Start: " + min, Color.GRAY);
AddLabel(1, "Secs " + secondselapsed + "/" + aggregationInSeconds + "   " + percntelapsed + "%", Color.YELLOW);
AddLabel(1, "CVol: " + vc, Color.WHITE);
AddLabel(1, "Prev CVol: " + prevcumulativehigh, Color.WHITE);
AddLabel(1, "x" + Round(vc / prevcumulativehigh, 2) + " Prev CVol", Color.WHITE);
AddLabel(1, "Proj Vol: " + Round(projection, 0), Color.DARK_ORANGE);
AddLabel(1, "Proj Multiplier x" + Round(multiplier, 2), Color.DARK_ORANGE);



CVol.SetDefaultColor(Color.DARK_GRAY);
CVol.SetLineWeight(2);
prevchigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
prevchigh.SetDefaultColor(Color.YELLOW);
projection.SetDefaultColor(Color.DARK_ORANGE);
projection.AssignValueColor(if Pos then Color.GREEN else if Neg then Color.RED else Color.GRAY);
projection.SetLineWeight(2);
cvolpassprevsig.SetPaintingStrategy(PaintingStrategy.POINTS);
cvolpassprevsig.SetLineWeight(3);
AddCloud(projection, CVol, CreateColor(0, 100, 200), CreateColor(0, 100, 200));
AddCloud(CVol, 0, Color.DARK_GRAY, Color.DARK_GRAY);
AddCloud(CVol, prevchigh, Color.YELLOW, Color.BLACK);
 
Added a few new options for gauging sentiment, give them a try.
Code:
#[email protected]
#Attempt at Volume Projection on low TICK charts
#Thanks to YungTraderFromMontana and evanevans for the ideas
#v8.30.2020
declare lower;

def NA = Double.NaN;
input Sentiment = {ContinuousCloseAboveBelowRatio, Inertia, SummativeStrength, HeikenAshiTrend, default AboveBelowMovAvg, AboveBelowHighVolTriggeredVWAP};
input aggregationInSeconds = 60;
input elapsedPercentSmoothValue = 5;
input elapsedProjectionDivisor = 2;
input showVerticalExceedPrevCvol = yes;
input showVerticalCycleEndCvol = yes;
def start = 0000;
def end = 1600;
def o = open;
def h = high;
def l = low;
def c = close;
def v = volume;
def bull = c > c[1];
def bear = c < c[1];
def neutral = c == o;
def min = Floor(SecondsFromTime(start) / aggregationInSeconds);
def till = SecondsTillTime(end) / aggregationInSeconds;
def test = min != min[1];
def vc = if test and !test[1] then v else if !test then vc[1] + v else vc[1];
def secondselapsed = (AbsValue(till - Ceil(till)) * aggregationInSeconds);
def secondsleft = aggregationInSeconds - secondselapsed;
def multipliertest = aggregationInSeconds / secondselapsed;
def multiplier  = if IsInfinite(multipliertest) then NA else multipliertest;
def percntelapsed = Round(((secondselapsed / aggregationInSeconds) * 100), 0);
def cl = if test then 1 else cl[1] + 1;
def ch = if test then cl[1] else ch[1];
def prevcumulativehigh = if test and !test[1] then vc[1] else prevcumulativehigh[1];
def cvolpassprev = vc >= prevcumulativehigh and vc[1] < prevcumulativehigh;
def highestprevchigh = HighestAll(prevcumulativehigh);
def projectioncalc = vc * multiplier;

######################
#Continuous Close Above/Below Previous Ratio
def upval = if test and !test[1] and bull then 1 else if !test and bull then upval[1] + 1 else if test and bear then 0 else upval[1];
def downval = if test and !test[1] and bear then 1 else if !test and bear then downval[1] + 1 else if test and bull then 0 else downval[1];
def ContinuousCloseRatio = upval / downval;

######################
#Inertia
input inertiaLength = 20;
input inertiaPrice = close;
def inertia = inertia(inertiaPrice,inertiaLength);

######################
#Summative Volume Strength based on close position
input summativeLength = 5;
def bvolsum = Sum(((c - l) / (h - l)) * v, summativeLength);
def svolsum = Sum(((h - c) / (h - l)) * v, summativeLength);

######################
#Heiken Ashi
def HAopen;
def HAhigh;
def HAlow;
def HAclose;
HAopen = CompoundValue(1, (HAopen[1] + HAclose[1]) / 2, (o[1] + c[1]) / 2);
HAhigh = Max(Max(h, HAopen), HAclose[1]);
HAlow = Min(Min(l, HAopen), HAclose[1]);
HAclose = ohlc4;

######################
#Above Below Moving Average
input movAvgPrice = close;
input movAvgType = AverageType.SIMPLE;
input movAvgLength = 50;
def MA = MovingAverage(movAvgType, movAvgPrice, movAvgLength);

######################
#Sigma Vol Filters
input avgVolLength = 20;
input volAverageType = AverageType.SIMPLE;
input Sigma2 = 2.0;
input Sigma3 = 3.0;
def VolAvg = MovingAverage(volAverageType, v, avgVolLength);
def sDev = StDev(data = v, length = avgVolLength);
def VolSigma2 = VolAvg + Sigma2 * sDev;
def VolSigma3 = VolAvg + Sigma3 * sDev;

######################
#VWAP
def vconf =if v > volsigma3 then 1 else if v > volsigma2 then 1 else 0;
def VolumeSum = if vconf then v else CompoundValue(1, VolumeSum[1] + v, v);
def VolumeVwapSum = if vconf then v * vwap else CompoundValue(1, VolumeVwapSum[1] + v * vwap, v * vwap);
def volumeVwap2Sum = if vconf then v * Sqr(vwap) else CompoundValue(1, volumeVwap2Sum[1] + v * Sqr(vwap), v * Sqr(vwap));
def VW = if !IsNaN(c) then VolumeVwapSum / VolumeSum else VW[1];

plot cvolpassprevsig = if cvolpassprev then vc else NA;
plot CVol = vc;
plot prevchigh = prevcumulativehigh;
plot cycleavg = Round(TotalSum(if test then ch[1] else 0) / min, 1);
plot cyclehigh = ch;
plot cyclelength = cl;
plot projection = if (projectioncalc >= highestprevchigh) and (percntelapsed < elapsedPercentSmoothValue) then projectioncalc / elapsedProjectionDivisor else projectioncalc;

cycleavg.Hide();
cyclehigh.Hide();
cyclelength.Hide();

AddVerticalLine(showVerticalExceedPrevCvol and !IsNaN(cvolpassprevsig), "                 " + secondselapsed + "s / " + aggregationInSeconds + " | " + percntelapsed + "%", Color.CYAN);
AddVerticalLine(showVerticalCycleEndCvol and test, " Length " + cyclelength[1] + "       CVol " + prevcumulativehigh, Color.GRAY, Curve.FIRM);

def Pos;
def Neg;
switch (Sentiment){
case ContinuousCloseAboveBelowRatio:
    Pos = !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio > 1;
    Neg = !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio < 1;
case Inertia:
    Pos = inertia > inertia[1];
    Neg = !Pos;
case SummativeStrength:
    Pos = bvolsum > svolsum;
    Neg = svolsum > bvolsum;
case HeikenAshiTrend:
    Pos = HAclose > HAopen;
    Neg = !Pos;
case AboveBelowMovAvg:
    Pos = close > MA;
    Neg = !Pos;
case AboveBelowHighVolTriggeredVWAP:
    Pos = close > VW;
    Neg = !Pos;
}

#Labels
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, upval, Color.GREEN);
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, downval, Color.RED);
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, "Cycle Sentiment: " + Round(ContinuousCloseRatio, 2), if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio > 1 then Color.GREEN else if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio < 1 then Color.RED else  Color.GRAY);
AddLabel(1, "Cycle Length: " + cyclelength[1], Color.GRAY);
AddLabel(1, "Prev Cycle Length: " + cyclehigh, Color.GRAY);
AddLabel(1, "Cycle Avg: " + cycleavg, Color.GRAY);
AddLabel(1, "Cycles Since Start: " + min, Color.GRAY);
AddLabel(1, "Secs " + secondselapsed + "/" + aggregationInSeconds + "   " + percntelapsed + "%", Color.YELLOW);
AddLabel(1, "CVol: " + vc, Color.WHITE);
AddLabel(1, "Prev CVol: " + prevcumulativehigh, Color.WHITE);
AddLabel(1, "x" + Round(vc / prevcumulativehigh, 2) + " Prev CVol", Color.WHITE);
AddLabel(1, "Proj Vol: " + Round(projection, 0), Color.DARK_ORANGE);
AddLabel(1, "Proj Multiplier x" + Round(multiplier, 2), Color.DARK_ORANGE);



CVol.SetDefaultColor(Color.DARK_GRAY);
CVol.SetLineWeight(2);
prevchigh.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
prevchigh.SetDefaultColor(Color.YELLOW);
projection.SetDefaultColor(Color.DARK_ORANGE);
projection.AssignValueColor(if Pos then Color.GREEN else if Neg then Color.RED else Color.GRAY);
projection.SetLineWeight(2);
cvolpassprevsig.SetPaintingStrategy(PaintingStrategy.POINTS);
cvolpassprevsig.SetLineWeight(3);
AddCloud(projection, CVol, CreateColor(0, 100, 200), CreateColor(0, 100, 200));
AddCloud(CVol, 0, Color.DARK_GRAY, Color.DARK_GRAY);
AddCloud(CVol, prevchigh, Color.YELLOW, Color.BLACK);

Thanks for updating. With this update, I can't seem to get sentiment label (I think the background of the label was changing colors as well) that was available with 8.25.2020 version iirc.

now to the question I have, a lot of questions as there are many lines running;

I see vertical gray lines reading lenght 12 to lenght 18 followed by another gray line (vertical) reading 10. What do these values mean?

Within the vertical lines 12 & 18. I see
1- green trending line (showing inflow/momo) & underneath a blue cloud, below the blue cloud is
2- purple horizontal line,
3- dark gray line with green dot that produces yellowish cloud & lastly,
4- light gray cloud under horiozontal purple & another dark blue-grayish cloud between purple horizontal line & dark gray line.

sorry posting pic here is a challenge.
 
Thanks for updating. With this update, I can't seem to get sentiment label (I think the background of the label was changing colors as well) that was available with 8.25.2020 version iirc.

now to the question I have, a lot of questions as there are many lines running;

I see vertical gray lines reading lenght 12 to lenght 18 followed by another gray line (vertical) reading 10. What do these values mean?

Within the vertical lines 12 & 18. I see
1- green trending line (showing inflow/momo) & underneath a blue cloud, below the blue cloud is
2- purple horizontal line,
3- dark gray line with green dot that produces yellowish cloud & lastly,
4- light gray cloud under horiozontal purple & another dark blue-grayish cloud between purple horizontal line & dark gray line.

sorry posting pic here is a challenge.
hopefully this image will explain what is going on
23tOYCV.png

the blue cloud is just to add a little contrast between the cumulative and projection area.
the sentiment label you were referring to was changed to only appear if you have ContinuousCloseAboveBelowRatio selected as the sentiment option , if you want the labels to be visible without having it selected then replace the following:
Code:
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, upval, Color.GREEN);
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, downval, Color.RED);
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, "Cycle Sentiment: " + Round(ContinuousCloseRatio, 2), if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio > 1 then Color.GREEN else if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio < 1 then Color.RED else  Color.GRAY);
with
Code:
AddLabel(1, upval, Color.GREEN);
AddLabel(1, downval, Color.RED);
AddLabel(1, "Cycle Sentiment: " + Round(ContinuousCloseRatio, 2), if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio > 1 then Color.GREEN else if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio < 1 then Color.RED else  Color.GRAY);
 
hopefully this image will explain what is going on
23tOYCV.png

the blue cloud is just to add a little contrast between the cumulative and projection area.
the sentiment label you were referring to was changed to only appear if you have ContinuousCloseAboveBelowRatio selected as the sentiment option , if you want the labels to be visible without having it selected then replace the following:
Code:
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, upval, Color.GREEN);
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, downval, Color.RED);
AddLabel(Sentiment == Sentiment.ContinuousCloseAboveBelowRatio, "Cycle Sentiment: " + Round(ContinuousCloseRatio, 2), if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio > 1 then Color.GREEN else if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio < 1 then Color.RED else  Color.GRAY);
with
Code:
AddLabel(1, upval, Color.GREEN);
AddLabel(1, downval, Color.RED);
AddLabel(1, "Cycle Sentiment: " + Round(ContinuousCloseRatio, 2), if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio > 1 then Color.GREEN else if !IsInfinite(ContinuousCloseRatio) and ContinuousCloseRatio < 1 then Color.RED else  Color.GRAY);

WoW! thank you for doing this explanation. I can now understand this script better & visualize more than just red/green projection line.
 
Last edited:
WoW! thank you for doing this explanation. I can now understand this script better & visual more than just red/green projection line.

I still don't understand. Can you guys explain a little bit more detail? May be with examples of how to use it?

EDIT: I now understand...but trade examples will be nice.
 
Last edited:
@Welkin you seam to be really good at the sec and tick format Can this be done
I'm trying to set up a 60 second timer then to give like a 8 seconds period, ( variable by input). So every start of the min a a Bubble would appear and last for approx 8 seconds, however I can not find any documentation
 
@Welkin you seam to be really good at the sec and tick format Can this be done
I'm trying to set up a 60 second timer then to give like a 8 seconds period, ( variable by input). So every start of the min a a Bubble would appear and last for approx 8 seconds, however I can not find any documentation
A label could show for 8 seconds. Would that work for you?
 
@Welkin you seam to be really good at the sec and tick format Can this be done
I'm trying to set up a 60 second timer then to give like a 8 seconds period, ( variable by input). So every start of the min a a Bubble would appear and last for approx 8 seconds, however I can not find any documentation
This is the script for a label, and you should know this can only work on a low tick count chart, as the elapsed time is only refreshed when there is activity.
Code:
#[email protected]
input aggregationInSeconds = 60;
input elapsedTrigger = 8;
def start = 0930;
def end = 1600;
def min = Floor(SecondsFromTime(start) / aggregationInSeconds);
def till = SecondsTillTime(end) / aggregationInSeconds;
def secondselapsed = (AbsValue(till - Ceil(till)) * aggregationInSeconds);

AddLabel(1, "   "+secondselapsed+" / "+aggregationInSeconds+"   ", if secondselapsed <= elapsedTrigger then Color.YELLOW else Color.DARK_GRAY);
because of the activity limitation, you might want to consider going another route... consider a separate application called timeleft, with it I think you could customize something that will alert you with a sound when the amount of time you want has passed. Just an idea, not sure if it'll actually work for what you want.
 
Last edited:
What was posted by MattATM would not automatically adjust the chart's tick aggregation, it could be used to dynamically set the seconds input, which I've been considering trying, but not sure how valuable that'll be because generally you want it set to the same aggregation your upper chart is set to (1 min, 5 min, etc..) so that you have insight into whats happening inside those candles. I don't think you'd want it automatically cycling through to 1 min, 3 min 5 min, 20 min cycles and so on...
@Welkin @YungTraderFromMontana @evanevans Mr. Welkin sir, I was thinking to adjust a time period that then adjusts the tick count (Instead of jerking the time in minutes up and down and up and down like a crazy man 👹 ) I haven't tried anything to see what TOS can do to adjust chart tick aggregation https://tlc.thinkorswim.com/center/reference/thinkScript/Functions/Fundamentals/tick-count

So If I can relate ticks per time then move time to get the right number of ticks?? Then I can adjust this indicator to be right for the chart!!! ;)
Easiest way to go from have ➡ to want ???
 
@Welkin, I noticed today, at many turns, that the tick coloring was many times green whilst the stock was tanking.
I had an idea why not reverse Freedom Of Movement to work inside here with this 1min timely volume display???
Below is Degree of Freedom and it regards the ease with which Volume moves and the ease of which Price moves...
The saturation of trades on the Lvl2 that makes a bridge to move +/- $0.01 easily IS (why we worship) VOLUME!
I have some thoughts but let me look at the work @Welkin was so kind to post since I have been around...
Code:
declare lower;
declare zerobase;
input length = 60;
input numDev = 2.0;
input allowNegativeValues = no;
def mov = AbsValue(close / close[1] - 1);
def minMov = Lowest(mov, length);
def maxMov = Highest(mov, length);
def nMov = 1 + (mov - minMov) / (maxMov - minMov) * 9;
def vol = (volume - Average(volume, length)) / StDev(volume, length);
def minVol = Lowest(vol, length);
def maxVol = Highest(vol, length);
def nVol = 1 + (vol - minVol) / (maxVol - minVol) * 9;
def vByM = nVol / nMov;
def rawFoM = (vByM - Average(vByM, length)) / StDev(vByM, length);
plot FoM = if allowNegativeValues then rawFoM else Max(0, rawFoM);
plot StDevLevel = numDev;
FoM.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
FoM.SetLineWeight(3);
FoM.DefineColor("Above", GetColor(0));
FoM.DefineColor("Below", GetColor(2));
FoM.AssignValueColor(if FoM >= numDev then FoM.Color("Above") else FoM.Color("Below"));
StDevLevel.SetDefaultColor(GetColor(7));
StDevLevel.SetStyle(Curve.SHORT_DASH);
 
Could I ask a favor? 😇 Could someone post a chart like those that they took the screenshots of? Just with the code already shared?
I could adjust the tick count and time myself but I only have a laptop with me and I have so many charts open a shared chart would save me some time 🕰 No problems if nobody has it but this way I could start from the same page as you all without wondering what security to use with what range...
 
Could I ask a favor? 😇 Could someone post a chart like those that they took the screenshots of? Just with the code already shared?
I could adjust the tick count and time myself but I only have a laptop with me and I have so many charts open a shared chart would save me some time 🕰 No problems if nobody has it but this way I could start from the same page as you all without wondering what security to use with what range...
this is the current grid I've been playing around with at night: http://tos.mx/yNg1H0l
edit: the upper grid was actually set to 5 min, changed it to 1 min to look at something and meant to change it back, incase you were wondering why the projection and profile indicator are set to 5 min and doesn't match the upper grid aggregation lol..

thanks for the response with the other stuff, I figured I'd probably misunderstood your direction with the script you mentioned. Never realized tick_count had those extra parameters, thanks for pointing that out! I'll try and mess around with some things before I call it a night. Took a look at the degree of freedom indicator you posted above, going to have to look closer to digest the script and what all it does, but just looking at the indicator itself it seems to point out lots of doji/indecisive/small range bars with medium to high volume? interesting, some new stuff to fiddle with :)
 
Last edited:

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
401 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