A terminal-based NSE stock screener/scanner, built by Khushal Jain, in the spirit of the open-source PKScreener project β same menu-driven flow (Scanners β Index β Criteria β Reversal Signals β Backtests), rebranded and rebuilt from scratch under a new name so it's fully yours to run, tweak, and extend.
β οΈ For learning / educational purposes only. Nothing here is investment advice. Past backtest performance never guarantees future results, and no screener or AI feature can promise a specific accuracy.
pip install -r requirements.txt
python main.pyNo internet? No problem β test everything with synthetic data first:
Here is a sneak peek of the powerful UI and features of the KJ Screener:
.png)
1. Main Dashboard & Real-Time Screener π
.png)
2. Advanced Technical Indicators & Charts π
.png)
3. Strategy Backtester & Performance Logs β‘
.png)
4. AI-powered Market Insights & Second Opinions π§
.png)
5. Easy Config & AI Setup Panel βοΈ
python main.py --demokjscreener/
βββ main.py # menu navigation / entry point
βββ requirements.txt
βββ requirements-optional.txt # only needed for the pywhatkit WhatsApp method
βββ watchlist.txt # sample watchlist (edit with your own NSE codes)
βββ kj_screener/
β βββ banner.py # ASCII banner ("KJ Screener")
β βββ config.py # scan-profile config + shared AI/WhatsApp settings
β βββ stocklists.py # bundled Nifty50...500, Smallcap/Midcap/F&O/IPOs
β βββ data.py # yfinance live fetch (daily + intraday) + demo data
β βββ indicators.py # RSI (Wilder), MACD, CCI, Aroon, ADX/+DI/-DI, trend
β βββ pivots.py # Camarilla / Fibonacci / Classic pivot levels
β βββ advisory.py # rules-based recommendation + English narrative
β βββ scanner.py # all screening criteria + 5-EMA cross signal
β βββ ai_predictor.py # optional OpenAI integration (Gap/BTST/STBT)
β βββ instruments.py # index/commodity dashboard instrument mapping
β βββ backtest.py # historical "summary of correctness" + Growth of 10k
β βββ alerts.py # WhatsApp (Twilio / pywhatkit)
β βββ nse_api.py # NSE option-chain experiment (unused by default)
β βββ ui.py # colored tables, progress bar, prompts
Main Menu
ββ X > Scanners
β ββ W > Screen stocks from my own Watchlist
β ββ N > Nifty Prediction using AI (Gap-Up/Gap-Down/BTST/STBT) - needs
β β an OpenAI key, see "AI Setup" below. This "N" is local to the
β β Scanners menu - different from the main menu's own "N >
β β Notify Mode" a few levels up.
β ββ E > Live Index Scan: 5 EMA for Intraday (also menu-local, distinct
β β from the main menu's "E > Edit user configuration")
β ββ 0 > Screen by NSE stock code
β ββ 1-11,13,14 > Nifty 50 / Next 50 / 100 / 200 / 500 / Smallcap
β β 50/100/250 / Midcap 50/100/150 / Newly Listed (IPOs) / F&O
β ββ (blank/Enter) > All Stocks (default)
β ββ Choose Criterion:
β 0 Full Screening 15 52wk low breakout
β 1 Probable Breakouts 17 52wk high breakout
β 2 Today's Breakouts 18 Bullish Aroon Crossover
β 3 Consolidating stocks 19 MACD Histogram below 0
β 4 Lowest volume in N-days 20 Bullish for next day
β 5 RSI screening 21 Most Popular Stocks
β 6 Reversal Signals ββ 23 Breaking out now
β 7 Chart Patterns β 24 Higher Highs/Lows/Close
β 9 Volume gainers β 25 Lower Highs/Lows
β 10 2%-up-3-days β 26 RSI>30 & price>EMA(proxy for PSAR)
β 14 NR4 Daily Today β 27 Intraday Momentum Build-up
β β 28 Extremely bullish close
β β 29 Rising RSI
β β 30 RSI entering bullish territory
β ββ 1 Buy Signal (Bullish Reversal)
β 2 Sell Signal (Bearish Reversal)
β 3 Momentum Gainers
β 4 Reversal at Moving Average
β 5 Volume Spread Analysis (VSA)
β 6 Narrow Range (NRx) Reversal
β 7 Lorentzian Classifier (simplified proxy)
β
ββ B > Backtests (Growth of 10k) - runs the chosen criterion over each
β stock's full downloaded history and reports forward 1/2/3/4/5/10/
β 15/22/30-day % returns, an overall correctness summary, and a
β simulated "Growth of βΉ10,000" for a 30-day hold.
β
ββ O > Live Dashboard - RSI/ADX/+DI/-DI on a timeframe you pick (5-Minute,
β 15-Minute, or Daily), Camarilla + Fibonacci + Classic pivots, a
β support/resistance summary, a plain-English analysis paragraph,
β and a transparent rules-based Buy/Sell/Hold recommendation - for
β NIFTY 50 / NIFTY BANK / NIFTY FIN SERVICE, Crude Oil / Natural Gas
β (with both USD and MCX-equivalent INR prices), or any F&O stock
β you type in. See the section below before trusting this with
β real money.
β
ββ I > Index & Commodity Scanner - simpler technical bias (Bullish/
β Bearish/Neutral) for indices + Crude Oil/Natural Gas.
β
ββ N > Notify Mode - re-runs a chosen scan on a timer (e.g. every 15 min)
β and sends a WhatsApp message ONLY when a genuinely NEW stock
β appears in the results (no repeat spam for stocks already alerted).
β Press Ctrl+C to stop.
β
ββ A > Alerts Setup (WhatsApp) - configure Twilio or pywhatkit, test-send
ββ G > AI Setup (OpenAI) - add your key once; powers the Scanners' "N >
β Nifty Prediction using AI" feature
β
ββ T > Toggle Long-term / Intraday configuration
ββ E > Edit user configuration (min/max price, volume multiple, etc.)
ββ Y > View current configuration
ββ Q > Quit
After any scan or backtest with matches, KJ Screener asks:
Send this result as a WhatsApp alert? (Y/N). There's also Notify Mode
(N from the main menu) for hands-free monitoring: it re-scans on a timer
and WhatsApps you only when a new stock shows up.
Set it up once via A > Alerts Setup:
Your WhatsApp number is pre-filled as the default in both methods below - you'll just need to add credentials (Twilio) or confirm the number (pywhatkit) and you're set.
-
Twilio (recommended) - works on a headless server, no browser needed.
- Free account at https://www.twilio.com/try-twilio
- Console β Messaging β Try it out β Send a WhatsApp message β join your sandbox by messaging the given code from your own WhatsApp
- Copy your Account SID + Auth Token from the Twilio Console home
- Paste those into KJ Screener's Alerts Setup, along with your WhatsApp
number as
whatsapp:+91XXXXXXXXXX - Note: Twilio's free sandbox needs you to re-join every ~72 hours (send the join code again); a paid WhatsApp Business number removes that.
-
pywhatkit (quick & dirty) - uses your own logged-in WhatsApp Web session in a real browser on the same machine. No API account, but needs a desktop (not headless) and momentarily opens a browser tab per message. Install with
pip install -r requirements-optional.txtfirst.
Set up once via G > AI Setup from the main menu. Three providers, pick
whichever suits you - the first two are genuinely free:
-
Gemini (Google) - free, hosted, recommended if you don't want to install anything.
- Get a free key (no credit card needed) at https://aistudio.google.com/app/apikey
- Paste it into
G > AI Setup > 1 - Default model
gemini-2.0-flashis fast and comfortably within the free tier for casual/personal use
-
Ollama - completely free, runs on your own computer, no API key at all. Best if you'd rather not create any account anywhere.
- Install from https://ollama.com (free)
- In a terminal:
ollama pull llama3.2(one-time download, a few GB) - Make sure Ollama is running (it usually auto-starts, or run
ollama serve) - In KJ Screener:
G > AI Setup > 2, accept the defaults This never leaves your machine and has no usage limits/cost, but needs a reasonably capable computer (a few GB RAM free) and the model download.
-
OpenAI - only if you already have a paid/billed account. This is the one that gives
insufficient_quotaerrors on a brand-new key with no billing set up - OpenAI's API is pay-per-use with no meaningful free tier, unlike the two options above.
Once any provider is configured, X > Scanners > N > Nifty Prediction using AI becomes usable - it feeds your already-computed RSI/ADX/DI/pivot
numbers to the AI and asks for a plain-English Gap-Up/Gap-Down and
BTST/STBT read for Nifty/Bank Nifty/Fin Service/any stock you type in.
What this is, honestly: the AI is reading the SAME numbers already
computed by this tool (RSI, ADX/DI, trend, pivots) and writing a
natural-language interpretation of them - it is not a separately-trained
predictive model, has no special ability to foresee market direction, and
every response should be read as commentary, not a signal. This holds
regardless of which of the three providers you pick. Nothing is sent
anywhere unless you configure a provider yourself; without one, N says
so clearly and does nothing else.
O from the main menu combines:
- RSI(14), ADX(14), +DI, -DI - on a timeframe YOU choose: 5-Minute, 15-Minute, or Daily. This matters more than it sounds: a daily RSI/ADX will never match what your broker shows on a 5-min intraday chart, since they're measuring completely different windows of price action. Pick 5-Minute or 15-Minute to match what you see on an intraday chart.
- Camarilla, Fibonacci, and Classic pivots - always computed from the previous COMPLETED day's High/Low/Close (the standard convention for all three), regardless of which RSI/ADX timeframe you picked above.
- A support/resistance summary pulled from all three pivot sets
- A plain-English analysis paragraph describing the bias, momentum
reading, and today's pivot/breakout/reversal/support levels in one
readable note - built from the exact numbers shown above it, in
kj_screener/advisory.py::generate_narrative() - A transparent Buy/Sell/Hold recommendation - every rule that
contributed to the score is printed right below it, in
kj_screener/advisory.py::generate_recommendation() - Crude Oil / Natural Gas: both the global USD futures price (Yahoo
Finance CL=F / NG=F) AND an MCX-equivalent INR price, computed as
USD price x live USD/INR rate- clearly labeled as an approximation, not the live MCX exchange-traded price (MCX has no free public data feed).
Removed on purpose: an earlier build of this tool attempted a live NSE
option-chain table (strike/CE/PE premium, PCR, Max Pain) by scraping
nseindia.com. It was hitting NSE's rate-limiting/blocking too often to be
worth keeping, so it's gone from the Live Dashboard. The code for it is
still in kj_screener/nse_api.py if you want to experiment with it later,
it's just not called from the main flow - so you get a dashboard that
works every time instead of one that's sometimes broken.
On accuracy - the honest answer: the Buy/Sell/Hold call and the analysis paragraph are a transparent combination of well-known technical rules, not a prediction. No screener, including this one, can promise a specific accuracy - markets are genuinely uncertain. Use it as one input, verify live prices on your broker terminal, and manage your own risk.
I from the main menu gives a live technical bias (Bullish / Bearish /
Neutral) for NIFTY 50, NIFTY BANK, SENSEX, NIFTY FIN SERVICE, Crude Oil,
and Natural Gas, built from the same RSI/MACD/MA/Trend/Aroon indicators as
the stock scanner. For indices it also shows a reference ATM strike
(spot price rounded to the standard interval) - not a live option premium
(see the Live Dashboard section above for why that's not available free).
stocklists.py includes Nifty 50/Next 50/100/200/500 (approximate),
Smallcap 50/100/250, Midcap 50/100/150, Newly Listed (recent IPOs), and an
expanded F&O-only set. These are curated/best-effort, not a live feed - the
real indices' membership drifts over time. Treat them as a solid starting
point; edit stocklists.py yourself, or use your own watchlist.txt /
custom-codes option, whenever you notice drift. A renamed/delisted stock
just fails to fetch gracefully (see "Fixed: TATAMOTORS ticker" below)
rather than crashing anything.
- RSI now uses Wilder's RMA smoothing, not a plain rolling average - matches TradingView/broker values (verified to 0.0 difference over the most recent ~50 bars of a 280-day series against a textbook-exact implementation).
- 52-week High/Low uses the actual High/Low columns, not Close, AND
the historical fetch uses
auto_adjust=False- Yahoo's default dividend adjustment was quietly shifting historical prices away from what your broker shows. - RSI/ADX/+DI/-DI timeframe is selectable (5-Minute/15-Minute/Daily) - a daily-candle RSI will never match an intraday chart; this was the real reason those numbers looked "wrong" before, not a bug.
- Noisy yfinance console spam is suppressed - failed/delisted lookups
used to dump raw
HTTP Error 404/possibly delistedtext straight to your terminal even though KJ Screener was already handling the failure correctly; now you only see its own clean messages. - AI/WhatsApp settings are shared globally across the Long-term/
Intraday config toggle (
T), stored in their ownconfig_integrations.json- configuringG/Aonce means it stays configured no matter which mode you're in. - Fixed a dispatch bug: the main menu used to print a
G > AI Setupoption that silently did nothing when selected (missing from the dispatch logic) - found via testing, now wired up correctly.
Tata Motors demerged in OctβNov 2025: the passenger-vehicle + EV + JLR
business kept the listed entity and was renamed Tata Motors Passenger
Vehicles Ltd, now trading under ticker TMPV; the commercial-vehicle
business was spun off separately as TMCV. The old TATAMOTORS ticker no
longer trades, which is why it was failing before.
This build now uses TMPV directly in the bundled Nifty 50 list, and
auto-redirects any leftover TATAMOTORS references (e.g. in your own
watchlist.txt) to TMPV via SYMBOL_ALIASES in kj_screener/stocklists.py.
- Data source: live mode uses
yfinance(Yahoo Finance) with theSYMBOL.NSsuffix for NSE stocks. It's free and needs no API key, but Yahoo can occasionally rate-limit or time out β every fetch has retries, and any stock that still fails is simply skipped (with a clear reason shown), so one bad symbol never crashes your scan. Failed symbols are cached briefly so repeated scans don't keep retrying a dead ticker. - "Lorentzian Classifier" in the Reversal Signals sub-menu is a simplified stand-in built from RSI/CCI/Aroon, not the original TradingView indicator - labeled as a proxy in the code and output.
- I tested this repeatedly in
--demomode (synthetic data, zero internet) across every menu path, plus scripted end-to-end runs covering every scanner, backtest, dashboard, and settings flow - all with zero crashes. I could not test the live Yahoo Finance fetch or the OpenAI API call from my own build environment (no internet access to those services from there) - please runpython main.pyonce on your own machine and let me know if you hit anything specific, so it can be fixed fast.
Edit via the in-app E > Edit user configuration menu, or directly in
config.json (created on first run) / config_intraday.json. AI/WhatsApp
settings live separately in config_integrations.json so they survive
toggling between the two:
| Key | Meaning |
|---|---|
period_days |
Days of history downloaded per stock |
timeframe_days |
Recent-days window used for breakout/consolidation |
min_price / max_price |
Price filter for stocks to buy |
volume_ratio |
Volume multiple vs 20-day average to flag a "gainer" |
consolidation_pct |
% range to call a stock "consolidating" |
shuffle |
Screen stocks in random order instead of alphabetical |
Add a function def crit_my_scan(snap, cfg): return True/False in
kj_screener/scanner.py (see existing ones for the fields available in
snap), then register it in CRITERIA_MENU with a new menu number.
This report/tool is for learning & analysis purposes ONLY β no responsibility is taken for any errors, omissions, or trading gains/losses arising from its use.