Culgan Wealth
Simple Screener v1
Pine Script® v6 TradingView

Simple Screener v1 — Pine Script® v6

This script scores every stock on your TradingView watchlist from 0 to 5 based on five technical conditions. Only trade stocks scoring 4 or 5. Copy the script below, paste it into TradingView's Pine Editor, and follow the setup guide.

Score Interpretation

What each score means and what to do

5 / 5
Perfect Setup
Run through full Trade Setup checklist immediately
4 / 5
Strong Setup
Add to watchlist — check which condition failed
3 / 5
Neutral
Monitor only — do not trade yet
2 / 5
Weak
Skip — too many conditions failing
0–1 / 5
Avoid
Do not trade — stock is not in a healthy trend

The 5 Conditions Explained

Click each condition to see the full logic

TradingView Setup Guide

Step-by-step — takes less than 5 minutes

01
Open TradingView Pine Editor
Go to TradingView.com → open any chart → click the 'Pine Editor' tab at the bottom of the screen.
02
Paste the script
Delete any existing code in the editor. Click the 'Copy Script' button above, then paste (Ctrl+V / Cmd+V) into the Pine Editor.
03
Add to chart
Click 'Add to chart' (play button). The AA Score indicator will appear as a panel below your price chart showing bars 0–5.
04
Add to Favourites
Click the star ★ icon next to the indicator name in the chart. This makes it available in the Pine Screener.
05
Open Pine Screener
Go to TradingView → Screener (bottom toolbar) → click 'Pine Screener' tab → select 'AA Simple Screener v1' from your favourites.
06
Filter by Score ≥ 4
In the Pine Screener, add a filter: Score ≥ 4. These are your high-quality setups. Score 5/5 = strongest signal.

TradingView Pro required for the Pine Screener feature. The indicator itself works on any plan — you can manually check the score on individual charts for free.

Pine Script® v6 Source Code

Copy and paste into TradingView Pine Editor

AA Simple Screener v1.pinev6
// Jessie's Simple Screener
// Culgan Wealth | Pine Script v6
// Scores each stock 0-5 across five conditions.
// Score 4-5 = TAKE A LOOK | 3 = NEUTRAL | 0-2 = SKIP
// HOW TO USE: Pine Editor > Add to chart > Star it > Open Screener > Pine Screener > filter Score >= 4

//@version=6
indicator("Jessie's Simple Screener", shorttitle="Jessie Score", overlay=false, max_bars_back=500)

// INPUTS
emaFastLen = input.int(21, "Fast EMA Length", group="EMA", minval=1)
emaSlowLen = input.int(50, "Slow EMA Length", group="EMA", minval=1)
rsiLen = input.int(14, "RSI Length", group="RSI", minval=1)
rsiThresh = input.float(40, "RSI Min Threshold", group="RSI", minval=1, maxval=100)
obvMaLen = input.int(20, "OBV MA Length", group="OBV", minval=1)
volMaLen = input.int(20, "Volume MA Length", group="Volume", minval=1)
swingLen = input.int(10, "Swing Lookback", group="Structure", minval=3)

// COLOURS
C_CYAN = color.rgb(0, 212, 170)
C_GREEN = color.rgb(34, 197, 94)
C_YELLOW = color.rgb(234, 179, 8)
C_ORANGE = color.rgb(249, 115, 22)
C_RED = color.rgb(239, 68, 68)
C_NAVY = color.rgb(13, 20, 33)
C_SLATE = color.rgb(148, 163, 184)
C_LIGHT = color.rgb(203, 213, 225)
C_WHITE = color.rgb(255, 255, 255)
C_BORDER = color.rgb(30, 58, 95)

// CONDITION 1 - Market Structure: Higher Highs and Higher Lows
pivotHigh = ta.pivothigh(high, swingLen, swingLen)
pivotLow = ta.pivotlow(low, swingLen, swingLen)
var float prevHigh1 = na
var float prevHigh2 = na
if not na(pivotHigh)
    prevHigh2 := prevHigh1
    prevHigh1 := pivotHigh
var float prevLow1 = na
var float prevLow2 = na
if not na(pivotLow)
    prevLow2 := prevLow1
    prevLow1 := pivotLow
higherHigh = not na(prevHigh1) and not na(prevHigh2) and prevHigh1 > prevHigh2
higherLow = not na(prevLow1) and not na(prevLow2) and prevLow1 > prevLow2
cond1 = higherHigh and higherLow

// CONDITION 2 - EMA Trend Filter: Price above EMA21 and EMA50
emaFast = ta.ema(close, emaFastLen)
emaSlow = ta.ema(close, emaSlowLen)
cond2 = close > emaFast and close > emaSlow and emaFast > emaSlow

// CONDITION 3 - OBV Momentum: OBV above 20-bar MA
obv = ta.obv
obvMa = ta.sma(obv, obvMaLen)
cond3 = obv > obvMa

// CONDITION 4 - RSI Strength: RSI above threshold
rsiVal = ta.rsi(close, rsiLen)
cond4 = rsiVal > rsiThresh

// CONDITION 5 - Volume Surge: Volume above 20-day average
volMa = ta.sma(volume, volMaLen)
cond5 = volume > volMa

// SCORE
score = (cond1 ? 1 : 0) + (cond2 ? 1 : 0) + (cond3 ? 1 : 0) + (cond4 ? 1 : 0) + (cond5 ? 1 : 0)

// SCORE COLOUR
scoreColor = score >= 5 ? C_CYAN : score == 4 ? C_GREEN : score == 3 ? C_YELLOW : score == 2 ? C_ORANGE : C_RED

// CONDITION COLOUR FUNCTION
condColor(c) => c ? color.new(C_CYAN, 20) : color.new(C_RED, 40)

// PLOTS - data window only, no chart clutter
plot(cond1 ? 1 : 0, "1. Market Structure", condColor(cond1), display=display.data_window)
plot(cond2 ? 1 : 0, "2. EMA Trend Filter", condColor(cond2), display=display.data_window)
plot(cond3 ? 1 : 0, "3. OBV Momentum", condColor(cond3), display=display.data_window)
plot(cond4 ? 1 : 0, "4. RSI Strength", condColor(cond4), display=display.data_window)
plot(cond5 ? 1 : 0, "5. Volume Surge", condColor(cond5), display=display.data_window)

// TABLE
var table t = table.new(position.top_right, 2, 7, bgcolor=color.new(C_NAVY, 10), border_color=color.new(C_BORDER, 80), border_width=1, frame_color=color.new(C_CYAN, 60), frame_width=1)

if barstate.islast
    table.cell(t, 0, 0, "Jessie's Simple Screener", text_color=C_CYAN, text_size=size.small, bgcolor=C_NAVY, text_halign=text.align_left)
    table.cell(t, 1, 0, "Culgan Wealth", text_color=C_SLATE, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_right)
    table.cell(t, 0, 1, "1. Market Structure", text_color=C_LIGHT, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_left)
    table.cell(t, 1, 1, cond1 ? "YES" : "NO", text_color=cond1 ? C_CYAN : C_RED, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_center)
    table.cell(t, 0, 2, "2. EMA Trend Filter", text_color=C_LIGHT, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_left)
    table.cell(t, 1, 2, cond2 ? "YES" : "NO", text_color=cond2 ? C_CYAN : C_RED, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_center)
    table.cell(t, 0, 3, "3. OBV Momentum", text_color=C_LIGHT, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_left)
    table.cell(t, 1, 3, cond3 ? "YES" : "NO", text_color=cond3 ? C_CYAN : C_RED, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_center)
    table.cell(t, 0, 4, "4. RSI Strength", text_color=C_LIGHT, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_left)
    table.cell(t, 1, 4, cond4 ? "YES" : "NO", text_color=cond4 ? C_CYAN : C_RED, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_center)
    table.cell(t, 0, 5, "5. Volume Surge", text_color=C_LIGHT, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_left)
    table.cell(t, 1, 5, cond5 ? "YES" : "NO", text_color=cond5 ? C_CYAN : C_RED, text_size=size.tiny, bgcolor=C_NAVY, text_halign=text.align_center)
    scoreLabel = score >= 4 ? str.tostring(score) + "/5 TAKE A LOOK" : score == 3 ? str.tostring(score) + "/5 NEUTRAL" : str.tostring(score) + "/5 SKIP"
    table.cell(t, 0, 6, "TOTAL SCORE", text_color=C_WHITE, text_size=size.small, bgcolor=C_NAVY, text_halign=text.align_left)
    table.cell(t, 1, 6, scoreLabel, text_color=scoreColor, text_size=size.small, bgcolor=C_NAVY, text_halign=text.align_center)

// BACKGROUND HIGHLIGHT for score 4+
bgcolor(score >= 4 ? color.new(C_CYAN, 95) : na, title="Strong Setup Highlight")

// SCREENER EXPORT
plot(score, "Score", display=display.none)
plot(rsiVal, "RSI", display=display.none)
plot(close / emaSlow * 100, "Price vs EMA50", display=display.none)