|
QuantForge is a research-oriented quantitative backtesting framework designed to separate signal from noise in trading strategy research. Built to prevent the common pitfalls of:
It provides a complete validation stack that distinguishes skill-based strategies from random chance through rigorous statistical testing. |
# Simple Strategy Example
def generate_signals(df):
fast = df['close'].ewm(50).mean()
slow = df['close'].ewm(200).mean()
signals = pd.Series(0, index=df.index)
signals[fast > slow] = 1.0 # Long
signals[fast < slow] = -1.0 # Short
return signals |
mindmap
root((QuantForge))
Core Engine
Event-driven execution
Next-bar semantics
Single & multi-asset
Transaction costs
Warmup periods
Analytics
Performance metrics
Risk measurement
Trade extraction
Timeframe-agnostic
Validation
Monte Carlo 6 variants
Walk-forward analysis
White's Reality Check
Benchmark comparison
Infrastructure
YAML configuration
Run manifests
Data fingerprinting
146 passing tests
graph LR
A[📥 Clone Repo] --> B[🐍 Setup venv]
B --> C[📦 Install deps]
C --> D[✅ Run tests]
D --> E[🚀 First backtest]
style A fill:#2E9EF7,stroke:#1976D2,stroke-width:2px,color:#fff
style B fill:#4CAF50,stroke:#2E7D32,stroke-width:2px,color:#fff
style C fill:#FF9800,stroke:#F57C00,stroke-width:2px,color:#fff
style D fill:#9C27B0,stroke:#6A1B9A,stroke-width:2px,color:#fff
style E fill:#E91E63,stroke:#C2185B,stroke-width:2px,color:#fff
# Clone the repository
git clone https://github.com/Abhidev-aiml/quantforge-v0.git
cd quantforge-v0
# Create virtual environment
python3.11 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Verify installation (should show 146 passing tests)
python -m pytest -v|
Single-Asset Backtest python -m execute.run_from_config \
configs/experiments/gold_goldencross.yamlWalk-Forward Validation python -m execute.run_walk_forward \
configs/experiments/gold_goldencross_wf.yaml |
Multi-Asset Portfolio python -m execute.run_multi_from_config \
configs/experiments/xs_momentum_14assets.yamlWhite's Reality Check python -m execute.run_whites_rc |
flowchart TB
subgraph Input["📥 Input Layer"]
A1[YAML Config]
A2[Market Data CSV]
end
subgraph Config["⚙️ Configuration Layer"]
B1[Schema Validation]
B2[Type Safety]
B3[Data Hashing]
end
subgraph Strategy["🎯 Strategy Layer"]
C1[Signal Generation]
C2[Contract Validation]
C3[Parameter Wiring]
end
subgraph Engine["🏗️ Engine Layer"]
D1[Event-Driven Execution]
D2[Transaction Costs]
D3[Position Management]
end
subgraph Analytics["📊 Analytics Layer"]
E1[Performance Metrics]
E2[Risk Measurement]
E3[Trade Extraction]
end
subgraph Validation["🔬 Validation Layer"]
F1[Monte Carlo]
F2[Walk-Forward]
F3[White's RC]
end
subgraph Output["📤 Output Layer"]
G1[Run Artifacts]
G2[HTML Tearsheet]
G3[Interactive Charts]
end
Input --> Config
Config --> Strategy
Strategy --> Engine
Engine --> Analytics
Analytics --> Validation
Validation --> Output
style Input fill:#2E9EF7,stroke:#1976D2,stroke-width:2px,color:#fff
style Config fill:#4CAF50,stroke:#2E7D32,stroke-width:2px,color:#fff
style Strategy fill:#FF9800,stroke:#F57C00,stroke-width:2px,color:#fff
style Engine fill:#9C27B0,stroke:#6A1B9A,stroke-width:2px,color:#fff
style Analytics fill:#E91E63,stroke:#C2185B,stroke-width:2px,color:#fff
style Validation fill:#00BCD4,stroke:#0097A7,stroke-width:2px,color:#fff
style Output fill:#795548,stroke:#5D4037,stroke-width:2px,color:#fff
sequenceDiagram
participant S as Strategy
participant E as Engine
participant M as Market
Note over M: Bar t closes
M->>S: OHLCV data (bar t)
S->>S: Calculate indicators
S->>E: Signal (from bar t)
Note over E: Queue target weight
Note over M: Bar t+1 opens
M->>E: Open price (bar t+1)
E->>E: Execute at t+1 open
E->>E: Apply slippage
E->>E: Charge commission
E->>E: Update position
Note over M: Bar t+1 closes
M->>E: Close price (bar t+1)
E->>E: Mark to market
|
Next-Bar Execution No Look-Ahead
Transaction Costs
Deterministic
|
graph TB
subgraph Layer1["Layer 1: Monte Carlo"]
MC1[Bootstrap Returns]
MC2[Randomize Trades]
MC3[Shuffle Signals]
MC1 --> MC4{p-value < 0.05?}
MC2 --> MC4
MC3 --> MC4
MC4 -->|Yes| MC5[Likely Skillful]
MC4 -->|No| MC6[Likely Random]
end
subgraph Layer2["Layer 2: Walk-Forward"]
WF1[Rolling Windows]
WF2[IS Optimization]
WF3[OOS Testing]
WF1 --> WF2 --> WF3
WF3 --> WF4{OOS > Benchmark?}
WF4 -->|Yes| WF5[Has Edge]
WF4 -->|No| WF6[No Edge]
end
subgraph Layer3["Layer 3: White's RC"]
WRC1[Strategy Universe]
WRC2[Excess Returns Matrix]
WRC3[Block Bootstrap]
WRC1 --> WRC2 --> WRC3
WRC3 --> WRC4{p-value < 0.05?}
WRC4 -->|Yes| WRC5[Survives Correction]
WRC4 -->|No| WRC6[Data Snooping]
end
Layer1 --> Layer2
Layer2 --> Layer3
style Layer1 fill:#2E9EF7,stroke:#1976D2,stroke-width:2px,color:#fff
style Layer2 fill:#4CAF50,stroke:#2E7D32,stroke-width:2px,color:#fff
style Layer3 fill:#FF9800,stroke:#F57C00,stroke-width:2px,color:#fff
|
Purpose: Test if observed performance could be random chance Methods:
|
from validation.monte_carlo import bootstrap_returns_iid
# Run Monte Carlo simulation
results = bootstrap_returns_iid(
equity=equity_curve,
n_sims=5000,
periods_per_year=252,
seed=42
)
print(f"p-value: {results['p_value']:.4f}")
print(f"Percentile: {results['percentile']:.1f}%")
# Verdict: p < 0.05 suggests skill-based performance |
gantt
title Walk-Forward Windows (Train → Test)
dateFormat X
axisFormat %s
section Window 1
Train :active, w1t, 0, 252
Test :crit, w1o, 252, 63
section Window 2
Train :active, w2t, 21, 252
Test :crit, w2o, 273, 63
section Window 3
Train :active, w3t, 42, 252
Test :crit, w3o, 294, 63
section Window 4
Train :active, w4t, 63, 252
Test :crit, w4o, 315, 63
|
Purpose: Prevent look-ahead bias and overfitting Process:
|
from validation.walk_forward import walk_forward
# Run walk-forward validation
wf_results = walk_forward(
data=df,
strategy_fn=generate_signals,
train_bars=252, # 1 year
test_bars=63, # 3 months
step_bars=21 # 1 month
)
# Verdicts
print(f"Robust: {wf_results['robust']}")
print(f"Has Edge: {wf_results['has_edge']}") |
|
Problem: Testing 100 strategies → ~99% chance of false positive Solution: Multiple-testing correction via bootstrap Process:
|
from validation.whites_reality_check import whites_reality_check
# Run White's Reality Check
wrc_results = whites_reality_check(
excess_returns_matrix, # (T, K) array
n_bootstrap=5000,
block_length=10,
seed=42
)
print(f"Best Strategy: {wrc_results['best_combo']}")
print(f"p-value: {wrc_results['p_value']:.4f}")
# Verdict: p < 0.05 survives multiple-testing correction |
mindmap
root((25+ Strategies))
Trend Following
Golden Cross 5 variants
EMA Cross
Absolute Momentum
Trend Pullback 4H/1H
Mean Reversion
RSI Overbought/Oversold
Bollinger Extremes
Z-Score Reversion
VWAP Deviation
Breakout
Donchian Channel
ATR Volatility
NY Opening Range 7 variants
Cross-Sectional
Relative Strength Momentum
Combined Indicators
Bollinger + RSI
VWAP Refined
|
|
gantt
title QuantForge Development Milestones
dateFormat YYYY-MM-DD
section Foundation
M1 Data Pipeline :done, m1, 2024-01-01, 2024-01-15
M2 Core Engine :done, m2, 2024-01-15, 2024-02-01
M3 Strategy Contract :done, m3, 2024-02-01, 2024-02-15
section Analytics
M4 Metrics & Analytics :done, m4, 2024-02-15, 2024-03-01
M5 Monte Carlo :done, m5, 2024-03-01, 2024-03-15
section Infrastructure
M6 Config System :done, m6, 2024-03-15, 2024-04-01
M7 Multi-Asset :done, m7, 2024-04-01, 2024-04-15
section Validation
M8 Walk-Forward :done, m8, 2024-04-15, 2024-05-01
M9 White's RC :done, m9, 2024-05-01, 2024-05-15
section Reporting
M10 Tearsheet Generator :done, m10, 2024-05-15, 2024-06-01
See docs/milestones/ for detailed documentation of each milestone.
# Run all tests
python -m pytest -v
# Run specific test module
python -m pytest tests/test_engine.py -v
# Run with coverage report
python -m pytest --cov=. --cov-report=html📋 Test Breakdown (Click to expand)
| Module | Tests | Coverage |
|---|---|---|
test_config.py |
6 | Schema validation, run context |
test_data.py |
10 | OHLCV validation, hashing |
test_engine.py |
13 | Execution semantics, costs |
test_engine_warmup.py |
2 | Warmup bar handling |
test_loader.py |
14 | Strategy loading, validation |
test_metrics.py |
11 | Performance metrics |
test_metrics_cagr.py |
2 | CAGR computation |
test_montecarlo.py |
7 | MC bootstrap correctness |
test_montecarlo_cost_adj.py |
3 | Cost-adjusted MC |
test_montecarlo_timeframe.py |
9 | Timeframe detection |
test_multi_data_hash.py |
4 | Universe hashing |
test_multi_engine.py |
9 | Multi-asset execution |
test_walk_forward.py |
17 | WF window mechanics |
test_whites_reality_check.py |
8 | WRC bootstrap |
test_xs_momentum.py |
4 | Cross-sectional strategy |
| Total | 146 | Full regression coverage |
engine:
initial_cash: 100000 # Starting capital
commission_bps: 1.0 # Commission (bps)
slippage_bps: 5.0 # Slippage (bps)
no_trade_band: 0.01 # Rebalance threshold
warmup_bars: 0 # Indicator warmupwalk_forward:
train_bars: 252 # 1 year IS
test_bars: 63 # 3 months OOS
step_bars: 21 # 1 month step |
monte_carlo:
enabled: true
n_simulations: 5000 # Bootstrap iterations
method: block # iid, block, null, trade
seed: 42 # Reproducibilitystrategy:
path: strategies/01_goldencross.py
params:
fast: 50
slow: 200 |
| Document | Description |
|---|---|
| Architecture | System design and component responsibilities |
| State | Current project state and handoff guide |
| Milestones | Detailed milestone completion reports |
| Context | Strategy-specific documentation |
# Create feature branch
git checkout -b feature/your-feature
# Make changes and add tests
# ...
# Run test suite
python -m pytest -v
# Commit with conventional commits
git commit -m "feat(engine): add feature"
# Push and create PR
git push origin feature/your-feature |
Key learnings from QuantForge:
|
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
|