All 3 scanners · copy/paste into ThinkorSwim · installation guide included · NVTS guard on every script
Scanner A — Primary
MASTER SCORE — STOCK SETUP
10-component 0-100 score. Checks price, liquidity, EMA stack, RSI zone, NVTS guard (5-day gain ceiling), Bollinger coil, volume build, relative strength, near-breakout position, and MACD direction. Hard disqualifiers force score to 0 for NVTS/BMBL-type situations.
Name it MasterScore → delete all default code → paste this script → OK
3
TOS → Scan → Stock Hacker → Add filter → Custom → Study Filter → select MasterScore
4
Set condition: plot MasterScore is greater than 65 · Add: Price $4-$12, Volume > 500,000
5
Save as OPERATOR-A-MasterScore · Sort by MasterScore descending · Review 80+ first
ThinkScript — paste into TOS Custom Column editor
# ================================================================
# SCANNER A: MASTER SCORE — STOCK SETUP FOUNDATION
# OPERATOR Trading System | 10 components x 10 pts = 100 max
# NVTS guard active: 5-day gain ceiling rejects extended stocks
# ================================================================input minPrice = 4.0;
input maxPrice = 12.0;
input minAvgVol = 1500000;
input rsiLow = 45;
input rsiHigh = 68;
input maxGain5Day = 18;
def price = close;
def avgVol = Average(volume, 20);
def relVol = volume / avgVol;
def ema9 = ExpAverage(close, 9);
def ema21 = ExpAverage(close, 21);
def ema50 = ExpAverage(close, 50);
def sma200 = Average(close, 200);
def rsiVal = RSI(length = 14).RSI;
def bbUpper = BollingerBands().UpperBand;
def bbLower = BollingerBands().LowerBand;
def bbWidth = (bbUpper - bbLower) / close * 100;
def high20 = Highest(high, 20);
def gain5 = (close - close[5]) / close[5] * 100;
def gain20 = (close - close[20]) / close[20] * 100;
def range10 = Highest(high, 10) - Lowest(low, 10);
def range30 = Highest(high, 30) - Lowest(low, 30);
def coiling = range10 < (range30 * 0.55);
def volNow5 = Average(volume, 5);
def volPrev = Average(volume[10], 5);
def volContr = volNow5 < volPrev * 0.85;
def macdLine = MACD().Value;
def macdSig = MACD().Avg;
def macdRise = macdLine > macdLine[3];
def spyNow = close(symbol = "SPY");
def spy20 = close(symbol = "SPY")[20];
def rsVsSpy = gain20 - (spyNow / spy20 - 1) * 100;
def s1 = if price >= minPrice and price <= maxPrice then10else0;
def s2 = if avgVol >= minAvgVol then10else if avgVol >= 800000then5else0;
def s3 = if ema9 > ema21 and ema21 > ema50 then10else if ema9 > ema21 then5else0;
def s4 = if rsiVal >= rsiLow and rsiVal <= rsiHigh then10else if rsiVal >= 40then5else0;
def s5 = if gain5 <= maxGain5Day and gain5 >= -8then10else if gain5 <= 25then3else0;
def s6 = if bbWidth < 12then10else if bbWidth < 18and coiling then10else if bbWidth < 22then5else0;
def s7 = if volContr and relVol >= 1.0then10else if relVol >= 1.2and relVol <= 4.0then7else if relVol >= 1.0then3else0;
def s8 = if rsVsSpy >= 5and rsVsSpy <= 30then10else if rsVsSpy >= 0then5else if rsVsSpy > 30then3else0;
def s9 = if close >= high20 * 0.92and close < high20 * 0.99then10else if close >= high20 * 0.85then5else0;
def s10 = if macdLine > macdSig and macdRise then10else if macdLine > macdSig then5else if macdRise then3else0;
def totalScore = s1+s2+s3+s4+s5+s6+s7+s8+s9+s10;
def hardFail = gain5 > 25or rsiVal > 75or close < sma200*0.90or avgVol < 300000;
plot MasterScore = if hardFail then0else totalScore;
MasterScore.AssignValueColor(if hardFail then Color.DARK_GRAY else if totalScore >= 80then Color.GREEN else if totalScore >= 65then Color.YELLOW else if totalScore >= 50then Color.ORANGE else Color.GRAY);
AddLabel(yes, "SCORE: " + totalScore + " P:"+s1+" L:"+s2+" T:"+s3+" R:"+s4+" E:"+s5+" C:"+s6+" V:"+s7+" RS:"+s8+" NB:"+s9+" M:"+s10, if hardFail then Color.DARK_GRAY else if totalScore >= 80then Color.GREEN else if totalScore >= 65then Color.YELLOW else Color.GRAY);
Scanner B — Options Layer
OPTIONS SCORE — IV + LIQUIDITY
Run on stocks scoring 80+ on Scanner A. Scores IV Rank, IV trend direction, options liquidity proxy, and premium affordability. Shows an action label: "Buy calls — ideal" or "Stock only — IV too high". Only trade options when B ≥ 70.
▼ SHOW CODE
1
Same as Scanner A — create a new Custom Column named OptionsScore
2
In Stock Hacker: add both filters — MasterScore > 80 AND OptionsScore > 70
3
Save as OPERATOR-B-OptionsScore · Only trade options when BOTH scanners agree
ThinkScript — paste into TOS Custom Column editor
# ================================================================
# SCANNER B: OPTIONS SCORE — OPTIONS ENVIRONMENT FILTER
# OPERATOR Trading System | Run on stocks scoring 80+ on Scanner A
# Only trade options when this score >= 70
# ================================================================def currentIV = imp_volatility();
def ivHigh52 = Highest(imp_volatility(), 252);
def ivLow52 = Lowest(imp_volatility(), 252);
def ivRange = ivHigh52 - ivLow52;
def ivRank = if ivRange > 0then (currentIV - ivLow52) / ivRange * 100else50;
def ivNow5 = Average(imp_volatility(), 5);
def ivPrior5 = Average(imp_volatility()[5], 5);
def ivRising = ivNow5 > ivPrior5 * 1.02;
def ivFalling = ivNow5 < ivPrior5 * 0.98;
def price = close;
def avgVol = Average(volume, 20);
def dteAdjust = 0.286;
def estPremium = price * (currentIV / 100) * dteAdjust * 0.4 * 100;
def ivScore = if ivRank < 20then40else if ivRank < 30then30else if ivRank < 50then15else if ivRank < 70then5else0;
def ivTrendScore = if ivRising and ivRank < 40then15else if !ivFalling then10else5;
def liqScore = if avgVol >= 5000000then25else if avgVol >= 3000000then20else if avgVol >= 1500000then15else if avgVol >= 800000then8else0;
def premScore = if estPremium <= 80then20else if estPremium <= 150then12else if estPremium <= 250then6else0;
def optionsTotal = ivScore + ivTrendScore + liqScore + premScore;
def optHardFail = ivRank > 70or currentIV <= 0or avgVol < 500000or price < 3.00;
plot OptionsScore = if optHardFail then0else optionsTotal;
OptionsScore.AssignValueColor(if optHardFail then Color.RED else if optionsTotal >= 85then Color.GREEN else if optionsTotal >= 70then Color.YELLOW else if optionsTotal >= 50then Color.ORANGE else Color.RED);
AddLabel(yes, "OPTIONS: "+optionsTotal+" IVR:"+Round(ivRank,0)+"% Est:$"+Round(estPremium,0), if optHardFail then Color.RED else if optionsTotal >= 85then Color.GREEN else if optionsTotal >= 70then Color.YELLOW else Color.ORANGE);
AddLabel(yes, if optHardFail then"ACTION: STOCK ONLY"else if optionsTotal >= 85then"BUY CALLS — ideal"else if optionsTotal >= 70then"BUY CALLS — good"else if optionsTotal >= 50then"STOCK PREFERRED"else"STOCK ONLY", if optHardFail then Color.RED else if optionsTotal >= 85then Color.GREEN else if optionsTotal >= 70then Color.YELLOW else Color.ORANGE);
Scanner C — Monday Morning
PRE-MARKET GAP SCANNER
Run 8:00–9:15 AM Monday only. Scores gap quality 0–10. Rejects BW (+13.69%), GRPN (+11.37%), BMBL (+53% prior run) — all correctly score 0. Only trade gaps scoring 8+ that were also on Sunday's watchlist from Scanner A.
▼ SHOW CODE
1
TOS → Scan → Stock Hacker → Add filter → Custom → Study Filter → paste this code
2
Name it GapScore · Condition: plot GapScan is greater than 5
3
Add: Price $3-$12, Volume > 500,000 · Save as OPERATOR-C-PreMarketGap
4
Run Monday 8:00–9:15 AM only. Do not run Sunday or during market hours.
ThinkScript — paste into TOS Stock Hacker study filter
The 4-step scan routine. Run Scanner A first every Sunday. Then B. Then C Monday morning. This sequence ensures you never buy an extended stock and always have the options environment checked before committing.
1
Sun 7:00 PM
Scanner A (Master Score) · Filter 65+ · Sort descending · Review green 80+ only
2
Sun 7:30 PM
Scanner B (Options Score) · Run on 80+ stocks · 70+ = calls OK · Under 50 = stock only
3
Sun 8:00 PM
Set TOS alerts · Price above 20-day high · Volume above 2× average
4
Mon 8-9:15 AM
Scanner C (Gap Score) · Run pre-market · 8+ AND on Sunday watchlist = trade it