market-lab: Designing a Screener That Refuses False Confidence

A static data product for every stock on India's National Stock Exchange

12 min read

A stock screener is dangerous when it feels cleaner than the market it describes. Most screeners let a user sort by a number, then leave caveats scattered across columns. I wanted market-lab to do the opposite: rank the NSE, but force every row to carry the reason to be skeptical.

The light market-lab board ranking NSE stocks with opportunity score, risk band, horizon, turnover, order impact and arguments for and against each row.
The light board keeps the research task dense but legible: score, liquidity, horizon and counter-argument stay in the same scan path.Kousik DuttaOriginal product screenshot

What was broken

The problem was not that screeners lack data. The problem is that they present data as if the user already knows how to weigh it. A high score can hide bad liquidity. A tempting small cap can be impossible to enter cleanly. A short-term signal can be read like a long-term thesis. The interface needed to make those mistakes harder.

Typical screener behavior
  • Lead with a sortable number
  • Treat liquidity as secondary
  • Hide the counter-case in extra columns
  • Let users infer the time horizon
market-lab behavior
  • Pair score with the objection
  • Show order impact beside turnover
  • Write the argument in plain language
  • Make horizon part of the row
The design goal was not to make the board simpler. It was to make the dangerous simplification visible.

Interactive preview

Try the score-with-doubt rule

Example ticker84 research score

Strong candidate, but the row still carries the strongest objection.

Research score84
This simplified model shows the product rule. A high research score only gets to lead when liquidity, risk and counter-argument stay visible beside it.

My role

I designed and built the product as a full stack static data system: Python data pipeline, scoring model, validation step, generated JSON, TypeScript board, light/dark visual system, SEO surface and scheduled publishing. The interesting design work was deciding what the interface was allowed to imply.

2,000+
NSE stocks in the scoring universe
0
runtime servers needed for the public board
2
theme-specific portfolio screenshots
1
rule: every score must show doubt
The build is intentionally boring operationally so the product can stay cheap, fast and durable.

The architecture is a design decision

I chose a static architecture because the product does not need a live server to be useful. A scheduled job can fetch the market data, compute scores, verify the output, write static files and publish to a CDN. That choice keeps the experiment inexpensive, resilient and easy to inspect.

Official exchange data

Scheduled fetch

Clean and normalize

Score
opportunity, risk, horizon, liquidity

Verification gates

Static JSON

TypeScript board

CDN publish

The user sees a fresh research surface. Underneath, the product is a verified static artifact regenerated by the pipeline.
LayerDesign concernEngineering choice
DataDo not let stale or malformed rows become confident UINormalize the exchange feed before scoring and publish only generated data
ScoringAvoid one magic number pretending to be truthCalculate multiple signals and expose the weakest one beside the strongest
InterfaceLet a user compare quickly without hiding riskDense row layout with score, risk, turnover, impact, horizon and thesis together
DeliveryKeep the public product cheap and durableStatic files on a CDN instead of an always-on app server
The engineering choices are not invisible implementation details. They are what let the product make honest promises.

The row is the product

market-lab Rankings view showing highest-ranked NSE stocks with score, risk, thesis, weakness, turnover and order impact.
Feature: Rankings. This is the core research surface: ranked stocks, thesis, weakness, risk, liquidity and order impact in one row so the score never travels alone.Kousik DuttaOriginal product screenshot

The hardest UI decision was resisting the detail-page instinct. In a financial product, burying the caveat is the same as removing it for most users. So the row had to carry the complete minimum argument: ticker, score, risk, horizon, turnover, order impact, case for and case against.

The dark market-lab board with the same NSE ranking, showing score chips, risk, horizon, turnover and counter-arguments in a dense row layout.
Both themes keep the same information hierarchy. The palette changes, but the ethical rule does not: the objection stays visible.Kousik DuttaOriginal product screenshot

That row design is where product design and engineering meet. The pipeline has to produce the fields. The TypeScript model has to preserve them. The UI has to keep them aligned. The visual system has to make the warning readable without turning the board into an alarm dashboard.

Responsive density without dropping the warning

The responsive problem was not fitting a desktop table onto a phone. It was preserving the minimum responsible argument when horizontal comparison disappeared. On desktop, a row supports cross-stock scanning. On mobile, each row becomes a research card: identity and score lead, the positive thesis and weakest signal stay together, and the remaining evidence follows in a deliberate reading order. Nothing safety-critical is pushed into an undiscoverable overflow menu.

Mobile market-lab Rankings view at 390 pixels wide with market status cards, a responsive stock research card and persistent bottom navigation.
Mobile Rankings at 390 x 844. The desktop row becomes a vertical argument while score, risk, positive thesis and weakest signal remain in the first scan.Kousik DuttaOriginal product screenshot
System ruleDesktop expressionMobile expression
Score never travels aloneScore, thesis, weakness, horizon and liquidity align in one dense rowThe card keeps score, risk, thesis and weakest signal above the fold
Navigation stays availableResearch destinations use the wide application shellFive primary destinations become a persistent, thumb-reachable bottom bar
Status remains contextualSession freshness and market breadth sit above the ranking tableStatus becomes stacked disclosure cards that preserve labels and tap targets
Themes preserve hierarchyColor tokens separate surface, data and warning rolesThe same semantic tokens maintain contrast without changing information order
The breakpoint changes composition, not product truth. The same generated fields and semantic tokens drive both layouts.

How I kept the score honest

market-lab Screener view showing controls for filtering and comparing NSE stocks.
Feature: Screener. The screener lets a user narrow the market, but keeps the same safety model: filtering is allowed only while the row still exposes risk and doubt.Kousik DuttaOriginal product screenshot
SignalWhy it existsHow it appears
Opportunity scoreGives the user a starting order for researchLarge enough to scan, never alone
Risk bandPrevents a high score from feeling universally goodChip near the row identity, not hidden at the end
Liquidity and order impactShows whether a real position can enter without moving the price too muchDisplayed as practical rupee-order context
Argument againstForces the product to state why the score might be misleadingWritten beside the positive thesis in plain language
The score is useful only because the interface makes it compete with the reasons not to trust it.

Every feature in the suite

market-lab Investors view showing stock research organized around investor needs and market context.
Feature: Investors. This surface reframes the board for investor behavior: not only which stock ranks, but what kind of investor, horizon and risk appetite the signal belongs to.Kousik DuttaOriginal product screenshot
market-lab Portfolio view showing a portfolio-focused research surface.
Feature: Portfolio. The portfolio view moves from stock discovery to position thinking: what a set of choices might imply together instead of treating each ticker as an isolated bet.Kousik DuttaOriginal product screenshot
market-lab Methodology view explaining how the scoring system works.
Feature: Methodology. The method is part of the product. It explains what refreshes, where the data comes from, what the score means and where the model is intentionally limited.Kousik DuttaOriginal product screenshot
market-lab AI assistant panel opened on top of the stock research board.
Feature: AI assistant. The assistant is constrained by the same research posture as the board: it helps interpret and compare, but the product keeps reminding the user that this is research, not advice.Kousik DuttaOriginal product screenshot

Failure states are part of the financial model

A research product becomes dangerous when missing data looks like weak data, or when a failed refresh quietly leaves yesterday's confidence on screen. I moved reliability into the shared data boundary: malformed numbers become unavailable, duplicate or damaged rows are counted, and a score is suppressed when its risk, liquidity or horizon context is not strong enough to support it.

market-lab recoverable market-data error showing the HTTP status, an explanation that scores are withheld without source data, and actions to retry or inspect the methodology.
Recoverable data failure. The shell remains usable, the product explains why no scores are shown, and recovery offers both retry and a route to understand the method.Kousik DuttaOriginal product screenshot
Failure classUnsafe behaviorDesigned response
Initial data failureRender an empty board or fabricate zero-like valuesWithhold scores, expose the failure reason and offer retry plus methodology
Background refresh failureReplace useful context with a generic errorKeep the last-known screen, mark it stale and let the user retry
Malformed or partial rowsLet missing risk or liquidity appear neutralMark fields unavailable, count rejected rows and suppress unsupported rankings
Restrictive filtersTreat zero results like a system outageExplain the active constraint and give a direct path to clear or widen filters
Invalid portfolio or assistant inputAccept a success-shaped answerAttach the error to the field or request and preserve the user's recoverable work
The state model distinguishes loading, empty, invalid, degraded and failed because each state needs a different recovery path.

Design engineering craft

This project is not impressive because it has a table. It is impressive because the table is the last mile of a system: generated data, typed fields, sort behavior, responsive density, theme-specific contrast, static routing and public deployment. I worked across product judgment, interaction design, semantic visual tokens, TypeScript implementation, pipeline verification and operational cost. A row that looks clean but drops a warning on mobile would be a product failure, not a CSS bug.

Accessibility was a release gate, not a final audit

The accessibility sweep covered every primary view, factsheets, assistant setup, both themes, and the loading, empty, degraded and error states. I fixed landmarks and headings, linked labels and errors, keyboard row activation, focus visibility and restoration, disclosure semantics, live status announcements, textual alternatives for financial signals, reduced motion, non-color risk communication and narrow-screen reflow.

66
Playwright checks passed across product and failure states
0
automated WCAG 2.2 A/AA violations in tested surfaces
320-430
pixel-wide mobile viewports exercised
200%
equivalent zoom/reflow coverage at 640 pixels
Automated coverage is evidence, not a conformance certificate. It was paired with keyboard-flow and responsive browser checks.
User needImplementation evidenceHow I checked it
Understand status without colorRisk and quality use text, iconography and semantic labels as well as colorLight/dark contrast checks and non-color state inspection
Operate the board without a pointerRows, filters, disclosures, factsheets and assistant controls have keyboard semanticsTab-order, focus visibility, Enter/Space activation and focus-return tests
Hear updates and errorsLoading, result counts, assistant responses and failures use appropriate status or alert behaviorAutomated role/name checks plus critical live-region inspection
Zoom or use a narrow viewportCards reflow without two-dimensional page scrolling and primary controls retain usable targets320, 390 and 430 pixel viewports plus 200%-equivalent reflow
The defensible claim is narrow: automated WCAG 2.2 A/AA checks found no violations in the tested views and states. Automated tools cannot prove complete screen-reader or assistive-technology conformance.

What I can and cannot claim

This was a solo experiment, so the evidence is end-to-end ownership: model rules, data boundaries, responsive interaction, accessibility, recovery, tests and deployment. It is not evidence of cross-functional leadership, and the rankings are not evidence of investment returns. The product should be evaluated on research quality: time to compare a shortlist, whether users notice the counter-argument, recovery from stale or failed data, and whether confidence drops appropriately when evidence is incomplete.

What I would improve next

The next version should make score movement easier to audit over time. I would add a change log for why a score moved after each trading session, expose the raw fields that contributed to the final judgment, and extend the accessibility pass with structured testing across multiple screen-reader and browser combinations.