An automated LLM-driven quantitative strategy arena with multi-role evolution. Multiple LLMs collaborate — a Strategist generates trading strategies, a Reviewer evaluates them, and a Narrator summarizes each round — while vectorbt backtests them at high speed. Top performers evolve across rounds.
┌────────────┐ ┌───────────┐ ┌──────────┐ ┌─────────┐
│ Strategist │───>│ Sanitizer │───>│ Engine │───>│ Judge │
│ (Claude) │ │ (AST scan)│ │(vectorbt)│ │(scoring)│
└────────────┘ └───────────┘ └──────────┘ └─────────┘
^ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
└──│ Evolver │<─│ Reviewer │<─│ Narrator │<─────┘
│ (top-K) │ │ (Gemini) │ │ (Gemini) │
└──────────┘ └──────────┘ └──────────┘
The arena runs in rounds. Each round:
- Generate — Strategist LLM produces N strategy functions (round 1 uses classic strategies as seeds)
- Sanitize — AST validation blocks unsafe code, forbidden imports, and look-ahead bias
- Backtest — vectorbt runs each strategy against historical data
- Review — Reviewer LLM evaluates each strategy's strengths, weaknesses, and risk
- Narrate — Narrator LLM summarizes the round in natural language
- Judge — Strategies are scored on Sharpe ratio, max drawdown, win rate, and trade count
- Evolve — Top-K strategies + reviews + commentary are fed back to the Strategist
Cross-run memory: leaderboard results persist across runs, so the Strategist learns from all prior experiments.
# Clone and install
git clone https://github.com/SYNR-AI/StrategyArena.git
cd StrategyArena
pip install -e ".[dev]"
# Set your API keys
cp .env.example .env
# Edit .env with your API keys (at minimum, set ANTHROPIC_API_KEY)
# Run the arena
arena runAll settings are managed via arena_config.toml:
[strategist]
provider = "claude"
model = "claude-opus-4-6"
[reviewer]
provider = "gemini"
model = "gemini-3-pro-preview"
[narrator]
provider = "gemini"
model = "gemini-3-pro-preview"
[data]
symbol = "BTC/USDT"
timeframe = "1d"
start = "2025-01-01"
end = "2026-01-01"
[arena]
strategies_per_round = 5
top_k = 3
max_rounds = 10
max_retries = 3
[backtest]
init_cash = 10000
fees = 0.001
slippage = 0.001Use a custom config file:
arena run --config my_config.toml| Provider | Models | Role |
|---|---|---|
claude |
claude-opus-4-6, etc. |
Strategist (default) |
gemini |
gemini-3-pro-preview, etc. |
Reviewer / Narrator (default) |
openai |
gpt-5, etc. |
Any role |
LLMs generate functions conforming to:
def strategy_logic(close, high, low, volume):
# close, high, low, volume are pd.Series
# Use pandas, numpy, pandas_ta, or vectorbt for indicators
sma_fast = close.rolling(10).mean()
sma_slow = close.rolling(50).mean()
entries = (sma_fast > sma_slow) & (sma_fast.shift(1) <= sma_slow.shift(1))
exits = (sma_fast < sma_slow) & (sma_fast.shift(1) >= sma_slow.shift(1))
return entries.fillna(False), exits.fillna(False)LLM-generated code runs in a sandboxed environment:
- AST validation -- Code is statically analyzed before execution
- Forbidden imports --
os,sys,subprocess,socket, etc. are blocked - Forbidden builtins --
open,exec,eval,getattr, etc. are blocked - Dunder protection --
__class__,__bases__,__subclasses__access is blocked - Look-ahead bias detection --
shift(-N)(using future data) is flagged - Execution timeout -- Each strategy is killed after 30 seconds
- Restricted globals -- Only
numpy,pandas,vectorbt, andpandas_taare available
strategy_arena/
├── arena.py # Main orchestrator — multi-role generation-review-evolve loop
├── cli.py # CLI entry point (typer)
├── config.py # TOML-based configuration with RoleConfig
├── data/
│ └── fetcher.py # Binance OHLCV data via ccxt with parquet caching
├── engine.py # vectorbt backtesting wrapper + sandboxed exec
├── evolver.py # Top-K selection + feedback prompt construction
├── generator.py # LLM provider abstraction (Claude/OpenAI/Gemini) + prompt templates
├── judge.py # Composite scoring, ranking, and result persistence
├── meta.py # Run metadata — tracks run IDs, data windows, cross-run state
├── models.py # Data classes (Strategy, BacktestResult, ScoredResult)
└── sanitizer.py # Code extraction, AST validation, security checks
Results are saved to results/:
results/round_N.json-- Per-round strategy results with code, metrics, reviews, and narrator summaryresults/leaderboard.json-- All-time best strategies across rounds and runsresults/meta.json-- Run metadata (run ID, fixed data window, totals)results/arena.log-- Execution logs
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Run a specific test file
pytest tests/test_sanitizer.py -v- Python 3.11+
- macOS or Linux (uses
signal.SIGALRMfor strategy timeouts, not available on Windows) - API keys for at least one LLM provider (see
.env.example)