1. How this dashboard is put together
Four independent analysis pillars — QoQ Fundamentals, 3-Month Price Action, Options positioning,
and ICT/Smart-Money structure — get computed for every Nifty 50 stock. Two different tabs blend
them differently:
That's the Trade Shortlist / Compare composite score — it deliberately has no ICT input.
The Main Dashboard's overall score is a separate, equal-weighted blend of Fundamentals, Technical
and ICT instead (no options input) — see section 2. The two scores are allowed to disagree on the
same stock; each answers a different question.
Fundamentals get the largest composite weight because they change slowly and are hardest to fake; price
action is weighted almost as high because it's what actually pays or costs you; options positioning gets
the smallest weight because it's a short-dated, sentiment-driven overlay, not a standalone reason to trade.
Every score in every tab is on a common 0–100 scale so they can be compared and blended directly.
Scores are built from linear ramps: below a lower bound the component scores 0, above an upper bound
it scores full marks, and in between it's a straight-line interpolation. Where an input is missing, most
ramps award ~40% of the points rather than 0 — a gap in data is treated as "unknown", not "bad".
Tabs at a glance
| Tab | What it's for | Guide section |
| Main Dashboard | Landing tab. Fundamental × Technical × ICT blended into an Overall score, sector-mix and ICT-bias-mix charts, a 4-way score-filtered shortlist table, an "Evaluate" button that runs the full top-down stock-focus workflow in one click, and a "Chart Insight" button for a single symbol/interval candle read (price change, volume, ICT structure, options). | 2 |
| Trade Shortlist | Ranked picks from the 45/40/15 composite score, with direction (long/short/watch), conviction, and ATR-based entry/stop/target levels. | 6 |
| QoQ Fundamentals | Quarter-on-quarter financials league table for all 50 stocks, plus a per-stock trend chart. | 3 |
| Price Action (3M) | 3-month daily candle league table — trend, RSI/ADX/ATR, relative strength — plus a per-stock candlestick chart. | 4 |
| Options | Options positioning league table (IV, PCR, max pain, futures basis) plus per-stock strategy ideas. | 5 |
| Compare & Top Picks | One table merging all three composite pillars for all 50 stocks, plus independently-ranked Top Buy / Top Sell leaderboards. | 6 |
| ICT Shortlist | Market structure, liquidity, order blocks, FVGs and the OTE zone off the same 3-month candles, plus Top Bullish / Top Bearish leaderboards. | 7 |
| ICT Strategies | Pick a symbol, a candle duration, and any combination of named ICT entry models; each is evaluated independently then combined into one consolidated opinion, plus a Nifty 50-wide Top 5 bullish/bearish scan. | 8 |
| Backtest | Walk-forward paper-trade of a chosen ICT strategy combination against one symbol's history — win rate, expectancy, drawdown, equity curve. | 11 |
| Portfolio | Where a Backtest-tab paper order goes when you press "Close & move to portfolio" — closed trades and still-running trades shown separately, each with invested amount and ROI%. | 13a |
| Liquidity | Trading-liquidity league table (ADTV, turnover velocity, options chain depth, Kite bid-ask spread when connected), plus Most Liquid / Thinnest-in-peer-group leaderboards. A different question from every other tab — tradeability, not direction or quality. | 9 |
| Nifty & BankNifty | Index-level pulse for the two F&O underlyings: 3-month price action + ICT off their own candles, index options positioning, a constituent fundamentals-breadth proxy, a liquidity read (options depth + ICT pool proximity), and a blended prediction with strategy ideas. | 10 |
| Sentiment | Positive/Negative/Neutral market-mood gauge for NIFTY and BANKNIFTY — the same sentiment_score/sentiment_label computed on the Nifty & BankNifty tab, given its own dedicated view (price/trend + options positioning + constituent breadth + India VIX regime + ICT structure). | 10 |
| Scalping | Intraday VWAP/CPR-Camarilla/Volume-Profile/EMA+ORB confluence setups for NIFTY/BANKNIFTY/FINNIFTY, plus a Nifty 50-wide intraday scan. | 12 |
| Trading Systems | Named, rule-based strategies and multi-skill systems (classical TA, ICT/SMC, Wyckoff, value/growth) screened across all 50 stocks against a fixed checklist of conditions per strategy. | 13 |
| Watchlist | Stocks you've starred anywhere in the app, with live-refetched data. Stored locally in this browser. | 16 |
| Field Guide | This document — every field and formula, downloadable as a standalone HTML file. | — |
| Dashboard Management | Show/hide, reorder and rename any tab above. Stored locally in this browser; can't hide itself. | — |
Nothing on this dashboard places an order. Every score, tag and price level is a mechanical
calculation from the formulas on this page — not investment advice. Verify every number against your
own broker before risking capital.
2. Main Dashboard tab
The landing tab. It blends three of the four pillars — QoQ Fundamentals, 3-month Technical
(price action) and ICT structure — into a fourth, Overall score, then charts the universe
on top of a filterable shortlist table.
Overall score
overall_score = ( fundamental_score + technical_score + ict_score ) / 3
A simple, equal-weighted average — deliberately not the same formula as the Trade
Shortlist's composite (45% fundamentals + 40% momentum + 15% options). Overall score has no options
input at all and gives ICT structure a full third of the say, so the two scores can rank the same stock
differently. Both are legitimate; they're answering different questions ("what does the options market
think", composite, vs. "does the chart's institutional structure agree with the fundamentals",
overall).
Charts
- Sector mix — ICT bias — every sector with at least one scanned stock, as a
horizontal bar split around a centre line: bullish count to the right (green), bearish to the left
(red); a sector with only neutral reads shows no bar. Ranked by how many stocks were scanned in
that sector.
- ICT bias mix — how many stocks currently read bullish / bearish / neutral on the
ICT Shortlist tab's bias, across the whole universe.
- Average overall score by sector — the mean Overall score per sector (top 10),
drawn as horizontal bars, colour-coded the same way as every other score bar on the dashboard.
All three are computed from the same scan that populates the table below — there's no separate
data pull for the charts. The table itself still respects the shared search/sector filter bar at the
top of the page.
Evaluate
A one-click, mechanical run of the full top-down workflow, both directions at once: Nifty &
Bank Nifty index bias (reuses the Nifty & BankNifty tab's index-pulse read) → sector
rotation (sectors with ≥2 Nifty 50 constituents, ranked by their constituents' average Overall
score — the top 2 feed the long screen, the bottom 2 feed the short screen) → a
universe screen for long ideas and, separately, a mirrored screen for short ideas → a full
per-candidate deep read (fundamentals, price action, liquidity, ICT, options) →
multi-system confluence (how many of the 5 Institutional Picks strategies and how many Trading
Systems families confirm it) → the precise ICT Strategies trigger (the consolidated
multi-model opinion from that tab) → the composite Trade Shortlist direction/levels. This
is the same 8-step process as the /stock-focus Claude Code slash command
(.claude/commands/stock-focus.md), reimplemented as fixed rules instead of an AI judgment
call — no API key, no LLM call, no per-click cost, same "mechanical formula" contract as every
other score on this dashboard.
long candidate: direction == "long" AND fundamental_score ≥ 70 (borderline ≥ 55)
AND ADX14 > 25 AND trend not in {sideways / weak, ranging} AND rel_strength_3m > 0
short candidate: direction == "short" AND fundamental_score < 40 (borderline < 55)
AND ADX14 > 25 AND trend not in {sideways / weak, ranging} AND rel_strength_3m < 0
The short screen is the long screen's exact mirror against section 1's
fundamental-score ramp: a primary short needs "Weak" fundamentals (<40) the same distance below the
neutral midpoint as a primary long's "Strong" (≥70) is above it. Within each side, candidates are
ranked sector-in-rotation (or out-of-favour, for shorts) first, then by how far the composite score
sits from neutral, capped at 3 primary + 2 borderline per side. Each candidate's headline
verdict (bullish / bearish / neutral) starts from the composite Trade Shortlist direction, then
gets downgraded to neutral whenever the ICT Strategies trigger disagrees with it, or has live
setups but no consolidated edge either way — that disagreement is surfaced as an explicit warning
on the card, not averaged into a single number. The entry zone/stop/targets shown are the ICT
trigger's levels when it agrees with the composite direction (the more precise, timing-aware read),
and the composite's own ATR-based levels otherwise.
Same disclaimer as everywhere else: analysis only, nothing here places an order, and
every level is a mechanical calculation to verify against your own broker — not advice.
Checklist
Next to Evaluate, the Checklist button (GET /api/checklist/pdf,
app/analysis/checklist.py) runs a fresh Evaluate and fills the dashboard's own paper
template — trade-setup-checklist.pdf's 7 sections (Seasonality & sector
strength, Fundamentals, Price structure, Liquidity sweep, ICT confirmation, Options data, Risk &
trade shortlist) — into a downloadable PDF, one page per long/short candidate.
Every checkbox traces back to a field this dashboard already computes: a green check means the data
genuinely supports that line (with the exact number shown underneath in small print), a red cross
means the data contradicts it. Anything this app doesn't track at all — an earnings/corporate-
action calendar, promoter-holding changes, filed-debt trend, position sizing against your own account,
whether you've actually logged the idea — is left an empty box marked "verify manually" rather
than guessed at. The NOTES section at the bottom of each page is auto-filled from that candidate's own
Trade Shortlist rationale and warning flags.
A checked box here is not a buy/sell signal by itself — it's a record of which of
your own dashboard's inputs agreed with the trade, at the time you generated it. Re-run it before
acting if meaningful time has passed.
PDF — written insights report
Next to Checklist, the PDF button (GET /api/insights/pdf,
app/analysis/insights_pdf.py) downloads this dashboard's current reading as a written
document rather than a form to tick. Part A walks the four Market-metrics cards section by
section — Options & derivatives, Fundamental analysis, Sentiment & market structure,
Technical indicators — for both indices, Nifty 50 first then Bank Nifty, so you get the
full set instead of whichever one the on-screen toggle happens to be on. Part B is the whole
Evaluate result: index bias, the sector-rotation table, then one page per long/short candidate with
its screen, ICT and options read, multi-system confluence, both sets of trade levels, rationale and
every warning.
Because a printed page has none of the screen's colours, bars and tooltips, each section opens with a
plain explanation of what it measures, each verdict prints the exact per-metric vote behind it
("IV percentile neutral / PCR bearish / OI Calls-Puts bearish / Max pain bullish"), and each number
carries a line on what that particular reading implies. The verdict rules are the same ones the
browser runs on the same payloads, so the PDF can't disagree with the card it came from; where a feed
genuinely isn't available (FII/DII flows, greeks without a Kite session) it says so rather than
printing a placeholder. It runs its own fresh Evaluate server-side, so it works whether or not you
pressed Evaluate first.
It's the slowest button here — a cold run does a full index pulse, a universe fundamentals
pass, a structure-event sweep and a complete Evaluate before a page is drawn — so instead of a
featureless spinner the button starts a background job
(POST /api/insights/pdf/start) and polls it, counting off the five real phases it's
working through (Index pulse → Universe fundamentals → Structure events → Evaluate
→ Rendering) with the elapsed seconds alongside. It's a genuine position in a known
sequence, not a made-up percentage: the label only advances when the server reports that phase has
started. On a warm cache the whole thing finishes in seconds; on a cold one it's a couple of minutes.
GET /api/insights/pdf still renders the same document in one blocking call if you'd
rather hit it directly.
Same disclaimer: a report, not advice. Every number in it is a mechanical calculation
off the same cached scan every other tab uses, and worth re-generating if meaningful time has passed.
Chart Insight
Below Evaluate, the Chart Insight panel (GET /api/chart-insight/{symbol}?interval=,
app/analysis/chart_insight.py) answers a narrower question than Evaluate: not "which stocks
to trade" but "what just happened, on this one symbol, on this one candle". Pick any Nifty 50 stock, or
NIFTY/BANKNIFTY for the index itself, and a candle interval — 5-Minute, 15-Minute, 30-Minute,
1-Hour, 4-Hour, Daily, Weekly or Monthly — and it reads the most recently closed candle at
that interval:
- Price change — that one candle's open→close move in points and %, and its
high–low range as a % of the open.
- Volume — that candle's volume vs the average of the 20 candles immediately before it
(not including it). Genuinely up ≥50% is flagged as a real expansion; down ≤−40% is
flagged as thin participation, worth discounting the price move.
- Market structure — the same ICT engine (section 9) run on real
intraday candles at the chosen interval instead of the usual 3-month daily window: trend, premium/
discount zone, and the latest confirmed BOS/CHoCH/MSS.
- Options — PCR, ATM IV, max pain and today's futures OI change from the same Sensibull/
Kite read the Options tab uses (section 5).
5-Minute/15-Minute/30-Minute/1-Hour candles are fetched directly (Kite when linked,
else yfinance); 4-Hour merges four 1-hour bars the same way the ICT Strategies tab's 4-Hour timeframe
does; Daily fetches daily candles directly; Weekly/Monthly resample those daily candles the same way
the ICT Strategies tab's Week/Month timeframes do — no separate fetch/resample logic, just reused
from there.
This is a snapshot read, not a per-candle options replay: Sensibull/Kite expose only
the current option chain, not a stored history of it, so the options fields are today's
day-level numbers, not reconstructed for the specific candle shown. The panel's own warning line says
so on every run — it is never silently presented as candle-specific.
Same rules as the /chart-insight Claude Code slash command
(.claude/commands/chart-insight.md), which runs this same mechanical read first and then
layers a judgment call on top — drawing on the ict-smc-analysis, classical-technical-analysis and
nifty-sentiment-scoring skills to say whether the structure/volume/options reads actually agree, the
way this fixed-rule version can't.
3. QoQ Fundamentals tab
Pulls the last few reported quarters (yfinance, with an optional enrichment source filling gaps) and
compares the latest quarter sequentially (QoQ, vs the immediately prior quarter) and annually
(YoY, vs the same quarter a year ago, matched 330–400 days back).
| Field | What it means | Calculation |
| Qtr | Label of the latest reported quarter used for every figure in the row. | Most recent quarter by period-end date. |
| Revenue | Latest quarter's total revenue, ₹ crore. | As reported. |
| Rev QoQ / Rev YoY | Revenue growth vs the prior quarter / vs a year ago. | (latest − previous) / |previous| × 100 |
| Net profit (PAT) | Latest quarter's profit after tax, ₹ crore. | As reported. |
| PAT QoQ / PAT YoY | Profit growth vs prior quarter / vs a year ago. | Same % change formula as revenue. |
| Net margin | Net profit as a % of revenue, latest quarter. | PAT / Revenue × 100 |
| Δ margin (QoQ) | How much the net margin moved vs the prior quarter. | latest margin % − previous margin %, in percentage points (pp) — not a % change, since margin is already a percentage. |
| TTM PE | Trailing-twelve-month price/earnings ratio. | From the data provider's company profile. |
| Score | 0–100 fundamental quality score for the quarter. Drives 45% of the composite. | See breakdown below. |
Fundamental score — 7 weighted components summing to 100
score =
ramp(Revenue QoQ%, -4 → 10, weight 18)
+ ramp(Profit QoQ%, -8 → 18, weight 20)
+ ramp(Margin QoQ, pp, -1.0→ 1.5, weight 14)
+ ramp(Revenue YoY%, 0 → 18, weight 14)
+ ramp(Profit YoY%, 0 → 25, weight 18)
+ ramp(Revenue consistency,25 →100, weight 8)
+ ramp(Profit consistency, 25 →100, weight 8)
────────────
max 100
ramp(value, lo, hi, points) is the shared linear scale used everywhere on this dashboard:
value ≤ lo scores 0, value ≥ hi scores the full points, and
anything in between is a straight-line interpolation. A missing value scores 0.4 × points
— neutral, not punitive.
Consistency is the share of the last 4 sequential quarters where the metric rose vs the quarter
before it (e.g. profit consistency of 75% = profit grew in 3 of the last 4 quarter-on-quarter steps).
It rewards steady compounding over one lucky quarter.
Verdict thresholds
| ≥ 70 | "Strong — growth and margins both improving" |
| ≥ 55 | "Healthy — steady quarter, no major cracks" |
| ≥ 40 | "Mixed — some lines improving, others not" |
| < 40 | "Weak — deteriorating quarterly trend" |
Red flags (any that apply are shown as warning chips)
- PAT fell more than 15% QoQ
- Revenue fell more than 5% QoQ
- Net margin compressed more than 1.5pp QoQ
- Latest quarter was loss-making
- Revenue up >3% but profit down >3% ("cost pressure")
- TTM PE above 70 ("rich valuation")
- Latest reported quarter is more than 130 days old (stale data)
4. Price Action (3M) tab
Shows the last 63 trading sessions (~3 months) of daily candles. Indicators are computed over a longer
400-day padded history first, so lookback windows like the 200-day EMA are already valid at the left edge
of the visible 3-month window, then the view is sliced down to 63 sessions.
| Field | What it means | Calculation |
| LTP | Last traded price. | Most recent daily close. |
| 1D / 1M / 3M | Return over 1 day / ~1 month (22 sessions) / the 3-month window. | (last − close N sessions ago) / close N sessions ago × 100 |
| vs Nifty | Relative strength — did the stock beat the index? | stock's 3M return % − Nifty's 3M return % over the same window. |
| From 3M high | How far the price sits below its own 3-month high. | (last − 3M high) / 3M high × 100 |
| RSI | Relative Strength Index (14-period) — momentum oscillator, roughly >70 overbought, <30 oversold. | Wilder's RSI: 100 − 100/(1+RS), RS = avg gain / avg loss, smoothed with Wilder's method after the first 14 periods. |
| ADX | Trend strength (not direction). >25 = trending market, below = choppy/range-bound. | Wilder's ADX(14) from smoothed +DI/−DI derived off true range and directional movement. |
| ATR% | Average daily trading range as a % of price — a volatility proxy, also used to size stop-loss/target levels. | ATR(14) / last price × 100. True range = max(high−low, |high−prev close|, |low−prev close|), Wilder-smoothed. |
| Vol 5/30 | Is participation (volume) expanding or drying up? | avg volume (last 5 days) / avg volume (last 30 days). >1 = expanding. |
| Trend | Plain-language read of the chart's structure. | See classification rules below. |
| Momentum | 0–100 price-action score. Drives 40% of the composite. | See breakdown below. |
Trend classification
- If the 20- or 50-day SMA isn't available yet → neutral.
- "Strong" means ADX(14) ≥ 25 (a genuinely trending tape, not just drifting).
- Price above SMA20 above SMA50, and above the 200-EMA → strong uptrend (or plain uptrend if not "strong").
- Price below SMA20 below SMA50, and below the 200-EMA → strong downtrend (or plain downtrend).
- Otherwise, if price is above SMA50 → recovering.
- Otherwise → sideways / weak.
Support / resistance are pivot levels from the last 20 sessions: resistance is the nearest high
above the current close, support is the nearest low below it.
Momentum score — 6 weighted components summing to 100
score =
trend_points[Trend] (0 → 30, fixed per label)
+ ramp(3-month return%, -10 → 20, 20)
+ ramp(Relative strength vs Nifty%, -8 → 12, 20)
+ RSI posture band (0 → 15)
+ ramp(Volume ratio 5/30, 0.7 → 1.5, 10)
+ ramp(% from 3-month high, -15 → -1, 5)
────────────
max 100
Trend points: strong uptrend 30 · uptrend 24 · recovering 16 · neutral 10 · sideways/weak 8 ·
downtrend 4 · strong downtrend 0.
RSI posture rewards the 50–70 "healthy trend" zone the most, and penalises both extremes:
50–70 → 15pts (full marks) · 40–50 → 9 · 70–80 → 10 (strong but extended) ·
>80 → 4 (overbought) · <40 → 3 (weak) · missing → 7.
5. Options tab
Two data layers, both optional: a no-login Sensibull summary (ATM IV, IV percentile, PCR, max pain,
futures basis) always tried first, and a full strike-by-strike chain with solved implied vols and
Black-Scholes greeks when a Kite Connect session is available.
| Field | What it means | Calculation |
| Spot | Current underlying price. | Live quote. |
| 1D | 1-day % change in spot. | Same % change formula as elsewhere. |
| Expiry / DTE | Nearest F&O expiry and days remaining to it. | — |
| ATM IV | Implied volatility at the at-the-money strike. | From Sensibull, or solved via Black-Scholes off live option prices when the Kite chain is connected. |
| Δ IV | Change in ATM IV. | — |
| IV %ile | Where today's IV sits within its own trailing 1-year range. | 0 = lowest IV in a year, 100 = highest. |
| PCR (OI) | Put-heavy vs call-heavy positioning. | Put open interest / Call open interest. >1 = put-heavy, <1 = call-heavy. |
| Max pain | The strike where option writers collectively lose the least at expiry — a "magnet", not a forecast. | The strike that minimises total intrinsic-value payout across all outstanding calls and puts. |
| Pain gap | How far spot is from max pain. | (max pain − spot) / spot × 100 |
| Basis | Futures premium/discount to spot. | (futures price − spot) / spot × 100 |
| Fut OI Δ | Change in futures open interest — used with price direction to read build-ups. | — |
| Exp move | 1-standard-deviation expected move by expiry. | ATM IV × √(days to expiry / 365) |
| Lot | NSE F&O contract lot size. | — |
Options score — starts neutral at 50, then nudged up/down (clamped 0–100)
- PCR: ≥1.3 → +12 · 1.0–1.3 → +6 · ≤0.6 → −12 · 0.6–0.8 → −6
- Spot vs max pain gap: >+1.5% → +6 · <−1.5% → −6
- Futures basis: >0.35% (premium, long build-up) → +8 · <−0.2% (discount, shorts) → −8
- Futures OI + price combo (when |OI change| > 1%): OI↑ & price↑ → +10 (long build-up) ·
OI↑ & price↓ → −10 (short build-up) · OI↓ & price↑ → +4 (short covering) ·
OI↓ & price↓ → −4 (long unwinding)
- IV percentile: <30 (cheap options, tailwind for buyers) → +5 · >80 (rich) → −5
- IV skew (25-delta put IV − 25-delta call IV) > 4 → −4 (steep put skew = downside demand)
Options bias
Each adjustment above also casts a directional vote (+1/−1). Bullish if the net vote ≥ 2
and the score ≥ 58. Bearish if the net vote ≤ −2 and the score ≤ 42.
Otherwise neutral.
Strategy ideas
Chosen from bias (bullish / bearish / neutral) crossed with whether IV percentile is rich (>70) or
cheap (<35): rich IV favours selling defined-risk spreads (Bull Put / Bear Call / Iron Condor), cheap IV
favours buying (Bull Call / Bear Put spreads, or an outright Long Call/Strangle when very cheap and enough
time remains). Every idea is risk-defined — the engine never suggests a naked short option. A
"max-pain pull" note is added whenever spot is more than 3% away from max pain, as context only.
6. Trade Shortlist & Compare tabs
These are the two tabs that combine all three pillars. Compare additionally shows the full 50-stock table
side by side with independently-ranked Top-Buy / Top-Sell leaderboards.
Composite score
composite = 0.45 × fundamental_score
+ 0.40 × momentum_score
+ 0.15 × options_score
If fundamentals failed to load, fundamental_score defaults to a neutral 45. If options
weren't requested or are unavailable, options_score defaults to a neutral 50 — a
missing pillar pulls the composite toward neutral rather than zeroing it out.
Direction (Call)
- Long: momentum score ≥ 55 (bullish chart) and fundamental score ≥ 55 (good books).
- Short: momentum score ≤ 38 (bearish chart) and fundamental score ≤ 40 (bad books).
- Watch: everything else — e.g. a strong chart running ahead of weak fundamentals, or solid
books whose chart hasn't turned up yet.
Conviction
Only long/short picks can reach high or medium; everything else is low.
- High: composite ≥ 66 and options positioning doesn't contradict the call (a long
needs options bias ≠ bearish; a short needs options bias ≠ bullish).
- Medium: composite ≥ 56.
- Low: everything else.
Entry / stop / target levels (ATR-based, long or short only)
Long:
entry zone = [price − 0.4×ATR , price + 0.3×ATR]
stop loss = min(support − 0.3×ATR , price − 1.8×ATR)
target 1 / 2 = price + 2.0×ATR / price + 3.5×ATR
Short:
entry zone = [price − 0.3×ATR , price + 0.4×ATR]
stop loss = max(resistance + 0.3×ATR , price + 1.8×ATR)
target 1 / 2 = price − 2.0×ATR / price − 3.5×ATR
risk:reward = |target 1 − price| / |price − stop loss|
ATR is the 14-day Average True Range from the Price Action tab; support/resistance are the same 20-session
pivot levels shown there. These are mechanical reference points for sizing risk, not price predictions.
Rationale & warnings
The bullet list on every card is auto-composed from real numbers elsewhere on the dashboard: the latest
QoQ revenue/profit/margin change, the YoY profit change, profit consistency %, the chart's trend plus its
3-month return / relative strength / RSI / ADX, how price reacted the day after the last quarterly result,
and (when available) the options read — PCR, ATM IV, futures basis and max pain. Warning chips combine
the fundamentals red flags above with two chart-side checks: ATR% > 4% ("high daily range") and
volume ratio < 0.6 ("volume drying up").
Ranking rules — why Trade Shortlist and Compare's Top Buy/Sell can differ
- Trade Shortlist ("Top N" picks) sorts the whole scan by direction priority first (long and
short both outrank watch), then by composite score, and truncates to N — so it's one interleaved
list mixing long and short names.
- Compare › Top Buy / Top Sell are two separate leaderboards: Top Buy takes only
direction = long picks sorted purely by composite score; Top Sell takes only
direction = short picks sorted purely by composite score. Each is ranked 1..N on its own,
independent of the other side. Seeing fewer than N names on one side just means fewer stocks cleared that
side's bar today — the rest are sitting in "watch".
7. ICT / Smart-Money-Concepts Shortlist tab
Reads the same 3-month daily candles as the Price Action tab — no extra data fetch — through
an ICT (Inner Circle Trader) / Smart Money Concepts lens: market structure, premium/discount, resting
liquidity, order blocks, fair value gaps and the Optimal Trade Entry zone.
ICT is a discretionary, visual framework with no official reference implementation.
This tab encodes one consistent, reproducible reading of it — not the only valid one. Session
and time-of-day concepts (Kill Zones, the Power of 3 / AMD schematic, the Silver Bullet) need intraday
(minute-level) data this dashboard does not fetch, so they are intentionally left out rather than faked
on daily bars, where a "session" has no meaning.
Swing points & market structure
A swing high/low is detected with a standard 5-candle fractal: a candle whose high (or low) is
strictly the most extreme within 2 candles on either side. The engine then walks the candles chronologically,
tracking the most recent unbroken swing high and swing low:
- Break of Structure (BOS): price closes beyond the tracked swing point in the direction the
trend is already moving — continuation.
- Change of Character (CHoCH): price closes beyond the tracked swing point against the
prevailing trend, with no displacement candle backing the break — the first, tentative sign of a
reversal.
- Market Structure Shift (MSS): the same reversal break, but confirmed by a displacement candle
on (or the bar immediately after) the break — the stronger, confirmed reversal signal.
Whichever direction just broke becomes the new trend, and the engine starts tracking the next fresh
swing point on watch.
Displacement
Validates that a break is a genuine institutional move, not a wick-driven liquidity sweep:
displacement = (candle body / candle range) ≥ 0.6
AND (candle range ≥ 1.5 × average range of the prior 14 candles)
Checked on the breaking candle itself, or the candle right after it.
Dealing range & Premium/Discount
The current dealing range is simply [most recent swing low, most recent swing high]. The zone is
where price sits inside that range:
| ≥ 55% of range | Premium — the "expensive" upper half; favours looking for shorts. |
| ≤ 45% of range | Discount — the "cheap" lower half; favours looking for longs. |
| 45–55% | Equilibrium — no edge either way. |
Liquidity pools & sweeps
Every swing high is a pocket of resting buy-side liquidity (BSL) — buy-stop orders from short
sellers and breakout buyers. Every swing low is sell-side liquidity (SSL) — sell-stop orders
from long holders. Swing points within 0.25% of each other are clustered into one pool (an "equal
highs/lows" magnet with a touch count > 1). A sweep is a candle whose wick pierces a pool but
whose close snaps back on the other side — a stop-run, not a real break. The dashboard reads the
most recent sweep as directional fuel: a swept low (SSL) is read as bullish (liquidity grabbed to fill
longs), a swept high (BSL) as bearish.
Fair Value Gaps (FVG)
A 3-candle imbalance: candle 1's wick and candle 3's wick don't overlap, leaving a gap in candle 2.
Bullish FVG: candle[i+1].low > candle[i-1].high → zone = [high(i-1), low(i+1)]
Bearish FVG: candle[i+1].high < candle[i-1].low → zone = [high(i+1), low(i-1)]
"Filled" tracks how far price has since retraced into the gap (as a % of its height); a gap is filled once
price has traded all the way through it.
Order Blocks & Breaker Blocks
For every displaced BOS/MSS, the engine searches backward (up to 6 candles) for the last
opposite-coloured candle before the impulsive move — its full high–low range is the order
block. It's flagged fvg_confirmed if an FVG formed within ~6 days in the same direction, and
bos_confirmed/MSS accordingly. If price later trades back through the block, it's
mitigated; if price then closes fully through the far side, the block has failed and flips
into a breaker — a former support zone that now acts as resistance, or vice versa.
Optimal Trade Entry (OTE)
Bullish: OTE = [dealing high − 0.79 × range, dealing high − 0.618 × range]
Bearish: OTE = [dealing low + 0.618 × range, dealing low + 0.79 × range]
The 61.8%–79% Fibonacci retracement of the current dealing range — the zone ICT treats as the
highest-probability entry on a pullback.
ICT score & bias — starts neutral at 50, clamped 0–100
- Structure trend: bullish +25 · bearish −25
- Displacement on the last break, same direction as trend: +10 / −10
- Zone: discount +10 · premium −10
- Last liquidity sweep: sell-side (bullish read) +15 · buy-side (bearish read) −15
- Freshest unmitigated order block: bullish +10 · bearish −10
Bias: ≥62 → bullish · ≤38 → bearish · otherwise neutral. Entry/stop/target
levels are only produced for a bullish or bearish bias, using the OTE zone as the entry, the far side of
the dealing range (ATR-buffered) as the stop, and the nearest opposing liquidity pool as target 1 —
the same ATR (14-day, from the Price Action tab) that powers the Trade Shortlist's levels.
8. Structure Events tab
A day-based feed of every Break of Structure, Change of Character, Market Structure Shift and diagonal
trendline break fired across all 50 stocks — the same market-structure walk as the ICT Shortlist
tab above, but exposing every event in the 3-month window (up to the most recent 30 BOS/CHoCH/MSS
events and 10 trendline breaks per stock) instead of collapsing it down to just the latest one.
Trendline breaks
A distinct signal from a BOS/CHoCH/MSS break, which is always a horizontal swing-level break. A
trendline break is diagonal: connect two consecutive lower swing highs into a descending
resistance line, or two consecutive higher swing lows into an ascending support line, extrapolate
it forward, and flag the first candle whose close trades through it.
Descending line (lower highs): slope = (H2.price − H1.price) / (H2.index − H1.index)
line(i) = H2.price + slope × (i − H2.index)
Bullish trendline break: close(i) > line(i)
Ascending line (higher lows): slope = (L2.price − L1.price) / (L2.index − L1.index)
line(i) = L2.price + slope × (i − L2.index)
Bearish trendline break: close(i) < line(i)
Lookback & the bullish/bearish split
The Lookback selector controls how far back the full event-log table reaches (by calendar date).
The Bullish today / Bearish today panels always show only the events dated on the single
most recent session date seen across the universe, regardless of the lookback selected, so the headline
split stays a clean "what fired today" read even when the table below is showing a wider window.
Same 3-month (63-session) daily candles as every other ICT tab — zero extra data
fetches. CHoCH and MSS are both reversal signals against the prevailing trend; the only difference is
whether a displacement candle confirms the break. BOS is a continuation, not a reversal, and is included
here for completeness rather than as a bullish/bearish "shift" signal.
Highlights: sector shift, order block, FVG
Every row/card also surfaces three highlight signals so a reversal isn't read in isolation:
- Sector shift: flagged when 2 or more stocks in the same sector bucket fire a
same-direction CHoCH/MSS on the same date — a broader, sector-wide reversal rather than one
stock's isolated break. This dashboard has no separate tradable sector-index price feed (only
NIFTY/BANKNIFTY are fetched as indices — see the Nifty & Bank Nifty Pulse tab), so this is a
breadth read built from the sector's own Nifty 50 constituents' structure events, not a distinct
sector-index candle series.
- OB bullish/bearish: that stock's current freshest unmitigated order block (from the same
ICT read as the ICT Shortlist tab) — independent of this specific event's date.
- FVG bullish/bearish: that stock's current nearest unfilled Fair Value Gap — same
caveat, it's the stock's present state, not dated to the event.
The "Sector-wide shifts" panel above the bullish/bearish split lists every sector that cleared the
2-stock bar on the latest session, with the count of reversing stocks out of that sector's total
Nifty 50 constituents.
9. ICT Strategy Picker tab
Same 3-month daily candles, same ICT engine as the shortlist above — but instead of one blended
score, this tab lets you pick a single symbol (any Nifty 50 stock, or the NIFTY 50 / Bank Nifty index
itself, off ^NSEI/^NSEBANK) and any combination of named ICT entry models
from ICT_Complete_Trading_Strategy_Playbook.md Section 10, each evaluated independently, then
combined into one consolidated opinion.
Session-timed models from the playbook (Silver Bullet, Judas Swing, AM/PM Session
Reversal) need intraday data this dashboard doesn't fetch — same reasoning as the ICT Shortlist tab
— so only the seven models below, all computable from daily candles, are offered.
The seven selectable strategies
| Strategy | Category | Applicable when… |
| Break / Shift of Structure (HTF Bias) | Structure |
A BOS or MSS has been confirmed in the 3-month window; direction = the break's direction,
confidence boosted for MSS (reversal) over BOS and for displacement. |
| Bread & Butter OTE Pullback | Premium/Discount |
Trend is bullish/bearish and an OTE zone exists; confidence highest when price is already sitting
in the expected discount (bullish) or premium (bearish) zone. |
| Order Block Retest | Order Block |
A fresh, unmitigated, non-breaker order block exists in the direction of trend. |
| Fair Value Gap Rebalance | FVG |
An unfilled FVG exists in the direction of trend; confidence highest when little of it has been
filled yet. |
| Liquidity Sweep Reversal (Turtle Soup) | Liquidity |
A buy-side or sell-side liquidity pool was swept in the last 8 sessions; direction is the
reversal read (SSL swept → bullish, BSL swept → bearish), boosted when it agrees with
HTF trend. |
| Breaker Block Retest | Order Block |
An order block has failed and flipped into a breaker anywhere in the window. |
| Premium/Discount Range Fade | Premium/Discount |
Price is off equilibrium (zone ≠ equilibrium); confidence highest at the outer 20% extremes of
the dealing range. |
Every strategy's entry/stop/target levels reuse the same ATR-buffered-stop / nearest-liquidity-pool-target
logic as the ICT Shortlist tab (ict._levels), just anchored to that strategy's own zone (an
order block, an FVG, the OTE zone, or a plain ATR band around the current price) instead of always the
OTE zone.
Consolidated opinion
Only the strategies you've ticked are evaluated. Among the ones with a live setup ("applicable"), each
contributes its own confidence (0–100) as a directional vote:
net = (sum of bullish confidences − sum of bearish confidences) / (sum of both)
overall_score = 50 + net × 50 (clamped 0–100)
overall_bias = bullish if score ≥ 62 · bearish if score ≤ 38 · else neutral
agreement % = share of applicable strategies whose direction matches overall_bias
The displayed entry/stop/target is taken from the single highest-confidence applicable strategy that
agrees with the overall bias (falling back to the ICT Shortlist's own OTE-based levels if none of your
selected strategies produced one). If none of your selected strategies has a live setup right now, the
opinion stays neutral and a warning says so — that's a valid, honest "stand aside" answer, not a
failure.
10. Liquidity tab
Answers a different question from every other tab: not "should I buy/sell this" but "can I actually
get in and out of a position in this without moving the price". It is deliberately kept out of the
composite/overall scores everywhere else — a great fundamental+technical setup in a name you can't
size into isn't actionable, but conflating the two would hide that.
Four independent signals, each optional/degradable
| Signal | Source | Extra data cost |
| ADTV & turnover velocity | Same 3-month candles (Price Action) and market cap (Fundamentals) already fetched for other tabs. | None |
| Options chain depth | Total call/put open interest already fetched for the Options tab. | None (only when options are included in the scan) |
| Bid-ask spread | Kite's 5-level market depth, batched once per scan via equity_liquidity(). | One batched Kite quote call — only when a Kite Connect session is linked |
| ICT liquidity-pool proximity | The same liquidity pools already computed for the ICT tab. | None — informational only, see below |
ADTV & turnover velocity
ADTV (₹cr) = avg(last 20 sessions' volume) × last price / 1e7
turnover velocity % = ADTV / market cap × 100
ADTV is the plain-English "how much of this trades per day, in rupees". Turnover velocity normalises
that by company size — a ₹500cr/day stock with a ₹5,00,000cr market cap turns over far less of
itself daily than the same ₹500cr/day on a ₹50,000cr company.
Options chain depth
avg OI = ( total call OI + total put OI ) / 2
Tagged Deep / Adequate / Moderate / Light against fixed thresholds (25L / 6L / 1.5L average OI) —
informational, shown alongside the score rather than folded into a single number silently.
Bid-ask spread
Top-of-book spread from Kite's market depth: (best ask − best bid) / best ask × 100.
Unavailable without a live Kite Connect session (python -m scripts.kite_login) — every
other signal still works without it.
ICT liquidity-pool proximity — shown, not scored
Distance from last price to the nearest untested resting liquidity pool from the ICT tab (section 7),
as a % of price. This answers "where might a stop-run happen", not "can I get filled" — a different
question from execution liquidity, so it's surfaced as context (and drawn on the detail-view chart as
dashed/solid horizontal lines) rather than mixed into the 0–100 score.
Liquidity score & tier — weights sum to 100 when every signal is available
score = ramp(ADTV, ₹80cr → ₹1,300cr, weight 55)
+ ramp(turnover velocity, 0.03% → 0.45%, weight 20)
+ ramp(options avg OI, 4L → 350L, weight 15)
+ ( 10 − ramp(bid-ask spread%, 0.05% → 1.0%, weight 10) ) [Kite only]
A missing signal scores ~40% of its own weight (same "unknown, not bad" convention as every other ramp
on this dashboard) rather than zeroing the score — e.g. without a Kite session, the spread component
defaults to 4 of its 10 points instead of 0.
| ≥ 70 | Very Liquid |
| ≥ 55 | Liquid |
| ≥ 40 | Moderate |
| < 40 | Below Average (Nifty 50) |
The ramp bounds above are calibrated against the Nifty 50's own distribution
(a live scan measured ADTV ranging ₹155cr–₹2,177cr and options avg OI 5.9L–1,134L across the
50 names), not the broader market. Every Nifty 50 constituent already clears NSE's index-inclusion
liquidity screen — so "Below Average (Nifty 50)" means less liquid than its index peers, not
illiquid in any absolute sense. Deliberately avoided the word "Thin"/"Illiquid" as a tier label for
exactly this reason.
Where it shows up
Its own league table + Most Liquid / Thinnest-in-peer-group leaderboards on this tab; a compact
Liquidity column on the Main Dashboard, Trade Shortlist cards, Compare and ICT Shortlist; and the shared
filter bar's Min liquidity control (section 10) works on every one of those. The Nifty & Bank
Nifty Pulse tab (section 9) also carries a Liquidity read, with ADTV/turnover velocity excluded —
see that section for why.
11. Nifty & Bank Nifty Pulse tab
The only tab that looks at the index itself — NIFTY and BANKNIFTY — rather than the
50 underlying stocks. It reuses the exact same pillars as the rest of the dashboard, just pointed at the
index's own daily candles and its own F&O chain instead of a constituent stock's.
Price action & ICT
Identical engines to the Price Action and ICT Shortlist tabs (same fixed 3-month / 63-session window,
same trend classification, same market-structure/liquidity/OTE logic), run against the index's own
candles — ^NSEI for Nifty 50, ^NSEBANK for Bank Nifty — instead of a
stock's. See sections 4 and 7 for the exact formulas.
Average OHLC (3-month)
The mean of each of open, high, low and close across the same fixed 3-month (63-session) candle
window used everywhere else — a smoothed read of the range, distinct from the single most-recent
session's OHLC and from the high_3m/low_3m extremes below.
avg_open = mean(open₁ … openⁿ) · avg_high = mean(high₁ … highⁿ)
avg_low = mean(low₁ … lowⁿ) · avg_close = mean(close₁ … closeⁿ), n = 63 sessions
Informational only — like the pivot ladder below, it does not feed any score.
Range & pivot ladder (3-month)
Two figures struck from the same fixed 3-month (63-session) high/low/close used everywhere
else on this dashboard — deliberately not the previous day's candle, so they stay
consistent with the range every other index-pulse figure is read from.
range_3m = high_3m − low_3m
Classic floor-trader pivot ladder, with H/L/C being the
3-month high, 3-month low, and latest close:
P = (H + L + C) / 3
R1 = 2P − L · S1 = 2P − H
R2 = P + (H − L) · S2 = P − (H − L)
R3 = H + 2(P − L) · S3 = L − 2(H − P)
Informational only — the pivot ladder does not feed any score.
Options
Same engine as the Options tab (section 5), run against the NIFTY / BANKNIFTY
index F&O chain instead of a stock's. Strategy ideas are generated the same way, cross-checked against
the index's own momentum score as the bias hint. Any strategy with concrete BUY/SELL legs gets the same
editable "Order legs — edit before creating the virtual order" table as an Evaluate/Find_Dir card
(section 13a's Portfolio tab is where it ends up once closed) — each leg's live/estimated LTP,
IV, delta and OI, editable quantity, and a Create virtual order button that records it to
data/backtest.json under the index symbol (NIFTY/BANKNIFTY)
itself, same as any stock's paper order.
Fundamentals — a breadth proxy, not the index's own result
Neither NIFTY nor BANKNIFTY files a quarterly result — there's no P&L to read QoQ. Instead this
panel aggregates the QoQ fundamental score (section 3) of the Nifty 50 constituents that make up the
index:
- Nifty 50: average, and breadth stats (% with positive QoQ revenue/profit growth, count scoring
≥70 "strong" / <40 "weak"), across all successfully-scanned Nifty 50 constituents.
- Bank Nifty: the same aggregate, restricted to Nifty 50 constituents tagged sector
"Bank". This dashboard's universe doesn't carry the official 12-stock Bank Nifty
constituent list, so this is a sector-breadth proxy from whichever of those names are also in the
Nifty 50 — read it as "how healthy are the large listed banks", not as the index's own
financials.
Liquidity — options depth & ICT pool proximity only
Same engine as the Liquidity tab (section 8), run against the index's own candles and F&O chain, with
one deliberate difference: ADTV and turnover velocity are excluded. Neither NIFTY nor BANKNIFTY is
itself traded — only their futures/options are — so the "volume" yfinance reports on
^NSEI/^NSEBANK candles is a proxy figure, not shares traded, and multiplying it
by the index level would produce a rupee-value ADTV that looks real but measures nothing. Those two
signals fall back to the same "unknown, not bad" 40%-of-weight default used whenever a signal is
unavailable elsewhere on this dashboard, rather than being fabricated from that number.
What's left — options chain depth (index F&O open interest) and distance to the nearest
untested ICT liquidity pool — are meaningful at the index level and score exactly as
described in section 8. Bid-ask spread also stays unavailable (Kite market depth is an equity-only
signal in this dashboard).
This tab additionally splits that single "nearest pool" figure into two directional reads —
buy-side liquidity (nearest untested pool above price, clustered from swing highs) and
sell-side liquidity (nearest untested pool below price, clustered from swing lows), each as a
signed % distance from the current index level. See the ict-smc-analysis skill / section 7 for what a
liquidity pool is and how buy-side/sell-side clustering works; like the single-pool figure, these are
informational and don't feed liquidity_score.
Liquidity has no inherent direction, so it never joins the bullish/bearish/neutral
vote below. But unlike every other tab on this dashboard, it is one of the five components
folded into overall_score here — see below.
Overall score
overall_score = ( fundamentals_breadth_avg + momentum_score + ict_score + options_score + liquidity_score ) / 5
A simple five-way average across every pillar computed for that index, including options and liquidity
this time (unlike the Main Dashboard's Overall score in section 2, which only averages three). A
missing/failed options or liquidity read defaults to a neutral 50, same convention as the composite
score in section 6.
Prediction & bias
Three independent directional signals are read off the index and majority-voted:
- Price trend → bullish if strong uptrend / uptrend / recovering, bearish if strong
downtrend / downtrend, else neutral.
- ICT bias — bullish / bearish / neutral, straight from the ICT engine (section 7).
- Options bias — bullish / bearish / neutral, straight from the options engine (section 5);
neutral if the options read is unavailable.
Two or more bullish votes → overall bias bullish; two or more bearish → bearish;
anything else (including a 1-1-1 split) → neutral. Confidence is
(votes agreeing with the overall bias) / 3, shown as a percentage — e.g. 2 of 3 signals
agreeing is 67%. This is a mechanical vote count, not a probability estimate.
Same disclaimer as everywhere else on this dashboard: this is a mechanical reading of
three formulas, not a forecast. Index options in particular are liquid and fast-moving — verify
every number against your broker before acting on it.
Each index card shows this vote as a directional indicator badge (▲/▼/▬ +
BULLISH/BEARISH/NEUTRAL + the confidence %) next to the index name, colour-matched to the rest of the
dashboard's up/down/flat convention — a more prominent restatement of overall_bias and
prediction_confidence, not a new calculation.
Sentiment score — Positive / Negative / Neutral
A second, differently-weighted read of the same index — a market-mood gauge, distinct from
the trade-direction vote (Overall bias) above. The two are computed from overlapping inputs but can
legitimately disagree: bias asks "which way should a trade lean", sentiment asks "how constructive does
the tape look right now". It blends five categories drawn from the classic market-sentiment toolkit
(price/trend, options positioning, breadth, volatility, market structure) — each scored 0-100,
then combined:
sentiment_score = 0.25 × price_trend + 0.25 × options_positioning
+ 0.20 × breadth + 0.15 × volatility + 0.15 × ict_structure
| Category | Source | What it reuses |
| Price & trend | Price Action engine (section 4) |
momentum_score — trend structure, 3M return, RSI posture, volume expansion,
already computed for this index. |
| Options positioning | Options engine (section 5) |
options_score — PCR (OI & volume), spot-vs-max-pain, futures basis/OI
build-up, IV percentile/skew, already computed above. |
| Breadth | New for this section |
Advance/decline + %-above-50-DMA proxy across the Nifty 50 constituents backing this index
(Bank-sector subset for Bank Nifty) — see below. |
| Volatility | New for this section |
India VIX level/regime (^INDIAVIX) — the same low/normal/elevated regime read
the Scalping tab's VIX filter uses (section 13), re-purposed here as a fear/complacency gauge. |
| ICT structure | ICT engine (section 7) |
ict_score — structure trend, displacement, premium/discount zone, liquidity
sweeps, already computed above. |
Breadth is an advance/decline-style proxy, not an official index breadth feed:
advancing_pct = % of constituents with positive 3-month return
above_50dma_pct = % of constituents trading above their own 50-DMA
breadth_score = ( advancing_pct + above_50dma_pct ) / 2
Volatility maps the India VIX regime to a score using the standard inverse VIX–Nifty
correlation (rising/elevated VIX = fear = bearish mood; low/falling VIX = confidence = bullish mood):
low (VIX < 15) → 70, normal (15–20) → 50, elevated (> 20) → 25; unavailable
→ a neutral 50, same "unknown, not bad" convention used elsewhere on this dashboard.
The blended score maps to a label: Positive ≥60, Negative ≤40, otherwise
Neutral. The card's breakdown panel shows each of the five category sub-scores individually so
you can see what's driving the label, plus the raw PCR/RSI/VIX/breadth figures behind it.
This dashboard has no news, social-media, or FII/DII cash-market-flow data source wired
up, so those sentiment categories — real inputs in a fuller sentiment model — are
deliberately left out here rather than approximated from something that isn't actually measuring them.
Like every other score on this dashboard, this is a mechanical formula over live market data, not an
NLP/LLM sentiment classifier.
Sentiment gauge (Sentiment tab)
The Sentiment tab (its own tab, reusing this same /api/index-pulse payload) renders
sentiment_score as a semicircular gauge, canvas-drawn with no charting library — three
coloured zones matching the label thresholds above (red 0–40 / amber 40–60 / green
60–100) with a needle at the current score. It is the single blended number from every category
in this section, given a visual read at a glance instead of a bare figure.
IV & greeks — ATM (current price)
A separate info block reading the option leg nearest the index's current spot price — the
ATM strike, where gamma/theta exposure is highest and the IV read is cleanest:
- ATM strike / ATM IV — always available from the Sensibull summary layer (section 5),
same figures already shown in this tab's
kv block above.
- Delta / Gamma / Theta / Vega (call and put) — only available when a live Kite option
chain is connected (section 5's "layer 2"): Kite's per-strike LTPs feed the Black-Scholes solver
(
app/analysis/bs.py) for a solved IV, then greeks off that IV. Without Kite, this block
shows ATM strike/IV only, with a note explaining why greeks are blank — same "degrade
gracefully, don't fabricate" rule as every other Kite-only signal on this dashboard (e.g. bid-ask
spread on the Liquidity tab).
These figures are informational — like the pivot ladder and average-OHLC blocks earlier in this
section, they don't feed sentiment_score or options_positioning directly
(that sub-score is options_score from section 5, which already factors ATM IV/skew when
available).
Option direction — day-by-day OI (this month)
A running, day-over-day read of Call vs Put open-interest change against the index's own price change
— the classic long-buildup / short-buildup / short-covering / long-unwinding matrix, applied
separately to calls and puts and then combined:
| Leg | Price up + OI up | Price down + OI up | OI down (either direction) |
| Calls | Bullish (long build-up) | Bearish (call writing / resistance) | Neutral (unwinding/covering) |
| Puts | Bullish (put writing / support) | Bearish (fresh put buying) | Neutral (unwinding/covering) |
Each day's call-signal and put-signal are combined: if they agree, that's the day's signal; if one is
neutral, the other wins; if calls and puts point opposite ways outright, the day reads neutral (no
consensus). The tab's option_direction badge takes the majority of the last 3 logged days.
This is built from open interest, not options volume — the Sensibull
summary this dashboard uses for the index F&O chain exposes total Call/Put OI but not total options
volume (only Kite's full chain would carry per-strike volume; even then, index-wide totals would need
summing across the whole chain). "Buying vs selling" is therefore read the standard OI-buildup way,
not from a raw volume tally.
Snapshots are logged once per calendar day into the same SQLite cache every other tab already shares
(app/cache.py, key oi_history:<NIFTY|BANKNIFTY>), with a ~400-day TTL so
it behaves as a permanent log rather than an expiring cache entry. Re-running the scan later the same
day updates today's row rather than duplicating it. The table shows the current calendar month, most
recent day first, and starts empty and builds up one row per day — there is no bulk
historical backfill, since neither Sensibull nor this dashboard's providers expose past-dated OI.
CMP strike-activity card
A second card under each index card, tracking option-chain activity at the strikes right around the
current market price (CMP): the ATM strike plus one strike above and one below (offset configurable to
±1/±2/±3 strikes via the card's own selector), split into Call and Put rows. It
reuses the same options chain already fetched for the card above it (OptionsReport.chain,
section 5) rather than a separate data source.
| Column | Meaning |
| LTP / OI / Volume / IV | Straight from that strike's OptionLeg (section 5)
— only populated once a Kite session is connected; see below. |
| OI Δ (open) | Change in that leg's OI since the first successful poll of the
current calendar day — the baseline is cached in the browser's localStorage
(nifty50_strike_open_baseline_v1) so it survives a page refresh, not a server-side
time-series store. |
| Vol Δ (poll) | Change in traded volume since the previous 15-second poll, kept only
in memory for that browser tab — used to spot short-term activity spikes rather than the
day's cumulative build-up. |
| Buildup | Long buildup / Short buildup / Short covering / Long unwinding, from the OI
Δ (open) vs LTP Δ (open) matrix — the same classic convention documented just above
for the OI-buildup log, applied per strike/leg instead of once a day for the whole index. |
Kite's quote API exposes total traded volume and OI, but not a buyer-initiated vs
seller-initiated ("buy volume" vs "sell volume") split — that classification needs tick-by-tick
trade data no provider in this dashboard supplies. OI-buildup direction is the standard NSE proxy used
here instead, and the same limitation already applies to the OI-buildup log above.
The table only populates once a Kite session is connected (Dashboard Management → Settings) —
OptionsReport.chain is empty in Sensibull-only mode, since Sensibull's free summary has no
per-strike ladder. The card falls back to a message explaining this rather than showing empty/fabricated
rows. The mini line chart below the table plots total CE OI vs total PE OI (summed across the three
strikes) across the last 40 polls held in that browser tab; it starts empty and fills in as polls
accumulate, same as the OI-buildup log's daily table above.
Polling happens every 15 seconds via GET /api/index-pulse/options/<NIFTY|BANKNIFTY>
while the Nifty & BankNifty tab is open (it stops the moment you switch tabs), but the figures
themselves only change as often as the shared 5-minute options cache TTL refreshes — this is
near-real-time within that cache window, not a tick-by-tick feed.
12. Sector tab
Every requested NSE sectoral index, compared against its own same-calendar-month average over the
trailing 5 years — not a flat average of every month in a 5-year window. If the current month is
August, the average is specifically the average of the last 5 Augusts, compared against this August's own
level so far. Powered by GET /api/sectors → app/analysis/sectors.py
build_report(), run in parallel across a thread pool (same pattern as the main scan), one Yahoo
Finance fetch per index.
five_year_avg = (Aug last year + Aug 2 years ago + Aug 3 years ago + Aug 4 years ago + Aug 5 years ago) / 5
(using whichever of those years have data, min. 3; "Aug" = whatever the current month is)
current_price = mean(daily close, current calendar month so far) — or latest close if the month has just started
pct_vs_5y_avg = (current_price − five_year_avg) / five_year_avg × 100
Each index ticker is fetched verbatim from Yahoo Finance (yfinance.download(ticker, period="6y",
interval="1d")) — unlike the per-stock provider, no .NS suffix is appended, since
index tickers don't follow that convention consistently (some carry a ^ prefix, some don't).
Daily closes are grouped by calendar year/month in-app (Yahoo's own monthly aggregation truncates history
to a single row for several of these tickers even though the full daily series exists), then averaged
per matching month. Results are cached for CACHE_TTL_SECTOR_HOURS (default 24h) since a
5-year seasonal average barely moves within a day.
The bar chart draws two bars per sector: grey for five_year_avg, green/red for
current_price (green when at/above the average, red when below). Each row is scaled to its
own max(five_year_avg, current_price) rather than one shared scale across all rows —
sectors sit at wildly different absolute index levels (Bank Nifty in the tens of thousands, Nifty Realty
in the hundreds), so a shared scale would flatten every low-level sector's bars to nothing. Bar length
therefore only compares within a sector; the pct_vs_5y_avg label next to the current-month
bar is what makes sectors comparable to each other.
| Field | Meaning |
Grey bar / five_year_avg | Average level of this same calendar month across up
to the last 5 years. |
Green/red bar / current_price | This calendar month's own average level so
far (or latest close if the month just started). Green when at/above the 5-year average, red when
below. |
pct_vs_5y_avg | How far the current month sits from its own 5-year seasonal
average, as a percentage. |
years_used | How many of the last 5 same-month years actually had data
(shown as "N/5" in the table). Below 5 means the index doesn't have a full 5-year history yet for that
month, but still has enough (≥3) to report. |
available | False when no ticker is known for that index, the fetch failed, or
fewer than 3 years of same-month history came back — the row then shows a note
instead of numbers. |
Several requested indices are reported unavailable rather than guessed at:
Nifty Chemicals, Nifty MidSmall IT & Telecom, Nifty MidSmall Financial Services, Nifty MidSmall
Healthcare and Nifty REITs & InvITs have no reliable free-data ticker on Yahoo Finance, and none of
the 11 sectoral indices NSE launched on 2026-06-15 (Power, Capital Goods, Telecommunications,
Construction, Consumer Services, Commercial & Transport Services, Retail, Hospitals, NBFC, Housing
Finance, Insurance) have enough trading history yet for even one same-month comparison. This list is
expected to shrink over time as those indices accumulate history and get listed.
Auto-preloaded on page open, same as every other scan-based tab — press Run scan to
force a refresh.
Single-sector seasonal growth card (above the main table): pick any sector with a known ticker
from the dropdown to see seven vertical bars, one per year (the current year back to 6 years prior)
— each bar is that specific year's own current-calendar-month growth, from the month's first close
to its last close. This is a different number from pct_vs_5y_avg above: that compares this
month's average level against the 5-year average of that month; this card shows each year's own
intra-month return in isolation, so you can see the seasonal trend behind the average rather than
just the average itself. The current year's bar is necessarily partial (start-of-month to the latest
available close, not a completed month) — it's marked with a dashed accent outline and a
"(so far)" sub-label so it isn't read as a like-for-like completed-year figure. Backed by
GET /api/sectors/<name>/monthly-growth → sectors.py
build_monthly_growth(), fetched on demand when a sector is selected (not part of the main scan).
A year with fewer than 2 trading sessions in that month shows "n/a" rather than a fabricated bar.
13. Backtest tab
A walk-forward simulation of the ICT Strategy Picker tab's own signal logic against a symbol's
daily candle history. Press Backtest on any card there (the Top 5 bullish/bearish scan cards, or
the single-symbol opinion card) to queue it here — the queue is localStorage-only,
same as the watchlist, so it isn't shared across devices. Press Run on a queued row to execute it.
At every historical session, it rebuilds a PriceActionReport from only the trailing
63-session (price_action.WINDOW_DAYS) window ending at that session's close — i.e.
only information that would actually have been available at the time — then re-runs the exact
same ict.build_report → ict_strategies.evaluate_signals →
consolidate pipeline the live tab uses. If the consolidated opinion is directional with
concrete entry/stop/target1 levels, it opens a paper trade at that session's close and walks forward
(up to Max hold bars) checking each day's high/low against the stop and target — a same-day
hit on both is scored as the stop (conservative). No exit inside the window closes the trade at Max hold
at that day's close ("timeout"). Trades never overlap: the next signal search starts after the prior
trade's exit session.
| Win rate / Avg R / Total R | R-multiple = (exit−entry)/(entry−stop),
sign-adjusted for direction. Total R is the sum across every trade; Avg R is the per-trade mean
(the backtest's expectancy). |
| Profit factor | Sum of winning trades' R divided by the absolute sum of losing trades' R.
Blank when there are no losing trades (undefined) or no trades at all. |
| Max drawdown | The largest peak-to-trough dip in cumulative R across the trade sequence
(the equity curve above the trade table), not a real intraday drawdown. |
This reuses the exact same signal logic the ICT Strategy Picker tab shows live, so a
result is a direct answer to "if I had blindly taken every setup this strategy combination flagged,
historically, what would have happened" — not a separate, hand-tuned trading system. It is also
not a full order-book simulation: no slippage, no partial fills, and same-day stop/target overlaps are
resolved conservatively (stop wins) rather than by intrabar sequencing this app can't see from daily
OHLC alone.
Options P&L overlay (NIFTY / BANKNIFTY only)
Checking Translate to NIFTY/BANKNIFTY options P&L before running a queued index backtest
overlays every trade with a buying-only options read — a long call (CE) for a bullish trade, a
long put (PE) for a bearish one — priced with this app's existing Black-Scholes engine
(app/analysis/bs.py, the same one the Options tab's IV solver uses). It is a deliberate
approximation, not a real option-chain replay:
- Strike: nearest at-the-money strike to the entry spot price (NIFTY: 50-point step,
BANKNIFTY: 100-point step).
- Volatility: the trailing 30-session realised volatility as of entry (falls back to a fixed
13% if there isn't enough price history yet) — used as a stand-in for market implied volatility,
since this app has no historical IV series to replay against.
- Time to expiry: assumed 7 calendar days from entry (a weekly-expiry proxy), ticking down by
the calendar days actually elapsed to the exit date, floored at 1 day so an exit is never priced at
literal zero time value.
premium = BlackScholes(spot, strike, t, vol, risk_free_rate, CE|PE)
premium_pnl = exit_premium − entry_premium
Requesting the overlay against an individual stock symbol is silently ignored (a warning explains why)
— it's only meaningful for the two index symbols this dashboard treats as options underlyings.
Treat the resulting P&L as a directional shape check (does theta/time decay eat this edge before it
plays out?), not an exact premium quote.
13a. Portfolio tab
Where a paper order from the Backtest tab goes once you're done tracking it live. Pressing
Close & move to portfolio beside a Backtest-tab order marks every leg to its current price
one last time (live Kite LTP, or a Black-Scholes estimate when Kite isn't connected — same pricing
as the Backtest tab), tags the trade closed with a closed_at timestamp, and
moves it out of data/backtest.json into data/portfolio.json
(app/analysis/portfolio.py). Nothing is ever sent to Zerodha — this only rearranges
which local JSON file the paper order lives in.
The tab shows two separate sections, each with its own summary row:
| Closed trades | Everything in data/portfolio.json — trades you've
explicitly closed. Their P&L and prices are frozen at the moment of closing; refreshing the
Portfolio tab does not re-mark them. |
| Running trades | Everything still in data/backtest.json — the same
orders the Backtest tab shows, marked to the current price on every load/refresh. Closing one here
(via the Backtest tab) moves it into Closed trades. |
| Invested ₹ | Net premium actually at risk: the absolute net debit/credit per share
(BUY legs add, SELL legs subtract) × lot size × lots. Blank when any leg's entry price
couldn't be priced. |
| ROI % | Trade P&L ÷ Invested ₹ × 100 — return on the premium
actually risked, not on the underlying's notional value. |
| Win rate | Share of priced trades in that section with positive P&L. |
A closed trade's invested amount and ROI% are computed once, at close time, and stored
verbatim in portfolio.json — they do not change afterwards even if you later reopen
the Backtest tab and place a new order on the same symbol/strategy.
14. Scalping tab
1–5 minute intraday scalp setups for NIFTY, BANKNIFTY and FINNIFTY, built from
nifty-banknifty-scalping-dashboard-prompt.md's Section 5 signal modules. Unlike every other
tab, this one reads intraday candles (5-minute bars via yfinance, delayed) instead of the fixed
3-month daily window — each index's own session, refetched every time you press Run scan.
Order-flow/footprint signals (unfinished auction, stacked imbalance, cumulative-delta
divergence) and the 0DTE gamma-blast / live-OI-shift setups from the spec need a tick-level (Level-2/TBT)
feed or Kite's WebSocket ticker, neither of which this dashboard wires up. They are not computed
here — this tab implements Sections 5.1 and 5.3–5.6 in full, plus a simplified India VIX
low-IV filter from 5.7.
Session status
Read off the current IST clock (not the data), Section 2 of the spec:
- Pre-open — before 9:15.
- Opening (signals suppressed) — 9:15–9:20, deliberately blank to avoid the
first-print volatility distortion.
- Live — 9:20–14:45.
- Live — position-limit snapshot window — 14:45–15:30, SEBI's intraday FutEq
monitoring window; signals still fire, just flagged.
- Closed — after 15:30, weekends, or holidays; the panel shows the last completed
session instead.
Regime banner — CPR width, virgin CPR, India VIX
Central Pivot Range, struck from the prior day's high/low/close:
P = (H + L + C) / 3 · BC = (H + L) / 2 · TC = 2P − BC
width = |TC − BC|
CPR regime: narrow (favour breakout setups, high trend-day probability) when
width / prev_close × 100 < 0.15%, else wide (favour mean-reversion
setups). A relative threshold, not a fixed point count, so the same rule reproduces the original
35pt-NIFTY / 80pt-BANKNIFTY tuning and also works unchanged for a ₹250 Nifty 50 stock in the
Nifty 50 filter below.
Virgin CPR: yesterday's CPR zone [BC, TC] is computed from the day before
yesterday's OHLC and checked against yesterday's actual traded range. If yesterday's session never
touched that zone, it's flagged as an untested magnet — price tends to gravitate back to it.
India VIX filter: current ^INDIAVIX close. Below 15 → low-IV regime, a banner
warns of theta-decay chop risk, and every signal's confidence is multiplied by 0.8 before it can reach
the confluence scorer.
Camarilla pivots
Also struck from the prior day's high/low/close, with the standard 1.1 multiplier:
H3 = C + (H−L)×1.1/4 · H4 = C + (H−L)×1.1/2
L3 = C − (H−L)×1.1/4 · L4 = C − (H−L)×1.1/2
H5 = (H/L)×C · H6 = H5 + 1.168(H5−H4) ·
L5 = C − (H5−C) · L6 = C − (H6−C)
VWAP suite (Section 5.3)
Session VWAP and running ±1 standard-deviation bands, recomputed from every 5-minute candle since
the day's open, volume-weighted on typical price (H+L+C)/3. Suppressed for the first 30
minutes of the session (SD is unstable with too few prints). Three setups:
- VWAP Reclaim (long) — price dipped below VWAP, closed back above it, RSI(9) 38–58.
- VWAP Rejection (short) — rally into VWAP from below rejected with a bearish close,
RSI(9) 45–65.
- VWAP Squeeze Breakout — multi-candle compression around VWAP resolved by a close outside
the ±1SD band on >2× the 20-candle average volume.
Camarilla mean-reversion & breakout (Section 5.6)
- H3/L3 fade — a reversal candle at the H3 or L3 boundary with RSI(9) at an extreme
(≥65 / ≤35) fades back toward the opposite boundary inside the band.
- H4/L4 breakout — a decisive close beyond H4 or L4 targets the H5/L5 Fibonacci
extension.
Volume Profile / POC (Section 5.1)
Session candles are bucketed into 20 price bins by closing price (a close-price proxy — true
volume profile needs tick data); the highest-volume bin's midpoint is the POC, and the tightest
set of bins covering 70% of session volume gives the Value Area High/Low.
- POC Mean Reversion — price stretched ≥0.10% of price away from POC with a flat
EMA9/EMA21 (no sustained directional flow) fades back toward POC.
- POC Migration — the session's first-half POC vs second-half POC has shifted ≥0.08%
of price — treated as trend-day confirmation, traded with the shift.
Both thresholds are relative (% of price), same reasoning as the CPR-width threshold above — it
keeps the setups meaningful whether they're running against the Nifty 50 index or an individual
constituent stock.
EMA momentum & Opening Range Breakout (Section 5.4)
- EMA 9/21 cross on the 5-minute chart, confirmed by the triggering candle's volume being
>1.3× the 20-candle average.
- 15-minute ORB — the first three 5-minute candles (9:15–9:30) set the opening
range; a close beyond it on a >1.5× volume spike targets 1.5× the range extended past
the broken level.
RSI throughout this tab uses a shortened RSI(9) lookback (not the 14-period used on the Price Action
tab), matching the spec's instruction to use faster oscillators intraday.
Confluence scorer & Top Picks (Section 6)
Signals are grouped by module family — vwap, cpr_camarilla,
volume_profile, ema_orb — and by direction. A pick needs
≥2 distinct confirming modules agreeing on the same direction; anything with only one
confirming module lands in Watch instead, never Top Picks.
confidence_pct = min(100, [Σ module_weight×(signal_confidence/100)] / Σ active_module_weight × 100 × vix_multiplier)
Module weights: VWAP 25%, CPR/Camarilla 20%, Volume Profile/POC 20%, EMA+ORB 15% (Order Flow's 20% is
absent for lack of tick data, so weights are normalised over whichever modules actually fired).
vix_multiplier is 0.8 in a low-IV regime, else 1.0.
Cost-aware breakeven check
Every candidate pick is netted against an estimated round-trip cost before it can appear in Top
Picks — Section 4's post-2026 SEBI cost constants, expressed in index points for an
ATM-option-equivalent scalp (this dashboard has no live option premium feed, so this is an approximation,
not a broker quote):
cost_points ≈ spot × (STT_sell_options% + exchange_txn_fee%) / 100 × (1 + GST% / 100)
STT (sell side, options) 0.15%, exchange transaction fee 0.03503%, GST 18% — re-verify these
against the latest NSE/SEBI circular; they change by circular, not by code release. A pick is rejected
(demoted to Watch) if cost_points exceeds 40% of the raw gross move, or if net points after
cost is ≤0.
Position sizing
A simple per-trade risk sizer against a default ₹100,000 capital base and 1% max risk per trade
(not yet user-configurable):
position_size_lots = floor( (capital × risk% / 100) / (|entry − stop| × lot_size) )
Lot sizes: NIFTY 65, BANKNIFTY 30, FINNIFTY 60 (post-2026 SEBI larger-lot regime) — also subject
to periodic re-verification against live NSE circulars, not a permanent constant.
Analysis only, same as every other tab — this dashboard never places orders. SEBI
data shows 87–93% of F&O retail traders lose money; nothing on this tab is a guarantee or a
recommendation, and every pick still needs a manual, explicitly-confirmed action.
Nifty 50 filter — Top Bullish / Top Bearish
A second, separately-triggered scan on the same tab (Scan Nifty 50 button, not auto-loaded on
page open since it's ~50 symbols' worth of intraday data). It runs the identical engine described
above — CPR/Camarilla, VWAP suite, Volume Profile/POC, EMA+ORB, the confluence scorer and the
net-of-cost check — against each Nifty 50 constituent stock's own 5-minute intraday
candles, one report per stock, in parallel (same ThreadPoolExecutor pattern as the shared
scan() used by every other tab).
Every stock's Top Picks (already vetted: ≥2 confirming modules, passing the cost check) are pooled
across all 50 names and split by direction:
Top Bullish = picks where direction = long, sorted by confidence_pct desc, top 10
Top Bearish = picks where direction = short, sorted by confidence_pct desc, top 10
India VIX is fetched once per scan and reused for all 50 stocks (not refetched per symbol) —
it's a single market-wide regime read, not something that varies stock to stock. There is no per-stock
Watch list here; a stock with only single-module signals simply doesn't appear in either ranking.
Position sizing is unset for these picks. Unlike the three index scalps, individual
Nifty 50 stocks don't have an F&O lot size available in this dashboard's offline data (it varies by
stock and by circular), so position_size_lots/lot_size are left blank rather
than guessed — check your broker's contract specifications before sizing a stock scalp.
15. Trading Systems & Strategies tab
Named, rule-based strategies built directly from this dashboard's skill references — classical
technical analysis, ICT/Smart-Money-Concepts, Wyckoff, and value/growth fundamentals — each one a
fixed checklist of conditions evaluated against the same fundamentals / 3-month price action / ICT /
options bundle every other tab's scan() already computes. No extra data is fetched.
A stock "qualifies" for a strategy when:
matched_count ≥ min_conditions, out of only the conditions that had enough data to be evaluated
(a condition with no underlying data — e.g. no options read — is skipped, never scored as a miss)
Every strategy has a bearish (short) mirror sharing the same family, so the tab splits each
family into a Bullish leaderboard (left) and a Bearish leaderboard (right) — the same
split2 layout as the ICT Shortlist and ICT Strategies tabs.
Two kinds of catalog entry:
- strategy — draws mainly on one or two skills (pure ICT, pure classical trend-following,
pure value/growth, pure Wyckoff).
- system — a multi-pillar composite requiring several different skills' conditions
to agree at the same time (fundamentals AND momentum AND ICT AND options) — the actual trading
system you get by combining skills rather than picking one.
| Family | Bullish side | Bearish side (mirror) |
Trend Momentum strategy · classical-technical-analysis |
Breakout — trend up, ADX(14) ≥ 20, RSI(14) 50–72, price above the 50-day SMA,
within 6% of the 3-month high. Needs 4 of 5. |
Breakdown — trend down, ADX(14) ≥ 20, RSI(14) 28–50, price below the 50-day
SMA, within 6% of the 3-month low. Needs 4 of 5. |
ICT Smart Money strategy · ict-methodology + smc-ict-wyckoff |
Reversal — bullish structure, discount/equilibrium zone, sell-side sweep, fresh
unmitigated bullish order block, bullish BOS/MSS. Needs 3 of 5. |
Distribution — bearish structure, premium/equilibrium zone, buy-side sweep, fresh
unmitigated bearish order block, bearish BOS/MSS. Needs 3 of 5. |
Fundamentals Quality strategy · value-growth-investing |
Compounder — fundamental score ≥ 65, consistency ≥ 60%, revenue and profit both
grew QoQ, RSI(14) < 68, not a downtrend. Needs 4 of 5. |
Breakdown — fundamental score ≤ 35, consistency ≤ 40%, revenue and profit both
fell QoQ, RSI(14) > 32, not an uptrend. Needs 4 of 5. |
Mean Reversion strategy · classical-technical-analysis |
Dip Buy — RSI(14) ≤ 38, within 2.5% of support, fundamental score ≥ 45, not a
strong downtrend, optional ICT sell-side sweep. Needs 3 of 5. |
Bounce Short — RSI(14) ≥ 62, within 2.5% of resistance, fundamental score ≤ 55,
not melting up, optional ICT buy-side sweep. Needs 3 of 5. |
Wyckoff strategy · smc-ict-wyckoff |
Spring — sell-side sweep, reclaimed above the swept support/3M low, discount/
equilibrium zone, volume ratio ≥ 1.0, ICT trend not bearish. Needs 3 of 5. |
Upthrust — buy-side sweep, rejected below the swept resistance/3M high, premium/
equilibrium zone, volume ratio ≥ 1.0, ICT trend not bullish. Needs 3 of 5. |
Multi-Pillar Confluence system · value-growth-investing + classical-technical-analysis + ict-methodology + algo-quant-trading |
Long system — fundamental ≥ 55, momentum ≥ 55, ICT bias bullish, options not
bearish, outperforming the Nifty. Needs 4 of 5 — the flagship system. |
Short system — fundamental ≤ 45, momentum ≤ 45, ICT bias bearish, options not
bullish, underperforming the Nifty. Needs 4 of 5. |
Each side of each family is ranked by its own key score (momentum, ICT, fundamental, or blended
composite as appropriate, inverted on the bearish side so "further from the bullish ideal" ranks
higher). Entry/stop/target levels on qualifying cards are the same ATR-derived reference points used on
every other tab (see section 6) — not recommendations. Discretionary frameworks (ICT, Wyckoff) are
encoded here as one consistent, reproducible reading of them, not the only valid one.
GET /api/strategies/catalog returns the static rule definitions (12 entries: 6 families
× bullish/bearish); GET /api/strategies/scan runs a chosen subset (or the whole
catalog) across all 50 stocks and returns them grouped back into families.
16. Institutional Picks tab
Five named fundamental + technical confluence strategies modelled on how bank research desks,
systematic/quant funds and veteran discretionary traders actually screen — each a
StrategyDefinition/StrategyMatch pair (bullish and its bearish mirror) run off
the same fundamentals/price-action/ICT bundle every other tab uses, filtered to its own Top 5 per
side, then all 5 merged into one final combined Top 5 Bullish / Top 5 Bearish for a
~1-month swing trade — not a long-term buy-and-hold position. This is a separate catalog from
the Trading Systems tab (section 14); the two don't share strategy IDs.
This app has no 13F/institutional-ownership feed, no insider-transaction feed, no analyst
estimate-revision feed, no weekly candle series, no sector-index price series, and no sector-median P/E.
Where the source strategy calls for one of those, the closest available signal from this app's own data
is substituted — documented per strategy below — rather than faked.
| Strategy | Bullish leg | Bearish leg (mirror) |
| 1. Quality + Momentum Factor Confluence |
Fundamental score ≥ 65, consistency ≥ 55%, price above both the 50-day SMA and 200-day EMA,
relative strength vs Nifty positive, momentum score ≥ 60. Needs 4 of 5. |
Fundamental score ≤ 40, consistency ≤ 40%, price below both MAs, relative strength negative,
momentum score ≤ 40. Needs 4 of 5. |
2. Smart Money / Institutional Footprint
Proxy: ICT order-flow footprint substitutes for 13F/insider data. |
ICT trend bullish, fresh unmitigated bullish order block, sell-side liquidity sweep, volume ratio
≥ 1.05, QoQ revenue/profit not both negative. Needs 3 of 5. |
ICT trend bearish, fresh unmitigated bearish order block, buy-side sweep, volume ratio ≥ 1.05,
QoQ revenue/profit not both positive. Needs 3 of 5. |
| 3. Earnings-Driven Breakout (CANSLIM-style) |
YoY net profit growth ≥ 20%, QoQ revenue & profit both grew, fundamental score ≥ 60,
volume ratio ≥ 1.4, within 5% of the 3-month high. Needs 4 of 5. |
YoY net profit growth ≤ -20%, QoQ revenue & profit both fell, fundamental score ≤ 40,
volume ratio ≥ 1.4, within 5% of the 3-month low. Needs 4 of 5. |
4. Top-Down Sector Rotation with Relative Strength
Proxy: same-sector relative-strength breadth substitutes for a sector-index chart. |
Sector in the top 3 by average 3-month relative strength across the scanned universe, stock beats
its own sector's average, momentum ≥ 55, fundamental score ≥ 45, not a downtrend. Needs 4 of 5. |
Sector in the bottom 3 by average relative strength, stock lags its own sector's average, momentum
≤ 45, fundamental score ≤ 55, not an uptrend. Needs 4 of 5. |
5. Deep Value with Technical Capitulation Timing
Proxy: trailing P/E vs a fixed absolute band, not sector-relative (no sector-median P/E feed). |
Trailing P/E ≤ 22, fundamental score ≥ 40, RSI(14) ≤ 30, within 4% of the 3-month low, a
positive 1-day bounce or volume ratio ≥ 1.3. Needs 3 of 5. |
Trailing P/E ≥ 45, fundamental score ≤ 55, RSI(14) ≥ 75, within 4% of the 3-month high, a
negative 1-day reversal or volume ratio ≥ 1.3. Needs 3 of 5. |
How the final combined Top 5 is ranked
Every stock any of the 5 strategies flagged (on a given side) is merged by symbol. Ranking is
conviction first: how many of the 5 strategies agree on that stock and direction, tie-broken by
the average condition-match % across the strategies it cleared — not any single strategy's own key
score, since those aren't on a common scale across strategies (RSI, ICT score, relative-strength % and
fundamental score all mean different things numerically).
rank key = (strategy_count DESC, avg_match_pct DESC)
strategy_count = how many of the 5 strategies qualified this stock on this side
avg_match_pct = mean of (matched_conditions / applicable_conditions × 100) across those strategies
Entry/stop/target levels reuse the same ATR-derived 2–6 week reference points as the Trade
Shortlist (see section 6) — sized for the ~1-month horizon this tab targets, not a long-term
position. GET /api/institutional/catalog returns the 10 static rule definitions (5 families
× bullish/bearish); GET /api/institutional/scan runs all 5 across the Nifty 50 and
returns each family's Top 5 per side plus the combined Top 5 Bullish/Bearish.
Educational and informational only, not personalized financial or investment advice.
17. Filter bar (top of every tab)
| Search | Matches the stock's symbol or company name, case-insensitive, substring match. |
| Sector | Exact match against the stock's NSE sector classification. |
| Call | Filters to Long / Short / Watch. Applies to the Trade Shortlist and Compare tabs directly; on the ICT tab it's mapped onto bias (Long→bullish, Short→bearish, Watch→neutral). Fundamentals/Price/Options rows carry neither field, so the filter has no effect there. |
| Liquidity sweep | ICT-only: filters to rows whose most recent ICT liquidity sweep was of sell-side liquidity (bullish read), buy-side liquidity (bearish read), or rows with no recent sweep at all. Every other tab's rows don't carry this field, so the filter has no effect there. Not to be confused with the Min liquidity filter below — this is the ICT order-flow concept (section 7), that one is trading liquidity (section 8). |
| Min score | Filters against each tab's own headline score: overall score on the Main Dashboard, fundamental score on QoQ Fundamentals, momentum score on Price Action, IV percentile on Options, composite score on Trade Shortlist and Compare, ICT score on the ICT tab. |
| Min liquidity | Filters against the Liquidity tab's 0–100 score (section 8). Applies to every tab whose rows carry a liquidity_score — Main Dashboard, Trade Shortlist, Compare, ICT Shortlist, QoQ Fundamentals, Price Action, and the Liquidity tab itself. No effect on Options (its league table doesn't run through the shared per-stock scan) or Watchlist. |
All filtering runs client-side against data already fetched for that tab — changing a filter is
instant and never re-triggers a live scan. The Main Dashboard also has four extra local filters of its
own (see section 2); the Nifty & BankNifty and Watchlist tabs ignore this bar entirely — the
former is always exactly two fixed rows (nothing to filter), the latter is a manually curated list, not a
scored/filterable scan (see section 15).
18. Data sources & caveats
- Fundamentals: yfinance quarterly financials, optionally patched from a secondary enrichment
source where a line item is missing.
- Prices: yfinance daily OHLCV candles.
- Options summary: Sensibull's public snapshot endpoint (no login required).
- Full option chain (strike ladder, live greeks): requires a Kite Connect session
(
python -m scripts.kite_login). Everything else works without it.
- ICT / Smart-Money-Concepts: pure computation over the same 3-month daily candles already
fetched for Price Action — no separate data source, no extra API cost.
- Liquidity: no new data source — ADTV/turnover reuse Price Action's candles and
Fundamentals' market cap, options depth reuses the Options tab's chain fetch, and the bid-ask spread
signal reuses a Kite quote batch (one extra call per scan, only when Kite is connected).
- Every API response is cached locally (SQLite, time-limited) so repeat views are fast; "Run scan" /
"Load league table" always does a fresh pass across all 50 stocks, which takes 30–90s cold and is
much faster once warm.
Analysis only. This tool never places orders. Scores, levels and rationale are
mechanically derived from the formulas above — they are not investment advice. Verify every number
against your broker before risking capital.
19. Watchlist
The ☆ next to every stock symbol — in any table row or any shortlist card, on any tab
— adds it to your watchlist; a filled ★ means it's already on there, and clicking it again
removes it.
- Stored in this browser's
localStorage only — nothing is sent to a server, it
isn't synced between browsers or devices, and clearing site data clears it too.
- The Watchlist tab doesn't cache a snapshot: every time you open it (or hit Refresh), it re-fetches
live fundamentals, 3-month price action and options data for each watched symbol via the same
per-stock endpoint the detail drawers use, so the numbers are always current.
- The tab label shows a running count, e.g. "Watchlist (5)".
- Click a stock's symbol in the table to open a 3-month (~90 calendar day) advanced candle
chart below the table — the same candlestick/volume/20&50-DMA chart used on the Price
Action tab, fetched fresh via
/api/price/{symbol}?markers=true.
- 10D / 30D / 90D Chg % columns are the percentage change from the close price 10, 30, and
90 trading sessions ago (capped at the earliest available candle within the fixed 63-session /
3-month window) to the current price.