ThinkorSwim Volume Spike Alert and Scanner

Asianraisin

New member
I am trying to set up a thinkscript study alert for high (8x higher than average) intraday volume. I'm trying to do this on the 1 min time frame. The goal is to catch the beginning of large moves like with what happened with $DIS today or with $TWLO and $BA earlier this week. What I've done so far is created a study alert (MarketWatch > study alerts) and put the following code in:

Code:
def afterStart = secondsfromtime(9000)>0;
def beforeEnd = secondstilltime(1430)>0;
def conditionTrue = volume > 8*average(volume, 390);
plot alert = afterStart and beforeEnd and conditionTrue;

I am trying to get alerted for volume 8x higher than average from the hours 9am cst to 2:30pm cst.(to avoid the early morning and late afternoon vol spikes). 390 representing the 390 mins in a trading day. Does this look right? I'm not sure if I'm doing this correctly. Is there any way to backtest this through OnDemand?

Thank you very much for taking time to look at my post.

Code:
#
# Pedro Uriarte 25 Aug 2019
# /CL 2500
#

declare lower;
declare zerobase;

input lengthAvg = 50;
input volumeAlert1 = 2500;
input volumeAlert2 = 3500;
input aggregationPeriod = AggregationPeriod.MIN;
input soundType = Sound.RING;
input alertType =  Alert.BAR;
Plot dinamicAlertLine = ((GetAggregationPeriod()/60000) - 1) * volumeAlert1;

plot Vol = volume;
plot VolAvg = Average(volume, lengthAvg);
Plot AlertLine1 = volumeAlert1;
Plot AlertLine2 = volumeAlert2;

Vol.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Vol.SetLineWeight(3);
Vol.DefineColor("Up", Color.UPTICK);
Vol.DefineColor("Down", Color.DOWNTICK);
Vol.AssignValueColor(if close > close[1] then Vol.color("Up") else if close < close[1] then Vol.color("Down") else GetColor(1));
VolAvg.SetDefaultColor(GetColor(8));
AlertLine1.SetDefaultColor(GetColor(5));
AlertLine2.SetDefaultColor(GetColor(5));
dinamicAlertLine.SetDefaultColor(GetColor(5));

# def afterStart = SecondsFromTime(0800) > 0;
# def beforeEnd = SecondsTillTime(1530) > 0;
def alertCondition = GetAggregationPeriod() == aggregationPeriod and (volume >= volumeAlert1 or (volumeAlert2!= 0 and volume >= volumeAlert2));

Alert(alertCondition, "High volume Alert", alertType, soundType);
 
Last edited by a moderator:

Slippage

Active member
@prap4trading The code looks fine to me. I played with scans for high volume breakouts last year and I would recommend a few things. I'd share what I created but I nuked it when I switched from day trading to swing trading.

Don't look for a single bar with high volume. Most of the signals you'll get will be worthless -- a single big order that hit a low volume stock and then nothing else happened. Instead, look for 2 or more consecutive bars. Reduce the time period if you're worried about how late that brings you to the party (3m instead of 5m).

Add a price component. True Range some multiple of Average True Range on the same bars as the increased volume. Or even ATR(3) > ATR()*3 or something like that to make the code simple.

I'd also recommend using the 3 minute timeframe due to the general understanding around the ThinkOrSwim community that 3 minutes is the soonest TOS servers will refresh your scan results.

Lastly, while you're testing/tweaking it helps to set an alert on the scan to email you when a symbol is added to the results. That way when you're finished trading for the day you can look at all of them to identify any adjustments you want to make. The email timestamps will tell you what times to look at on the charts.
 

prap4trading

New member
@prap4trading The code looks fine to me. I played with scans for high volume breakouts last year and I would recommend a few things. I'd share what I created but I nuked it when I switched from day trading to swing trading.

Don't look for a single bar with high volume. Most of the signals you'll get will be worthless -- a single big order that hit a low volume stock and then nothing else happened. Instead, look for 2 or more consecutive bars. Reduce the time period if you're worried about how late that brings you to the party (3m instead of 5m).

Add a price component. True Range some multiple of Average True Range on the same bars as the increased volume. Or even ATR(3) > ATR()*3 or something like that to make the code simple.

I'd also recommend using the 3 minute timeframe due to the general understanding around the ThinkOrSwim community that 3 minutes is the soonest TOS servers will refresh your scan results.

Lastly, while you're testing/tweaking it helps to set an alert on the scan to email you when a symbol is added to the results. That way when you're finished trading for the day you can look at all of them to identify any adjustments you want to make. The email timestamps will tell you what times to look at on the charts.
Thanks and would be great if you can point some sample scripts to start with.
 

Slippage

Active member
Thanks and would be great if you can point some sample scripts to start with.

Here's an example you could start with and tweak as desired. With the code you already posted, you can change the last line to this:

Ruby:
plot alert =
  afterStart and beforeEnd # it's the right time of day
  and conditionTrue and conditionTrue[1] # volume increase
  and ATR(2) > ATR() * 2 # price range increase
;

If you want 3 qualifying candles instead of 2 you can add and conditionTrue[2] and change ATR(2) to ATR(3).

You can play with ATR() * 2 and make it ATR() * 1.5 or less or ATR() * 3 or higher depending on how strict it needs to be for it to be useful to you.

My experience has been it's better to start with looser criteria and tighten if needed. If it's too strict at the start you won't see any results and it's hard to adjust from there when you have multiple criteria.

Putting the conditions on separate lines like I did here has a few advantages.
  1. Can easily comment out a single condition in the middle of the statement while debugging
  2. Can place comments behind individual conditions within the overall statement
  3. More readable, in my opinion
 

prap4trading

New member
Here's an example you could start with and tweak as desired. With the code you already posted, you can change the last line to this:

Ruby:
plot alert =
  afterStart and beforeEnd # it's the right time of day
  and conditionTrue and conditionTrue[1] # volume increase
  and ATR(2) > ATR() * 2 # price range increase
;

If you want 3 qualifying candles instead of 2 you can add and conditionTrue[2] and change ATR(2) to ATR(3).

You can play with ATR() * 2 and make it ATR() * 1.5 or less or ATR() * 3 or higher depending on how strict it needs to be for it to be useful to you.

My experience has been it's better to start with looser criteria and tighten if needed. If it's too strict at the start you won't see any results and it's hard to adjust from there when you have multiple criteria.

Putting the conditions on separate lines like I did here has a few advantages.
  1. Can easily comment out a single condition in the middle of the statement while debugging
  2. Can place comments behind individual conditions within the overall statement
  3. More readable, in my opinion
Thanks, will try this out following code. Please let me know your thoughts'

P.S: I am in PST zone and my time on TOS is also set to PST so i believe 0645 and 1245
should take care of first 15 and last 15 minutes noise.

Code:
def afterStart = secondsfromtime(0645)>=0;
def beforeEnd = secondstilltime(1245)>=0;
def vol_length = 30;
def AVGV = Average(volume, vol_length);
def lastNmins = (volume);
# scans for volume is greater than 500% of  average volume
def conditionTrue = lastNmins >  (AVGV * 5);

plot alert = afterStart and beforeEnd and
   conditionTrue and conditionTrue[1] # volume increase
   and ATR(2) > ATR() * 2; # price range increase
 
Last edited:

Jonas99

Active member
VIP
@prap4trading The code looks fine to me. I played with scans for high volume breakouts last year and I would recommend a few things. I'd share what I created but I nuked it when I switched from day trading to swing trading.

Don't look for a single bar with high volume. Most of the signals you'll get will be worthless -- a single big order that hit a low volume stock and then nothing else happened. Instead, look for 2 or more consecutive bars. Reduce the time period if you're worried about how late that brings you to the party (3m instead of 5m).

Add a price component. True Range some multiple of Average True Range on the same bars as the increased volume. Or even ATR(3) > ATR()*3 or something like that to make the code simple.

I'd also recommend using the 3 minute timeframe due to the general understanding around the ThinkOrSwim community that 3 minutes is the soonest TOS servers will refresh your scan results.

Lastly, while you're testing/tweaking it helps to set an alert on the scan to email you when a symbol is added to the results. That way when you're finished trading for the day you can look at all of them to identify any adjustments you want to make. The email timestamps will tell you what times to look at on the charts.
@Slippage you seem to be a seasoned hand, could you talk about your chart setup, how, and why? What do you pay attention to most? What are the most important lessons in swing trading? Thank you.
 

Jonas99

Active member
VIP
Thanks, will try this out following code. Please let me know your thoughts'

P.S: I am in PST zone and my time on TOS is also set to PST so i believe 0645 and 1245
should take care of first 15 and last 15 minutes noise.

Code:
def afterStart = secondsfromtime(0645)>=0;
def beforeEnd = secondstilltime(1245)>=0;
def vol_length = 30;
def AVGV = Average(volume, vol_length);
def lastNmins = (volume);
# scans for volume is greater than 500% of  average volume
def conditionTrue = lastNmins >  (AVGV * 5);

plot alert = afterStart and beforeEnd and
   conditionTrue and conditionTrue[1] # volume increase
   and ATR(2) > ATR() * 2; # price range increase
why do you think the first and last 15 min are noise?
 

Slippage

Active member
@Slippage you seem to be a seasoned hand, could you talk about your chart setup, how, and why? What do you pay attention to most? What are the most important lessons in swing trading? Thank you.

A complete response to that would be be off topic and probably long winded. I'm not really seasoned. I just have a couple of advantages. I'm an early retired software engineer so using ThinkScript and figuring out software features both come easily to me. Not to mention having a systematic approach to things. No longer having a job sucking most of my life away allows me to focus as much time as I want on trading and quite often it's 16+ hours a day while I'm in a learning or scripting/testing phase.

I'm working on a new strategy that takes elements from Raghee Horner's 34 ema wave strategy and combines it with multiple timeframes of MACD, which I got into because of Moxie. I'll probably post everything here once it's complete if it has good results. It's been working great the two weeks I've been using it while still developing the code.
 

Jonas99

Active member
VIP
A complete response to that would be be off topic and probably long winded. I'm not really seasoned. I just have a couple of advantages. I'm an early retired software engineer so using ThinkScript and figuring out software features both come easily to me. Not to mention having a systematic approach to things. No longer having a job sucking most of my life away allows me to focus as much time as I want on trading and quite often it's 16+ hours a day while I'm in a learning or scripting/testing phase.

I'm working on a new strategy that takes elements from Raghee Horner's 34 ema wave strategy and combines it with multiple timeframes of MACD, which I got into because of Moxie. I'll probably post everything here once it's complete if it has good results. It's been working great the two weeks I've been using it while still developing the code.
Nice! so you are with simpler trading? are you on discord?
 

Slippage

Active member
Nice! so you are with simpler trading? are you on discord?

No, I'm not with ST or anyone else. Nor would I ever want to be since that would be having job. I'm just a trader with a bit more than a year of experience day trading whatever stocks were in play each day, or sometimes index ETFs, and then transitioned to swing trading a few months ago. I've put a ridiculous amount of time into ThinkScript experiments so things like this volume scan are roads I've already been down. I'd say I'm still getting a handle on swings since I haven't settled on a strategy yet.

My focus on ST strategies is mainly because they're accessible. My day trading strategies are mostly not applicable to swings, though one, maybe two, of them can be adapted. Squeeze seems to be the most used swing strategy on YouTube. Where else can we get proven strategies that enough people are executing to give us some confidence we're not wasting our time on marketing hype with no results? I didn't really care for squeeze while trading it as described in John Carter's book so I started looking at ST's other stuff. I'd probably like squeeze more now that I know other criteria to couple it with.

The Moxie strategy appealed to me so I decided to pursue that. Once I got into it further I realized it's not as objective as I'd prefer. I want a strategy with little enough subjectivity it's relatively easy to define it in code. It enables scripting back tests. It enables writing chart studies and scans that do most of the work. For the main strategy I used for day trading I was able to script a test and then use the script to test variations of the rules. That gave me data for literally hundreds of thousands of trades covering 50 stocks over a 180 day period (longest period for which TOS will give you a 5m chart). That gave me a lot of confidence in the strategy which made it easy to follow the rules.

My goal is to spend 1 to 2 hours to review my swing positions, move stops or place exit orders, scan for new setups, place a couple of entry orders and then forget about the market until I repeat the routine the next day or a day or two later. My willingness to put so much time and effort in up front is to hopefully reach that goal sooner.

Yes, you can find me on useThinkScript's Discord if you want to discuss something there.
 

burns56

New member
Hello everyone!!! Today i would like to share what has made me profitable in the stock market Smalls caps to Mid caps... I have had entire months green NOT a single red day if you follow what i will tell you...

1. Whole and half numbers are key areas like 1.50 2 2.50 $3 these are physiological areas where stocks top tick or go over just a bit and then come back down where you can then cover for the wash...

2. This is a SCALPING strategy NOT trend trading you are in and out short the pop cover the drop or buy the dip sell the rip.

3. We use whole and half numbers with a nice spike or huge up move within 1-2 BIG candles with volume low floats... into these areas NOT GRINDS we short then cover into the wash for 10-20 cents maybe more

4. I also use Time/Sales and level 2 you MUST have a fast tape/time & sales we must see speed on the time and sales with green green green prints then once it runs out of fuel you will see the tape pause and will see red/white prints coming through this is what we want to see along with big sellers on the level 2 again we short the pop cover the drop vise versa for long we want a huge drop and want to see the time/sales pause and want to see it speed up with green prints along with big buyers on the level 2 if you short at 5.50 and it goes past we will look to add the same share size at $6 that will give us a 5.75 average if i add to the trade i will look to cut it off for break even or a small loss YOU MUST have a big enough account to add or just get in small size...

5. I promise you if you follow this to the T the right way you will have a 90% + win rate because i do this has what worked for me i can not trade trends so i trade the pops and the drops quick in and out you short at 5.50 and it drops to 5.25 1000 shares that is $250 easy money trading does not have to be hard people make it hard..

6. What to do if the trade goes against you? I follow what i call the 3 minute rule if the stock does not do what i want in 3 min i cut it off...

7. Hope some of you can follow this and start becoming consistent i have tested so many strategy's and they did not work for me anddd i did not have a high win rate this is what works for me any questions please ask also i will post a really good script below to go with this strategy as confirmation

SCRIPT NO REPAINT PS: DO NOT USE WITH GRINDS ONLY POPS.

Code:
def agg=aggregationPeriod.FIVE_MIN;
def na = Double.NaN;
input ORBegin = 930;
input OREnd = 1600;
def ORActive = if SecondsTillTime(OREnd) > 0 and SecondsTillTime(ORBegin) <= 0 then 1 else 0;
def today = GetDay() == GetLastDay();
def numDevDn = -2.0;
def numDevUp = 2.0;
def timeFrame = 3 ;

def cap = getAggregationPeriod();
def errorInAggregation =
    timeFrame == 3 and cap >= AggregationPeriod.WEEK or
    timeFrame == 3 and cap >= AggregationPeriod.MONTH;
assert(!errorInAggregation, "timeFrame should be not less than current chart aggregation period");

def yyyyMmDd = getYyyyMmDd();
def periodIndx;
#switch (timeFrame) {
#case DAY:
    periodIndx = yyyyMmDd;
#}
#def isPeriodRolled = compoundValue(1, periodIndx != periodIndx[1], yes);

def volumeSum;
def volumeVwapSum;
def volumeVwap2Sum;

#if (isPeriodRolled) {
    volumeSum = volume;
    volumeVwapSum = volume * vwap;
    volumeVwap2Sum = volume * Sqr(vwap);

def price = volumeVwapSum / volumeSum;
def deviation = Sqrt(Max(volumeVwap2Sum / volumeSum - Sqr(price), 0));

input filterfrom_1_20= 10;
def Sover_bought = 80;
def Sover_sold = 20;
def SKPeriod = 14;
def SDPeriod = 3;
def SpriceH = high;
def SpriceL = low;
def SpriceC = close;
def SaverageType = AverageType.SIMPLE;

def SlowK = reference StochasticFull(Sover_bought, Sover_sold, SKPeriod, SDPeriod, SpriceH, SpriceL, SpriceC, 3, if (SaverageType == 1) then AverageType.SIMPLE else AverageType.EXPONENTIAL).FullK;
def SlowD = reference StochasticFull(Sover_bought, Sover_sold, SKPeriod, SDPeriod, SpriceH, SpriceL, SpriceC, 3, if (SaverageType == 1) then AverageType.SIMPLE else AverageType.EXPONENTIAL).FullD;
def SOverBought = Sover_bought;
def SOverSold = Sover_sold;

#-----------------------------------------------------MACD--------------------------------
def MfastLength = 12;
def MslowLength = 26;
def MACDLength = 9;
def MaverageType = AverageType.EXPONENTIAL;
def MshowBreakoutSignals = no;

def Value = MovingAverage(MaverageType, close, MfastLength) - MovingAverage(MaverageType, close, MslowLength);
def Avg = MovingAverage(MaverageType, Value, MACDLength);

def Diff = Value - Avg;
def ZeroLine = 0;
def hod = if today and hod[1] == 0  then Value else if ORActive and today and Value > hod[1] then Value else hod[1];
def lod = if today and lod[1] == 0  then Value else if ORActive and today and Value < lod[1] then Value else lod[1];

def prctcalc = (filterfrom_1_20/ 100);
def separation = (hod - lod) * prctcalc;
#addlabel(yes,separation,color.green);
#addlabel(yes,prctcalc);
def conditionlong1 = SlowK crosses above SlowD and SlowK < Sover_sold and SlowD < Sover_sold;
def conditionlong2 = Value < 0 and Avg < 0 and Value - Avg > separation or Value < 0 and Avg < 0 and Value - Avg < -separation;

def conditionshort1 = SlowK crosses below SlowD and SlowK > Sover_bought and SlowD > Sover_bought;
def conditionshort2 = Value > 0 and Avg > 0 and Value - Avg > separation or Value > 0 and Avg > 0 and Value - Avg < -separation;
def confirmation = Value crosses below Avg;
plot long = if SecondsFromTime(ORBegin) > 0  and SecondsFromTime(OREnd) < 0 and conditionlong1 and conditionlong2 then low else  Double.NaN;
long.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
long.SetDefaultColor(Color.GREEN);
plot short =  if SecondsFromTime(ORBegin) > 0  and SecondsFromTime(OREnd) < 0 and  conditionshort1 and conditionshort2 then high else Double.NaN;
short.SetPaintingStrategy(PaintingStrategy.ARROW_DOWN);
short.SetDefaultColor(Color.RED);
Hi what was the best time frame you found? 1min, 3min or greater? Tia
 

Similar threads

Top