Skip to content

System Architecture

Overview

Maricusco is a multi-agent trading system built on LangGraph that orchestrates specialized AI agents to analyze market data and make informed trading decisions. The architecture follows a modular monolith pattern with clear separation of concerns, enabling maintainability and future microservices migration.

Technology Stack

Category Technology Purpose
Language & Runtime Python Core programming language
uv Package manager and dependency resolver
Web Framework FastAPI REST API framework
Uvicorn ASGI server
Pydantic Data validation
Orchestration LangGraph Multi-agent workflow orchestration
LangChain LLM integration framework
LLM Providers OpenAI GPT models
Anthropic Claude models
Google Gemini Gemini models
Ollama Local LLM hosting
OpenRouter Unified LLM API
Data Sources yfinance Stock price data
Alpha Vantage Financial data API
Google News News aggregation
Reddit PRAW Social sentiment
Databases PostgreSQL Relational database
TimescaleDB Time-series extension
Redis Caching layer
ChromaDB Vector database
Monitoring Prometheus Metrics collection
Grafana Metrics visualization
structlog Structured logging
Containerization Docker Container runtime
Docker Compose Multi-container orchestration
CI/CD GitHub Actions Continuous integration
Development Tools Ruff Linter and formatter
Pyright Type checker
Pytest Testing framework
Pre-commit Git hooks

High-Level Architecture

graph TB
    subgraph "User Interface Layer"
        CLI[CLI Interface]
        API[FastAPI REST API]
    end

    subgraph "Orchestration Layer"
        TG[Trading Graph<br/>LangGraph Workflow]
        CL[Conditional Logic]
        SY[Synchronization]
        PR[Propagation]
    end

    subgraph "Agent Layer"
        subgraph "Analysts"
            TA[Technical Analyst]
            FA[Fundamentals Analyst]
            SA[Sentiment Analyst]
            NA[News Analyst]
        end

        subgraph "Researchers"
            BR[Bull Researcher]
            BER[Bear Researcher]
            RM[Research Manager]
        end

        subgraph "Trading"
            TR[Trader Agent]
        end

        subgraph "Risk Management"
            AD[Aggressive Debator]
            CD[Conservative Debator]
            ND[Neutral Debator]
            RMG[Risk Manager]
        end
    end

    subgraph "Data Layer"
        DI[Data Interface]
        CACHE[Cache Client]
        MEM[Memory System]

        subgraph "Data Vendors"
            YF[yfinance]
            AV[Alpha Vantage]
            GN[Google News]
            RD[Reddit]
            LOC[Local Data]
        end
    end

    subgraph "Infrastructure Layer"
        PG[(PostgreSQL<br/>TimescaleDB)]
        RDS[(Redis Cache)]
        CHR[(ChromaDB<br/>Vector Store)]
        PROM[Prometheus]
        GRAF[Grafana]
    end

    CLI --> TG
    API --> TG
    TG --> CL
    TG --> SY
    TG --> PR

    CL --> TA
    CL --> FA
    CL --> SA
    CL --> NA
    CL --> BR
    CL --> BER
    CL --> RM
    CL --> TR
    CL --> AD
    CL --> CD
    CL --> ND
    CL --> RMG

    TA --> DI
    FA --> DI
    SA --> DI
    NA --> DI
    BR --> MEM
    BER --> MEM
    RM --> MEM
    TR --> MEM
    RMG --> MEM

    DI --> CACHE
    DI --> YF
    DI --> AV
    DI --> GN
    DI --> RD
    DI --> LOC

    CACHE --> RDS
    MEM --> CHR
    TG -.metrics.-> PROM
    PROM --> GRAF

    style CLI fill:#7A9A7A,stroke:#6B8E6B,color:#fff
    style API fill:#7A9A7A,stroke:#6B8E6B,color:#fff
    style TG fill:#7A9FB3,stroke:#6B8FA3,color:#fff
    style DI fill:#C4A484,stroke:#B49474,color:#fff
    style PG fill:#9B8AAB,stroke:#8B7A9B,color:#fff
    style RDS fill:#9B8AAB,stroke:#8B7A9B,color:#fff
    style CHR fill:#9B8AAB,stroke:#8B7A9B,color:#fff

Architecture Layers

1. User Interface Layer

CLI Interface (cli/)

  • Interactive terminal interface using typer and rich
  • Provides user-friendly prompts for ticker selection, date range, analyst selection
  • Displays formatted reports and trading decisions
  • Supports mock mode for cost-free development

FastAPI REST API (maricusco/api/)

  • Health check endpoint (/health) with dependency validation
  • Metrics endpoint (/metrics) for Prometheus scraping
  • Extensible for future trading API endpoints
  • Asynchronous request handling with uvicorn

2. Orchestration Layer (maricusco/orchestration/)

The orchestration layer manages agent workflow execution using LangGraph.

Trading Graph (trading_graph.py)

  • Defines the complete trading workflow as a LangGraph state machine
  • Manages state transitions between analyst, researcher, trader, and risk management phases
  • Handles error propagation and recovery

Conditional Logic (conditional_logic.py)

  • Determines workflow routing based on state conditions
  • Decides which agents to invoke based on configuration
  • Manages debate round limits and termination conditions

Propagation (propagation.py)

  • Main entry point for workflow execution
  • Initializes state and invokes the trading graph
  • Handles final decision extraction and report generation

3. Agent Layer (maricusco/agents/)

Specialized AI agents that perform specific analysis and decision-making tasks.

Analysts (agents/analysts/)

Technical Analyst (technical_analyst.py) - Analyzes price patterns, trends, and technical indicators - Uses MACD, RSI, moving averages, volume analysis - Identifies support/resistance levels and chart patterns - Tools: get_stock_data, get_technical_indicators

Fundamentals Analyst (fundamentals_analyst.py) - Evaluates company financials and performance metrics - Analyzes P/E ratio, EPS, revenue, market cap, growth rates - Assesses financial health and intrinsic value - Tools: get_fundamental_data

Sentiment Analyst (sentiment_analyst.py) - Analyzes social media and public sentiment - Aggregates sentiment from Reddit, Twitter, news sources - Provides sentiment scores and distribution analysis - Tools: get_sentiment_data

News Analyst (news_analyst.py) - Monitors global news and macroeconomic indicators - Interprets impact of events on market conditions - Assesses news sentiment and relevance - Tools: get_news_data

Researchers (agents/researchers/)

Engage in structured debates to refine investment theses.

Bull Researcher (bull_researcher.py) - Advocates for bullish positions - Identifies growth opportunities and positive signals - Challenges bearish arguments with data-driven counterpoints - Uses memory to recall past successful bull scenarios

Bear Researcher (bear_researcher.py) - Advocates for bearish positions - Identifies risks, valuation concerns, and negative signals - Challenges bullish arguments with risk analysis - Uses memory to recall past risk scenarios

Research Manager (research_manager.py) - Facilitates debates between bull and bear researchers - Synthesizes arguments from both sides - Makes definitive investment decisions (BUY/SELL/HOLD) - Provides balanced recommendations based on strongest evidence

Trading (agents/trader/)

Trader Agent (trader.py) - Composes reports from analysts and researchers - Determines timing and magnitude of trades - Creates detailed investment plans with entry/exit parameters - Considers risk-reward ratios and position sizing

Risk Management (agents/risk_mgmt/)

Evaluates trading proposals through multi-perspective debate.

Aggressive Debator (aggressive_debator.py) - Advocates for higher-risk, higher-reward strategies - Identifies maximum upside potential - Challenges conservative risk assessments

Conservative Debator (conservative_debator.py) - Advocates for lower-risk, capital preservation strategies - Emphasizes downside protection and risk mitigation - Challenges aggressive risk-taking

Neutral Debator (neutral_debator.py) - Provides balanced risk assessment - Mediates between aggressive and conservative perspectives - Identifies optimal risk-reward balance

Risk Manager (risk_manager.py) - Consolidates risk perspectives into final trading plan - Applies risk management rules and constraints - Validates position sizing and stop-loss parameters - Produces executable trading plan (used for simulated execution)

4. Data Layer (maricusco/data/)

Provides unified interface to multiple market data sources.

Data Interface (interface.py)

  • Unified API for accessing market data across vendors
  • Vendor selection based on configuration and data type
  • Automatic fallback to alternative vendors on failure
  • Caching layer for performance optimization

Cache Client (cache.py)

  • Redis-backed caching with automatic fallback to in-memory cache
  • Configurable TTL and eviction policies
  • Metrics instrumentation for cache hit/miss rates
  • Async-compatible for high-performance data access

Memory System (memory.py)

  • ChromaDB-backed vector memory for agent learning
  • Stores past trading scenarios, recommendations, and outcomes
  • Semantic search for retrieving relevant historical context
  • Per-agent memory isolation with shared memory support

LLM Factory (llm_factory.py)

  • Creates LLM instances based on configuration
  • Supports OpenAI, Anthropic, Google Gemini, Ollama, OpenRouter
  • Mock LLM support for cost-free development
  • Configurable model parameters and retry logic

Data Vendors (data/vendors/)

yfinance (y_finance.py) - Primary source for stock price data and technical indicators - Free, no API key required - Historical and real-time data support

Alpha Vantage (alpha_vantage_*.py) - Stock data, technical indicators, fundamentals, news - Requires API key (free tier available) - Modular implementation per data type

Google News (google.py) - News articles and headlines via Google News RSS - No API key required - Real-time news aggregation

Reddit (data/utils/reddit_utils.py) - Social sentiment from financial subreddits - Requires Reddit API credentials - Sentiment analysis on post titles and comments

Local Data (local.py) - Cached data storage for offline development - CSV-based historical data - Mock data for testing

Data Tools (data/tools/)

LangChain tool wrappers for agent access to data sources.

  • core_stock_tools.py: Stock price and volume data
  • technical_indicators_tools.py: MACD, RSI, moving averages
  • fundamental_data_tools.py: Financial statements, ratios
  • news_data_tools.py: News articles and sentiment
  • agent_utils.py: Shared utilities for tool creation

5. Infrastructure Layer

PostgreSQL with TimescaleDB

  • Time-series database for storing trading data
  • Optimized for time-series queries and aggregations
  • Persistent storage for historical analysis
  • Port: 5432

Redis Cache

  • In-memory caching layer for market data
  • Reduces API calls and improves performance
  • Session storage and rate limiting
  • Port: 6379

ChromaDB Vector Store

  • Vector database for agent memory storage
  • Semantic search for historical trading scenarios
  • Embeddings-based similarity matching
  • Port: 8000

Prometheus

  • Metrics collection and time-series storage
  • Scrapes /metrics endpoint every 15 seconds
  • 15-day retention for historical analysis
  • Port: 9090

Grafana

  • Metrics visualization and dashboards
  • Pre-provisioned dashboards for system monitoring
  • Alerting and anomaly detection
  • Port: 3000

Data Flow

Analysis Workflow

sequenceDiagram
    participant User
    participant CLI
    participant TradingGraph
    participant Analysts
    participant Researchers
    participant Trader
    participant RiskMgmt
    participant DataInterface
    participant Vendors

    User->>CLI: Request analysis (ticker, date)
    CLI->>TradingGraph: Initialize state

    par Parallel Analyst Execution
        TradingGraph->>Analysts: Technical Analyst
        TradingGraph->>Analysts: Fundamentals Analyst
        TradingGraph->>Analysts: Sentiment Analyst
        TradingGraph->>Analysts: News Analyst
    end

    Analysts->>DataInterface: Request market data
    DataInterface->>Vendors: Fetch data (cached)
    Vendors-->>DataInterface: Return data
    DataInterface-->>Analysts: Return data

    Analysts-->>TradingGraph: Analyst reports

    TradingGraph->>Researchers: Bull Researcher
    Researchers->>TradingGraph: Bull arguments
    TradingGraph->>Researchers: Bear Researcher
    Researchers->>TradingGraph: Bear arguments
    TradingGraph->>Researchers: Research Manager
    Researchers->>TradingGraph: Investment decision

    TradingGraph->>Trader: Trader Agent
    Trader->>TradingGraph: Investment plan

    TradingGraph->>RiskMgmt: Risk debate
    RiskMgmt->>TradingGraph: Final trading plan

    TradingGraph-->>CLI: Final decision
    CLI-->>User: Display reports

Configuration Management

Configuration Sources (Priority Order)

  1. Environment Variables (highest priority)
  2. MARICUSCO_* prefixed variables
  3. Docker Compose .env file
  4. System environment

  5. Configuration File (maricusco/config/settings.py)

  6. DEFAULT_CONFIG dictionary
  7. Vendor selection and API keys
  8. Agent parameters and debate rounds

  9. Runtime Parameters (lowest priority)

  10. CLI arguments
  11. API request parameters
  12. Programmatic configuration

Key Configuration Options

DEFAULT_CONFIG = {
    # Execution
    "parallel_execution": True,  # Enable parallel analyst execution
    "max_debate_rounds": 1,      # Bull/bear debate rounds (default)
    "max_risk_discuss_rounds": 1, # Risk debate rounds (default)

    # Mock Mode
    "mock_mode": False,          # Enable mock LLM/memory
    "mock_llm_responses_file": None,
    "mock_agent_delays_ms": {},  # Latency simulation

    # LLM Configuration
    "llm_provider": "openai",    # openai, anthropic, google, ollama
    "deep_think_llm": "o4-mini", # Deep thinking agents
    "quick_think_llm": "gpt-4o-mini", # Quick thinking agents
    "backend_url": "https://api.openai.com/v1",
    "llm_temperature": 0.7,

    # Data Vendors
    "data_vendors": {
        "core_stock_apis": "yfinance",
        "technical_indicators": "yfinance",
        "fundamental_data": "alpha_vantage",
        "news_data": "alpha_vantage",
    },

    # Directories
    "data_cache_dir": "maricusco/data/data_cache",
    "results_dir": "data/results",

    # Observability
    "metrics_enabled": False,
    "logging": {
        "level": "INFO",
        "format": "json",
    },
}

State Management

Agent State Schema

The trading graph maintains a shared state that flows through all agents:

class AgentState(TypedDict):
    # Input
    ticker: str
    date: str

    # Analyst Reports (parallel execution)
    technical_report: Optional[str]
    fundamentals_report: Optional[str]
    sentiment_report: Optional[str]
    news_report: Optional[str]

    # Research Debate
    investment_debate_state: Dict[str, Any]
    investment_recommendation: Optional[str]

    # Trading
    trader_investment_plan: Optional[str]

    # Risk Management
    risk_debate_state: Dict[str, Any]
    final_trade_decision: Optional[str]

    # Metadata
    selected_analysts: List[str]
    config: Dict[str, Any]

State Transitions

  1. Initialization: ticker, date, selected_analysts, config
  2. Analyst Phase: Populate analyst reports in parallel
  3. Synchronization: Validate all reports complete
  4. Research Phase: Populate investment_debate_state, investment_recommendation
  5. Trading Phase: Populate trader_investment_plan
  6. Risk Phase: Populate risk_debate_state, final_trade_decision
  7. Completion: Extract final decision and generate reports

Observability

Structured Logging

  • Framework: structlog with JSON output (production) or human-readable (development)
  • Context propagation: correlation_id, session_id, ticker, user, agent_name
  • Log levels: DEBUG, INFO, WARNING, ERROR, CRITICAL
  • Rotation: Size-based (10MB) or time-based (daily)

Metrics

Prometheus metrics exposed at /metrics:

Counters: - maricusco_api_calls_total: API calls by vendor/agent/operation - maricusco_api_errors_total: API failures - maricusco_events_total: Domain events - maricusco_cache_hits_total, maricusco_cache_misses_total: Cache outcomes

Gauges: - maricusco_active_agents: Active agent executions - maricusco_queue_size: Queue depth

Histograms: - maricusco_latency_seconds: External/internal step latency - maricusco_execution_time_seconds: Agent execution time - maricusco_request_duration_seconds: API request duration

Health Checks

FastAPI /health endpoint validates: - PostgreSQL connectivity - Redis connectivity - Data vendor availability (optional)

Returns 200 (healthy) or 503 (unhealthy) with detailed dependency status.

Security Considerations

API Key Management

  • Store API keys in environment variables or .env file
  • Never commit API keys to version control
  • Use .secrets.baseline for secret detection
  • Rotate keys regularly

Input Validation

  • Validate ticker symbols and date ranges
  • Sanitize user inputs to prevent injection attacks
  • Rate limiting on API endpoints

Dependency Security

  • Regular dependency updates via Dependabot
  • Security scanning with bandit and pip-audit
  • Trivy scanning for Docker image vulnerabilities
  • Pre-commit hooks for secret detection

Network Security

  • Docker network isolation for services
  • Expose only necessary ports
  • Use TLS for production deployments
  • Secure Grafana and Prometheus with authentication

Performance Optimization

Parallel Execution

  • Analyst agents execute concurrently (2-4x speedup)
  • Independent data fetching per analyst
  • Synchronization barrier ensures consistency

Caching Strategy

  • Redis cache for market data (TTL: 5 minutes)
  • In-memory fallback when Redis unavailable
  • Cache warming for frequently accessed data

Database Optimization

  • TimescaleDB for efficient time-series queries
  • Indexed columns for ticker and timestamp
  • Partitioning for large datasets

LLM Optimization

  • Response caching for identical prompts
  • Streaming responses for real-time feedback
  • Batch processing for multiple tickers

Deployment

Docker Compose

services:
  app:          # Maricusco application
  postgres:     # PostgreSQL with TimescaleDB
  redis:        # Redis cache
  chromadb:     # ChromaDB vector store
  prometheus:   # Metrics collection
  grafana:      # Metrics visualization

See Docker Setup for configuration details.

References