New Members: Be sure to confirm your email address by clicking on the link that was sent to your email inbox. You will not be able to post messages until you click that link.

Looking for a trading range scan? This one's a monster...

Hello S.C.A.N Community,

I have been on here before, looking for a way to scan for what can be called an "Anticipation Scan." Basically, it is a scan looking for a range before a breakout. I wasn't able to find one that I felt met me criteria, so I created one! It's a VERY long scan, but it doesn't take long to execute.

Basically, I wanted to create a scan that looked at the past 20 days of price action. I wanted the prices to be contained in a 4 to 6% price range (I settled on 6% as to not be too restrictive and allow some discretionary liberty).

I also wanted the current day's price to not break out of the range, and I didn't want any one day price range to be larger than 3%.

So I created a scan that calculates the average of the past 20 days of closings. This number is used to establish a range 3% above and 3% below that 20 day closing price average.

So here it is:

// This is my Anticipation Scan (Anticipation of breaking out of a range).
// It scans for stocks that closed below 103% and above 97% of 20 day average closing price.
// (effectively creating a 6% range of the 20 day average of closing prices)

// Basic Scan Criteria for Mid and Micro Cap Stocks in U.S.
[type = stock] AND [country is US] AND [Daily SMA(20,Daily Volume) > 50000] AND [market cap < 2,000] AND [market cap > 300] AND [group is not ETF] and [name not contains "Trust"] and [name not contains "Notes Due"] and [name not contains "Shares"] and [name not contains "Fund"]

// These expression checks to see that closing for the past 2 weeks are below 103% of 20 day average closing price.

and [today close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03]

and [2 days ago close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03]

and [4 days ago close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03]

and [6 days ago close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03]

and [8 days ago close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03]

and [10 days ago close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03]

and [12 days ago close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03]

and [14 days ago close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03]

and [16 days ago close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03]

and [18 days ago close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03]

and [20 days ago close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03]

// These expression checks to see that closing for the past 2 weeks are above 97% of 20 day average closing price

and [today close > [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * .97]

and [2 days ago close > [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * .97]

and [4 days ago close > [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * .97]

and [6 days ago close > [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * .97]

and [8 days ago close > [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * .97]

and [10 days ago close > [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * .97]

and [12 days ago close > [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * .97]

and [14 days ago close > [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * .97]

and [16 days ago close > [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * .97]

and [18 days ago close > [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * .97]

and [20 days ago close > [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * .97]

//These expressions weed out the stocks that are at the top or bottom of the range.

and [today's close < yesterday's daily max(20,high)]
and [today's close > yesterday's daily min(20,low)]

// These expressions checks to see that there are no inter-day swings over 3% within the 20 day range.

and [ [today high - today low] / today low < .03]
and [ [yesterday high - yesterday low] / yesterday low < .03]
and [ [2 days ago high - 2 days ago low] / 2 days ago low < .03]
and [ [3 days ago high - 3 days ago low] / 3 days ago low < .03]
and [ [4 days ago high - 4 days ago low] / 4 days ago low < .03]
and [ [5 days ago high - 5 days ago low] / 5 days ago low < .03]
and [ [6 days ago high - 6 days ago low] / 6 days ago low < .03]
and [ [7 days ago high - 7 days ago low] / 7 days ago low < .03]
and [ [8 days ago high - 8 days ago low] / 8 days ago low < .03]
and [ [9 days ago high - 9 days ago low] / 9 days ago low < .03]
and [ [10 days ago high - 10 days ago low] / 10 days ago low < .03]
and [ [11 days ago high - 11 days ago low] / 11 days ago low < .03]
and [ [12 days ago high - 12 days ago low] / 12 days ago low < .03]
and [ [13 days ago high - 13 days ago low] / 13 days ago low < .03]
and [ [14 days ago high - 14 days ago low] / 14 days ago low < .03]
and [ [15 days ago high - 15 days ago low] / 15 days ago low < .03]
and [ [16 days ago high - 16 days ago low] / 16 days ago low < .03]
and [ [17 days ago high - 17 days ago low] / 17 days ago low < .03]
and [ [18 days ago high - 18 days ago low] / 18 days ago low < .03]
and [ [19 days ago high - 19 days ago low] / 19 days ago low < .03]
and [ [20 days ago high - 20 days ago low] / 20 days ago low < .03]

Phew! I know that was SUPER LONG..., and if anyone has suggestions on how to condense any part of this scan, I'm all ears!

I hope this helps someone out, and thank you S.C.A.N community for your contributions that allowed me to put this together. I wish you many successful trading days!

Phil K.

Comments

  • markdmarkd ✭✭✭
    edited February 18
    Pretty interesting scan. I noticed when I ran it (2/18/17), that it also captured stocks already in up trends (but very orderly ones), e.g. ADX, AEH, ISF. If you wanted to eliminate those, you could compare the sma(20,close) versus the 20 days ago sma(20, close) to limit them to some maximum per cent separation.

    The scan below is less specific than yours but I think approximates your requirements reasonably well. It uses Price Channels and max() and min() functions to avoid the day by day specification. Of course there may be a trade-off between time saved writing the scan and time spent editing the results. You have already done the work for this scan, but maybe this example would be helpful for constructing future scans.

    // all prices in the last twenty bars (including current bar) are within 3 per cent of the average (Middle Price Chan) of the 20 bar highest high (Upper Price Chan) and lowest low (Lower Price Chan)
    and [ max(20, Upper Price Chan(20)) < Middle Price Chan(20) * 1.03]
    and [min(20, Lower Price Chan(20)) > Middle Price Chan(20) * .97]

    // no bar in the last 20 bars is wider than 3 per cent of the 20 bar lowest low
    and [max(20, range) < min(20, Lower Price Chan(20)) * 1.03]

    // no breakout bar today
    and [close < 1 day ago Upper Price Chan(20)]
    and [close > 1 day ago Lower Price Chan(20)]
  • edited February 19
    Hey Markd,

    Thanks for the input on my scan, and for your simplified version. I've read a bunch of your prior posts and have seen the results from your use of price channels, but did not understand the nuts and bolts behind the scan; hence, I was unwilling to use it at the time.

    I've been able to look at your scan and now understand the logic behind it. I'm still trying to visualize the:

    and [max(20, range) < min(20, Lower Price Chan(20)) * 1.03]

    expression, but I'm sure once I step away for a bit, it'll hit me. giving your scan and test drive and I like what I see so far :smile:

    Alas, I still can't seem to get rid of the small orderly moves (which the whole move does not violate my scan). I've tried some things with the SMA with no success. Any ideas? Thanks!
  • markdmarkd ✭✭✭
    edited February 20
    two comments:

    re the quoted line of code: instead of calculating 3% for every bar, this line just chooses the lowest low of the past 20 bars (actually the lowest value of the Lower Price Chan - but most of the time they will probably be the same) and calculates the 3% limit for range from that low. It just makes the assumption that the lowest low will be reasonably representative of all the lows (which may not be valid all the time, but seems (to me) a reasonable trade off). If you want to admit a (probably slightly) wider range, you could try max(20, ...) instead. Or, you could just use min(20, low) or max(20,low) in place of Lower Price Chan(20).

    re can't get small orderly moves: remember, they aren't always out there to get. If you are finding them with visual inspection of your chart lists, but the scan doesn't pick them up, then the scan needs tweaking. Also, remember that chart scaling affects how you perceive past moves. If you are looking at charts that had a smooth range prior to a big run up, reset the dates on the chart so that it ends just before the take-off. The range will look less orderly.
  • markdmarkd ✭✭✭
    edited February 20
    Here's another approach:

    [group is sp500]

    // the sma has stayed in a 6 per cent range
    and [sma(20, close) < 20 days ago sma(10,close) * 1.03]
    and [sma(20, close) > 20 days ago sma(10,close) * .97]

    // no high or low has exceed the 6 per cent range
    and [max(20, high) < 20 days ago sma(20, close) * 1.03]
    and [min(20, low) > 20 days ago sma(20, close) * .97]
  • Thanks again for your response! I don't know why, but going the channel route over the same period results in less hits on my scan than my previously written one.

    I have found another way to SIGNIFICANTLY decrease the actual written scan itself with the following expression:

    [ [max (20, high) - min (20, low) ] / min (20, low) < .06]

    in place of:

    and [today close < [ [2 days ago close + 4 days ago close + 6 days ago close + 8 days ago close + 10 days ago close + 12 days ago close + 14 days ago close + 16 days ago close + 18 days ago close + 20 days ago close] / 10] * 1.03] (etc...)

    I'm still going to use the:

    and [ [today high - today low] / today low < .03]
    and [ [yesterday high - yesterday low] / yesterday low < .03] (etc...)

    qualifier to limit the range of each individual bar in my date range (I just like the rigidity and i just makes more sense rattling around in my head...).

    Thanks again for all the help. It's great to be able to bounce around ideas with others to get those creative juices flowing! Hope this thread helps you guys out, and as always, I wish y'all successful trading :grin:
  • markdmarkd ✭✭✭
    @pkneeland78 Super! Good luck with it.
Sign In or Register to comment.