Accessing Seconds from 1min Chart

evanevans

evanevans

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
 
YungTraderFromMontana

YungTraderFromMontana

Well-known member
I want to do a something similar but on a larger scale, if anyone can do it @Welkin can but I'm not sure this way is possible because it goes down to seconds
 
Welkin

Welkin

Active member
VIP
@evanevans might be possible but it'd need to be done on a tick chart, this is the only way you'll get the data to use before a 1 min bar closes. I'll fiddle around with it and see what happens.
 
Welkin

Welkin

Active member
VIP
Ok, back already, spent about an hour or so messing with it. This is what I came up with. Perhaps someone else can use this as a base to add more features on top of...


Code:
#[email protected]
#Thanks to YungTraderFromMontana and evanevans for the ideas
declare lower;

def NA = Double.NaN;
input aggregationInSeconds = 60;
input elapsedPercentSmoothValue = 5;
input elapsedProjectionDivisor = 2;
def start = 0000;
def end = 1600;
def o = open;
def h = high;
def l = low;
def c = close;
def v = volume;
def bb = Max(o, c) == c;
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;

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;

AddVerticalLine(!IsNaN(cvolpassprevsig), "                      "+secondselapsed+"s / "+aggregationInSeconds+" | "+percntelapsed+"%", Color.CYAN);
AddVerticalLine(test, "                      CVol "+prevcumulativehigh, Color.GRAY, Curve.FIRM);

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, "Proj Vol: " + Round(projection, 0), Color.DARK_ORANGE);
AddLabel(1, "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.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.DARK_GREEN, Color.BLACK);
This was tested on a 1 tick chart. The user inputs the number of seconds for the aggregation they want to use(in this case it is set to 60 seconds for a 1 min bar). Depending on the time of day when there is more activity (was testing during futures globex session) and/or if you are adjusting the aggregationsInSeconds input to higher values, then you can increase the ticks on the chart aggregation. Play around and find a readable balance.

edit:
  • Cleaned up the script a little
  • Added some more variables and labels for them so that I and others can play around with them and discover some things in relation to volatility spikes, etc.
  • Previous cycle value for CVol is now carried over as a yellow line, allowing you to better see visually when the current cycle meets/exceeds the previous CVol level. I'd like to script something with this that better shows the relations between current cycle length, previous cycle length, and the amount of time it took to meet those CVol levels when volatility starts to spike.
  • Also made it so that projection isn't plotted when multiplier value is infinite
 
Last edited:
evanevans

evanevans

Member
Dude, that's pretty freaking great. It shows the projection at each moment, and the actual is the gray area? Phenomenal. I can just put this underneath my main 1m charts, in a tick chart, and that will help me do the forecasting. I'm sure you can see the usefulness as I do. Looks like you can see if the prediction is waning .... or "waxing".
 
evanevans

evanevans

Member
Well that was certainly amazing in action. Before the first big volume candle zoomed up and the candlestick price zoomed up, you could see the explosion in volume. If I had a video of it happening it would be very revealing... but, essentially, you could see the volume exploding before price changed. It was beautiful to see. And very easy to see after a consolidation period of low volume because of the differential (between low volume and insane volume).



I have some questions and further ideas:

1. Could each tick cloud moment be colored whether it was up in price (ex: green: bright green if it hit the ask; forest green if it was the same as last which was up) or down in price (ex: red: bright red if it hit the bid; dark red if it was the same as last which was down)? I can almost picture a thermograph in the cloud area.

2. I also notice there is a ROC or velocity in this tick flow that is useful and should be converted into something we can see/interpret.

3. Could we compress the output to put no further than 1 seconds data into the minute region? Because on some very heavily traded stocks which experience light volume, one has to be on 1 tick to see anything significant, but then suddenly when 5 million shares trade in a minute, that 1 minute ends up spanning several scrolled windows worth of data! :)

4. Finally, I think there must be something that can be done about the first 5-10 seconds of each aggregation period. Many times it way overprojects the math. Maybe for the first 10 seconds, it can compare to the previous 10 seconds, and feather out, just so it's not so blind at the start each time. Perhaps this could even be a rolling 10 second "smoother" throughout.

P.S. Going to send you a PayPal donation good sir, well done!
 
Last edited:
YungTraderFromMontana

YungTraderFromMontana

Well-known member
I'm working on a daily conversion, I think I should be able to get it to work by using 23,400 as the seconds value and 0930 as start. I think the improvements we can have from here on out will be with the volume estimate. This will be especially tricky on daily because the simple formula that is used now won't cut it because of volume spikes in the morning. @mashume can you help with this project.

On a larger scale for which it wasn't intended for there are a ton of bugs, but thank you for taking the most difficult first step. I see amazing potential in this as I'm sure many others do. @Welkin
 
Last edited by a moderator:
StockT8er

StockT8er

Member
VIP
This is great. One question now how do I convert my strategy to work on a tick chart. I tried placing the beginning of this and did not work
 
evanevans

evanevans

Member
@Welkin can anything be done to colorize it according to whether it was an uptick or downtick, etc, as I mentioned in my first reply above? That could create the extra visual confirmation needed in order to act swiftly to buy into a rally or get out on a sell off.
 
S

shizah

New member
@evanevans - I'm trying to get the same tick volume chart layout you have for $PIXY. What do you have the tick settings at? Did you move the study into the upper?

Thanks!
 
Welkin

Welkin

Active member
VIP
@Welkin can anything be done to colorize it according to whether it was an uptick or downtick, etc, as I mentioned in my first reply above? That could create the extra visual confirmation needed in order to act swiftly to buy into a rally or get out on a sell off.
sorry wasn't able to do anything last night, think ToS was doing some late night maintenance so couldn't really test anything, i'll mess around with it some time tonight or tomorrow and let you know.
 
evanevans

evanevans

Member
@evanevans - I'm trying to get the same tick volume chart layout you have for $PIXY. What do you have the tick settings at? Did you move the study into the upper?
I added a C2 (second chart from the right "Grid" sidebar choices) to the chart (C1). I then removed it from displaying the upper chart (on that C2 second chart) so it only had the lower indicator. Then I set the timeframe on the lower C2 to Ticks. Depending on the stock volume, one has to choose 1 tick, 10 tick, 50 ticks, 5 ticks, depends, because every stock has a different amount of volume. Looks like @Welkin is going to have a go at my suggestions, so maybe there will be something coming to address the non-uniformity between different levels of tick volume. When it's a lot, it requires choosing a larger amount of ticks per data point (10+). I think if we can always "sub-aggregate" those down to 1 second bars, that might be the ideal, although I really dig the speed of the realtime. There must be a solution. Maybe 250ms bars. 100ms bars. Something unified, no matter what volume of tick data there is, it has a standardized display method across varying stocks.
 
MattATM

MattATM

Active member
VIP
@Welkin my goodness get it together man... How long did it take you to overthrow NYC and fix the power? Also why haven't you finished colonizing Mars??? You probably got distracted performing remote surgery with nanobots but man get your schedule together maybe a life coach! We expect more out of you...

I did something I think might add functionality to your solution... Only thing is at some point we will be moving so fast we will be deceived by HighFreqTrading https://usethinkscript.com/threads/automating-aggregation-selection-for-thinkorswim.3183/#post-29405
 
YungTraderFromMontana

YungTraderFromMontana

Well-known member
That is really cool and useful, thank you!
@Welkin there is a bug that I'm not sure how to fix that is artificially inflating the cumulative volume. I don't think it is much of an issue on the 1m but it becomes an issue on the 1d conversion I'm working on. It all works well except it says the ending daily volume of a stock like SPY is 160 million. I am using all correct info.

I'm fairly sure this bug is in this portion of the code because everything else looks good and I can't completely understand all of this.

Code:
def test = if min != min[1] then 1 else 0;
def vc = if (test == 1) and (test[1] == 0) then v else if (test == 0) then vc[1] + volume else vc[1];
plot vct = if test == 1 then NA else vc;
def secondselapsed = (AbsValue(till - ceil(till))*aggregationInSeconds);
nevermind the code is fine, the issue I was having is caused by setting the tick chart to the past 5 days. The script will then take the cumulative volume the last 5 days instead of only today.
 
Last edited by a moderator:
YungTraderFromMontana

YungTraderFromMontana

Well-known member
Here's a v1 for a daily predicted volume. I assisted the prediction by eyeballing when the volume came in on SPY, very primitive but still much more effective at this point. Prediction seems to be pretty accurate even very early in the day. Next steps are trying to find statistical ratios using previous data instead of manual ones as well as a better way of smoothing so there aren't spikes in the prediction during ratio changes.
Code:
#[email protected]
declare lower;
def NA = Double.NaN;
input aggregationInSeconds = 23400;
def start = 0930;
def v = volume;
def min = Floor(SecondsFromTime(start) / aggregationInSeconds);
def till = SecondsTillTime(start) / aggregationInSeconds;
def test = if min != min[1] then 1 else 0;
def vc = if (test == 1) and (test[1] == 0) then v else if (test == 0) then vc[1] + volume else vc[1];
plot vct = if test == 1 then NA else vc;
def secondselapsed = (AbsValue(till - Ceil(till)) * aggregationInSeconds);
def secondsleft = aggregationInSeconds - secondselapsed;
def multiplier = aggregationInSeconds / secondselapsed;
def prj = vc * multiplier;
input Time = 0934;
input Time2 = 0945;
input Time3 = 0958;
input Time4 = 1010;
input Time5 = 1025;
input Time6 = 1040;
input Time7 = 1100;
input Time8 = 1125;
input Time9 = 1150;
input Time10 = 1300;
input Time11 = 1540;
def Active = SecondstillTime(Time) >= 0;
def Active2 = SecondstillTime(Time2) >= 0;
def Active3 = SecondstillTime(Time3) >= 0;
def Active4 = SecondstillTime(Time4) >= 0;
def Active5 = SecondstillTime(Time5) >= 0;
def Active6 = SecondstillTime(Time6) >= 0;
def Active7 = SecondstillTime(Time7) >= 0;
def Active8 = SecondstillTime(Time8) >= 0;
def Active9 = SecondstillTime(Time9) >= 0;
def Active10 = SecondstillTime(Time10) >= 0;
def Active11 = SecondstillTime(Time11) >= 0;
plot prjmod = if Active then prj / 3 else if Active2 then prj / 2.3 else if Active3 then prj / 2.15 else if Active4 then prj / 2 else if Active5 then prj / 1.7 else if Active6 then prj / 1.55 else if Active7 then prj / 1.4 else if Active8 then prj / 1.3 else if Active9 then prj / 1.15 else  if active10 then prj/.97 else if active11 then prj/.9 else prj;
AddLabel(1, multiplier, Color.ORANGE);
AddVerticalLine(test, " ", Color.GRAY);
AddLabel(1, "Cycles Since Start: " + min, Color.WHITE);
AddLabel(1, "Seconds Elapsed: " + secondselapsed, Color.YELLOW);
AddLabel(1, "Seconds Left: " + secondsleft, Color.YELLOW);
AddLabel(1, "Current Cumulative Vol: " + vc, Color.WHITE);
AddLabel(1, "Projected Volume: " + Round(prjmod, 0), Color.DARK_ORANGE);
AddCloud(vct, 0, Color.GRAY, Color.GRAY);
AddCloud(prjmod, vct, Color.BLUE, Color.BLUE);
vct.SetDefaultColor(Color.WHITE);
prjmod.SetDefaultColor(Color.DARK_ORANGE);
Here's a pic, no prediction after 3:50 eastern because there is no point
 
zeek

zeek

Active member
2019 Donor
I added a C2 (second chart from the right "Grid" sidebar choices) to the chart (C1). I then removed it from displaying the upper chart (on that C2 second chart) so it only had the lower indicator. Then I set the timeframe on the lower C2 to Ticks.
How do you do that? (the bolded part)
 

Similar threads

Top