FinancialsWatcher

  • Python
  • asyncio
  • Gemini
  • FastAPI
  • PostgreSQL
  • discord.py
  • Kafka
  • Confluent Cloud
  • Docker

What it does

FinancialsWatcher monitors SEC Form 8-K earnings filings, analyzes the associated press release, and posts structured alerts to Discord channels watching that ticker. The alert combines reported EPS and revenue, guidance changes, management tone, and risk flags, with a link back to the filing.

The project is implemented in beating-the-sec. It covers the path from finding a filing to delivering one analysis to multiple subscribed servers, rather than running a separate AI workflow for each subscriber.

White board design.
White board design of the Planner Agent.

Architecture

Earnings calendar + subscribed tickers
                 ↓
Budgeted SEC polling → fetch earnings exhibit
                 ↓
Normalize text → deduplicate → split sections
                 ↓
Parallel Gemini workers: extraction / sentiment / risk
                 ↓
Aggregate structured alert → Discord webhook fan-out

PostgreSQL holds the ticker registry, earnings calendar, guild subscriptions, alerts, and persisted analysis. The default Docker Compose setup runs the ingestion–analysis–delivery pipeline in one process with an in-memory queue, alongside separate bot, admin, database, and calendar-refresh services.

For a split deployment, the repository also implements Kafka stages using Confluent connection settings: ingestion publishes filing metadata to raw_filings, an AI consumer produces filing_results, and delivery consumers route those results to subscribers. Failed AI-stage messages can be sent to filing_dlq.

Engineering decisions

Spend polling capacity on relevant companies. A shared rotation scheduler replaces independent polling loops per company. Its calendar-backed hot set selects subscribed tickers expected to report that day, with configurable windows around estimated report times and broader session windows when the time is unknown. The current configuration polls batches of up to seven companies, leaves headroom for document fetches, and times out slow individual polls. Post-detection cooldowns prevent immediate repeat polling.

Run independent analysis concurrently. Financial extraction, sentiment, and risk workers run through asyncio.gather, each receiving the sections relevant to its task. The single-process consumer also limits how many filings undergo analysis simultaneously. This overlaps external API waits without letting every filing create unrestricted concurrent AI work.

Reuse expensive results. Content hashes filter duplicate normalized documents. In the single-process path, successful analyses are also persisted by (ticker, accession) and reused when that filing is processed again. The analysis and alert can be shared across subscribed guilds instead of paying for another set of model calls per recipient.

Keep the final signal inspectable. Gemini returns structured fields, while a separate deterministic aggregator applies explicit weights to earnings surprises, guidance, sentiment confidence, and risk. The bullish/neutral/bearish label is a heuristic summary—not a validated trading prediction.

Discord setup and operations

Server administrators choose an alert channel with /setup and manage tickers with /watch add, /watch remove, and /watch list. Alerts are guild-level broadcasts, not personalized messages to individual members. A /calendar command shows upcoming earnings, and deleted or invalid webhooks trigger guild deactivation.

The FastAPI admin interface manages the ticker universe and guild bans, displays API and command statistics, and streams selected container logs. Command timings and buffered API-request logs provide operational visibility. Docker Compose and GitHub Actions supply deployment wiring.

Discord bot.
Signal from the Discord bot.

Testing and limits

The repository includes mocked tests for normalization, aggregation, scheduling, and Discord delivery behavior, plus opt-in checks against SEC, Gemini, Kafka, Discord, and PostgreSQL. Its Locust scenarios exercise the HTTP API; they do not establish end-to-end filing-detection latency.

Detection depends on the active hot set, polling and document-fetch times, calendar accuracy, model response times, and delivery. Calendar gating reduces unnecessary requests but can miss filings outside the expected date or window; the alternative accession-prediction backstop is not wired into the active watcher.

Content deduplication and cached analyses also do not guarantee exactly-once delivery. Durable retry and delivery tracking, together with better treatment of partial AI failures, remain important reliability improvements.