Volume Spike Scan at specific time, Thinkorswim


Category:
0
0

Hi Pete,

First thanks for a great website, very helpful!

I am trying to create a scan that returns tickers with volume spikes at a specific time. Basically I would like to compare the 1 minute bar volume at say, 6:59am est and 7:00am est. Here is the script I have come up with:

def time659 = round(secondsFromTime(0659)/60,0);
def time700 = round(secondsFromTime(0700)/60,0);

def volume_at_time659 = getvalue(volume, time659);
def volume_at_time700 = getvalue(volume, time700);

#volume at 7:00am is 5 times the volume at 6:59am:
def check = if volume_at_time700 > 5*volume_at_time659 then 1 else 0;
plot scan = check > 0;

This scan should work for today for the ticker HUGE. I have been attempting to debug using labels within charts (see 2nd attached screenshot).

My guess is there may be a limitation with scans and the getvalue function. Any ideas?

Thanks in advance!

-Chris

Attachments:
RESOLVED
Marked as spam
Posted by (Questions: 1, Answers: 1)
Asked on March 17, 2021 6:24 am
803 views
0
Private answer

First and most important detail is that all custom scans on Thinkorswim use Eastern timezone. I notice from your chart and your selected times you are using Pacific timezone. So the first thing we need to do is adjust those times to match Eastern timezone. Which give us the target times of 9:59 and 10:00.

The next detail I want to explain is that my approach is completely different. Rather than try to create an offset value to the target bar and accessing the value from that bar using the GetValue() function, I simply use the input times to directly read the volume data from each target bar. Then I use recursion to carry those values forward, which can then be used as in a comparison to check if your condition is true.

The screenshot below shows what this looks like on a chart. The red line is generated based on the first time input. The white line is generate based on the second time input. Notice in this example you provided, the first volume bar is higher than the second. So this particular ticker symbol does NOT satisfy your condition.

To be clear, your example code includes a multiplier in your condition. Such that the second volume bar (white line) must be 5 times higher than the first (red line).

Here is the code to display as shown in the chart:

input targetTimeOne = 959;
input targetTimeTwo = 1000;
rec volumeAtTimeOne = if SecondsTillTime(targetTimeOne) == 0 then volume else volumeAtTimeOne[1];
rec volumeAtTimeTwo = if SecondsTillTime(targetTimeTwo) == 0 then volume else volumeAtTimeTwo[1];
plot test1 = volumeAtTimeOne;
plot test2 = volumeAtTimeTwo;

And here is the code required to run your scan:

input targetTimeOne = 959;
input targetTimeTwo = 1000;
input volumeMultiplier = 5.0;
rec volumeAtTimeOne = if SecondsTillTime(targetTimeOne) == 0 then volume else volumeAtTimeOne[1];
rec volumeAtTimeTwo = if SecondsTillTime(targetTimeTwo) == 0 then volume else volumeAtTimeTwo[1];
plot scan = volumeAtTimeTwo > volumeAtTimeOne * volumeMultiplier;

Attachments:
Marked as spam
Posted by (Questions: 37, Answers: 4084)
Answered on March 17, 2021 9:28 am
0
Hi Pete, thanks for your quick response. The 0659 and 0700 from my original post are already in the Eastern Timezone (premarket). 1 minute volume bars on HUGE for these two at these times are: 0659 = 26,879 0700 = 454,940 which should satisfy the 5x multiplier as shown in the light green labels from my 2nd picture above (check = 1). That aside, I am getting the following error with your code for the scan: Trying to self-assign a non-initialized rec: volumeAtTimeTwo. Do you know why this is occurring? Thanks again, -Chris
( at March 17, 2021 3:39 pm)
0
I have corrected the code in my answer to address the error message and it should work correctly now.
( at March 17, 2021 4:05 pm)
0
Thanks Pete, now works flawlessly. To expand upon the script, if volumeAtTimeOne is equal to zero, is there a way to iterate backward from targetTimeOne to the first time where volume > 0? For example, the ticker BHTG today did not have a volume greater than zero until 6:08am EST. (volume at 6:08 was 464, volume at 6:59 was 0, volume at 7:00 was 77,261). I am playing around with 'fold' but wondering if there is an easier way. Thanks!
( at March 18, 2021 5:38 am)
0
Sorry but for this answer I have already exceeded the amount of time I allocate to each free solution provided in the Q&A Forum. And I would never touch the "fold" looping structure in Thinkorswim without considerable compensation. Coming from a background in C++ and Java, I absolutely detest Thinkorswim's lame attempt at looping.
( at March 18, 2021 8:17 am)
0
Hi Pete, I completely agree with you on fold. I think I may have found an easier way. Instead of trying to iterate backward and find the time, we can just use the previous bar number. Only issue with the following code is the "volumeAtPreviousBar" is returning the current bar volume for some reason. Can you take a look? Thanks! CODE START- input targetTime = 0700; input volumeMultiplier = 5.0; rec volumeAtTime = if SecondsTillTime(targetTime) == 0 then volume else volumeAtTime[1]; rec barnumberAtTargetTime = if SecondsTillTime(targetTime) == 0 then BarNumber() else barnumberAtTargetTime[1]; rec volumeAtPreviousBar = if barnumberAtTargetTime - 1 then volume else volumeAtPreviousBar[1]; plot scan = volumeAtTime > volumeAtPreviousBar * volumeMultiplier; -CODE END For ticker ZKIN today: Volume @ 0700 (bar # 644) = 1592 Volume @ previous bar #643 (time = 0652) = 185
( at March 19, 2021 8:53 am)
0
Sorry but for this answer I have already exceeded the amount of time I allocate to each free solution provided in the Q&A Forum.
( at March 19, 2021 11:33 am)
0
I understand, thanks Pete! I was able to figure out a workaround and wanted to update this thread with the new working scan for completeness. Here it is: CODE START- input targetTime = 0700; input volumeMultiplier = 5.0; def volumeAtTargetTime = if SecondsTillTime(targetTime) == 0 then volume else volumeAtTargetTime[1]; def barnumberAtTargetTime = if SecondsTillTime(targetTime) == 0 then BarNumber() else barnumberAtTargetTime[1]; def previousBarNumberToTargetTime = barnumberAtTargetTime - 1; def current_bar = barnumber(); def barOffset = current_bar - previousBarNumberToTargetTime; def volumeAtPreviousBarNumber = getvalue(volume, barOffset); plot scan = volumeAtTargetTime > volumeAtPreviousBarNumber * volumeMultiplier; -CODE END
( at March 19, 2021 1:36 pm)
0
Ah, very good. Thanks. If this is the best solution to your question then please post this a a new solution to the question and I will approve that.
( at March 19, 2021 2:08 pm)