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.
Metadata
Release files for quantplay-lab 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| quantplay_lab-0.1.0.tar.gz | 20.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| quantplay_lab-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.4 kB
Release files / quantplay_lab-0.1.0.tar.gz
| Download URL | quantplay_lab-0.1.0.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
903fc53872575183ee78495b43e8e3ae363935de003c9a5a70b9534e4a643132
|
|
BLAKE2b-256 checksum How to use checksums |
bd552e40f63f15a5b89482bbe8f344608a97db3d8f11b3345d77caa1867fba3f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.2
|
Release files / quantplay_lab-0.1.0-py3-none-any.whl
| Download URL | quantplay_lab-0.1.0-py3-none-any.whl |
|---|---|
| Size | 21.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
431f186e39fc302cda2441b506d8618a8d56594d8ef25645d69792349a478066
|
|
BLAKE2b-256 checksum How to use checksums |
d03f91e01ca6d715f1afdf6bd95e135f02217cd11155a6d936b527de03a06219
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.12.2
|
Security for quantplay-lab 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.