Skip to content

Architecture Overview

TerraFin is a contract-first stack: every data source returns one of a small set of predefined contracts, the DataFactory is the single facade in front of those providers, and one CacheManager owns refresh and invalidation for every source.

Routes / Agent / Frontend
   DataFactory ──── CacheManager (uniform cache for all sources)
   Providers (all return predefined contracts only)
   ├── yfinance        (market data, fundamentals)
   ├── FRED            (economic indicators)
   ├── market indicator (VIX, MOVE, ...)
   ├── economic        (UNRATE, M2, derived indicators)
   ├── private_access  (CAPE, fear/greed, breadth, P/E spread — HTTP to sibling DataFactory)
   ├── SEC EDGAR       (filings, 13F)
   └── corporate       (yfinance fundamentals)

Signal pipeline

Signals (name, ticker, severity, message, snapshot) flow into TerraFin from two directions, sharing one dataclass. The pull side is analytics/analysis/patterns/ — call evaluate(ticker, ohlc) and get back any patterns that match the latest bar (used by the agent flow, weekly reports, ad-hoc backtests). The push side is interface/monitor/ — an external realtime monitor service (DataFactory) holds a broker WebSocket open, runs intraday detectors, and POSTs each fired event to /signals/api/signal, where it is HMAC-verified, deduped, and forwarded to the user's Telegram via interface/channels/.

Components

The single most important rule across components: providers never expose ad-hoc dicts. They return a contract from src/TerraFin/data/contracts/, and everything downstream — routes, agent, frontend — depends only on those contract types.