Added documentation for: - Duplicate simulation prevention in JobManager.create_job() - Cross-job portfolio continuity in position tracking - Updated CLAUDE.md with Duplicate Simulation Prevention section - Updated docs/developer/architecture.md with Position Tracking Across Jobs section
14 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
AI-Trader-Server is a REST API service for autonomous AI trading competitions where multiple AI models compete in NASDAQ 100 trading with zero human intervention. Each AI starts with $10,000 and uses standardized MCP (Model Context Protocol) tools to make fully autonomous trading decisions.
Key Innovation: Historical replay architecture with anti-look-ahead controls ensures AI agents can only access data from the current simulation date and earlier.
Development Commands
Environment Setup
# Install dependencies
pip install -r requirements.txt
# Configure environment variables
cp .env.example .env
# Edit .env and set:
# - OPENAI_API_BASE, OPENAI_API_KEY
# - ALPHAADVANTAGE_API_KEY, JINA_API_KEY
# - AGENT_MAX_STEP (default: 30)
Data Preparation
# Download/update NASDAQ 100 stock data
cd data
python get_daily_price.py # Fetch daily prices from Alpha Vantage
python merge_jsonl.py # Merge into unified format (merged.jsonl)
cd ..
Starting Services
# Start all MCP services (Math, Search, Trade, LocalPrices)
cd agent_tools
python start_mcp_services.py
cd ..
# MCP services use fixed internal ports (8000-8003)
# These are not exposed to the host and should not be changed
Docker Deployment
# Build Docker image
docker-compose build
# Run with Docker Compose
docker-compose up
# Run in background
docker-compose up -d
# Run with custom config
docker-compose run ai-trader-server configs/my_config.json
# View logs
docker-compose logs -f
# Stop and remove containers
docker-compose down
# Pull pre-built image
docker pull ghcr.io/xe138/ai-trader-server:latest
# Test local Docker build
docker build -t ai-trader-server-test .
docker run --env-file .env -v $(pwd)/data:/app/data ai-trader-server-test
Releasing Docker Images
# Create and push release tag
git tag v1.0.0
git push origin v1.0.0
# GitHub Actions automatically:
# 1. Builds Docker image
# 2. Tags with version and latest
# 3. Pushes to ghcr.io/xe138/ai-trader-server
# Verify build in Actions tab
# https://github.com/Xe138/AI-Trader-Server/actions
Running Trading Simulations
# Run with default config
python main.py
# Run with custom config
python main.py configs/my_config.json
# Environment variables can override config dates:
INIT_DATE=2025-01-01 END_DATE=2025-01-31 python main.py
Complete Workflow
# All-in-one startup script (data + services + trading + web)
bash main.sh
Architecture
Core Components
1. Agent System (agent/base_agent/base_agent.py)
BaseAgent: Base class for all trading agents- Manages MCP tool connections, AI model initialization, trading execution loops
- Handles position management and logging
- Supports retry logic with exponential backoff (
max_retries,base_delay)
2. Main Entry Point (main.py)
- Dynamic agent class loading via
AGENT_REGISTRY - Multi-model concurrent trading support
- Date range validation and weekday filtering
- Configuration management (JSON + environment variables)
3. MCP Toolchain (agent_tools/)
tool_math.py: Mathematical calculations (port 8000)tool_jina_search.py: Market intelligence search (port 8001)tool_trade.py: Buy/sell execution (port 8002)tool_get_price_local.py: Price queries (port 8003)start_mcp_services.py: Service orchestration with health checks
4. Data Management (data/)
daily_prices_*.json: Individual stock OHLCV datamerged.jsonl: Unified price data formatagent_data/[signature]/position/position.jsonl: Position recordsagent_data/[signature]/log/[date]/log.jsonl: Trading logs
5. Utilities (tools/)
general_tools.py: Config management, message extractionprice_tools.py: Price queries, position updatesresult_tools.py: Performance calculations
Data Flow
- Initialization: Agent loads config, connects to MCP services, initializes AI model
- Trading Loop: For each date:
- Get system prompt with current positions, yesterday's prices, today's buy prices
- AI agent analyzes market, calls search/math/price tools
- Makes buy/sell decisions via trade tool
- Logs all decisions and updates position.jsonl
- Position Tracking: Each trade appends to
position.jsonlwith date, action, and updated holdings
Configuration System
Multi-layered config priority:
- Environment variables (highest)
- Model-specific config (
openai_base_url,openai_api_keyin model config) - JSON config file
- Default values (lowest)
Runtime configuration (API mode only):
- Dynamically created per model-day execution via
RuntimeConfigManager - Isolated config files prevent concurrent execution conflicts
- Contains:
TODAY_DATE,SIGNATURE,IF_TRADE,JOB_ID - Written by
write_config_value(), read byget_config_value()
Agent System
BaseAgent Key Methods:
initialize(): Connect to MCP services, create AI modelrun_trading_session(date): Execute single day's trading with retry logicrun_date_range(init_date, end_date): Process all weekdays in rangeget_trading_dates(): Resume from last date in position.jsonlregister_agent(): Create initial position file with $10,000 cash
Adding Custom Agents:
- Create new class inheriting from
BaseAgent - Add to
AGENT_REGISTRYinmain.py:"CustomAgent": { "module": "agent.custom.custom_agent", "class": "CustomAgent" } - Set
"agent_type": "CustomAgent"in config JSON
System Prompt Construction
Dynamic prompt generation (prompts/agent_prompt.py):
get_agent_system_prompt()builds prompt with:- Current date
- Yesterday's closing positions
- Yesterday's closing prices
- Today's buy prices
- Yesterday's profit/loss
- AI agent must output
<FINISH_SIGNAL>to end trading session
Anti-Look-Ahead Controls
Data access restrictions:
- Price data: Only returns data for
date <= TODAY_DATE - Search results: News filtered by publication date
- All tools enforce temporal boundaries via
TODAY_DATEfromruntime_env.json
Duplicate Simulation Prevention
Automatic Skip Logic:
JobManager.create_job()checks database for already-completed model-day pairs- Skips completed simulations automatically
- Returns warnings list with skipped pairs
- Raises
ValueErrorif all requested simulations are already completed
Example:
result = job_manager.create_job(
config_path="config.json",
date_range=["2025-10-15", "2025-10-16"],
models=["model-a"],
model_day_filter=[("model-a", "2025-10-15")] # Already completed
)
# result = {
# "job_id": "new-job-uuid",
# "warnings": ["Skipped model-a/2025-10-15 - already completed"]
# }
Cross-Job Portfolio Continuity:
get_current_position_from_db()queries across ALL jobs for a given model- Enables portfolio continuity even when new jobs are created with overlapping dates
- Starting position = most recent trading_day.ending_cash + holdings where date < current_date
Configuration File Format
{
"agent_type": "BaseAgent",
"date_range": {
"init_date": "2025-01-01",
"end_date": "2025-01-31"
},
"models": [
{
"name": "model-display-name",
"basemodel": "provider/model-id",
"signature": "unique-identifier",
"enabled": true,
"openai_base_url": "optional-override",
"openai_api_key": "optional-override"
}
],
"agent_config": {
"max_steps": 30, // Max reasoning iterations per day
"max_retries": 3, // Retry attempts on failure
"base_delay": 1.0, // Base retry delay (seconds)
"initial_cash": 10000.0
},
"log_config": {
"log_path": "./data/agent_data"
}
}
Data Formats
Position Record (position.jsonl):
{
"date": "2025-01-20",
"id": 1,
"this_action": {
"action": "buy",
"symbol": "AAPL",
"amount": 10
},
"positions": {
"AAPL": 10,
"MSFT": 0,
"CASH": 9737.6
}
}
Price Data (merged.jsonl):
{
"Meta Data": {
"2. Symbol": "AAPL",
"3. Last Refreshed": "2025-01-20"
},
"Time Series (Daily)": {
"2025-01-20": {
"1. buy price": "255.8850",
"2. high": "264.3750",
"3. low": "255.6300",
"4. sell price": "262.2400",
"5. volume": "90483029"
}
}
}
Important Implementation Details
Trading Day Logic:
- Only weekdays (Monday-Friday) are processed
get_trading_dates()automatically resumes from last date inposition.jsonl- Skips days already processed (idempotent)
Error Handling:
- All async operations use
_ainvoke_with_retry()with exponential backoff - MCP service failures raise detailed error messages with troubleshooting hints
- Missing API keys halt startup with clear error messages
Tool Message Extraction:
extract_conversation(response, "final"): Get AI's final answerextract_tool_messages(response): Get all tool results- Handles both dict and object-based message formats
Logging:
- Each trading day creates
log/[date]/log.jsonl - Logs include timestamps, signature, and all message exchanges
- Position updates append to single
position/position.jsonl
Development Mode:
AI-Trader supports a development mode that mocks AI API calls for testing without costs.
Deployment Modes:
DEPLOYMENT_MODE=PROD: Real AI calls, production data pathsDEPLOYMENT_MODE=DEV: Mock AI, isolated dev environment
DEV Mode Characteristics:
- Uses
MockChatModelfromagent/mock_provider/ - Data paths:
data/dev_agent_data/anddata/trading_dev.db - Dev database reset on startup (controlled by
PRESERVE_DEV_DATA) - API responses flagged with
deployment_modefield
Implementation Details:
- Deployment config:
tools/deployment_config.py - Mock provider:
agent/mock_provider/mock_ai_provider.py - LangChain wrapper:
agent/mock_provider/mock_langchain_model.py - BaseAgent integration:
agent/base_agent/base_agent.py:146-189 - Database handling:
api/database.py(automatic path resolution)
Testing Dev Mode:
DEPLOYMENT_MODE=DEV python main.py configs/default_config.json
Mock AI Behavior:
- Deterministic stock rotation (AAPL → MSFT → GOOGL → etc.)
- Each response includes price query, buy order, and finish signal
- No actual AI API calls or costs
Testing Changes
Automated Test Scripts
The project includes standardized test scripts for different workflows:
# Quick feedback during development (unit tests only, ~10-30 seconds)
bash scripts/quick_test.sh
# Full test suite with coverage (before commits/PRs)
bash scripts/run_tests.sh
# Generate coverage report with HTML output
bash scripts/coverage_report.sh -o
# CI/CD optimized testing (for automation)
bash scripts/ci_test.sh -f -m 85
# Interactive menu (recommended for beginners)
bash scripts/test.sh
Common test script options:
# Run only unit tests
bash scripts/run_tests.sh -t unit
# Run with custom markers
bash scripts/run_tests.sh -m "unit and not slow"
# Fail fast on first error
bash scripts/run_tests.sh -f
# Run tests in parallel
bash scripts/run_tests.sh -p
# Skip coverage reporting (faster)
bash scripts/run_tests.sh -n
Available test markers:
unit- Fast, isolated unit testsintegration- Tests with real dependenciese2e- End-to-end tests (requires Docker)slow- Tests taking >10 secondsperformance- Performance benchmarkssecurity- Security tests
Manual Testing Workflow
When modifying agent behavior or adding tools:
- Create test config with short date range (2-3 days)
- Set
max_stepslow (e.g., 10) to iterate faster - Check logs in
data/agent_data/[signature]/log/[date]/ - Verify position updates in
position/position.jsonl - Use
main.shonly for full end-to-end testing
Test Coverage
- Minimum coverage: 85%
- Target coverage: 90%
- Configuration:
pytest.ini - Coverage reports:
htmlcov/index.html,coverage.xml, terminal output
See docs/developer/testing.md for complete testing guide.
Documentation Structure
The project uses a well-organized documentation structure:
Root Level (User-facing)
- README.md - Project overview, quick start, API overview
- QUICK_START.md - 5-minute getting started guide
- API_REFERENCE.md - Complete API endpoint documentation
- CHANGELOG.md - Release notes and version history
- TESTING_GUIDE.md - Testing and validation procedures
docs/user-guide/
configuration.md- Environment setup and model configurationusing-the-api.md- Common workflows and best practicesintegration-examples.md- Python, TypeScript, automation examplestroubleshooting.md- Common issues and solutions
docs/developer/
CONTRIBUTING.md- Contribution guidelinesdevelopment-setup.md- Local development without Dockertesting.md- Running tests and validationarchitecture.md- System design and componentsdatabase-schema.md- SQLite table referenceadding-models.md- How to add custom AI models
docs/deployment/
docker-deployment.md- Production Docker setupproduction-checklist.md- Pre-deployment verificationmonitoring.md- Health checks, logging, metricsscaling.md- Multiple instances and load balancing
docs/reference/
environment-variables.md- Configuration referencemcp-tools.md- Trading tool documentationdata-formats.md- File formats and schemas
docs/ (Maintainer docs)
DOCKER.md- Docker deployment detailsRELEASING.md- Release process for maintainers
Common Issues
MCP Services Not Running:
- Error: "Failed to initialize MCP client"
- Fix:
cd agent_tools && python start_mcp_services.py - Verify ports not already in use:
lsof -i :8000-8003
Missing Price Data:
- Ensure
data/merged.jsonlexists - Run
cd data && python get_daily_price.py && python merge_jsonl.py - Check Alpha Vantage API key is valid
Runtime Config Issues:
- Runtime configs are automatically managed by the API
- Configs are created per model-day execution in
data/directory - Ensure
data/directory is writable
Agent Doesn't Stop Trading:
- Agent must output
<FINISH_SIGNAL>withinmax_steps - Increase
max_stepsif agent needs more reasoning time - Check
log.jsonlfor errors preventing completion