license: mit
tags:
- quantitative-finance
- alpha-generation
- worldquant-brain
- ml-intern
Alpha Factory v0.2.0
LLM-assisted alpha expression generator for WorldQuant BRAIN.
This is a Python application, not a model. It generates candidate BRAIN expressions for manual review and submission.
What It Actually Does
| Mode | What it does | Needs LLM? | Submits to BRAIN? |
|---|---|---|---|
Proven Templates (--proven) |
Generates valid BRAIN expressions using hardcoded templates with novel fields | No | Optional (--enable-brain) |
| LLM Mode (default) | Uses 1.5B-72B LLMs to generate hypothesis β expression β evaluation | Yes (local/cloud) | Optional |
The pipeline runs:
- Theme sampling β picks under-explored themes from field registry
- Expression generation β deterministic templates OR LLM hypothesis + compile
- Static lint β validates BRAIN syntax (operator arity, look-ahead, parentheses)
- Deduplication β SHA256 hash to avoid duplicates
- Store β persists to DuckDB for review
- Local sim β lightweight numpy backtest as triage (lenient thresholds, never blocks)
- Acceptance checklist β 14-point pre-submission gate
- Crowd Scout β novelty assessment (LLM or heuristic)
- BRAIN submission β live submission (requires
BRAIN_SESSION_TOKEN) - Performance Surgeon β diagnoses weak alphas, suggests mutations
- Gatekeeper β final go/no-go (LLM)
Quick Start
git clone https://huggingface.co/gaurv007/alpha-factory
cd alpha-factory
pip install -e ".[all]"
Proven Templates (RECOMMENDED β no LLM, guaranteed valid)
python -m alpha_factory.run --proven --batch-size 10
Uses proven Alpha 15/6 structures with novel AC=0 fields. Every expression is syntactically valid.
LLM-Assisted Generation
# Needs Ollama or HF token
python -m alpha_factory.run --batch-size 5 --dry-run
Standalone Proven Generator
python -m alpha_factory.generate_proven
Run Tests
pytest tests/ -v
BRAIN Setup
BRAIN uses session-based authentication (browser cookies), not API keys. The session token expires quickly.
- Log in to brain.worldquant.com
- Open browser DevTools β Network tab
- Run any simulation, look for request to
api.worldquantbrain.com - Copy the
Cookie: session=...header value - Set:
export BRAIN_SESSION_TOKEN=your_token_here
No token = dry-run mode only. The pipeline will generate expressions but not submit them.
Architecture
Theme Sampler β Expression Generation β Static Lint β Dedup β Store β Local Sim β Checklist
β (Templates or LLM) β β β β
Crowd Scout β Performance Surgeon β Gatekeeper β BRAIN Submit
β (iteration queue)
Winner Memory β Mutator β Performance Surgeon
Components
| Module | Purpose | Status |
|---|---|---|
proven_templates.py |
Deterministic expression generation | β Working |
lint.py |
BRAIN syntax validation (arity, lookahead, parens) | β Working |
pipeline.py |
Orchestrates all stages | β Working |
expression_compiler.py |
Jinja2 templates + LLM fallback | β Working |
crowd_scout.py |
Novelty / correlation assessment | β Working |
performance_surgeon.py |
Diagnose failures, suggest mutations | β Working |
gatekeeper.py |
Final go/no-go memo | β Working |
wq_client.py |
BRAIN API submission | β οΈ Needs BRAIN_SESSION_TOKEN |
brain_sim.py |
Local numpy backtest (triage, lenient) | β Wired (never blocks) |
regime_tagger.py |
Vol/trend/rate/style regimes | β Wired via Performance Surgeon |
Key Features
- Proven template mode: No LLM required. Generates valid BRAIN expressions instantly.
- Field registry: 40+ real BRAIN fields with coverage, alpha counts, and sign conventions.
- Novel group keys: Uses under-explored neutralization groups (AC β€ 30) for lower correlation.
- Static lint: Catches syntax errors before submission (operator arity, look-ahead, unbalanced parens).
- Kill switches: Circuit breakers for runaway pipelines (consecutive fails, daily limits, token budget).
- Winner memory: Tracks which field/archetype combinations work, feeds back to generation.
- Expression mutator: Auto-generates decay, horizon, neutralization, and sign-flip variants.
- DuckDB store: Persistent history of all alphas, metrics, and verdicts.
- Retry logic: LLM client retries transient failures (429, 502, 503, 504, timeout) with exponential backoff. Non-retryable errors (401, 400, OOM) abort immediately.
- Unified pipeline: Both proven and LLM paths flow through
_process_candidate()β no code duplication.
Known Limitations
- BRAIN auth is session-based: Token expires. No automatic refresh. You must re-copy from browser.
- Local simulation is triage-only:
brain_sim.pyruns with lenient thresholds (min_sharpe=0.3) and prints warnings but never blocks a candidate. It's for sanity checking, not filtering. - LLM generation can hallucinate fields: Static lint catches most errors, but field names from LLMs may not exist on BRAIN.
- Weights inside
rank()are decorative:rank(0.6*a + 0.4*b)is monotonic β coefficients don't linearly combine. The signal comes from which fields are combined. - Not a guarantee of profitable alphas: This generates candidates. BRAIN's simulation is the ground truth.
Configuration
All settings in alpha_factory/config.py. Key ones:
batch_size = 10 # Candidates per run
use_proven_templates = False # Set True for deterministic mode
enable_brain_client = False # Set True for live BRAIN submission
max_parallel_candidates = 3 # Concurrent LLM calls
Or via CLI:
python -m alpha_factory.run --proven --batch-size 10 --enable-brain
Cost
| Item | Cost |
|---|---|
| Proven template mode | $0 (no LLM) |
| Local Ollama (7B) | $0 (your GPU) |
| HuggingFace Inference API | Free tier / rate-limited |
| BRAIN submissions | $0 (uses your existing BRAIN credits) |
File Structure
alpha_factory/
βββ config.py # All settings (Pydantic v2)
βββ run.py # Entry point (single asyncio.run)
βββ schemas/ # Typed Pydantic contracts
βββ deterministic/
β βββ lint.py # Static pre-flight (Layer 2)
β βββ theme_sampler.py # Gap analysis (Layer 1)
β βββ fitness.py # Composite scoring
β βββ proven_templates.py # Deterministic generation
β βββ expression_mutator.py # Evolutionary variants
β βββ acceptance_checklist.py # 14-point pre-submission gate
β βββ brain_sim.py # Local numpy backtest (triage)
β βββ regime_tagger.py # IQR-based regime detection
βββ infra/
β βββ model_manager.py # Ollama + HF auto-detection
β βββ llm_client.py # Unified LLM interface (token budget + retry)
β βββ factor_store.py # DuckDB persistence (parameterized SQL)
β βββ wq_client.py # BRAIN API wrapper (session auth, circuit breaker)
β βββ winner_memory.py # Feedback loop
βββ local/
β βββ brain_sim.py # (identical, part of deterministic)
βββ personas/
β βββ hypothesis_hunter.py # Persona 1 (LLM)
β βββ expression_compiler.py # Persona 2 (templates + LLM fallback)
β βββ crowd_scout.py # Persona 4 (heuristic + LLM)
β βββ performance_surgeon.py # Persona 5 (heuristic + LLM)
β βββ gatekeeper.py # Persona 6 (LLM)
βββ orchestration/
βββ pipeline.py # Full DAG (unified _process_candidate)
Changelog v0.2.0
- Fixed:
pv13_ustomergraphrankβpv13_customergraphranktypos - Fixed:
operators.csvarity mismatches (ts_mean, ts_std, ts_delta now correctly listed as 2-arg) - Fixed:
cleanup.pyno longer blacklists valid BRAIN fields (vwap,close,volume, etc.) - Fixed:
personas/__init__.pyimports real modules instead of stubs - Fixed:
infra/__init__.pyimports realBrainClientinstead of stub class - Fixed: Expression compiler sign logic β now per-component, no global blind negation
- Fixed: LLM client stops error amplification (no more 3x API calls on auth/network failures)
- Fixed: LLM client enforces token budget (was declared but never checked)
- Fixed: LLM client adds retry logic with exponential backoff for transient failures
- Fixed: LLM client JSON parsing regex no longer strips all whitespace (was mangling responses)
- Fixed:
pipeline.pyNameError: max_corrβ correlation is now computed before checklist call - Fixed:
pipeline.py_submit_or_dryrunreusesself.braininstead of creating new clients - Fixed:
run.pyuses singleasyncio.run()β no more session leak - Fixed:
acceptance_checklist.pyRETURNS-CORR check no longer always fails (lowered from 0.05 to 0.95) - Fixed:
factor_store.pyuses DuckDB transaction context manager instead of string-based BEGIN/COMMIT - Fixed:
ui.pySQL uses parameterized LIMIT instead of f-string injection - Fixed:
expression_compiler.py_validate_expressionis now called, issues logged - Fixed:
expression_mutator.pyregex now handles uppercase field IDs (e.g.,mdl77_2GlobalDev...) - Fixed:
proven_templates.pydecay parameter is now passed through (was hardcoded to 5) - Fixed:
theme_sampler.pypick_theme()has alive-theme fallback when all themes exhausted - Fixed: Removed dead
enable_local_simconfig field and--local-simCLI flag - Fixed: Removed orphan
rag.py(arXiv retrieval not wired, will be re-added when integrated) - Fixed: Added missing
local/__init__.pyandorchestration/__init__.py - Fixed:
pyproject.tomlversion bumped to 0.2.0, removed unusedscipydependency - New: Proven template mode (
--proven) generates expressions without any LLM - New: Winner memory integration in pipeline (records winners/failures/iterations)
- New: Expression mutator integration (auto-generates decay/horizon/group/sign variants)
- New: Acceptance checklist (14 checks, wired before BRAIN submission)
- New: Parallel batch processing with
max_parallel_candidatessemaphore - New: 64+ comprehensive tests covering templates, lint, mutations, config, fitness, fields, groups
- New:
_process_candidate()unified path β both proven and LLM candidates flow through same pipeline - Updated: Honest README that accurately describes what works and what doesn't
License
MIT β use at your own risk. This is not financial advice. BRAIN simulations are the ground truth.
Generated by ML Intern
This repository was generated by ML Intern, an agent for machine learning research and development on the Hugging Face Hub.
- Try ML Intern: https://smolagents-ml-intern.hf.space
- Source code: https://github.com/huggingface/ml-intern