High-performance backtesting engine for algorithmic trading with focus on Indian markets
Project description
Quantlab
High-performance backtesting engine for algorithmic trading with focus on Indian markets (NSE, BSE, NFO, BFO).
Features
- 🚀 High Performance: Built on Polars for lightning-fast data processing
- 🇮🇳 Indian Markets: Native support for NSE, BSE equities and derivatives
- 📊 Comprehensive Metrics: Detailed performance analytics including drawdown, win rate, and BPS
- 💰 Accurate Charges: Built-in Indian market charges calculation (STT, brokerage, etc.)
- 🎯 Multiple Strategy Types: Support for INTRADAY, OVERNIGHT, SWING strategies
- 📈 Beautiful Reports: Rich console output with detailed statistics
Installation
pip install quantlab
Quick Start
from quantlab import Strategy, Backtest
import polars as pl
class SimpleMovingAverage(Strategy):
def __init__(self):
super().__init__()
self.name = "sma_crossover"
self.type = "INTRADAY"
self.exchange = "NSE"
self.product = "MIS"
self.instrument_universe = {
"NSE_EQ": {"is_liquid": True}
}
def generate_signals(self, data):
# Your strategy logic here
equity_data = data["NSE:EQ"]
# Example: Simple moving average crossover
signals = equity_data.with_columns([
pl.col("close").rolling_mean(window_size=20).alias("sma20"),
pl.col("close").rolling_mean(window_size=50).alias("sma50")
])
# Generate buy signals when SMA20 crosses above SMA50
trades = signals.filter(
(pl.col("sma20") > pl.col("sma50")) &
(pl.col("sma20").shift(1) <= pl.col("sma50").shift(1))
)
# Format output for backtesting
return trades.select([
pl.col("symbol").alias("tradingsymbol"),
pl.col("date").alias("entry_time"),
# Add exit time, quantity, etc.
])
# Run backtest
strategy = SimpleMovingAverage()
results = strategy.run_backtest(data_range=(2020, 2023))
Architecture
quantlab/
├── core/ # Backtesting engine
├── data/ # Data loading utilities
├── strategy/ # Strategy framework
├── analysis/ # Performance metrics
├── reporting/ # Results visualization
└── market/ # Market-specific logic (charges, etc.)
Strategy Development
Basic Strategy Structure
from quantlab import Strategy
import polars as pl
class MyStrategy(Strategy):
def __init__(self):
super().__init__()
self.name = "my_strategy"
self.type = "INTRADAY" # or "OVERNIGHT", "SWING"
self.exchange = "NSE"
self.product = "MIS" # or "CNC", "NRML"
self.STRATEGY_EXIT_TIME = time(15, 15)
self.interval = 5 # 5-minute candles
# Define universe
self.instrument_universe = {
"NSE_EQ": {"is_liquid": True},
"NSE_INDICES": {"underlying": ["NIFTY 50"]}
}
def generate_signals(self, data):
"""
Generate trading signals
Returns DataFrame with columns:
- tradingsymbol: Symbol to trade
- entry_time: Entry timestamp
- exit_time: Exit timestamp
- transaction_type: "BUY" or "SELL"
- quantity: Number of shares
- stoploss: Optional SL percentage
"""
# Your strategy logic here
pass
Data Access
The data parameter in generate_signals is a dictionary with market data:
{
"NSE:EQ": pl.DataFrame, # Equity data
"NSE:INDICES": pl.DataFrame, # Index data
"NFO:FUT": pl.DataFrame, # Futures data
"NFO:OPT": pl.DataFrame, # Options data
}
Each DataFrame contains columns: date, open, high, low, close, volume, oi (for F&O).
Performance Metrics
Quantlab provides comprehensive metrics:
- PnL Analysis: Total, monthly average, yearly breakdown
- Risk Metrics: Maximum drawdown, risk/reward ratio
- Trade Statistics: Win rate, number of trades, BPS
- Time Analysis: Hourly and time-based performance
- Trade Details: Top winning and losing trades
Indian Market Support
Charges Calculation
Built-in support for Indian market charges:
- Securities Transaction Tax (STT)
- Exchange transaction charges
- SEBI charges
- Stamp duty
- GST
Supported Segments
- Equity: NSE, BSE cash markets
- Derivatives: NFO, BFO futures and options
- Indices: NIFTY, SENSEX and sectoral indices
Advanced Features
Custom Data Loading
from quantlab.data import BacktestDataLoader
loader = BacktestDataLoader(data_path="./market_data")
data = loader.load_data({
"NSE_EQ": {"is_liquid": True},
"NFO_OPT": {"underlying": ["NIFTY"]}
})
Multi-timeframe Strategies
class MultiTimeframe(Strategy):
def __init__(self):
super().__init__()
self.interval = 15 # 15-minute primary timeframe
def generate_signals(self, data):
# Access different timeframes
data_5min = self.aggregate_data(data["NSE:EQ"], interval=5)
data_15min = self.aggregate_data(data["NSE:EQ"], interval=15)
# Strategy logic using multiple timeframes
Requirements
- Python >= 3.10
- polars >= 1.24.0
- See
requirements.txtfor full list
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Disclaimer
This software is for educational purposes only. Do not use this for actual trading without understanding the risks involved. Past performance is not indicative of future results.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quantplay_lab-0.1.0.tar.gz.
File metadata
- Download URL: quantplay_lab-0.1.0.tar.gz
- Upload date:
- Size: 20.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
903fc53872575183ee78495b43e8e3ae363935de003c9a5a70b9534e4a643132
|
|
| MD5 |
bb9fe3b7c45b38af7fe4ce22414bc301
|
|
| BLAKE2b-256 |
bd552e40f63f15a5b89482bbe8f344608a97db3d8f11b3345d77caa1867fba3f
|
File details
Details for the file quantplay_lab-0.1.0-py3-none-any.whl.
File metadata
- Download URL: quantplay_lab-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
431f186e39fc302cda2441b506d8618a8d56594d8ef25645d69792349a478066
|
|
| MD5 |
18c502660f5a30e64cbd24785930dd8f
|
|
| BLAKE2b-256 |
d03f91e01ca6d715f1afdf6bd95e135f02217cd11155a6d936b527de03a06219
|