QuantCoder Technical Documentation
AI-powered CLI for generating QuantConnect trading algorithms from research articles
What is QuantCoder?
QuantCoder is a Python CLI tool that bridges the gap between academic finance research and live algorithmic trading. It automates the full pipeline from discovering research articles on CrossRef and arXiv, extracting strategy logic via NLP, generating QuantConnect-compatible Python code through specialized AI agents, and validating the output through compilation and backtesting. The tool supports multiple LLM providers, autonomous self-improvement loops, and an evolution engine inspired by AlphaEvolve for iterating on strategy variants.
Key Features
CLI Commands
- 7 command categories
- Interactive chat mode
- Direct CLI commands
- Programmatic --prompt flag
Multi-Agent System
- 5 specialized agents
- Coordinator, Universe, Alpha, Risk, Strategy
- Parallel async execution
- Structured result aggregation
Code Generation
- QuantConnect LEAN Python output
- Local AST + cloud validation
- Auto-refinement on errors
- Multi-file algorithm support
Local LLM
- Ollama-only, no cloud API keys
- qwen2.5-coder:14b (code)
- mistral (reasoning)
- Task-based model routing
Autonomous Mode
- Self-improving generation loop
- Error pattern learning
- Prompt refinement
- Performance tracking
Evolution Engine
- AlphaEvolve-inspired variation
- Structural mutation operators
- Fitness-based selection
- Elite pool tracking
Architecture
System Overview
QuantCoder is organized around three execution paths that all feed into a shared generation and validation pipeline. The system is designed for modularity: each component (article processing, code generation, validation, backtesting) operates independently and communicates through well-defined interfaces.
Execution Paths
| Path | Entry Point | Description |
|---|---|---|
| Interactive Chat | quantcoder (default) |
Rich terminal UI with command history, tab completion, auto-suggest, and full tool access. The default mode when no subcommand is provided. |
| --prompt Flag | quantcoder --prompt "..." |
Programmatic single-shot execution. Ideal for scripting, cron jobs, and CI/CD pipelines. Returns structured output to stdout. |
| Direct CLI | quantcoder <command> |
Direct command invocation (search, download, generate, validate, backtest, etc.) for targeted operations. |
Core Pipeline
Regardless of the execution path, all code generation flows through the same pipeline:
Design Patterns
| Pattern | Where Used | Purpose |
|---|---|---|
| Factory | LLM Providers | Instantiates the correct LLM client via task-based routing (e.g., LLMFactory.create(task="coding") selects qwen2.5-coder, task="reasoning" selects mistral). |
| Strategy | Tools | Each tool (SearchTool, DownloadTool, GenerateTool, ValidateCodeTool, BacktestTool, SummarizeTool) implements a common interface and is selected at runtime. |
| Coordinator | Multi-Agent System | A coordinator agent plans execution order, spawns specialized agents (Universe, Alpha, Risk, Strategy), and integrates their results into a final algorithm. |
| Async/Await | Parallel Execution | Agents run concurrently via asyncio.gather() where dependencies allow, reducing total generation time. |
Directory Structure
quantcoder/
├── cli/ # Click CLI commands and chat interface
│ ├── main.py # Entry point, command groups
│ ├── chat.py # Interactive chat with prompt-toolkit
│ ├── auto_commands.py # Autonomous mode commands
│ ├── evolve_commands.py# Evolution engine commands
│ ├── library_commands.py# Library builder commands
│ └── schedule_commands.py# Scheduled automation commands
├── core/ # Core business logic
│ ├── llm.py # LLMHandler - multi-provider abstraction
│ ├── article_processor.py # PDF extraction + NLP
│ └── config.py # Configuration management (TOML + .env)
├── tools/ # Tool implementations
│ ├── search_tool.py # CrossRef/arXiv search
│ ├── download_tool.py # PDF download via Unpaywall
│ ├── summarize_tool.py # LLM-based article summarization
│ ├── generate_tool.py # Code generation with agents
│ ├── code_tools.py # ValidateCodeTool + BacktestTool
│ └── deep_search.py # Tavily web search integration
├── agents/ # Multi-agent system
│ ├── base_agent.py # BaseAgent abstract class
│ ├── coordinator.py # CoordinatorAgent orchestration
│ ├── universe_agent.py # Universe selection logic
│ ├── alpha_agent.py # Signal generation logic
│ ├── risk_agent.py # Risk management logic
│ └── strategy_agent.py # Final integration agent
├── autonomous/ # Autonomous mode
│ ├── runner.py # Self-improving generation loop
│ ├── learning_db.py # SQLite pattern storage
│ ├── error_learner.py # Error pattern analysis
│ ├── prompt_refiner.py # Dynamic prompt improvement
│ └── performance_learner.py # Indicator tracking
├── evolution/ # Evolution engine
│ ├── engine.py # Core evolution loop
│ ├── operators.py # Mutation/crossover operators
│ └── fitness.py # Fitness evaluation
├── library/ # Library builder
│ ├── builder.py # Strategy library construction
│ └── categories.py # Predefined strategy categories
├── scheduler/ # Scheduled automation
│ └── scheduler.py # APScheduler-based automation
├── mcp/ # QuantConnect MCP integration
│ └── quantconnect_mcp.py # MCP client for QC cloud
└── tests/ # 18 test files
├── test_cli.py
├── test_llm.py
├── test_agents.py
└── ...
Installation
Prerequisites
- Python 3.10+ (tested on 3.10, 3.11, 3.12)
- pip or pipx for package installation
- Git for cloning the repository
Clone and Install
# Clone the repository
git clone https://github.com/SL-Mar/quantcoder.git
cd quantcoder-cli
# Install in editable mode (recommended for development)
pip install -e .
# Or install directly
pip install .
Pull Ollama Models
QuantCoder v2.0 requires Ollama running locally with two models:
# Install Ollama (https://ollama.ai)
curl -fsSL https://ollama.ai/install.sh | sh
# Pull the required models
ollama pull qwen2.5-coder:14b
ollama pull mistral
Configure Environment
Create the configuration directory and environment file at ~/.quantcoder/.env:
# Optional - QuantConnect cloud compilation and backtesting
QUANTCONNECT_API_KEY=...
QUANTCONNECT_USER_ID=...
# Optional - Notion integration for publishing results
NOTION_API_KEY=secret_...
# Optional - Tavily deep search for article discovery
TAVILY_API_KEY=tvly-...
Verify Installation
# Check that QuantCoder is installed and accessible
quantcoder version
# Launch interactive chat mode
quantcoder
# Run a test search
quantcoder search "momentum trading strategies"
Tech Stack
Core
| Technology | Version | Purpose |
|---|---|---|
| Python | 3.10+ | Primary language, async support, type hints |
| Click | 8.x | CLI framework, command groups, option parsing |
| Rich | 13.x | Terminal UI, progress bars, tables, syntax highlighting |
| prompt-toolkit | 3.x | Interactive chat, command history, tab completion, auto-suggest |
AI / ML
| Technology | Version | Purpose |
|---|---|---|
| Ollama | - | Local LLM inference — all models run locally, no cloud API keys required |
| qwen2.5-coder:14b | - | Code generation, refinement, error fixing (via Ollama) |
| mistral | - | Reasoning, summarization, chat (via Ollama) |
| pdfplumber | 0.10+ | PDF text extraction from research articles |
| spaCy | 3.x | NLP analysis of extracted article text |
Infrastructure
| Technology | Version | Purpose |
|---|---|---|
| aiohttp | 3.x | Async HTTP client for API calls (CrossRef, arXiv, Unpaywall) |
| APScheduler | 3.x | Scheduled automation (daily/weekly strategy generation) |
| toml | 0.10+ | Configuration file parsing (config.toml) |
| python-dotenv | 1.x | Environment variable management (.env files) |
Testing
| Technology | Version | Purpose |
|---|---|---|
| pytest | 8.x | Test framework, fixtures, parametrized tests |
| pytest-cov | 5.x | Code coverage reporting |
CLI Commands
QuantCoder provides 7 command categories accessible from the terminal. All commands follow the pattern quantcoder <category> <action> [options].
Core Commands
The primary workflow commands for searching, downloading, summarizing, generating, validating, and backtesting trading algorithms.
Search CrossRef and arXiv for academic trading papers matching the query. Results are cached locally and assigned numeric IDs for subsequent commands.
Download the PDF for a previously searched article using Unpaywall open-access links. Falls back to alternative sources if the primary link is unavailable.
Extract text from the downloaded PDF and generate a structured summary using the configured LLM. Output includes strategy logic, indicators, entry/exit conditions, and risk parameters.
Generate a complete QuantConnect algorithm from the article summary using the multi-agent system. Output is written to generated_code/algorithm_<id>.py.
Validate a generated algorithm through local AST parsing and (optionally) QuantConnect cloud compilation. Reports syntax errors, import issues, and compilation warnings.
Submit the validated algorithm to QuantConnect for backtesting over the specified date range. Extracts Sharpe ratio, total return, drawdown, and trade statistics from results.
Example Workflow
# Step 1: Search for research papers
quantcoder search "momentum trading strategies"
# Step 2: Download the first result
quantcoder download 1
# Step 3: Summarize the article
quantcoder summarize 1
# Step 4: Generate QuantConnect algorithm
quantcoder generate 1
# Step 5: Validate the generated code
quantcoder validate generated_code/algorithm_1.py
# Step 6: Backtest over 6 months
quantcoder backtest --start 2024-01-01 --end 2024-06-30
Autonomous Mode
Autonomous mode runs a self-improving generation loop that learns from errors and iterates until a performance threshold is met.
Start an autonomous generation run. Searches for articles, generates algorithms, validates, backtests, and learns from failures. Continues until --min-sharpe is achieved or --max-iterations is reached.
Check the status of the current autonomous run, including iteration count, best Sharpe ratio achieved, and error patterns learned.
Generate a detailed report of the autonomous run including all iterations, learned patterns, prompt refinements, and the best-performing algorithm.
Example
# Start autonomous generation targeting Sharpe > 1.0
quantcoder auto start --query "momentum trading" --max-iterations 50 --min-sharpe 1.0
# Check progress
quantcoder auto status
# View final report
quantcoder auto report
Library Builder
The library builder generates a comprehensive collection of trading strategies across multiple categories, with checkpoint/resume support for long-running builds.
Build a strategy library. Use --comprehensive for all 13+ categories, or --categories to specify a comma-separated subset. Checkpoints progress automatically.
Resume a previously interrupted library build from the last checkpoint.
Export the completed strategy library as a ZIP archive or JSON manifest file.
Example
# Build a comprehensive library (all categories, up to 24 hours)
quantcoder library build --comprehensive --max-hours 24
# Build specific categories only
quantcoder library build --categories momentum,mean_reversion
# Resume an interrupted build
quantcoder library resume
# Export the library
quantcoder library export --format zip --output strategies.zip
Evolution Mode
The evolution engine creates structural variants of an existing algorithm and selects the fittest through backtesting, inspired by AlphaEvolve.
Start an evolution run for the specified article. Creates --variants structural mutations per generation for --gens generations (default: 3), selecting the best-performing variants to seed the next generation. With --push-to-qc, automatically creates a QuantConnect project with the best variant.
List all evolution runs with their status, generation count, and best fitness score.
Show detailed results for a specific evolution run, including fitness progression across generations and the elite pool.
Export the best-performing algorithm from an evolution run to a Python file.
Example
# Evolve article 1 over 3 generations with 5 variants each
quantcoder evolve start 1 --gens 3 --variants 5
# Evolve and push best variant to QuantConnect
quantcoder evolve start 1 --gens 3 --push-to-qc
# List all evolution runs
quantcoder evolve list
# Show details of a specific run (includes CAGR, Win Rate, Trades)
quantcoder evolve show abc123
# Export the best algorithm
quantcoder evolve export abc123 --output best_algo.py
Scheduled Automation
Schedule recurring strategy generation and backtesting runs using APScheduler.
Start a scheduled automation pipeline. Runs the full search-generate-backtest cycle at the specified interval for each comma-separated query.
Trigger an immediate one-off scheduled run with the specified minimum Sharpe ratio threshold.
View the status of all scheduled jobs, including next run time, last result, and cumulative statistics.
Example
# Schedule daily runs at 6 AM for two strategy types
quantcoder schedule start --interval daily --hour 6 --queries "momentum,mean reversion"
# Run immediately with Sharpe filter
quantcoder schedule run --min-sharpe 1.0
# Check scheduler status
quantcoder schedule status
Logging
View and manage application logs for debugging and auditing.
Display recent log entries. Use --lines to control output length and --json for machine-readable format.
List all available log files with sizes and timestamps.
Clear old log files, keeping the most recent --keep files.
Example
# Show last 100 log lines
quantcoder logs show --lines 100
# Show logs in JSON format
quantcoder logs show --json
# List all log files
quantcoder logs list
# Clear old logs, keep 1
quantcoder logs clear --keep 1
Code Generation
Pipeline Flow
The code generation pipeline transforms a research article PDF into a validated QuantConnect algorithm through a series of stages:
- PDF Text Extraction - pdfplumber extracts raw text from each page of the research article
- NLP Analysis - spaCy processes the extracted text to identify key entities, indicators, and strategy parameters
- Summary Generation - The configured LLM creates a structured summary with entry/exit logic, indicators, and risk parameters
- Code Generation - The multi-agent system (or single-agent mode) generates QuantConnect LEAN Python code from the summary
- Validation - Local AST syntax validation followed by optional QuantConnect cloud compilation
- Refinement - If validation fails, errors are fed back to the LLM for automatic correction (up to 3 iterations)
Code Generation Rules
All generated algorithms must comply with the following QuantConnect LEAN engine constraints. These rules are enforced in the generation prompt and validated during the AST check:
| Rule | Requirement |
|---|---|
| Import Statement | Must use from AlgorithmImports import * as the only import |
| Method Naming | All methods must use snake_case (QuantConnect Python convention) |
| Indicator Registration | Indicators must be registered via self.register_indicator() or helper methods (e.g., self.sma()) |
| Indicator Readiness | All indicator values must be gated by .is_ready checks before use |
| Indicator Naming | Must use underscore-prefixed names (e.g., self._rsi) to avoid conflicts with built-in QCAlgorithm methods |
| Base Class | Algorithm class must extend QCAlgorithm |
| Initialize Method | Must implement initialize() with start/end dates and cash |
Generated Algorithm Template
# region imports
from AlgorithmImports import *
# endregion
class MomentumStrategy(QCAlgorithm):
"""
Momentum-based trading strategy derived from research article.
Strategy Logic:
- Entry: RSI crosses above 30 with positive momentum
- Exit: RSI crosses below 70 or stop loss triggered
Risk Management:
- Position size: 5% of portfolio per position
- Stop loss: 2% per position
- Max positions: 10
- Time stop: 3:55 PM ET daily liquidation
"""
def initialize(self):
self.set_start_date(2024, 1, 1)
self.set_end_date(2024, 6, 30)
self.set_cash(100000)
# Add securities
self.symbol = self.add_equity("SPY", Resolution.MINUTE).symbol
# Register indicators (underscore prefix to avoid conflicts)
self._rsi = self.rsi(self.symbol, 14, Resolution.MINUTE)
self._sma = self.sma(self.symbol, 20, Resolution.MINUTE)
# Risk parameters
self._position_pct = 0.05
self._stop_loss_pct = 0.02
self._max_positions = 10
# Schedule end-of-day liquidation
self.schedule.on(
self.date_rules.every_day(),
self.time_rules.before_market_close("SPY", 5),
self._liquidate_all
)
def on_data(self, data):
if not self._rsi.is_ready or not self._sma.is_ready:
return
if not self.portfolio[self.symbol].invested:
if self._rsi.current.value > 30 and data[self.symbol].close > self._sma.current.value:
self.set_holdings(self.symbol, self._position_pct)
elif self._rsi.current.value > 70:
self.liquidate(self.symbol)
def _liquidate_all(self):
self.liquidate()
Interactive Chat
The default mode when running quantcoder without arguments. Provides a rich terminal interface powered by prompt-toolkit with full access to all tools and commands.
Features
| Feature | Description |
|---|---|
| Command History | Persistent history across sessions, navigable with up/down arrows |
| Tab Completion | Auto-complete for tool names, commands, and file paths |
| Auto-Suggest | Ghost text suggestions based on history (accept with right arrow) |
| Context Management | Maintains conversation context across turns, including article state and generated code |
| Rich Output | Syntax-highlighted code, formatted tables, progress bars via Rich library |
Tool Integration
All 6 core tools are available within the interactive chat. The LLM can invoke them automatically based on your natural language requests:
| Tool | Chat Invocation |
|---|---|
| SearchTool | "Search for momentum trading papers" |
| DownloadTool | "Download article 3" |
| SummarizeTool | "Summarize the downloaded article" |
| GenerateTool | "Generate a QuantConnect algorithm from article 1" |
| ValidateCodeTool | "Validate the generated code" |
| BacktestTool | "Backtest from January to June 2024" |
Usage Example
$ quantcoder
QuantCoder Interactive Chat v1.0
Type 'help' for available commands, 'quit' to exit.
> Search for mean reversion strategies in equity markets
Searching CrossRef and arXiv for: "mean reversion strategies in equity markets"
Found 12 results. Showing top 5:
1. "Mean Reversion in Stock Prices: Evidence and Implications" (2023)
2. "Pairs Trading and Mean Reversion" (2022)
...
> Download article 1 and generate an algorithm
Downloading PDF... Done.
Extracting text... Done.
Generating algorithm with multi-agent system...
[Coordinator] Planning execution order...
[UniverseAgent] Selecting universe criteria...
[AlphaAgent] Generating signal logic...
[RiskAgent] Defining risk parameters...
[StrategyAgent] Assembling final algorithm...
Algorithm written to: generated_code/algorithm_1.py
Validating... AST check passed. Cloud compilation passed.
> Backtest from 2024-01-01 to 2024-06-30
Submitting backtest to QuantConnect...
Results:
Sharpe Ratio: 1.24
Total Return: 8.3%
Max Drawdown: -3.1%
Total Trades: 47
Article Processing
The article processing module handles the full lifecycle of research paper discovery, retrieval, and analysis.
Search
QuantCoder searches two academic databases in parallel:
- CrossRef - Comprehensive metadata for published journal articles and conference papers. Returns DOIs, titles, authors, abstracts, and publication dates.
- arXiv - Preprint server for quantitative finance, computer science, and related fields. Returns full abstracts and PDF links.
Results are deduplicated by DOI, ranked by relevance, and cached locally with assigned numeric IDs for subsequent commands.
PDF Download
PDF retrieval uses a multi-source fallback chain:
- Unpaywall - Open-access link resolution via the Unpaywall API (primary source)
- arXiv Direct - Direct PDF links for arXiv preprints
- Publisher Open Access - Publisher-provided open access links when available
Downloaded PDFs are stored in ~/.quantcoder/articles/ with filenames derived from the DOI.
Text Extraction and NLP
The ArticleProcessor class handles text extraction and analysis:
- pdfplumber extracts raw text page-by-page, preserving tables and figures where possible
- spaCy performs named entity recognition, keyword extraction, and section detection
- The processor identifies key strategy components: indicators, entry conditions, exit conditions, risk parameters, universe criteria
LLM Summarization
The extracted text is passed to the configured LLM (via the summary provider) with a structured prompt that requests:
- Strategy description (one paragraph)
- Trading universe and selection criteria
- Entry and exit signals with specific indicator parameters
- Risk management rules (position sizing, stop losses, profit targets)
- Backtesting methodology from the paper (if described)
- Key parameters and their optimal values
Deep Search (Optional)
When a Tavily API key is configured, QuantCoder can perform deep web searches to supplement article discovery:
# Deep search is invoked automatically when standard search returns few results
# Or manually via the interactive chat:
> Deep search for "pairs trading cointegration statistical arbitrage"
Searching Tavily for supplementary sources...
Found 8 additional references:
- "A Modern Approach to Pairs Trading" (blog, 2024)
- "Cointegration-Based Pairs Trading in Python" (tutorial, 2024)
...
Agent Architecture
QuantCoder's multi-agent system decomposes algorithm generation into specialized subtasks, each handled by a dedicated agent. All agents extend a common BaseAgent abstract class.
BaseAgent
The abstract base class that all agents inherit from. Provides the LLM communication interface and result formatting.
class BaseAgent(ABC):
"""Abstract base class for all agents."""
def __init__(self, llm_handler: LLMHandler, config: dict):
self.llm = llm_handler
self.config = config
@abstractmethod
async def execute(self, context: dict) -> AgentResult:
"""Execute the agent's task given the context."""
pass
async def _generate_with_llm(self, prompt: str, system: str = None) -> str:
"""Send a prompt to the LLM and return the response text."""
return await self.llm.generate(prompt, system=system)
AgentResult
A structured dataclass returned by every agent after execution:
@dataclass
class AgentResult:
agent_name: str # Name of the agent (e.g., "UniverseAgent")
success: bool # Whether the agent completed successfully
code: str # Generated code fragment
metadata: dict # Additional context (indicators used, parameters, etc.)
errors: list[str] # Any errors encountered during execution
duration: float # Execution time in seconds
Parallel Execution
The coordinator determines which agents can run in parallel based on their dependencies. Independent agents (Universe, Alpha, Risk) execute concurrently, while the Strategy agent waits for all results:
# Simplified execution flow in the coordinator
async def orchestrate(self, context: dict) -> dict:
# Phase 1: Run independent agents in parallel
universe_result, alpha_result, risk_result = await asyncio.gather(
self.universe_agent.execute(context),
self.alpha_agent.execute(context),
self.risk_agent.execute(context),
)
# Phase 2: Run strategy agent with all results
context["universe"] = universe_result
context["alpha"] = alpha_result
context["risk"] = risk_result
strategy_result = await self.strategy_agent.execute(context)
return strategy_result
Coordinator Agent
The CoordinatorAgent is the orchestration layer that plans execution order, spawns specialized agents, and integrates their outputs into a final algorithm.
Responsibilities
- Execution Planning: Analyzes the article summary to determine which agents are needed and their execution order
- Context Distribution: Prepares and distributes the appropriate context (summary, parameters, constraints) to each agent
- Result Integration: Collects
AgentResultobjects from all agents and passes them to the StrategyAgent for final assembly - Error Recovery: If an agent fails, the coordinator can retry with modified parameters or fall back to a simpler generation strategy
- Progress Reporting: Emits status updates during multi-agent execution for display in the interactive chat
Workflow
Fallback Behavior
When the multi-agent system encounters errors, the coordinator employs a graceful degradation strategy:
| Scenario | Coordinator Action |
|---|---|
| Single agent failure | Retry the failed agent up to 2 times with rephrased prompts |
| Multiple agent failures | Fall back to single-agent generation mode (one LLM call for entire algorithm) |
| LLM timeout | Retry with adjusted timeout or switch to a smaller Ollama model if configured |
| Context too large | Truncate article summary to fit within the LLM context window |
Specialized Agents
Each specialized agent generates a specific component of the final QuantConnect algorithm. The agents operate independently and produce code fragments that the StrategyAgent integrates.
UniverseAgent
Generates the stock universe selection logic - the criteria for which securities the algorithm trades.
| Property | Detail |
|---|---|
| Input | Article summary with universe criteria (market cap, sector, liquidity, etc.) |
| Output | Universe.py component - coarse/fine universe selection filters |
| Key Methods | coarse_selection_function(), fine_selection_function() |
| Dependencies | None (runs in parallel) |
# Example UniverseAgent output
def coarse_selection_function(self, coarse):
"""Select liquid, mid-cap US equities."""
filtered = [x for x in coarse
if x.has_fundamental_data
and x.price > 5
and x.dollar_volume > 1e6]
sorted_by_volume = sorted(filtered, key=lambda x: x.dollar_volume, reverse=True)
return [x.symbol for x in sorted_by_volume[:100]]
AlphaAgent
Generates the trading signal logic - the indicators and conditions that trigger entry and exit decisions.
| Property | Detail |
|---|---|
| Input | Article summary with indicator definitions, entry/exit conditions, parameter values |
| Output | Alpha.py component - indicator registration, signal generation methods |
| Key Methods | register_indicators(), generate_signals(), on_data() |
| Dependencies | None (runs in parallel) |
# Example AlphaAgent output
def register_indicators(self):
"""Register technical indicators for signal generation."""
self._rsi = self.rsi(self.symbol, 14, Resolution.DAILY)
self._macd = self.macd(self.symbol, 12, 26, 9, Resolution.DAILY)
self._bb = self.bb(self.symbol, 20, 2, Resolution.DAILY)
def generate_signals(self, data):
"""Generate BUY/SELL signals based on indicator convergence."""
if not all([self._rsi.is_ready, self._macd.is_ready, self._bb.is_ready]):
return None
if (self._rsi.current.value < 30
and self._macd.current.value > self._macd.signal.current.value
and data[self.symbol].close < self._bb.lower_band.current.value):
return "BUY"
if self._rsi.current.value > 70:
return "SELL"
return None
RiskAgent
Generates risk management logic - position sizing, stop losses, profit targets, and portfolio-level constraints.
| Property | Detail |
|---|---|
| Input | Article summary with risk parameters, drawdown limits, position sizing rules |
| Output | Risk.py component - position sizing, stop loss/take profit, portfolio limits |
| Key Methods | calculate_position_size(), check_stop_loss(), check_profit_target() |
| Dependencies | None (runs in parallel) |
# Example RiskAgent output
def calculate_position_size(self, symbol):
"""Calculate position size based on portfolio risk budget."""
portfolio_value = self.portfolio.total_portfolio_value
max_risk_per_trade = portfolio_value * self._risk_per_trade # 1% risk
current_price = self.securities[symbol].price
stop_distance = current_price * self._stop_loss_pct # 2% stop
shares = int(max_risk_per_trade / stop_distance)
max_position = portfolio_value * self._max_position_pct / current_price
return min(shares, int(max_position))
def check_stop_loss(self, symbol):
"""Check if stop loss has been triggered."""
if symbol not in self._entry_prices:
return False
entry = self._entry_prices[symbol]
current = self.securities[symbol].price
return (entry - current) / entry > self._stop_loss_pct
StrategyAgent
The integration agent that assembles outputs from all other agents into a complete, runnable QuantConnect algorithm.
| Property | Detail |
|---|---|
| Input | AgentResults from Universe, Alpha, and Risk agents |
| Output | Main.py - complete algorithm file combining all components |
| Key Tasks | Merge code fragments, resolve naming conflicts, ensure proper initialization order, add scheduling |
| Dependencies | Requires all Phase 1 agent results |
The StrategyAgent performs the following integration steps:
- Merges import statements (deduplicating)
- Combines class-level attributes from all agents
- Integrates
initialize()method with universe, indicator, and risk setup - Wires signal generation into
on_data()with risk checks - Adds scheduling (intraday checks, end-of-day liquidation)
- Validates the assembled code passes AST parsing
Autonomous Mode
Autonomous mode implements a self-improving generation loop that learns from compilation errors, backtest failures, and successful patterns to progressively generate better algorithms.
How It Works
Each iteration of the autonomous loop follows this cycle:
- Search - Find research articles matching the query
- Generate - Create an algorithm using the multi-agent system with refined prompts
- Validate - Check syntax and compile on QuantConnect
- Backtest - Run the algorithm and extract performance metrics
- Learn - Analyze errors and successes, update the learning database
- Refine - Adjust prompts based on learned patterns
- Repeat - Continue until min_sharpe is achieved or max_iterations is reached
Learning Components
LearningDatabase
SQLite-backed storage for all patterns learned across autonomous runs. Persists between sessions.
| Table | Contents |
|---|---|
error_patterns |
Compilation/runtime errors mapped to their fixes |
successful_patterns |
Code structures that compiled and backtested successfully |
prompt_history |
Prompt variants and their corresponding algorithm quality scores |
indicator_performance |
Which indicators correlated with higher Sharpe ratios |
ErrorLearner
Analyzes compilation and runtime errors to build a knowledge base of common mistakes and their solutions:
- Categorizes errors by type (syntax, import, indicator, API misuse)
- Maps error patterns to specific code fixes
- Injects avoidance rules into generation prompts after repeated occurrences
PromptRefiner
Dynamically adjusts generation prompts based on iteration results:
- Adds specific constraints when errors recur (e.g., "always check .is_ready before using indicators")
- Emphasizes successful patterns (e.g., "use RSI + SMA combination which produced Sharpe > 1.5")
- Adjusts risk parameters based on backtest drawdown analysis
PerformanceLearner
Tracks which indicators, timeframes, and strategy types produce the best backtest results:
- Correlates indicator combinations with Sharpe ratio outcomes
- Identifies optimal parameter ranges (RSI period, SMA window, etc.)
- Feeds high-performing patterns into subsequent generation prompts
~/.quantcoder/learning.db and accumulates knowledge across all autonomous runs. This means each new run benefits from patterns learned in previous sessions.
Library Builder
The library builder generates a comprehensive collection of validated trading strategies spanning 13+ predefined categories. It is designed for long-running batch operations with checkpoint/resume support.
Strategy Categories
| # | Category | Description |
|---|---|---|
| 1 | Momentum | Trend-following strategies based on price momentum and relative strength |
| 2 | Mean Reversion | Strategies that profit from price returning to a historical mean |
| 3 | Statistical Arbitrage | Pairs trading, cointegration-based strategies |
| 4 | Volatility | VIX-based, volatility surface, and variance premium strategies |
| 5 | Factor Investing | Value, growth, quality, size, and multi-factor models |
| 6 | Machine Learning | ML-enhanced signal generation and portfolio construction |
| 7 | Event-Driven | Earnings, M&A, dividend, and news-based strategies |
| 8 | Market Microstructure | Order flow, bid-ask spread, and tick data strategies |
| 9 | Seasonal / Calendar | Day-of-week, month-of-year, and holiday effects |
| 10 | Options | Options-based strategies (covered calls, straddles, iron condors) |
| 11 | Sector Rotation | Business cycle-based sector allocation strategies |
| 12 | Risk Parity | Risk-budget allocation and equal risk contribution strategies |
| 13 | Multi-Asset | Cross-asset class strategies (equities, bonds, commodities, FX) |
Features
- Coverage Tracking: Monitors how many strategies have been generated per category and overall completion percentage
- Checkpoint/Resume: Saves progress to disk after each successful generation, allowing interrupted builds to resume from the last checkpoint
- Time Budget: The
--max-hoursflag sets a time limit; the builder prioritizes under-represented categories - Export: Completed libraries can be exported as a ZIP archive (containing all .py files) or a JSON manifest (with metadata and backtest results)
# Build progress is displayed in real-time
$ quantcoder library build --comprehensive --max-hours 24
Library Builder - Comprehensive Mode
=====================================
Categories: 13 | Time Budget: 24h | Checkpoint: enabled
[1/13] Momentum ............... 3/3 strategies generated
[2/13] Mean Reversion ......... 3/3 strategies generated
[3/13] Statistical Arbitrage .. 2/3 strategies generated (1 failed validation)
[4/13] Volatility ............. generating...
Progress: 11/39 strategies | 28% complete | Elapsed: 2h 15m
Evolution Engine
The evolution engine applies structural variation to existing algorithms, inspired by DeepMind's AlphaEvolve approach. It mutates algorithm components, evaluates fitness through backtesting, and selects the best-performing variants across multiple generations.
How It Works
- Seed: Start with a base algorithm (from article generation or user-provided)
- Mutate: Create N structural variants per generation by modifying specific components
- Evaluate: Backtest each variant and compute fitness (Sharpe ratio, return, drawdown)
- Select: Keep the top-performing variants in an elite pool
- Iterate: Use elite pool members as seeds for the next generation
Mutation Operators
The engine applies targeted mutations to specific algorithm components:
| Operator | Target | Example Mutation |
|---|---|---|
| Indicator Swap | Alpha signals | Replace RSI(14) with Stochastic(14,3) or change RSI period to 21 |
| Risk Adjustment | Risk management | Tighten stop loss from 2% to 1.5%, increase position count from 5 to 8 |
| Entry/Exit Modification | Signal logic | Add a confirmation indicator, change threshold values, add time filters |
| Universe Variation | Stock selection | Change market cap filter, add volume requirements, modify sector focus |
| Timeframe Shift | Resolution | Switch from daily to hourly, or add multi-timeframe confirmation |
Fitness Evaluation
Each variant is scored using a composite fitness function:
Elite Pool
The elite pool maintains the top-K variants across all generations. Key properties:
- Fixed size (default: 5 members)
- New variants replace the worst member if they score higher
- Elite members are used as seeds for mutations in subsequent generations
- The pool is persisted to disk, allowing evolution runs to be resumed
# Example evolution progress output
$ quantcoder evolve start 1 --gens 3 --variants 5 --push-to-qc
Evolution Engine - Article 1
============================
Base algorithm: momentum_rsi_sma.py (Sharpe: 0.85)
Generation 1: 5 variants | Best fitness: 1.02 (+20.0%)
Generation 2: 5 variants | Best fitness: 1.15 (+35.3%)
Generation 3: 5 variants | Best fitness: 1.28 (+50.6%)
Elite Pool:
1. variant_g2_v3 Sharpe=1.28, Return=10.5%, MaxDD=2.5%, CAGR=15.2%, WinRate=62.0%, Trades=47
2. variant_g1_v1 Sharpe=1.15, Return=8.7%, MaxDD=2.9%, CAGR=12.1%, WinRate=58.0%, Trades=39
3. variant_g3_v2 Sharpe=1.02, Return=7.3%, MaxDD=3.1%, CAGR=10.5%, WinRate=55.0%, Trades=42
✓ Created QC project: Evolved_abc123
Project ID: 25541234
URL: https://www.quantconnect.com/terminal/25541234
QC Integration
When using the --push-to-qc flag, the evolution engine automatically:
- Creates a new QuantConnect project named
Evolved_{evolution_id} - Uploads the best variant's code as
main.py - Compiles and verifies the code on the QC cloud
- Prints the project ID and direct URL for immediate access
This eliminates the manual step of copying evolved code into QuantConnect after evolution completes.
Backtest Metrics
All backtest commands now display 6 structured metrics extracted from QuantConnect results:
| Metric | Description | Source Statistic |
|---|---|---|
| Sharpe Ratio | Risk-adjusted return (annualized) | Sharpe Ratio |
| Total Return | Net profit as percentage | Net Profit |
| CAGR | Compounding annual growth rate | Compounding Annual Return |
| Max Drawdown | Largest peak-to-trough decline | Drawdown |
| Win Rate | Percentage of profitable trades | Win Rate |
| Total Trades | Number of orders executed | Total Orders |
Scheduled Automation
The scheduled automation module runs the full QuantCoder pipeline on a recurring basis using APScheduler. It automates the complete cycle from article search through backtesting and optionally publishes results to Notion.
Pipeline
Each scheduled run executes the following steps automatically:
- Search - Query CrossRef/arXiv for each configured search term
- Download - Retrieve PDFs for top results (skipping previously processed articles)
- Summarize - Extract strategy logic from new articles
- Generate - Create QuantConnect algorithms via the multi-agent system
- Validate - Compile on QuantConnect cloud
- Backtest - Run backtests and extract performance metrics
- Filter - Keep only algorithms meeting the minimum Sharpe threshold
- Publish - (Optional) Send results to Notion database for review
Configuration
| Parameter | Default | Description |
|---|---|---|
--interval |
daily | Run frequency: daily, weekly, or hourly |
--hour |
6 | Hour of day to run (0-23, in local time) |
--queries |
- | Comma-separated list of search queries |
--min-sharpe |
0.5 | Minimum Sharpe ratio to keep a generated algorithm |
--max-articles |
5 | Maximum articles to process per query per run |
--publish |
false | Publish results to Notion (requires NOTION_API_KEY) |
Notion Integration
When the --publish flag is set and a Notion API key is configured, the scheduler automatically creates entries in a Notion database with:
- Article title and DOI
- Strategy summary
- Backtest results (Sharpe, return, drawdown, trade count)
- Generated algorithm code
- Timestamp and run metadata
# Example: daily scheduled pipeline
quantcoder schedule start \
--interval daily \
--hour 6 \
--queries "momentum,mean reversion,volatility" \
--min-sharpe 1.0 \
--publish
# Output:
Scheduler started. Jobs:
[daily-6am] "momentum" - next run: 2024-07-15 06:00:00
[daily-6am] "mean reversion" - next run: 2024-07-15 06:00:00
[daily-6am] "volatility" - next run: 2024-07-15 06:00:00
Press Ctrl+C to stop the scheduler.
LLM Provider
QuantCoder v2.0 runs exclusively on Ollama for local LLM inference. No cloud API keys are required. All models run on your machine.
Models
| Model | Task | Description |
|---|---|---|
qwen2.5-coder:14b |
Code generation, refinement, error fixing | Selected via LLMFactory.create(task="coding") |
mistral |
Reasoning, summarization, chat | Selected via LLMFactory.create(task="reasoning") |
Task-Based Model Routing
The LLMFactory automatically selects the right model based on the task type. This replaces the previous multi-provider configuration:
# In ~/.quantcoder/config.toml
[model]
provider = "ollama"
model = "qwen2.5-coder:14b"
code_model = "qwen2.5-coder:14b"
reasoning_model = "mistral"
ollama_base_url = "http://localhost:11434"
ollama_timeout = 600
Setup
# Install Ollama (https://ollama.ai)
curl -fsSL https://ollama.ai/install.sh | sh
# Pull the required models
ollama pull qwen2.5-coder:14b
ollama pull mistral
# Verify Ollama is running
curl http://localhost:11434/api/tags
# Launch QuantCoder
quantcoder
Remote Ollama
To use a remote Ollama instance on another machine:
[model]
ollama_base_url = "http://192.168.1.100:11434"
Configuration
QuantCoder uses a TOML configuration file at ~/.quantcoder/config.toml for persistent settings, supplemented by environment variables in ~/.quantcoder/.env for secrets.
Configuration File
Full example config.toml with all available options:
# ~/.quantcoder/config.toml
# ============================================================
# Model Configuration (Ollama-only)
# ============================================================
[model]
provider = "ollama"
model = "qwen2.5-coder:14b"
code_model = "qwen2.5-coder:14b" # Code generation, refinement
reasoning_model = "mistral" # Summarization, chat
# Generation parameters
temperature = 0.5
max_tokens = 3000
# Ollama connection
ollama_base_url = "http://localhost:11434"
ollama_timeout = 600
# ============================================================
# UI Configuration
# ============================================================
[ui]
# Interactive chat settings
theme = "dark" # dark or light
show_progress = true # Show progress bars during generation
show_agent_logs = true # Show per-agent status in multi-agent mode
syntax_highlight = true # Highlight generated code in terminal
# ============================================================
# Tools Configuration
# ============================================================
[tools]
# Article search
max_search_results = 20 # Max results from CrossRef + arXiv
cache_articles = true # Cache downloaded articles locally
articles_dir = "~/.quantcoder/articles"
# Code generation
output_dir = "generated_code" # Where generated algorithms are saved
validate_locally = true # Run AST validation before cloud compile
validate_cloud = true # Compile on QuantConnect cloud
# Backtesting defaults
default_start_date = "2024-01-01"
default_end_date = "2024-06-30"
default_cash = 100000
# QuantConnect project ID (optional - auto-created if not set)
quantconnect_project_id = ""
# Deep search
enable_deep_search = false # Auto-enable Tavily deep search
tavily_max_results = 10
# ============================================================
# Logging Configuration
# ============================================================
[logging]
level = "INFO" # DEBUG, INFO, WARNING, ERROR
log_dir = "~/.quantcoder/logs"
max_log_files = 10 # Rotate after this many files
log_format = "text" # text or json
# ============================================================
# Autonomous Mode
# ============================================================
[autonomous]
default_max_iterations = 50
default_min_sharpe = 1.0
learning_db_path = "~/.quantcoder/learning.db"
enable_prompt_refinement = true
enable_error_learning = true
# ============================================================
# Evolution Engine
# ============================================================
[evolution]
default_generations = 3
default_variants = 5
elite_pool_size = 5
fitness_weights = [0.40, 0.25, 0.25, 0.10] # sharpe, return, drawdown, error
# ============================================================
# Library Builder
# ============================================================
[library]
strategies_per_category = 3
checkpoint_interval = 1 # Checkpoint after each strategy
export_dir = "~/.quantcoder/library"
# ============================================================
# Scheduler
# ============================================================
[scheduler]
default_interval = "daily"
default_hour = 6
default_min_sharpe = 0.5
max_articles_per_query = 5
publish_to_notion = false
Environment Variables
Sensitive credentials are stored in ~/.quantcoder/.env (never committed to version control):
# No LLM API keys required — Ollama runs locally
# Optional - QuantConnect cloud compilation and backtesting
QUANTCONNECT_API_KEY=...
QUANTCONNECT_USER_ID=...
# Optional - Notion publishing
NOTION_API_KEY=secret_...
# Optional - Deep search
TAVILY_API_KEY=tvly-...
.env file to version control. The ~/.quantcoder/ directory should contain a .gitignore file that excludes .env and learning.db. API keys grant access to paid services and should be treated as passwords.
Validation & Testing
Test Suite
QuantCoder includes 18 test files covering all major modules. Tests use pytest with fixtures for mocking LLM responses and QuantConnect API calls.
# Run all tests
pytest tests/
# Run with coverage report
pytest tests/ --cov=quantcoder --cov-report=html
# Run a specific test file
pytest tests/test_agents.py -v
# Run tests matching a pattern
pytest tests/ -k "test_generate" -v
Test Coverage
| Module | Test File | Key Tests |
|---|---|---|
| CLI | test_cli.py |
Command parsing, option validation, output formatting |
| LLM Handler | test_llm.py |
Provider factory, API calls, error handling, retry logic |
| Article Processor | test_article_processor.py |
PDF extraction, NLP analysis, summary generation |
| Agents | test_agents.py |
BaseAgent, Coordinator, Universe, Alpha, Risk, Strategy agents |
| Tools | test_tools.py |
Search, Download, Summarize, Generate, Validate, Backtest tools |
| Autonomous | test_autonomous.py |
Learning database, error learner, prompt refiner, runner loop |
| Evolution | test_evolution.py |
Mutation operators, fitness evaluation, elite pool management |
| Library | test_library.py |
Category management, checkpoint/resume, export |
| Scheduler | test_scheduler.py |
Job scheduling, pipeline execution, Notion publishing |
| Config | test_config.py |
TOML parsing, .env loading, default values |
Validation Pipeline
Generated algorithms pass through a multi-stage validation pipeline before being accepted:
Stage 1: Local AST Syntax Validation
Parses the generated Python code using the ast module to check for syntax errors without executing the code. This catches:
- Invalid Python syntax
- Unclosed brackets, parentheses, or strings
- Indentation errors
- Invalid escape sequences
Stage 2: QuantConnect Cloud Compilation
Submits the algorithm to QuantConnect via MCP for cloud compilation. This catches:
- Missing or incorrect imports
- Incorrect LEAN API usage (wrong method names, argument types)
- Indicator registration errors
- Missing
initialize()oron_data()methods
Stage 3: Backtest Execution
Runs the compiled algorithm on QuantConnect's backtesting engine. Extracts:
- Sharpe ratio
- Total return and annualized return
- Maximum drawdown
- Total number of trades
- Win rate and profit factor
Stage 4: Autonomous Error Learning Validation
If autonomous mode is active, the learning system validates that known error patterns have been avoided:
- Checks for previously seen compilation errors
- Validates indicator
.is_readyguards are present - Ensures underscore-prefixed indicator names
- Confirms risk management parameters are set