Inspiration

Earnings calls move stocks. They happen at 5 PM. Most retail investors are at dinner.

By the next morning, Twitter has formed the opinion for them. They buy at the open from a 280-character take. The pros had analysts on the call, in a war room, reading the language as it was spoken. We wanted retail to have the same depth at the same moment.

What it does

You share a Chrome tab playing an earnings call. The cockpit does the rest.

  • Transcript. The call is written out as it happens, speaker-tagged.
  • Five investors react. Cathie Wood, Michael Burry, Druckenmiller, Cramer, and Howard Marks read the call through their own lens and react every minute.
  • Sentiment. The whole call gets scored on results, demand, margins, credibility, and competition.
  • Memory. MongoDB Atlas Vector Search finds the closest past verdict for what's being said right now. ("This call is a 92% match to NVIDIA, Q3 last year.")
  • Committee. Ten specialist agents vote. A Chairman built on Google's Agent Development Kit weighs the votes and writes the thesis. The verdict is BUY, HOLD, or SHORT.
  • Paper trade. One click executes against Alpaca paper. No real money.
  • PDF report. When the call ends, the cockpit generates the full analyst report and saves it as a PDF.

The Committee shows you the verdict. You make the final call. Even when the Committee says HOLD, the BUY and SHORT buttons stay live — you can override the agents with your own conviction.

How we built it

Agents (Google Cloud)

  • Gemini 3.1 Flash Live for transcription, speaker-tagged at ~150 ms
  • Gemini 3.5 Flash for the 10 specialist agents and the 5 named-investor pulse
  • Gemini 2.5 Flash TTS for the analyst voice replies
  • gemini-embedding-001 (768-d) for verdict embeddings
  • Google Agent Development Kit (LlmAgent) for the Chairman, with 13 registered tools and 5 named-investor sub-agents
  • The Chairman streams every tool call as Server-Sent Events to the cockpit, so you watch the reasoning live

Memory (MongoDB Atlas)

  • Atlas free-tier M0, replica set atlas-1ne3w6-shard-0
  • verdict_vec_idx — Vector Search index, cosine, 768-d
  • find_similar_past_verdict registered as an ADK tool — the Chairman queries it before writing every new verdict
  • remember_verdict writes the new conclusion back, so the next call references this one
  • 22 verdicts indexed, query p50 230 ms

Backend

  • FastAPI + WebSockets + uvicorn
  • Server-Sent Events for ADK streaming
  • Process-wide pymongo singleton, async Atlas writer queue
  • Circuit breaker on every external API boundary

Frontend

  • React 19 cockpit with a custom history-based router
  • Six tabs: Verdict, Committee, Live audio, Memory, Sentiment, Coverage
  • Browser tab share API for live audio capture
  • html2pdf for the analyst report download

Data

  • Finnhub (quotes, analyst consensus, news)
  • Financial Modeling Prep (fundamentals, earnings calendar)
  • FRED (macro)
  • Alpaca (paper trading)

Deployment

Challenges we ran into

Atlas was rejecting Heroku's egress IPs. TLS handshakes from production were failing with TLSV1_ALERT_INTERNAL_ERROR. We chased the wrong fix for hours — custom pymongo retry loops, certifi bundle swaps — before realizing Atlas silently TLS-rejects unallowlisted IPs. It looks like a TLS bug but it's a network ACL. Once we added 0.0.0.0/0 to Network Access and shared one pymongo client across all readers, Vector Search went from 5-second timeouts to 230 ms.

React error #310 was killing the cockpit during live audio. Every time transcript data arrived, the page went blank. We deployed six "fixes" against the backend (Atlas circuit breakers, WebSocket rejection codes, persona pulse memory pressure, browser cache, bundle hash collisions) before a DevTools console screenshot pinpointed the actual bug in five seconds: PersonaPulsePanel.jsx had a useState below a conditional return null, so hook count changed between renders and React unmounted the whole tree. One-line fix. Six wasted deploys. We added a memory note: ask for the console screenshot before guessing.

Heroku Basic dyno (512 MB). Live audio + parallel persona calls + Atlas writes was tight. We cut the MongoDB MCP sidecar from the production image, pinned a thinner requirements-prod.txt, shared every external client as a singleton, and added a process-wide circuit breaker.

Committee was too conservative. The original BUY/SHORT thresholds (70/30) needed every specialist to have data, but during the first 30 seconds of a call the Metrics agent returns neutral. We lowered the hysteresis bands to 60/40 so the committee produces decisive verdicts mid-call when sentiment, news, and persona consensus agree — without rubber-stamping anything.

Accomplishments that we're proud of

  • A real, live earnings call goes through the cockpit end-to-end: audio share → transcript → five-investor reactions → sentiment → pattern match → committee verdict → paper trade → PDF report. No mocking.
  • MongoDB Atlas Vector Search is genuinely live in production, not stubbed. 22 verdicts indexed, similarity 0.90+ on relevant matches, 230 ms p50.
  • All five named-investor reactions run in parallel and complete in ~1.5 seconds.
  • The Chairman's tool calls stream as Server-Sent Events — you watch the agent reason in real time.
  • Public live URL with no setup. Judges hit it directly: https://earningsedge-3391b61f61d9.herokuapp.com

What we learned

  • Atlas's silent TLS reject on unallowlisted IPs is the single most confusing failure mode we've ever debugged. We shipped a /api/atlas/health endpoint that returns a structured error so the next person spends 10 seconds, not 10 hours.
  • React's minified error codes decode at react.dev/errors/<code> and pinpoint the file:line. Server logs will never show a frontend crash. Always ask for the DevTools console screenshot first.
  • Giving each ADK sub-agent a clear human lens (innovation, forensic, macro, narrative, cycles) produces tighter prompts than abstract "bull" / "bear" labels.
  • Atlas free-tier M0 supports Vector Search. The index builds in ~30 seconds. Free tier is enough for a hackathon demo.

What's next for EarningsEdge

  • More personas. Sector specialists like Mary Meeker on consumer tech and Bill Ackman on activist plays.
  • Real-money mode behind explicit consent gates — Alpaca live API.
  • Mobile cockpit. Chrome on iOS supports tab audio share; we need the responsive pass.
  • Daily morning briefing. Overnight, the agents listen to every call on your watchlist and email you the verdicts by 8 AM Wednesday.

Built With

Share this project:

Updates