Skip to content

Antoine-Moniz/backtesting_framework

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Investment Strategy Backtesting Framework

Overview

This project implements a comprehensive and extensible backtesting framework designed to evaluate and compare investment strategies on historical financial data. Developed as part of the M2 Quantitative Finance program at Université Paris Dauphine-PSL, this framework provides researchers, students, and practitioners with professional-grade tools for strategy development, testing, and analysis.

The framework adopts a modular, object-oriented architecture that balances ease of use with powerful functionality. Users can create custom strategies through either class inheritance or decorator-based approaches, test them against historical data with realistic transaction costs and slippage, and analyze results through comprehensive metrics and visualizations.

Features

Core Capabilities:

  • Simple and intuitive API for strategy creation and testing
  • Support for multiple data formats (CSV, Parquet, pandas DataFrame)
  • Comprehensive performance metrics
  • Multi-backend visualization support (matplotlib, seaborn, plotly)
  • Realistic trading simulation with transaction costs and slippage
  • Multi-asset portfolio support through dictionary-based position API
  • Flexible rebalancing frequency configuration (daily, weekly, monthly)

Advanced Features:

  • Walk-forward analysis for temporal validation
  • Parameter optimization and robustness testing
  • Strategy comparison and correlation analysis
  • Benchmark-relative metrics (alpha, beta)
  • Customizable risk-free rates and market benchmarks

Installation & Usage

Installation

Clone the repository and install the package:

git clone https://github.com/Antoine-Moniz/backtesting_framework.git
cd backtesting_framework
pip install -e .

For development with testing dependencies:

pip install -e ".[dev]"

Quick Start Example

import pandas as pd
from backtesting_framework import Backtester, Strategy
from strategies.buy_and_hold import BuyAndHoldStrategy
from strategies.moving_average_cross import MovingAverageCrossStrategy

# Load historical data (CSV, Parquet, or DataFrame)
data = pd.read_csv('data.csv')
backtester = Backtester(
    data=data,
    initial_capital=100000,
    transaction_cost=0.001,  # 0.1% per trade
    slippage=0.0005          # 0.05% slippage
)

# Create and test a strategy
strategy = MovingAverageCrossStrategy(short_window=10, long_window=30)
result = backtester.run_backtest(strategy)

# Display results
print(result.summary())
result.plot_performance(backend='matplotlib')

Creating Custom Strategies

Method 1: Class Inheritance

from backtesting_framework import Strategy

class RSIStrategy(Strategy):
    def __init__(self, window=14, oversold=30, overbought=70):
        self.window = window
        self.oversold = oversold
        self.overbought = overbought
        self.is_fitted = False
        self.rebalance_frequency = 'D'
    
    @property
    def name(self):
        return f"RSI Strategy ({self.window}, {self.oversold}, {self.overbought})"
    
    def fit(self, historical_data):
        self.is_fitted = True
    
    def get_position(self, data, positions):
        if len(data) < self.window + 5:
            return {'asset': 0.0}
        
        rsi = self.calculate_rsi(data['close'], self.window)
        
        if rsi < self.oversold:
            return {'asset': 1.0}  # Buy (oversold)
        elif rsi > self.overbought:
            return {'asset': 0.0}  # Sell (overbought)
        else:
            return positions  # Keep current position

Method 2: Decorator for Simple Strategies

from backtesting_framework import strategy_decorator

@strategy_decorator(name="Simple MA Strategy")
def simple_strategy(historical_data, current_position):
    if len(historical_data) < 10:
        return 0
    
    # Simple moving average logic
    short_ma = historical_data['close'].rolling(5).mean().iloc[-1]
    long_ma = historical_data['close'].rolling(10).mean().iloc[-1]
    
    return 1 if short_ma > long_ma else -1

Comparing Multiple Strategies

from backtesting_framework import compare_results

# Create multiple strategies
buy_hold = BuyAndHoldStrategy()
ma_cross = MovingAverageCrossStrategy(short_window=5, long_window=20)
rsi = RSIStrategy()

# Run backtests
result1 = backtester.run_backtest(buy_hold)
result2 = backtester.run_backtest(ma_cross)
result3 = backtester.run_backtest(rsi)

# Compare visually
compare_results(result1, result2, result3, backend='matplotlib')

For detailed examples including walk-forward analysis, parameter optimization, and advanced visualizations, see examples/example_usage.ipynb.

Project Structure

backtesting_framework/
├── backtesting_framework/
│   ├── __init__.py              # Package exports and initialization
│   ├── strategy.py              # Abstract Strategy class and decorators
│   ├── backtester.py            # Core backtesting engine
│   ├── result.py                # Results analysis and visualization
│   └── data_handler.py          # Data loading and validation utilities
│
├── examples/
│   ├── strategies/              # Built-in strategy implementations
│   │   ├── buy_and_hold.py
│   │   ├── moving_average_cross.py
│   │   └── mean_reversion.py
│   └── example_usage.ipynb      # Comprehensive usage demonstration
│
├── tests/
│   ├── test_backtester.py       # Backtester unit tests
│   ├── test_strategy.py         # Strategy tests
│   ├── test_result.py           # Results analysis tests
│   └── test_multi_asset.py      # Multi-asset support tests
│
├── pyproject.toml               # Package configuration and dependencies
├── README.md                    # Project documentation
└── LICENSE                      # MIT License

Methodology Summary

Object-Oriented Architecture

The framework implements core object-oriented programming principles:

  • Abstraction: The abstract Strategy class defines the interface all strategies must implement, hiding implementation complexity behind a simple API.
  • Inheritance: Custom strategies inherit from Strategy, gaining access to common functionality while implementing specific trading logic.
  • Polymorphism: All strategies share the same interface (get_position, fit), allowing the Backtester to work with any strategy implementation.
  • Encapsulation: Each class encapsulates its data and methods, exposing only necessary interfaces.

Backtesting Process

  1. Data Preparation: Load and validate historical data (OHLCV format)
  2. Strategy Initialization: Configure strategy parameters and training
  3. Simulation Loop: Iterate through historical data, generating positions
  4. Position Management: Apply transaction costs, slippage, and rebalancing
  5. Metrics Calculation: Compute comprehensive performance statistics
  6. Visualization: Generate interactive charts and comparison plots

Performance Metrics

The framework calculates 15+ performance metrics:

  • Returns: Total, annualized, cumulative
  • Risk Measures: Volatility, Value at Risk (VaR), maximum drawdown
  • Risk-Adjusted Ratios: Sharpe, Sortino, Calmar
  • Benchmark Analysis: Alpha, Beta, correlation
  • Trading Statistics: Number of trades, win rate, transaction costs

Testing Strategy

Comprehensive test coverage includes:

  • Unit Tests: Individual component validation
  • Integration Tests: Cross-component interaction verification
  • Multi-Asset Tests: Portfolio strategy validation
  • Edge Cases: Boundary condition handling

Reports

Key Deliverables

  • Technical Implementation: Complete source code with modular architecture

  • Documentation: Comprehensive README, docstrings, and inline comments

  • Example Notebook: Detailed Jupyter notebook (example_usage.ipynb) demonstrating:

    • Data loading from Yahoo Finance
    • Built-in strategy testing (Buy & Hold, MA Cross, Mean Reversion)
    • Custom strategy creation (RSI, Momentum, Simple ML)
    • Performance comparison and visualization
    • Walk-forward analysis and parameter optimization
    • Professional conclusions and insights
  • Test Suite: Unit and integration tests covering all components

  • Package Configuration: Professional pyproject.toml enabling pip installation

Performance Results

Testing on Apple (AAPL) stock from 2020-2023 yielded:

Strategy Total Return Sharpe Ratio Max Drawdown Trades
Momentum 151.55% 1.21 -51.35% 1005
Simple ML 19.06% 0.29 -32.37% 1005
RSI 2.47% 0.02 -34.82% 1005

Results demonstrate the framework's capability to differentiate strategy performance and provide actionable insights for investment decision-making.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Authors / Contact

M2 Quantitative Finance - Université Paris Dauphine-PSL

For issues, discussions, or contributions, please open an issue or pull request on the project's GitHub page

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages