StockLens API Console

The open-source stock research engine that keeps score. Every endpoint below is generated from the live OpenAPI document, and every example response was captured from a real call on deterministic demo data.

A model that keeps score

Most analytics stacks end at "show the number". StockLens is organised around what happens next: every claim is committed, checked against what happened, and fed back.

The proof loop: report, commit, ledger, resolve, grade, decide, back to report 1 · Score regime → 8 families → blend quant · research · drivers 2 · Commit P(up in 21 sessions), 1σ range features · model version 3 · Ledger append-only · one per symbol/day written before the outcome exists 4 · Resolve 21 sessions later, write-once outcome · inside range? 5 · Grade Brier skill · reliability curve t-test over independent blocks 6 · Test every claim Evidence lab: walk-forward, permutation, deflated Sharpe · harness: regime A/B 7 · Earn the weights picked defaults stay labelled "picked" until the record says otherwise (ADR 0006) Data aggregators stop at step 1. Steps 2–7 are what make a number on this site checkable.
Browser to edge proxy to the StockLens container, which reaches market data, SEC EDGAR, the Anthropic API and PostgreSQL Container · non-root · read-only FS · no shell Egress allowlist Browser strict CSP Edge TLS 1.2+ · WAF rate limit · firewall Security middleware headers · token bucket · API key · request ID · JSON logs API routes /api/v1 · validation Analyst agent bounded tool loop Report builder one report feeds the page, the agent and the evaluator Analytics engines signals · quant · research Data facade providers · TTL cache Persistence (SQLAlchemy Core) snapshots · forecast ledger · agent_runs (append-only) Anthropic API Claude, tool use Market data bars · news (read-only) SEC EDGAR XBRL filings PostgreSQL private network

Pure engines

analytics, quant, research, forecast and evidence are pure Python over plain dataclasses: no I/O, no framework, no NumPy. One report object is shared by the page, the agent and the evaluator.

Append-only state

Snapshots, the forecast ledger and agent runs are append-only. A forecast is written before its outcome exists and resolved exactly once.

Tested on noise

Each estimator is tested on a seeded random walk, where it must find nothing, and on a planted signal, where it must find it.

Secure by default

Strict CSP, token-bucket limits, constant-time API keys, ticker allowlist before any upstream URL, non-root read-only container, default-deny egress.

Anatomy of /api/v1/symbols/{symbol}/report

One object, computed in a single pass, read by the page, the AI analyst and the evaluation harness alike. Click a section to see its example.

Select a section

The analyst's tools

Every tool is read-only, takes no symbol, URL or free-form query, and is bound server-side to one report. The terminal submit_report is re-validated and every cited figure is checked against what these tools returned.

Run it locally in a minute

No keys needed: demo mode generates a deterministic factor-model market per ticker.

Install and run

git clone https://github.com/anand4286/stocklens.git
cd stocklens
python3 -m venv .venv && source .venv/bin/activate
pip install --require-hashes -r requirements-dev.lock -r requirements-build.lock
pip install --no-deps --no-build-isolation -e .
uvicorn --factory stocklens.app:app_factory --port 8080

Call the API

curl -s localhost:8080/api/v1/symbols/MSFT/report \
  | jq '{call: .forecast.p_up,
         regime: .quant.regime.trend,
         beta: .drivers.attribution.market_beta.value}'

curl -s localhost:8080/api/v1/track-record \
  | jq '.simulated.scoring.verdict'

Real data (optional, free tiers)

STOCKLENS_DATA_PROVIDER=alpaca
STOCKLENS_ALPACA_API_KEY_ID=…
STOCKLENS_ALPACA_API_SECRET_KEY=…
STOCKLENS_SEC_USER_AGENT="Your Name you@example.com"
STOCKLENS_ANTHROPIC_API_KEY=…

Secrets live only in your environment or a secret manager — never in the repository.

"Try it" from this page

Set Server above to your instance and press Send on any endpoint. Your instance must allow this origin: STOCKLENS_CORS_ORIGINS=["https://anand4286.github.io"]. Calls go from your browser to your server only.