Skip to content

GML-FMGroup/FinanceAgent

Repository files navigation

FinanceAgent

A modular, layered trading agent system for real financial markets. Each capability is an independent module that can be developed, tested, and replaced individually, collaborating through clear interface contracts.

Architecture

Screening → Data Layer → Decision → Execution Engine → Execution Results
                                ↑                      ↓
                          Playbook              Trading Evolution (Learning)
                                ↑                      │
                                └──────────────────────┘
                                      Auto-evolution loop

                    ┌──────── Dashboard (Web UI) ────────┐
                    │  FastAPI + SSE → Real-time Control │
                    └────────────────────────────────────┘

The Data Layer pre-prepares all factual data (K-line/technical indicators, news, macro). The Decision Agent executes trades through a deterministic backtest engine (pure in-memory, zero I/O, fully reproducible) — no runtime information fetching, ensuring reasoning stability. After trading completes, the evolution system automatically reflects on trading experience, discovers errors and missed opportunities, generates improvement hypotheses, and validates them through Walk Forward testing before promoting new strategies.

Module Structure

Module Path Responsibility
Stock Screening modules/screening/ Broad-index constituent hard filtering → candidate pool
Data Layer data_layer/ Factual data layer (K-line/technical indicators, news, macro, LLM news summaries)
Decision v2 modules/decision_v2/ Chain of Insight (COI) 4-step structured reasoning + deterministic execution engine
Trade Execution Engine modules/execution/ Deterministic executor: in-memory state management, weighted average cost, P&L calculation
Strategy Playbook modules/playbook/ Narrative trading strategy content (text only); version management lives in learning/
Trading Evolution learning/ Automatic strategy evolution: reflect → knowledge → hypothesize → validate → promote
Dashboard dashboard/ FastAPI Web UI: real-time SSE updates, Start/Stop/Resume control, portfolio charts

Cross-module shared: shared/tools/ (LLM configuration, price tools, general utilities)

Quick Start

# Install environment (using uv)
uv sync

# Configure API keys
cp .env.example .env   # Edit .env and fill in your keys

# Run directly (uses deterministic execution engine)
python main.py

# Generate trading context using Data Layer CLI
python -m data_layer AAPL 2025-10-01 --news-analysis

# Run execution engine tests
pytest tests/test_backtest_engine.py -v

Dashboard

The dashboard provides a web-based control panel for the trading agent:

# Start the dashboard (browser opens at http://127.0.0.1:8080)
python -m dashboard

Features

  • Web UI Control Panel — Configure trading parameters (symbols, date range, cash, market) and start trading from the browser
  • Real-time Updates — SSE (Server-Sent Events) pushes trade progress, portfolio value, and P&L live to the browser
  • Portfolio Chart — Portfolio value over time, daily returns, and trade markers
  • Stop Control — Graceful stop (finishes current day) or immediate cancel
  • Resume / New Run — Auto-detects interrupted runs; choose to continue from where it left off or start fresh
  • Deduplication Safety Net — Chart data automatically deduplicated by date to prevent duplicate entries

Data Caching

The system caches context snapshots and news data automatically to avoid redundant API calls:

Cache Location Behavior
Context Snapshots context_store/{SYMBOL}/{DATE}/ Second run of same date returns in ~0.003s (zero API calls)
News Incremental context_store/_news_cache/ After first full fetch, only pulls new records (~95% API savings)
News Analysis context_store/_news_analysis/ SHA256 hash-based LLM cache (disabled by default)

Already-fetched dates will not trigger API calls on re-run. See CLAUDE.md for details.

Configuration

configs/config.json — Main configuration file:

Key Field Description
decision_version "v2" — COI structured reasoning (default)
market Market identifier, default "us"
stock_symbols List of trading symbols
date_range Simulation start/end dates (init_date, end_date)
price_data_dir Local CSV data directory, default "data/US_Stock_Data"
layered_config Screening parameters (stock universe, initial filter conditions)
data_layer_config Data layer settings (max_analysis_symbols)
agent_config Initial cash (initial_cash)
policy_dir Playbook directory, default modules/playbook
evolution_enabled Whether to enable automatic strategy evolution (requires v2, auto-triggers when trading days >= 7). See Evolution System Guide
daily_journal_enabled Whether to record daily reflection journals (observation/error/opportunity per trading day)
dashboard_enabled Whether to start the Web dashboard after trading completes
dashboard_port Dashboard HTTP port, default 8080
evolution_config Evolution parameters: reflection_trigger_mode (both/on_demand/scheduled), reflection_window_days, reflection_interval_days, validation_rules (min_sharpe / max_drawdown / min_trades / min_sharpe_improvement), warning_triggers, Walk Forward window configuration, backtest_frequency (token-saving sampling interval, default 3), evolution_dir, llm_model

.env — Model & API keys:

LLM_MODEL=deepseek-v4-flash
OPENAI_API_BASE=https://api.deepseek.com/v1
OPENAI_API_KEY=your_key

See configs/README.md and .env.example for details.

V2's 5-step reasoning: Market Analysis → Portfolio Analysis → Policy Check → Decision Synthesis → Execution (execution engine)

Single-Module Development

# Test stock screening module (no LLM needed)
python -c "
from modules.screening import run_stock_screening, get_default_universe
u = get_default_universe()
print(run_stock_screening(u[:5], '2024-06-01', {'enabled': True}))
"

# Test execution engine (39 deterministic tests)
pytest tests/test_backtest_engine.py -v

# Generate trading context with Data Layer
python -m data_layer AAPL 2025-10-01

# Test Decision V2 (Mock mode, using deterministic engine)
python tests/test_decision_v2_mock.py

# Sync K-line data to local CSV
python scripts/sync_kline_data.py AAPL

Project Structure

main.py                              # Online trading entry point
configs/config.json                  # Main configuration
.env                                 # API keys
pyproject.toml                       # Project dependencies

modules/
├── screening/                       # Stock screening
├── execution/                       # Deterministic trade execution engine
│   ├── engine.py                    # BacktestEngine (in-memory state management)
│   └── schemas.py                   # PortfolioSnapshot, ExecutionResult
├── decision_v2/                     # Decision (COI)
│   ├── core/agent_coi.py            # TradingAgentCOI (calls BacktestEngine)
│   ├── prompts/                     # 4-step COI prompts (narrative strategy evaluation)
│   ├── inputs/                      # Input builders
│   ├── schemas.py                   # Data models
│   └── outputs/logger.py            # Trajectory logger
└── playbook/                        # Strategy content (trading_policy.json + thin loader)

data_layer/                          # Data layer
├── context_builder/                 # TradingContextBuilder
├── services/                        # KlineService, NewsService, MacroService, NewsAnalysisService
├── storage/                         # ContextStore snapshot persistence
├── io/                              # Authoritative CSV I/O (csv_reader, calendar)
├── schemas/                         # Data models (metadata, trading_context)
└── cli.py                           # CLI entry point

shared/                              # Cross-module shared
└── tools/                           # Utility functions (LLM config, price tools, general utilities)

learning/                            # Trading evolution system
├── schemas/                         # Data models (reflection, memory, evolution, strategy_schema)
├── reflection/                      # Reflection engine (error identification + opportunity discovery)
├── memory/                          # Memory layer (short-term 30-day window + long-term knowledge base)
└── evolution/                       # Evolution layer (hypothesis, experiment, policy_store, curator, controller)

dashboard/                           # Live trading dashboard (web UI)
│   ├── app.py                       # FastAPI application + SSE endpoint
│   ├── session.py                    # TradingSession (state machine + background loop)
│   ├── evolution_monitor.py          # Evolution progress tracking + SSE broadcast
│   ├── server.py                     # Uvicorn server launcher
│   └── status_writer.py              # Status.json persistence for resume
data/US_Stock_Data/                  # Local market data CSV files
evolution_data/                     # Evolution system data (memory, history)
tests/                               # All tests (6 files)
│   ├── test_backtest_engine.py      # Deterministic execution engine (39 tests)
│   ├── test_decision_v2_mock.py     # Decision V2 COI smoke test
│   ├── test_evolution_e2e.py        # Evolution system E2E tests
│   ├── test_episode_memory.py       # Short-term memory unit tests
│   ├── test_news_analysis_llm.py    # News analysis with LLM
│   └── test_semantic_memory.py      # Semantic memory unit tests
scripts/                             # Utility scripts (2 files)
├── sync_kline_data.py               # Download K-line data from Yahoo Finance
└── evolution_dashboard.py           # Evolution system monitoring panel

See modules/*/README.md for detailed module documentation.

Trading Evolution System

When evolution_enabled: true and trading days >= 7, main.py automatically triggers an evolution cycle after trading completes:

Trading Trajectories → Reflection Engine (ReflectionEngine)
  ├── Error Identification: audit decision consistency with strategy principles (non-parametric)
  ├── Opportunity Discovery: identify missed trading opportunities based on strategy philosophy
  └── Output ReflectionResult (0+ errors + 0+ missed opportunities)
              ↓
        Episode Memory (EpisodeMemory) ← 30-day JSONL window
        Semantic Memory (SemanticMemory) ← Long-term knowledge base
              ↓
        Hypothesis Generation (HypothesisEngine) → LLM-driven strategy improvement hypotheses
              ↓
        Experiment Validation (ExperimentEngine) → Walk Forward rolling backtest (Mock + Live dual mode)
              ↓
        Policy Validation (PolicyValidator) → Multi-level gating (Sharpe, drawdown, win rate)
              ↓
        Strategy Curation (CuratorAgent) → Intelligently merge validated hypotheses into narrative strategy
              ↓
        Policy Promotion (PolicyVersionManager) → Version tree tracking + auto-promote after passing

Reflection principle: Based on strategy philosophy, not parameter thresholds. Evaluates "did the trade follow the principles described in the strategy" rather than "is RSI > 50". See Evolution System Guide.

Troubleshooting

Agent never trades (all HOLD)

Zero trades may occur when the strategy is too conservative. Common causes:

  • Conservative strategy philosophy: Principles like "don't chase rallies", "wait for perfect setup", "cash is a strategic asset" may cause the agent to stay on the sidelines
  • Single symbol + choppy market: With only 1 stock and no clear market direction, trend-following strategies struggle to find entry points
  • Limited technical signals: Without auxiliary data like volume or sector comparison, LLMs tend to be conservative

Suggestions: Increase candidate symbol count (stock_symbols), adjust strategy narratives to encourage more active entry, or increase trading days for more opportunities.

Evolution cycle validation fails

The most common cause of validation failure is candidate and baseline strategies producing identical performance (e.g., both with 0 trades), resulting in no Sharpe improvement. Ensure sufficient trade records exist in the trading cycle for the evolution system to learn from.

[INFO] Finnhub macro API requires premium subscription (403)

The free Finnhub API Key does not have access to the economic calendar endpoint. The system will automatically skip macro data without affecting trading decisions. Upgrade your Finnhub subscription if macro data is needed.

[WARNING] FINNHUB_API_KEY not set

Set FINNHUB_API_KEY in .env. Without an API Key, news and macro data will return empty, which does not affect basic trading functionality (K-line data is provided via local CSV).

Working memory shows 0 records

Working memory filters out all HOLD decisions (no actual trades). This is normal behavior — entries are only recorded when there are BUY/SELL actions.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors