FULL DOCUMENTATION / README CONTENT
Backtesting Engine for Systematic Trading Strategies
Realistic Backtesting with Stress Testing, Risk Management, and Walk-Forward Optimization (WFO).
Core Capabilities
- 300+ Technical Indicators (
pandas_taintegration). - Meta-Strategy Engine supporting multi-indicator voting.
- Realistic Stress Simulation (Transaction Costs and Slippage).
- Advanced Risk Management (Trade-level TP/SL).
- Walk-Forward Analysis & Optimization with Purge and Embargo.
- Professional Quant Metrics (Sharpe, Alpha, Beta, Expectancy, Payoff).
- Market Regime Detection (Bull, Bear, Sideways, Volatile).
Quick Start Example
Run a simple single-indicator backtest or combine multiple indicators with a configuration object.
from src_backtester import backtest, StrategyConfig
# Single Indicator Backtest (EMA Crossover)
backtest("AAPL", "EMA", (9, 21))
# Multi-Indicator Meta-Strategy (Requires 1 vote to enter)
backtest("AAPL",
"EMA", (9, 21),
"MACD", (12, 26, 9),
config = StrategyConfig(min_votes_required=1)
)
1. π‘οΈ StrategyConfig: Risk & Stress Management
This class is used to configure risk parameters and inject **realism** into the backtest through transaction costs and simulated slippage.
StrategyConfig Parameters
| Parameter | Type | Purpose / Example |
|---|---|---|
| take_profit_ratio | float or None | Percentage gain (e.g., 0.10 for 10%) to close the position early (TP). |
| stop_loss_ratio | float or None | Percentage loss (e.g., 0.05 for 5%) to close the position early (SL). |
| min_votes_required | int | Minimum number of indicators that must agree for the meta-strategy to enter a trade. |
| transaction_cost_pct | float | Cost per trade (entry and exit) as a percentage (e.g., 0.001 for 0.1%). |
| slippage_pct | float | Simulated execution slippage percentage (e.g., 0.0005). |
Example Configuration
config = StrategyConfig(
take_profit_ratio=0.05, # 5% Take Profit
stop_loss_ratio=0.03, # 3% Stop Loss
min_votes_required=2, # Requires 2 votes in meta-strategy
transaction_cost_pct=0.001, # 10bps Commission
slippage_pct=0.0005 # 5bps Slippage
)
2. π‘ Technical Indicators & Meta-Strategy Engine
Indicator Support
The library includes optimized built-in indicators and automatically loads 300+ indicators dynamically from pandas_ta.
- Built-in: SMA crossover, EMA crossover, MACD crossover.
- Generic Rule: Long signal when Close > indicator_line (for most generic indicators).
- Special Rules: MACD uses MACD line crossing above Signal line. KDJ uses %K > %D.
Use indicators.help() to print all available dynamic indicators.
Meta-Strategy (Voting Logic)
When multiple indicators are passed, the engine switches to a robust voting system.
- Each indicator returns a binary signal (0 or 1).
- The signals are summed.
- If the Total Votes ≥
min_votes_required, the position is entered.
# Strategy requires at least 2 indicators to agree (min_votes_required=2)
strategy_specs = [
("EMA", (9, 21)),
("MACD", (12, 26, 9)),
("RSI", (14,))
]
# If EMA=1, MACD=1, RSI=0 -> Total Votes = 2 -> Signal is Long.
# If EMA=1, MACD=0, RSI=0 -> Total Votes = 1 -> Signal is Flat.
3. π Core Engine Analytics & Financial Metrics
Performance Metrics
- Returns / Net Returns (After Costs)
- Cumulative Returns
- CAGR (Compound Annual Growth Rate)
- Sharpe Ratio, Sortino Ratio
- Calmar Ratio, Ulcer Index
- Max Drawdown (MDD)
Trade Analytics Engine
Provides granular, trade-level statistics.
- Expectancy (P_win * Avg_win + P_loss * Avg_loss)
- Payoff Ratio (Avg_win / abs(Avg_loss))
- Probability of Win/Loss
- Average Trade Duration
- Total Trades
Sensitivity Metrics
Measures the strategy's correlation and risk relative to a market benchmark.
- Correlation (Strategy vs. Market)
- Beta (Volatility relative to Benchmark)
- Jensenβs Alpha (Excess return adjusted for market risk)
Market Regime Detection
The engine classifies periods into regimes based on 120-day rolling cumulative return and volatility, providing context for performance via regime_metrics.
4. π Walk-Forward Analysis (WFA) & Optimization (WFO)
The backtest_walk_forward() function rigorously tests strategy robustness by simulating real-world decision-making across sequential windows.
Key Parameters & Concepts
- Train Window: In-Sample period used for parameter optimization (WFO) or simple metric collection (WFA).
- Test Window: Out-of-Sample period where the strategy is evaluated using the best parameters from the *Train Window*. This is the true performance metric.
- Purge: Removes data points near the test window boundary from the training set to prevent look-ahead bias from trade PnL overlap.
- Embargo: Imposes a cool-down period after the test window, preventing the immediately successful data from influencing the next train optimization.
Mode 1: WFA (Fixed Parameters)
Pass a single tuple of parameters. The strategy runs with these fixed values across all windows.
# WFA Example (Fixed EMA 9, 21)
backtest_walk_forward(
"AAPL",
"EMA", (9,21), # Fixed Tuple
start_date="2018-01-01",
train_period_days=500,
test_period_days=120
)
Mode 2: WFO (Parameter Search)
Pass a list of tuples (parameter space). The engine finds the best parameter set in each *Train Window* and uses it for the subsequent *Test Window*.
# WFO Example (Optimizing EMA periods)
param_space = [(5,15), (9,21), (10,30)]
backtest_walk_forward(
"AAPL",
"EMA", param_space, # List of Tuples
start_date="2018-01-01",
train_period_days=500,
test_period_days=120
)
5. π Main Function & Practical Examples
backtest() Function Signature
The main function accepts the ticker, one or more indicator specs (Name, Params), and an optional StrategyConfig object.
backtest(
ticker: str,
*indicators: Tuple[str, tuple],
config: Optional[StrategyConfig] = None,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
) -> DataFrame
Example A: Simple MACD with TP/SL
config = StrategyConfig(
take_profit_ratio=0.12,
stop_loss_ratio=0.05
)
backtest("TSLA", "MACD", (12, 26, 9), config=config)
Example B: Multi-Indicator Meta-Strategy
Requires 2 out of 3 indicators to agree (min_votes_required=2)
config = StrategyConfig(min_votes_required=2)
backtest(
"ETH-USD",
"EMA", (9, 21),
"RSI", (14,),
"MACD", (12, 26, 9),
config=config
)
6. βοΈ Internal Architecture & Plotting
Architecture Overview
The design prioritizes realism and modularity, avoiding unrealistic vectorized assumptions often found in simple backtesters.
- Data Fetcher: Uses
yfinanceto fetch 5 years (default), auto-adjusts prices, and cleans OHLCV data. - INDICATORS Dict: Maps names to internal or dynamic
pandas_tafunctions. - Risk Engine: Processes TP/SL logic on a trade-by-trade basis.
- Backtester: Handles return calculation, stress simulation, and metric computation.
Built-in Plotting
A detailed plot is automatically generated after every backtest run.
- Equity Curve: Strategy Net Returns vs. Market Benchmark.
- Price Chart: Price, Buy/Sell signals, and plotted indicator lines (e.g., SMA, BBands).
- Drawdown: Daily drawdown curve, often shaded by Market Regime.