ShortSqueeze SqueezeScan # TOS Short Squeeze Scanner # Run in: TOS -> Tools -> Run Scan (or save to Scan Library) # Data period: Pre-Market (select in scan data settings) # Columns: Symbol, Ticker, SI%(manual), Squeeze, Gap%, PremkVol, PremkVolPct, PremkRange%, PremkAboveVWAP, PremkBid, PremkAsk, PremkMid # # HOW TO USE: # 1. TOS -> Tools -> Run Scan. Paste this entire file into the "ThinkScript" box. # 2. Set data period: Pre-Market. Exclusions: None. # 3. Universe: US stocks, price > $1, volume > 0. # (For a tighter list, add a static pre-filter for float < 30M shares.) # 4. Run. Sort by SqueezeScore. # 5. Manually enter each candidate's short float % (SI%) using TOS stock # details page, S3 Partners, or your usual source. This column feeds # the SqueezeScore but the technical flags work without it. # 6. Best candidates: Squeeze=1 AND PremkAboveVWAP=0 AND PremkVolPct > 1.5 # AND SI% > 25. input gapUpMin = 1.0; # min % gap up from prev close input gapUpMax = 12.0; # max % gap up (above this = news/pop already done) input volPctMin = 1.5; # min premarket volume as % of 1-day avg input vwAPBand = 0.75; # % band around VWAP where "hug" is valid input squeezeScoreMin = 1; # min score to show (1-5 scale) # ---- Price levels (premarket context) ---- def prevClose = Close[-1]; def open = Open; def high = High; def low = Low; def close = Close; def vol = Volume; def gapPct = if prevClose > 0 then (open - prevClose) / prevClose * 100.0 else Double.NaN; # ---- Pre-market VWAP approximation ---- # Built from the day's bars so far, so it includes premarket prints. def vwapCalc = if Sum(vol, 1) > 0 then Sum(close*vol, 1) / Sum(vol, 1) else Double.NaN; def vwapPctFromClose = if vwapCalc > 0 then (close - vwapCalc) / vwapCalc * 100.0 else Double.NaN; # ---- Pre-market volume as % of 1-day average ---- def avgVol1D = Average(vol, 22); # ~1 trading day of 1-min bars def volPct = if avgVol1D > 0 then vol / avgVol1D * 100.0 else Double.NaN; # ---- Pre-market range as % of prev close (narrow range = coiling) ---- def rangePct = if prevClose > 0 then (high - low) / prevClose * 100.0 else Double.NaN; # ---- Is price hugging/just under VWAP? ---- def huggingVWAP = vwapCalc > 0 and vwapPctFromClose >= -vwAPBand and vwapPctFromClose <= vwAPBand; # ---- Squeeze flags ---- def flagGap = gapPct >= gapUpMin and gapPct <= gapUpMax; def flagVol = volPct >= volPctMin; def flagHug = huggingVWAP; def flagNarrow = rangePct <= 2.5; # narrow range = coiling, ready to spring # ---- Squeeze score: 0-5 (add SI% manually in the column) ---- def score = (if flagGap then 1 else 0) + (if flagVol then 1 else 0) + (if flagHug then 1 else 0) + (if flagNarrow then 1 else 0) + 0; # SI% is manual - add +1 in your head if SI > 25 # ---- Composite squeeze signal ---- def squeezeSignal = flagGap and flagVol and flagHug and squeezeScore >= squeezeScoreMin; # ---- Output columns ---- plot Ticker = GetSymbol(); plot Symbol = GetSymbol(); plot SI_Pct = Double.NaN; # MANUAL: paste short float % per ticker plot Squeeze = squeezeSignal ? 1 : 0; plot GapPctOut = gapPct; plot PremkVol = vol; plot PremkVolPct = volPct; plot PremkRangePct = rangePct; plot PremkAboveVWAP = if vwapPctFromClose > 0 then 1 else 0; plot PremkVWAPPct = vwapPctFromClose; plot PremkBid = BidPrice; plot PremkAsk = AskPrice; plot PremkMid = (BidPrice + AskPrice) / 2; plot SqueezeScore = score; # ---- Scanner conditions (filter rows) ---- # Adjust to taste. Starting: at least a gap-up + elevated volume + VWAP hug. condition SqueezeSetup = squeezeSignal; condition GapUpOnly = flagGap and flagVol; condition VolSpikeOnly = flagVol;