Skip to content

Repository files navigation

Strategy Arena

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.

How It Works

┌────────────┐    ┌───────────┐    ┌──────────┐    ┌─────────┐
│ Strategist │───>│ Sanitizer │───>│  Engine  │───>│  Judge  │
│ (Claude)   │    │ (AST scan)│    │(vectorbt)│    │(scoring)│
└────────────┘    └───────────┘    └──────────┘    └─────────┘
      ^                                                 │
      │  ┌──────────┐  ┌──────────┐  ┌──────────┐      │
      └──│ Evolver  │<─│ Reviewer │<─│ Narrator │<─────┘
         │ (top-K)  │  │ (Gemini) │  │ (Gemini) │
         └──────────┘  └──────────┘  └──────────┘

The arena runs in rounds. Each round:

  1. Generate — Strategist LLM produces N strategy functions (round 1 uses classic strategies as seeds)
  2. Sanitize — AST validation blocks unsafe code, forbidden imports, and look-ahead bias
  3. Backtest — vectorbt runs each strategy against historical data
  4. Review — Reviewer LLM evaluates each strategy's strengths, weaknesses, and risk
  5. Narrate — Narrator LLM summarizes the round in natural language
  6. Judge — Strategies are scored on Sharpe ratio, max drawdown, win rate, and trade count
  7. 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.

Quick Start

# 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 run

Configuration

All 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.001

Use a custom config file:

arena run --config my_config.toml

Supported Providers

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

Strategy Interface

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)

Security

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, and pandas_ta are available

Project Structure

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

Output

Results are saved to results/:

  • results/round_N.json -- Per-round strategy results with code, metrics, reviews, and narrator summary
  • results/leaderboard.json -- All-time best strategies across rounds and runs
  • results/meta.json -- Run metadata (run ID, fixed data window, totals)
  • results/arena.log -- Execution logs

Development

# Install with dev dependencies
pip install -e ".[dev]"

# Run tests
pytest tests/ -v

# Run a specific test file
pytest tests/test_sanitizer.py -v

Requirements

  • Python 3.11+
  • macOS or Linux (uses signal.SIGALRM for strategy timeouts, not available on Windows)
  • API keys for at least one LLM provider (see .env.example)

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages