Explainable Trade Insights for the London Stock Exchange
An AI-powered fintech platform that combines real-time market data, natural-language screening, technical pattern detection, and news intelligence to deliver actionable, explainable trade insights for LSE-listed stocks.
- Features
- Architecture
- Tech Stack
- Project Structure
- Prerequisites
- Installation
- Configuration
- Running the Project
- API Reference
- Frontend Pages
- How It Works
- Contributing
- License
| Category | Description |
|---|---|
| Opportunity & Risk Scoring | Every stock gets a 0–100 opportunity score and a 0–100 risk score, computed from fundamentals, price action, and momentum indicators. |
| Explainable Drivers | Each score is broken down into named drivers (e.g., "Strong ROE", "High Debt-to-Equity") with impact values a trader can audit. |
| Natural-Language Screener | Type queries like "Show me stocks with ROE above 20% and PE below 15" — a LangGraph supervisor agent parses the intent, builds SQL, and returns ranked results. |
| Technical Pattern Scanner | Automated detection of Golden Cross, Death Cross, RSI Oversold/Overbought, Near Breakout, Volume Surges, MACD crossovers, and more — refreshed every 30 minutes. |
| Custom Pattern Strategies | Describe a strategy in plain English (e.g., "Find oversold stocks with bullish MACD near 52-week low") and the LLM translates it into a multi-condition technical scan. |
| Market Intel Feed | RSS ingestion from BBC Business, CNBC, Google News, MarketWatch, and Yahoo Finance — deduplicated into stories, enriched with LLM sentiment analysis, entity extraction, and per-stock impact mapping. |
| Interactive Charts | OHLCV candlestick charts with SMA-50, SMA-200, RSI, MACD, and volume overlays powered by Recharts. |
| Discovery Dashboard | Leaderboard of most-screened stocks and biggest daily movers. |
| Firebase Auth | Google sign-in via Firebase Authentication with protected routes. |
| Saved Queries & Screens | Persist any screener result or query to revisit later. |
┌─────────────────────────────────────────────────────────────────┐
│ Next.js Frontend │
│ (React 19 · Tailwind CSS 4 · Recharts · Firebase Auth) │
└──────────────────────────────┬──────────────────────────────────┘
│ REST (JSON)
▼
┌─────────────────────────────────────────────────────────────────┐
│ FastAPI Backend │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────────────┐ │
│ │ Supervisor │ │ Screener │ │ Market Feed Pipeline │ │
│ │ Agent │→ │ Agent │ │ (fetch → dedup → │ │
│ │ (LangGraph) │ │ (NL → SQL) │ │ LLM enrich → store) │ │
│ └─────────────┘ └──────────────┘ └────────────────────────┘ │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────────────┐ │
│ │ Scoring │ │ Pattern │ │ Chart Data │ │
│ │ Engine │ │ Scanner │ │ (yfinance OHLCV) │ │
│ └─────────────┘ └──────────────┘ └────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
SQLite DB Yahoo Finance OpenAI / GPT
(companies, (live prices, (intent routing,
stories, fundamentals, NL parsing,
screens, OHLCV data) enrichment)
queries)
- Python 3.11+ — runtime
- FastAPI — async REST API framework
- LangChain + LangGraph — multi-agent orchestration (supervisor → screener / analyzer / market-feed)
- OpenAI GPT-4o-mini — intent classification, NL-to-SQL, sentiment analysis, entity extraction
- yfinance — real-time and historical market data from Yahoo Finance
- pandas / NumPy — data processing and scoring computations
- NLTK — text processing utilities
- SQLite (WAL mode) — lightweight embedded database
- Next.js 16 (App Router,
"use client"components) - React 19 — UI framework
- Tailwind CSS 4 — utility-first styling
- Recharts — interactive charting library
- Firebase — Google authentication & analytics
fintech-code/
├── README.md
├── package.json
├── backend/
│ ├── requirements.txt # Python dependencies
│ ├── .env # Environment variables (create this)
│ ├── data/
│ │ ├── lse_tickers.csv # LSE ticker list (~350 companies)
│ │ └── finlse.db # SQLite database (auto-created)
│ └── app/
│ ├── main.py # FastAPI app, routes, background schedulers
│ ├── db.py # SQLite schema & connection management
│ ├── scoring.py # Opportunity/Risk scoring engine
│ ├── patterns.py # Technical pattern scanner (Golden Cross, RSI, etc.)
│ ├── ingest.py # Bulk company fundamentals ingestion
│ ├── models.py # Pydantic models (request/response + LLM structured output)
│ └── agents/
│ ├── supervisor.py # LangGraph supervisor — routes to specialist agents
│ ├── screener.py # NL→SQL screener agent
│ ├── market_feed.py # RSS ingest → dedup → LLM enrich → query pipeline
│ └── prompts.py # System prompts for all LLM agents
├── finlse-frontend/
│ ├── package.json
│ ├── next.config.ts
│ ├── tsconfig.json
│ ├── app/
│ │ ├── layout.tsx # Root layout with NavBar
│ │ ├── page.tsx # Home — unified prompt bar (screener/pattern/intel)
│ │ ├── globals.css # Global styles
│ │ ├── analyze/page.tsx # Single-ticker deep analysis
│ │ ├── chart/[ticker]/page.tsx # Interactive OHLCV chart
│ │ ├── discovery/page.tsx # Leaderboard & hot stocks
│ │ ├── market-feed/page.tsx # News intelligence feed
│ │ ├── patterns/page.tsx # Technical patterns dashboard
│ │ ├── screens/page.tsx # Saved screens list
│ │ ├── screens/[id]/page.tsx # Saved screen detail
│ │ ├── queries/page.tsx # Saved queries list
│ │ ├── queries/[id]/page.tsx # Saved query detail
│ │ ├── login/page.tsx # Firebase Google sign-in
│ │ ├── register/page.tsx # Registration page
│ │ └── components/ # Reusable UI components
│ │ ├── NavBar.tsx
│ │ ├── PriceChart.tsx
│ │ ├── ScoreRing.tsx
│ │ ├── SentimentGauge.tsx
│ │ ├── DriverList.tsx
│ │ └── ui/ (Badge, Button, Card, Input)
│ └── lib/
│ └── firebase.ts # Firebase config & auth helpers
| Tool | Version | Purpose |
|---|---|---|
| Python | 3.11+ | Backend runtime |
| Node.js | 18+ | Frontend runtime |
| npm | 9+ | Frontend package manager |
| OpenAI API Key | — | Required for NL screening, pattern parsing, and market-feed enrichment |
git clone https://github.com/<your-username>/fintech-code.git
cd fintech-code# Create a Python virtual environment (from the repo root)
python -m venv .venv
# Activate it
# Windows (PowerShell):
.\.venv\Scripts\Activate.ps1
# Windows (CMD):
.\.venv\Scripts\activate.bat
# macOS / Linux:
source .venv/bin/activate
# Install Python dependencies
pip install -r backend/requirements.txtcd finlse-frontend
npm install
cd ..Create a .env file inside the backend/ directory:
# backend/.env
# Required — OpenAI API key for LLM agents
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Optional — override the default model (default: gpt-4o-mini)
LLM_MODEL=gpt-4o-miniOptionally, create a .env.local in finlse-frontend/ for Firebase and API overrides:
# finlse-frontend/.env.local
NEXT_PUBLIC_API_BASE=http://localhost:8000
# Firebase (optional — defaults are built-in)
NEXT_PUBLIC_FIREBASE_API_KEY=your-key
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-projectTerminal 1 — Backend:
cd backend
..\.venv\Scripts\python.exe -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000Terminal 2 — Frontend:
cd finlse-frontend
npm run dev# Terminal 1:
cd backend; ..\.venv\Scripts\python.exe -m uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
# Terminal 2:
cd finlse-frontend; npm run dev| Service | URL |
|---|---|
| Frontend | http://localhost:3000 |
| Backend API | http://localhost:8000 |
| Swagger Docs | http://localhost:8000/docs |
| Health Check | http://localhost:8000/health |
On first startup, the backend auto-initializes the SQLite database. To bulk-load company fundamentals:
cd backend
..\.venv\Scripts\python.exe -m app.ingest # all ~350 LSE tickers
..\.venv\Scripts\python.exe -m app.ingest --limit 10 # quick test with 10Note: Always
cdinto the correct directory before running commands. Runningnpm run devfrom the repo root will cause Turbopack to resolve packages from the wrong directory.
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/analyze?ticker=VOD |
Opportunity/risk scores + explainable drivers for a single ticker |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/query |
Routes to screener, pattern, or intel mode based on query content. Body: { "query": "...", "mode": "auto" } |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/chat |
Free-form NL query routed through the LangGraph supervisor agent. Body: { "message": "..." } |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/market-feed/ingest |
Trigger RSS ingestion → dedup → LLM enrichment pipeline |
POST |
/api/market-feed/query |
NL query over ingested stories. Body: { "query": "...", "limit": 10 } |
GET |
/api/market-feed/stories |
Paginated story list. Params: page, limit |
GET |
/api/market-feed/stories/:id |
Story detail with AI analysis, entities, and stock impacts |
GET |
/api/market-feed/status |
Auto-ingest scheduler status |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/patterns |
Cached pattern scan results (Golden Cross, RSI, Breakout, etc.) |
POST |
/api/patterns/scan |
Manually trigger a full pattern scan |
GET |
/api/stock/:ticker/chart |
OHLCV + indicators chart data. Params: period, interval |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/screens |
Save a screen |
GET |
/api/screens |
List saved screens |
GET |
/api/screens/:id |
Get screen detail + results |
DELETE |
/api/screens/:id |
Delete a screen |
POST |
/api/queries |
Save a query |
GET |
/api/queries |
List saved queries (optional ?mode= filter) |
GET |
/api/queries/:id |
Get saved query + result snapshot |
DELETE |
/api/queries/:id |
Delete a query |
| Method | Endpoint | Description |
|---|---|---|
GET |
/api/discovery/leaderboard |
Most-screened stocks across saved screens |
GET |
/api/discovery/hot |
Biggest daily movers by absolute price change |
GET |
/api/companies |
Paginated company list sorted by market cap |
| Route | Description |
|---|---|
/ |
Home — Unified prompt bar with three modes: Screener, Patterns, Market Intel |
/analyze |
Analyze — Single-ticker deep analysis with score rings, driver list, and sentiment gauge |
/chart/[ticker] |
Chart — Interactive OHLCV chart with SMA, RSI, MACD overlays |
/discovery |
Discovery — Leaderboard of popular stocks + hot movers |
/market-feed |
Market Feed — Browse and search AI-enriched news stories |
/patterns |
Patterns — Technical pattern dashboard (Golden Cross, RSI Oversold, etc.) |
/screens |
Screens — List and manage saved screening results |
/queries |
Queries — List and manage saved queries across all modes |
/login |
Login — Google sign-in via Firebase |
/register |
Register — Account registration |
The ingest.py module reads lse_tickers.csv and fetches fundamentals (PE, ROE, margins, growth, debt ratios) and price-change data from Yahoo Finance for each LSE-listed company, storing everything in SQLite.
scoring.py downloads 6 months of daily price data for a given ticker, computes momentum indicators (RSI, MACD, moving averages, volatility), and combines them with fundamental ratios into a weighted Opportunity Score and Risk Score (both 0–100). Each contributing factor is returned as a named Driver with an impact value and human-readable explanation.
The backbone of the NL interface is a LangGraph state machine with three specialist agents:
- Supervisor — classifies user intent (
screen,analyze, orgeneral) and routes to the correct sub-graph. - Screener — parses NL queries into structured SQL filters using GPT-4o-mini with Pydantic structured output, executes the query against the
companiestable, and summarizes results. - Market Feed — a four-stage pipeline (fetch RSS → deduplicate articles → LLM-enrich stories with sentiment/entities/impact mapping → persist to SQLite) plus a query pipeline with NL expansion for retrieval.
patterns.py scans all LSE tickers every 30 minutes for pre-defined chart patterns (Golden Cross, Death Cross, RSI Oversold/Overbought, Near Breakout, Volume Surge, MACD crossovers, Consolidation). Results are cached and served via API. Users can also describe custom strategies in natural language, which the LLM converts into multi-condition scans.
On startup, the FastAPI lifespan context launches two background tasks:
- Auto-ingest — refreshes the market-feed every 60 minutes
- Pattern scan — refreshes technical patterns every 30 minutes
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m "Add my feature" - Push to the branch:
git push origin feature/my-feature - Open a Pull Request
Please ensure your code follows the existing project style and includes appropriate error handling.
This project is licensed under the MIT License.