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
typerandrich - 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 datatechnical_indicators_tools.py: MACD, RSI, moving averagesfundamental_data_tools.py: Financial statements, ratiosnews_data_tools.py: News articles and sentimentagent_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
/metricsendpoint 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)¶
- Environment Variables (highest priority)
MARICUSCO_*prefixed variables- Docker Compose
.envfile -
System environment
-
Configuration File (
maricusco/config/settings.py) DEFAULT_CONFIGdictionary- Vendor selection and API keys
-
Agent parameters and debate rounds
-
Runtime Parameters (lowest priority)
- CLI arguments
- API request parameters
- 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¶
- Initialization:
ticker,date,selected_analysts,config - Analyst Phase: Populate analyst reports in parallel
- Synchronization: Validate all reports complete
- Research Phase: Populate
investment_debate_state,investment_recommendation - Trading Phase: Populate
trader_investment_plan - Risk Phase: Populate
risk_debate_state,final_trade_decision - Completion: Extract final decision and generate reports
Observability¶
Structured Logging¶
- Framework:
structlogwith 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
.envfile - Never commit API keys to version control
- Use
.secrets.baselinefor 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
banditandpip-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.