Multi-source investment intelligence: SEC filings x earnings x news x prediction market odds — structured into a PM-ready research memo with inline source citations.
| Feature | Typical Portfolio Project | Research Signal Agent |
|---|---|---|
| Input/Output | Chat over PDFs | Ticker in, structured memo out |
| Data Sources | Single source (filings OR news) | SEC + News + Market Data + Prediction Markets + Web Search |
| Attribution | Black box answers | Inline colored source badges with hover tooltips |
| Confidence | None | Per-section confidence bars + Polymarket probability calibration |
| LLM Lock-in | Hardcoded to GPT-4 | 4 providers via dropdown (Bedrock, Anthropic, OpenAI, Groq) |
| Evaluation | None | Citation faithfulness scorer + FinanceBench harness |
| Accessibility | Dark mode only | Light / Dark / System with WCAG AA contrast |
- Type
NVDAin the ticker search (autocomplete from 7000+ SEC EDGAR tickers), click Run Research - Watch the 5-agent pipeline trace stream in real time (SSE): MarketData -> Fundamental -> News -> MarketOdds -> Synthesis
- Review the structured memo: investment thesis, key stats (price, P/E, market cap, beta), catalysts with confidence bars, risks with severity flags
- Browse the right panel tabs: Sources (rich cards with type badges), Signals (Polymarket probability bars), Eval (citation faithfulness + provider benchmarks)
- Switch provider in the top bar, re-run — same memo structure, different latency/quality
- Click the theme toggle (sun/moon/monitor): light -> dark -> system
- Hit Stop during a run to abort the pipeline immediately
Ticker Input (e.g. NVDA)
|
v
+--------------------------------------------------+
| Orchestrator (FastAPI SSE) |
+------+--------+--------+---------+---------------+
| | | |
v v v v
MarketData Fundamental News MarketOdds
Agent Agent Agent Agent
(FMP API) (SEC EDGAR (Polygon, (Polymarket
+ Tavily Finnhub, Gamma API)
web search) Tavily)
| | | |
+--------+--------+---------+
|
v
SynthesisAgent
(LLM: structured JSON memo
with inline [n] citations)
|
v
+---------------------------+
| 3-Panel React Frontend |
| Left: Pipeline + History |
| Center: Research Memo |
| Right: Sources/Signals/ |
| Eval (tabbed) |
+---------------------------+
| Agent | Source | What It Adds | LLM? |
|---|---|---|---|
| MarketDataAgent | Financial Modeling Prep (/stable/ API) |
Price, P/E, P/B, beta, market cap, sector, peers | No |
| FundamentalAgent | SEC EDGAR XBRL + Tavily web search | Revenue, margins, cash flow, earnings, analyst estimates | Yes |
| NewsAgent | Polygon.io + Finnhub + Tavily | Recent articles, catalyst extraction, sentiment | Yes |
| MarketOddsAgent | Polymarket Gamma API (no auth needed) | Crowd probability on macro events, earnings, regulatory risk | No |
| SynthesisAgent | All of the above | Structured JSON memo with [n] citations, thesis, catalysts/risks | Yes |
- Investment thesis — 1-2 sentence bull/bear/neutral stance
- Key Statistics — price, market cap, P/E, beta in a 4-column grid
- Inline source citations — colored badges (SEC=blue, News=green, Web=teal, Earnings=purple) with hover tooltips showing title, date, snippet, and link
- Two-column catalysts/risks — catalysts with confidence bars, risks with severity flags and warning icons
- Confidence chips — per-section confidence (high/medium/low) color-coded
- Searches for prediction markets related to the company and macro events (no API key required)
- Probability bars with trading volume
- Divergence flags when LLM confidence differs from crowd odds
- SEC EDGAR: 10-K/10-Q XBRL data (free, no key)
- Financial Modeling Prep: Real-time price, ratios, sector, peers (free tier)
- Polygon.io: Market news (free tier)
- Finnhub: Company news + sentiment (free tier)
- Tavily: Web search for earnings results, analyst estimates (free tier, 1000/mo)
- Polymarket: Prediction market probabilities (public API)
- All sources attributed with type, date, and clickable links
Switch providers with one dropdown or env variable:
| Provider | Model | Use Case |
|---|---|---|
| AWS Bedrock | Claude Sonnet 4 | Production (your AWS account) |
| Anthropic | Claude Sonnet 4 | Direct API, highest quality |
| OpenAI | GPT-4o | Alternative |
| Groq | Llama 3.3 70B | Fastest, cheapest |
- Left (220px): Horizontal pipeline trace with per-agent timing, recent memo history with confidence scores, clear history button
- Center (flex): Full research memo with thesis, metrics, catalysts/risks grid, inline citations
- Right (300px): Tabbed — Sources (rich cards), Signals (Polymarket), Eval (faithfulness + benchmarks). Feedback + export pinned at bottom
- Stop button appears during execution — cancels the fetch via
AbortController - History — past memos stored in SQLite, clickable to reload
- Clear history — one-click delete all
- Citation faithfulness: LLM-as-judge scores claim grounding (0.0-1.0)
- FinanceBench precision@k: Accuracy against golden Q&A pairs from real 10-Ks
- Provider benchmarks: Side-by-side latency comparison across all 4 providers
- Light / Dark / System theme toggle — persists to localStorage, respects OS
prefers-color-scheme - WCAG AA compliant contrast ratios in both themes
prefers-reduced-motiondisables all animations- Visible
:focus-visiblerings for keyboard navigation - Token-based CSS — zero hardcoded colors in components
- Memo-grounded chat answers follow-up questions
- When the memo lacks info, the agent triggers a Tavily web search automatically
- Two-pass streaming: detects
[SEARCH: query]marker, fetches results, re-prompts with context
| Layer | Technology |
|---|---|
| Frontend | React 18 + TypeScript + Vite |
| Backend | FastAPI + Uvicorn (async) |
| Database | SQLite + aiosqlite |
| LLM SDKs | anthropic, openai, boto3 (Bedrock Converse API) |
| HTTP Client | httpx (async) |
| Data Validation | Pydantic v2 |
| News | Polygon.io, Finnhub |
| Market Data | Financial Modeling Prep (/stable/ API) |
| Web Search | Tavily |
| Prediction Markets | Polymarket Gamma API |
| Eval | LLM-as-judge (faithfulness + precision@k) |
- Python 3.11+
- Node.js 18+
git clone https://github.com/AruneshDev/research-signal-agent.git
cd research-signal-agent
# Backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# Frontend
cd frontend && npm install && cd ..cp .env.example .envEdit .env:
# Required — at least one LLM provider
ANTHROPIC_API_KEY=sk-ant-...
# or BEDROCK_API_KEY=...
# or OPENAI_API_KEY=sk-...
# Recommended — data sources (all free tiers)
FINNHUB_API_KEY=... # finnhub.io/register (instant, free)
POLYGON_API_KEY=... # polygon.io (free tier)
FMP_API_KEY=... # financialmodelingprep.com (free, select "Live Stock Data")
TAVILY_API_KEY=tvly-... # tavily.com (1000 searches/mo free)
# Polymarket — no key needed (public API)# Terminal 1 — Backend
uvicorn backend.main:app --reload --port 8000
# Terminal 2 — Frontend
cd frontend && npm run devbackend/
├── agents/
│ ├── base.py # BaseAgent ABC — run(state) -> state
│ ├── orchestrator.py # 5-agent sequential pipeline
│ ├── market_data_agent.py # FMP /stable/profile + /ratios-ttm + /stock-peers
│ ├── fundamental_agent.py # SEC EDGAR XBRL + Tavily web search
│ ├── news_agent.py # Polygon + Finnhub + Tavily
│ ├── market_odds_agent.py # Polymarket Gamma API
│ └── synthesis_agent.py # LLM structured memo (with JSON repair)
├── chat/
│ ├── chat_agent.py # Memo-grounded chat + [SEARCH:] web search
│ └── chat_service.py # Two-pass streaming with search detection
├── providers/
│ ├── base.py # LLMProvider ABC (complete + stream)
│ ├── anthropic.py # Claude via Anthropic SDK
│ ├── openai.py # GPT-4o / Groq via OpenAI SDK
│ └── bedrock.py # AWS Bedrock Converse API
├── tools/
│ ├── web_search.py # Tavily REST API wrapper
│ └── market_data.py # FMP /stable/ API wrapper
├── eval/
│ ├── faithfulness.py # LLM-as-judge citation scorer
│ └── bench.py # FinanceBench precision@k harness
├── routers/
│ ├── research.py # POST /api/research + /stream
│ ├── chat.py # POST /api/chat/session + /stream
│ ├── history.py # GET/DELETE /api/history
│ ├── eval_router.py # POST /api/eval/faithfulness
│ └── feedback.py # POST /api/feedback
├── db/
│ ├── database.py # aiosqlite init (sessions, messages, feedback)
│ └── session_repo.py # All SQL — CRUD + clear_all_sessions
├── models/
│ ├── schemas.py # ResearchMemo, KeyStatistics, PolymarketSignal, etc.
│ └── chat_schemas.py # ChatMessage, ChatSession, etc.
└── config.py # Pydantic Settings from .env
frontend/src/
├── pages/
│ └── ResearchPage.tsx # 3-panel layout (220px / flex / 300px)
├── components/
│ ├── Topbar.tsx # Logo + centered search/run/stop + provider pill + theme
│ ├── LeftPanel.tsx # Pipeline dot-track + step timing + history + clear
│ ├── MemoPanel.tsx # Memo with inline SourceBadge citations + two-col catalysts/risks
│ ├── RightPanel.tsx # Tabbed: Sources cards / Signals bars / Eval scores
│ └── TickerSearch.tsx # SEC EDGAR autocomplete (7000+ tickers)
├── hooks/
│ ├── useResearch.ts # Pipeline state + stop() via AbortController
│ ├── useStream.ts # SSE lifecycle with real abort
│ ├── useTheme.ts # Light/dark/system + localStorage
│ ├── useHistory.ts # Memo history + clear()
│ └── useEval.ts # Faithfulness eval scoring
├── api/
│ ├── client.ts # Typed fetch + SSE + export (JSON/CSV/PDF)
│ └── chat.ts # Chat session + streaming
└── index.css # Design tokens: light/dark/system + short-name aliases
tests/
├── unit/test_agents.py # Agent logic with MockProvider
├── integration/ # End-to-end pipeline tests
└── evals/ # Faithfulness + golden Q&A cases
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/research/stream |
Run 5-agent pipeline, stream AgentEvents via SSE |
POST |
/api/research |
Run pipeline, return completed memo (blocking) |
POST |
/api/chat/session |
Create memo-grounded chat session |
POST |
/api/chat/stream |
Stream chat reply (with web search fallback) |
GET |
/api/history |
List recent research memos |
GET |
/api/history/{id} |
Load specific memo by session |
DELETE |
/api/history |
Clear all memo history |
POST |
/api/eval/faithfulness |
Score citation faithfulness (LLM-as-judge) |
POST |
/api/feedback |
Submit thumbs up/down on memo |
GET |
/health |
Health check |
LLM-agnostic by construction. Agents receive an LLMProvider interface via dependency injection. Swap Claude -> GPT-4o -> Groq with one env variable. Only provider files import SDKs.
Agents are pure functions over state. BaseAgent.run(state) -> state. No globals, no side effects. Fully testable with MockProvider.
Polymarket as a risk-weighting signal. Prediction market probabilities calibrate the memo's risk assessment. Divergence between LLM confidence and crowd odds is flagged automatically.
JSON repair for smaller models. The SynthesisAgent includes a multi-strategy JSON parser that handles trailing commas, unescaped characters, and truncated output — so even Haiku/Llama can produce valid memos.
Eval is first-class. Citation faithfulness scoring and FinanceBench recall ship alongside application code, not as an afterthought.
Theme system is fully tokenized. Zero hardcoded colors in any component CSS. Short-name aliases (--bg, --surface, --green, etc.) resolve to theme-aware --color-* variables. WCAG AA in both light and dark.
- LiveTradeBench — Multi-market LLM agent evaluation across equities + Polymarket
- AlphaAgents — Role-based multi-agent equity research with internal debating
- Financial Agent + FinBloom — Real-time news + tabular data grounding for LLMs
- Multi-HyDE Financial RAG — Multi-query retrieval achieving 92.51% recall on financial corpora
MIT


