Home
AKQuant is a high-performance quantitative research framework built on Rust and Python. It combines the extreme performance of Rust with the ease of use of Python, providing powerful backtesting and research tools for quantitative traders.
The latest version features a modular design, independent portfolio management, advanced order type support, and convenient data loading and caching mechanisms.
📖 Design and Development Guide (DESIGN.md): If you want to understand the internal architecture, learn how to design such systems, or contribute to development, please read this document.
Core Features¶
- Extreme Performance: The core backtesting engine is written in Rust and exposed to Python via PyO3.
- Benchmark: In an SMA strategy backtest with 200k bars, AKQuant took only 1.31s (~152k bars/sec), about 20x faster than Backtrader (26.55s).
- Zero-Copy Access (New): Historical data (
ctx.history) maps directly to Rust memory via PyO3 Buffer Protocol / Numpy View, enabling zero-copy access and significantly boosting indicator calculation performance in Python.
- Modular Architecture:
- Engine: Event-driven core matching engine using BinaryHeap for event queue management.
- Clock: Trading clock precisely managing TradingSessions and time flow.
- Portfolio: Independent portfolio management supporting real-time equity calculation.
- MarketModel: Pluggable market models with built-in A-share T+1 and Futures T+0 rules.
- T+1 Strict Risk Control: For stocks/funds, strictly enforces T+1 available position checks to prevent day trading (unless configured as T+0 market).
- Available Position Management: Automatically maintains
available_positionsand deducts frozen quantities from pending sell orders to prevent overselling.
- Event System:
- Timer: Supports
schedule(timestamp, payload)to register timed events, triggeringon_timercallbacks for complex intraday timing logic.
- Timer: Supports
- Risk Control System (New):
- Independent Interception Layer: Built-in
RiskManagerintercepts violating orders directly at the Rust engine layer. - Available Position Check: Checks available positions (Available - Pending Sell) in real-time before ordering.
- Flexible Configuration:
RiskConfigallows configuring max order amount, max position ratio, blocklists, etc.
- Independent Interception Layer: Built-in
- Data Ecosystem:
- Streaming CSV (New): Supports streaming loading of large CSV files (
DataFeed.from_csv) to minimize memory usage. - Pandas Integration: Supports loading Pandas DataFrame directly.
- Smart Caching: Supports local data caching (Pickle) to avoid repeated downloads and accelerate strategy iteration.
- Streaming CSV (New): Supports streaming loading of large CSV files (
- Machine Learning (New):
- ML Framework: Built-in high-performance ML training framework supporting Walk-forward Validation.
- Adapter Pattern: Unifies Scikit-learn and PyTorch interfaces.
- 📖 Machine Learning Guide: Learn how to build AI-driven strategies.
- Flexible Configuration:
- StrategyConfig: Global strategy configuration.
- ExecutionMode: Supports
CurrentCloseandNextOpenmodes.
- Rich Analysis Tools:
- PerformanceMetrics:
- Return: Total Return, Annualized Return, Alpha, Win Rate.
- Risk: Max Drawdown, Sharpe Ratio, Sortino Ratio, Ulcer Index, UPI.
- Fit: Equity R².
- TradeAnalyzer: Detailed trade statistics including win rate, PnL ratio, max consecutive PnL, etc.
- PerformanceMetrics:
- Simulation Enhancements:
- Slippage Model: Supports Fixed and Percent slippage models.
- Volume Limit: Supports limiting order fill quantity by bar volume ratio and partial fills.
Why Choose AKQuant?¶
AKQuant aims to solve the performance bottlenecks of traditional Python backtesting frameworks (like Backtrader) and the high development barriers of pure C++/Rust frameworks. We have achieved breakthroughs in five core dimensions through our hybrid architecture:
1. Extreme Performance: Rust Core + Python Ecosystem¶
- Hybrid Architecture: The core computation layer (matching, capital, risk control) is written in Rust and exposed to Python via PyO3.
- Zero-Copy Access: Leveraging Rust's
arrowandnumpyview technologies, Python access to historical data (OHLCV, indicators) achieves zero-copy, avoiding massive memory copying overhead. - Benchmark: In a 200k bar SMA strategy test, it took only 1.31s (~152k bars/sec), 20x faster than Backtrader.
- Incremental Calculation: Internal indicator calculations use incremental update algorithms instead of full recalculation, suitable for ultra-long history backtesting.
2. Machine Learning First¶
- Built-in Training Framework: Unlike traditional frameworks that only support simple technical indicators, AKQuant features a built-in full ML Pipeline.
- Walk-forward Validation: Natively supports rolling window training (Walk-forward) to effectively prevent look-ahead bias and overfitting.
- Adapter Pattern: Provides unified adapters (
QuantModel) for Scikit-learn and PyTorch, allowing AI model integration into strategies with just a few lines of code. - Feature Engineering:
DataFeedsupports dynamic feature calculation, facilitating integration with Talib or Pandas for feature preprocessing.
3. Precise and Flexible Event-Driven Engine¶
- Precise Simulation: Featuring a precise time flow model and order lifecycle management.
- Complex Order Support: Supports Market, Limit, Stop, TakeProfit, and other order types.
- Multi-Asset Mixing: Supports mixed backtesting of stocks, futures, ETFs, etc., with independent fee, slippage, and trading session configurations for each asset.
- Intraday Scheduled Tasks: Supports
scheduleto register intraday timed events (e.g., close positions daily at 14:50), offering more flexibility than simpleon_bar.
4. Production-Grade Risk Control and Live Trading¶
- Built-in Risk Manager: The engine layer includes a
RiskManagersupporting hard limits on capital, position ratios, blocklists, etc., to prevent runaway strategies. - Seamless Live Trading Switch: Strategy code is decoupled from live trading interfaces. Theoretically, switching to live trading only requires replacing
BrokerandDataFeedadapters (live interface under development). - Data Aggregator:
DataFeedsupports multi-source aggregation, handling data alignment issues for different frequencies.
5. Ultimate Developer Experience¶
- LLM Friendly: Clear code structure, detailed documentation, and optimized Type Hints facilitate strategy writing with Copilot or GPT.
- Dual-Style API: Supports both Class-based and Functional (Zipline-style) strategy writing styles to suit different user habits.
- Strict Type Checking: Core logic is strictly checked by the Rust compiler, and Python code is checked via
mypy, minimizing runtime errors.
Installation¶
For detailed installation steps, please refer to the Installation Guide.
Quick Start¶
1. Quick Backtest using helper (Recommended)¶
AKQuant provides a convenient entry point run_backtest similar to Zipline.
import pandas as pd
import numpy as np
from akquant import Strategy, run_backtest
# 1. Prepare data (example using random data)
# Real scenario: pd.read_csv("data.csv")
def generate_data():
dates = pd.date_range(start="2023-01-01", end="2023-12-31")
n = len(dates)
price = 100 * np.cumprod(1 + np.random.normal(0.0005, 0.02, n))
return pd.DataFrame({
"date": dates,
"open": price, "high": price * 1.01, "low": price * 0.99, "close": price,
"volume": 10000,
"symbol": "600000"
})
# 2. Define Strategy
class MyStrategy(Strategy):
def on_bar(self, bar):
# Simple strategy logic (example)
# For real backtests, using IndicatorSet for vectorized calculation is recommended
position = self.get_position(bar.symbol)
if position == 0:
self.buy(symbol=bar.symbol, quantity=100)
elif position > 0:
self.sell(symbol=bar.symbol, quantity=100)
# 3. Run Backtest
df = generate_data()
result = run_backtest(
strategy=MyStrategy, # Pass class or instance
data=df, # Explicitly pass data
symbol="600000", # SPD Bank
cash=500_000.0, # Initial cash
commission=0.0003 # 0.03% commission
)
# 4. View Results
print(f"Total Return: {result.metrics.total_return_pct:.2f}%")
print(f"Sharpe Ratio: {result.metrics.sharpe_ratio:.2f}")
print(f"Max Drawdown: {result.metrics.max_drawdown_pct:.2f}%")
# 5. Get Detailed Data (DataFrame)
# Performance metrics table
print(result.metrics_df)
# Trade record table
print(result.trades_df)
# Daily position table
print(result.daily_positions_df)
2. Functional API (Zipline Style)¶
If you are used to Zipline or Backtrader's functional style, you can also use:
from akquant import run_backtest
def initialize(ctx):
ctx.stop_loss_pct = 0.05
def on_bar(ctx, bar):
position = ctx.get_position(bar.symbol)
if position == 0:
ctx.buy(symbol=bar.symbol, quantity=100)
elif position > 0:
ctx.sell(symbol=bar.symbol, quantity=100)
run_backtest(
strategy=on_bar,
initialize=initialize,
data=df, # Use data generated above
symbol="600000"
)
3. Using Custom Factors¶
AKQuant supports passing any number of custom numeric fields (such as factors, signals, etc.) in the DataFrame, which can be accessed via the bar.extra dictionary in on_bar.
import pandas as pd
import numpy as np
from akquant import Strategy, run_backtest
# 1. Prepare data
def generate_data():
dates = pd.date_range(start="2023-01-01", end="2023-12-31")
n = len(dates)
price = 100 * np.cumprod(1 + np.random.normal(0.0005, 0.02, n))
return pd.DataFrame({
"date": dates,
"open": price, "high": price * 1.01, "low": price * 0.99, "close": price,
"volume": 10000,
"symbol": "600000"
})
df = generate_data()
# 2. Add custom factors (must be numeric)
df["momentum"] = df["close"] / df["open"] # Factor 1
df["volatility"] = df["high"] - df["low"] # Factor 2
df["sentiment_score"] = np.random.rand(len(df)) # Factor 3
# 3. Access these fields simultaneously in the strategy
class MyStrategy(Strategy):
def on_bar(self, bar):
# Access by key name (returns float type)
mom = bar.extra.get("momentum", 0.0)
vol = bar.extra.get("volatility", 0.0)
score = bar.extra.get("sentiment_score", 0.0)
# Comprehensive judgment
if mom > 1.02 and score > 0.8:
self.buy(bar.symbol, 100)
# 4. Run Backtest
run_backtest(strategy=MyStrategy, data=df, symbol="600000")
For more examples, please refer to the examples/ directory.