Real Trading Script Examples

These scripts were generated by STP Market Pulse. Every example is real output from the generator — copy, paste into thinkorswim, and it works.

📈 Chart Study: VWAP Bounce + EMA Cross Chart Study
VWAP Bounce + EMA 9/20 Cross • AND mode

Draws buy arrows on your chart when price bounces off VWAP and the 9 EMA crosses above the 20 EMA at the same time. Includes indicator overlays, signal count label, and alerts. This is the most popular output type.

109 lines
#
# CHART STUDY: VWAP Bounce + EMA 9/20 Cross
#
# Script type:    Chart Study (upper chart)
# Patterns:       VWAP Bounce, EMA 9/20 Cross
# Mode:           AND — ALL patterns must fire on the same bar
# Generated:      2026-10-10
# Source:         STP Market Pulse Generator
#
# SIGNAL TIMING:
#   - Conditions evaluate on COMPLETED bars only.
#   - Signal arrow appears on the bar where conditions are met.
#   - Alert fires at bar completion, not intra-bar.
#   - No future data is used. No repainting.
#
# NO STATISTICAL EDGE VERIFIED.
# This script implements pattern detection rules. It does not
# guarantee profitability. Backtest and validate before use.

declare upper;

# — User Inputs —
input showSignals    = yes;
input showBubbles    = yes;
input showAlerts     = yes;
input colorCandles   = no;
input showIndicators = yes;
input rthOnly        = yes;
input minBarNumber   = 20;

# — Session Filter —
def isRTH = if rthOnly then SecondsFromTime(0930) >= 0 and SecondsTillTime(1600) > 0 else yes;
def hasHistory = BarNumber() >= minBarNumber;

# — Indicator Calculations —
def vwapVal = VWAP();
def ema9 = ExpAverage(close, 9);
def ema20 = ExpAverage(close, 20);

# — Signal Logic (AND) —
def rawSignal = (low <= vwapVal and close > vwapVal and close > open) and (ema9 crosses above ema20);
def signal = rawSignal and isRTH and hasHistory;

# — Signal Markers —
plot BuyArrow = if showSignals and signal then low * 0.997 else Double.NaN;
BuyArrow.SetPaintingStrategy(PaintingStrategy.ARROW_UP);
BuyArrow.SetDefaultColor(Color.GREEN);
BuyArrow.SetLineWeight(3);
BuyArrow.HideBubble();

plot SignalDot = if showSignals and signal then close else Double.NaN;
SignalDot.SetPaintingStrategy(PaintingStrategy.POINTS);
SignalDot.SetLineWeight(5);
SignalDot.AssignValueColor(if close > open then Color.GREEN else Color.RED);
SignalDot.HideBubble();
SignalDot.HideTitle();

# — Chart Bubbles —
AddChartBubble(showBubbles and signal, low * 0.995, "VWAP Bounce + EMA 9/20 Cross", Color.GREEN, no);

# — Candle Coloring —
AssignPriceColor(if !colorCandles then Color.CURRENT
  else if signal and close > open then Color.GREEN
  else if signal and close <= open then Color.RED
  else Color.CURRENT);

# — Indicator Overlays —
plot pVwap = if showIndicators then vwapVal else Double.NaN;
pVwap.SetDefaultColor(Color.ORANGE);
pVwap.SetStyle(Curve.FIRM);
pVwap.SetLineWeight(2);
pVwap.HideBubble();
plot pEma9 = if showIndicators then ema9 else Double.NaN;
pEma9.SetDefaultColor(Color.CYAN);
pEma9.SetLineWeight(2);
pEma9.HideBubble();
plot pEma20 = if showIndicators then ema20 else Double.NaN;
pEma20.SetDefaultColor(Color.YELLOW);
pEma20.SetLineWeight(2);
pEma20.HideBubble();
AddCloud(pEma9, pEma20, Color.DARK_GREEN, Color.DARK_RED);

# — Signal Count Label —
def sigCount = TotalSum(if signal then 1 else 0);
AddLabel(showSignals, "Signals: " + sigCount, if sigCount > 0 then Color.GREEN else Color.GRAY);

# — Alert —
Alert(showAlerts and signal, "STP Signal: VWAP Bounce + EMA 9/20 Cross", Alert.BAR, Sound.Ding);
  1. Open thinkorswim and go to Studies > Edit Studies
  2. Click Create to open a new study editor
  3. Delete any existing code and paste the script above
  4. Click OK to save
  5. Click Apply to add it to your chart
🔍 Scanner: Hammer + High Volume Scanner
Hammer + Elevated Relative Volume • AND mode

Scans the entire market for stocks showing a hammer candle with above-average volume. Paste into Stock Hacker to find potential reversal candidates in real time.

28 lines
#
# SCANNER QUERY: Pattern Combo
#
# Script type:    Stock Hacker Scan (Custom Study filter)
# Patterns:       Hammer, Elevated Relative Volume
# Mode:           AND
# Generated:      2026-10-10
#
# INSTALLATION:
#   1. TOS > Scan > Stock Hacker
#   2. Add filter > Study > Custom
#   3. Paste this code
#   4. Set aggregation to match your intended timeframe
#   5. Set "is true" in the filter condition
#
# LIMITATIONS:
#   - Scanner evaluates on the most recent completed bar only.
#   - Some functions have restricted availability in scanner.
#   - If compilation fails, simplify or split into multiple scans.
#
# NO STATISTICAL EDGE VERIFIED.

# — Scan Condition (AND) —
plot scan = (AbsValue(close - open) > 0 and (Min(open, close) - low) >= 2 * AbsValue(close - open) and (high - Max(open, close)) <= AbsValue(close - open) * 0.5) and (volume > 2 * Average(volume, 20));
  1. Open thinkorswim and go to Scan > Stock Hacker
  2. Click Add Study Filter > Custom
  3. Paste the script above
  4. Set the filter condition to "is true"
  5. Click Scan to find matching stocks
⚙ Strategy: Bullish Engulfing + RSI Oversold Strategy
Bullish Engulfing + RSI Oversold Cross Up • AND mode

Simulates buying when a bullish engulfing candle appears while RSI crosses back above 30. Includes profit target (1.5%), stop loss (0.6%), and end-of-day exit. Shows entry/exit bubbles, target/stop lines, and a P/L cloud. Does NOT place real orders.

123 lines
#
# STRATEGY: Pattern Combo Backtest
#
# Script type:    Strategy (upper chart)
# Patterns:       Bullish Engulfing, RSI Oversold Cross Up
# Mode:           AND
# Position:       Long only, one position at a time
# Generated:      2026-10-10
#
# SIGNAL TIMING:
#   - Entry signal evaluates on completed bars.
#   - Simulated fill occurs at NEXT BAR OPEN (TOS default).
#   - This is NOT a live order. AddOrder simulates trades
#     for backtesting only. It does not place broker orders.
#
# EXIT RULES:
#   - Profit target: configurable % above entry (default 1.5%)
#   - Stop loss: configurable % below entry (default 0.6%)
#   - Time exit: closes at session end (EOD)
#   - Two consecutive lower closes also trigger exit
#
# NO STATISTICAL EDGE VERIFIED.

# — User Inputs —
input targetPct       = 1.5;
input stopPct         = 0.6;
input tradeSize       = 100;
input rthOnly         = yes;
input closeAtEOD      = yes;
input minBarNumber    = 20;

# — Session Filter —
def isRTH = if rthOnly then SecondsFromTime(0930) >= 0 and SecondsTillTime(1600) > 0 else yes;
def isEOD = SecondsTillTime(1555) <= 0 and SecondsTillTime(1600) > 0;
def hasHistory = BarNumber() >= minBarNumber;

# — Indicator Calculations —
def rsiVal = RSI(length = 14);

# — Entry Signal (AND) —
def rawBuySignal = (close > open and close[1] < open[1] and open <= close[1] and close >= open[1]) and (rsiVal[1] < 30 and rsiVal >= 30);
def buySignal = rawBuySignal and isRTH and hasHistory;

# — Exit Signals —
def exitLowerCloses = close < close[1] and close[1] < close[2];
def entryPx = EntryPrice();
def targetHit = entryPx > 0 and close >= entryPx * (1 + targetPct / 100);
def stopHit   = entryPx > 0 and close <= entryPx * (1 - stopPct / 100);
def eodExit = closeAtEOD and isEOD;
def sellSignal = exitLowerCloses or targetHit or stopHit or eodExit;

# — Simulated Orders (backtest only) —
AddOrder(OrderType.BUY_TO_OPEN, buySignal, open[-1], tradeSize, Color.GREEN, Color.GREEN, "BUY: Pattern Signal");
AddOrder(OrderType.SELL_TO_CLOSE, sellSignal, open[-1], tradeSize, Color.RED, Color.RED, "SELL: Exit");

# — Target & Stop Lines —
def inPosition = entryPx > 0;
plot TargetLine = if inPosition then entryPx * (1 + targetPct / 100) else Double.NaN;
TargetLine.SetDefaultColor(Color.GREEN);
TargetLine.SetStyle(Curve.SHORT_DASH);
TargetLine.SetLineWeight(2);
TargetLine.HideBubble();
TargetLine.HideTitle();

plot StopLine = if inPosition then entryPx * (1 - stopPct / 100) else Double.NaN;
StopLine.SetDefaultColor(Color.RED);
StopLine.SetStyle(Curve.SHORT_DASH);
StopLine.SetLineWeight(2);
StopLine.HideBubble();
StopLine.HideTitle();

plot EntryLine = if inPosition then entryPx else Double.NaN;
EntryLine.SetDefaultColor(Color.YELLOW);
EntryLine.SetStyle(Curve.FIRM);
EntryLine.SetLineWeight(1);
EntryLine.HideBubble();
EntryLine.HideTitle();

AddCloud(TargetLine, EntryLine, Color.DARK_GREEN, Color.DARK_GREEN);
AddCloud(EntryLine, StopLine, Color.DARK_RED, Color.DARK_RED);

AddChartBubble(buySignal, low * 0.995, "ENTRY", Color.GREEN, no);
AddChartBubble(sellSignal and inPosition and targetHit, high * 1.005, "TARGET", Color.GREEN, yes);
AddChartBubble(sellSignal and inPosition and stopHit and !targetHit, high * 1.005, "STOP", Color.RED, yes);
AddChartBubble(sellSignal and inPosition and eodExit and !targetHit and !stopHit, high * 1.005, "EOD", Color.YELLOW, yes);
  1. Open thinkorswim and go to Studies > Edit Studies
  2. Click Create to open a new study editor
  3. Delete any existing code and paste the script above
  4. Make sure the script type is set to "Strategy"
  5. Click OK to save, then Apply
  6. Check the Strategy Report tab for backtest results
📋 Watchlist Column: Squeeze Release + Volume Spike Watchlist
TTM Squeeze Release + Volume Spike • OR mode

Adds a custom column to your watchlist that shows 'YES' in green when either a TTM squeeze releases or volume spikes 3x above average. Quickly scan your watchlist for actionable setups.

36 lines
#
# WATCHLIST COLUMN: Pattern Combo
#
# Script type:    Custom Quote / Watchlist Column
# Patterns:       TTM Squeeze Release, Volume Spike (vs Prior Bars)
# Mode:           OR
# Generated:      2026-10-10
#
# INSTALLATION:
#   1. TOS > Watchlist > Customize > Custom Quotes
#   2. Click pencil icon > thinkScript Editor
#   3. Paste this code > OK > Add to watchlist
#   4. Set aggregation in column header (right-click)
#
# The column displays:
#   "YES" (green) when pattern is active
#   "no"  (gray)  when pattern is not active

def bbUp = BollingerBands(length = 20).UpperBand;
def bbDn = BollingerBands(length = 20).LowerBand;
def kcUp = ExpAverage(close, 20) + 1.5 * Average(TrueRange(high, close, low), 20);
def kcDn = ExpAverage(close, 20) - 1.5 * Average(TrueRange(high, close, low), 20);
def sqzOn = bbDn > kcDn and bbUp < kcUp;

def patternSignal = (sqzOn[1] and !sqzOn) or (volume >= 3 * Average(volume, 10)[1]);

plot col = patternSignal;
col.AssignValueColor(if patternSignal then Color.GREEN else Color.GRAY);
AssignBackgroundColor(if patternSignal then Color.DARK_GREEN else Color.CURRENT);
  1. Right-click a watchlist column header
  2. Select Customize > Create Custom Quote
  3. Paste the script above
  4. Click OK to add the column
🔔 Alert: Support Bounce + Volume Expansion Alert
Support Bounce + Rising Price with Expanding Volume • OR mode • Morning session

Sends an audio alert when price bounces off a 20-bar support level or when price rises with expanding volume during the morning session. No chart clutter — works great on TOS Mobile.

27 lines
#
# ALERT-ONLY STUDY (minimal — no chart clutter)
#
# Patterns: Support Bounce, Rising Price + Expanding Volume
# Mode:     OR
# Generated: 2026-10-10
#
# INSTALLATION:
#   1. TOS > Studies > Edit Studies > Create
#   2. Paste this code > Apply
#   3. Study Settings > Alerts tab > Enable alerts
#   4. Works on TOS Desktop and Mobile

input rthOnly = yes;
def isRTH = if rthOnly then SecondsFromTime(0930) >= 0 and SecondsTillTime(1600) > 0 else yes;

def supLevel = Lowest(low, 20)[1];

def alertSignal = (low <= supLevel * 1.002 and close > supLevel and close > open) or (close > close[1] and close[1] > close[2] and volume > volume[1] and volume[1] > volume[2]) and isRTH;

Alert(alertSignal, "Support Bounce + Rising Price + Expanding Volume", Alert.BAR, Sound.Ding);

# Alerts only — no chart overlays. Lightweight for TOS Mobile.
  1. Open thinkorswim and go to Studies > Edit Studies
  2. Click Create to open a new study editor
  3. Paste the script above and click Apply
  4. Go to Study Settings > Alerts tab and enable alerts
  5. Works on TOS Desktop and Mobile

Ready to build your own?