The full quant workflow in one framework: build strategies, vector & event-driven backtest at scale, compare in a single dashboard, and deploy the winner 🚀
<img src="https://github.com/coding-kitties/investing-algorithm-framework/raw/v8.10.0/static/features/hero-dark.svg" alt="Investing Algorithm Framework — features overview" style="max-width: 100%;">
Proudly sponsored by

Investing Algorithm Framework is a Python framework that covers the entire quant workflow: define a strategy once, vector-backtest thousands of parameter variants to find promising signals, narrow down with a storage layer that ranks 10k+ results in milliseconds, validate the winners in a realistic event-driven simulation, compare everything in a single interactive HTML dashboard, and deploy the best performer live, all with the same TradingStrategy class, no code rewrites between stages.
Most quant frameworks stop at "here's your backtest result." You get a number, maybe a chart, and then you're on your own figuring out which strategy variant is actually better, whether the result is robust across time windows, and how to go from research to production. This framework closes that gap.
Want to see this in practice? Check out the
examples/tutorial/: a series of runnable notebooks that walk you through every stage: defining a strategy, visualizing its signals, sweeping parameters across rolling windows, detecting overfitting with Monte Carlo permutation tests, filtering and ranking with the storage layer, and deploying the winner.
Features
.iafbt Backtest Bundle Format — An explicit, versioned, compressed, language-portable container (zstd + msgpack with magic-byte header) plus a separate parquet index for fast filtering without loading. ~21× smaller and ~27× fewer files than standard filebased directory layouts, with parallel I/O for fast load/save of large amounts of backtests..iafbt bundles with a Tier-1 SQLite index (sub-100 ms ranks/filters over 10k+ backtests), a swappable BacktestStore protocol (LocalDirStore, LocalTieredStore), content-addressed Tier-3 OHLCV deduplication, and a CLI (iaf index / iaf list / iaf rank / iaf migrate-store) that plugs straight into the HTML dashboard.deposit_schedule= / auto_sync=True. Backtests simulate the deposits; live mode reconciles with the broker — same context.sync_portfolio() API in both modes.context.record()CooldownRules: per-symbol or portfolio-wide, side-aware (trigger="sell", blocks="buy"), enforced identically by the vector and event-driven enginesStrategy Definition
Declare what data your strategy needs and when to buy or sell as a TradingStrategy subclass — the framework wires up data loading, signal evaluation, order execution, position management, and reporting around it. The same class runs unchanged in vector backtests, event-driven backtests, paper trading and live.
Want strategy ideas to start from? Check out
examples/strategies_showcase/: a collection of runnable strategy templates (trend following, mean reversion, cross-sectional momentum, multi-factor, pairs trading, and more).
Risk and execution behaviour are expressed as declarative rule lists rather than ad-hoc code paths, so the engines can enforce them identically across modes:
position_sizes: PositionSize per symbol (fixed amount or percentage of portfolio).stop_losses / take_profits: StopLossRule / TakeProfitRule with fixed or trailing thresholds and partial-exit sell_percentage.scaling_rules: ScalingRule for pyramiding (scale_in_percentage=[…], max_entries, per-symbol cooldown_in_bars).cooldowns: CooldownRule to throttle whipsaw — per-symbol or portfolio-wide, side-aware (e.g. trigger="sell", blocks="buy", bars=12). Enforced bar-for-bar in both the vector and event-driven engines.trading_costs: TradingCost per symbol (fees, slippage, fixed costs).from investing_algorithm_framework import (
TradingStrategy,
PositionSize,
ScalingRule,
StopLossRule,
TakeProfitRule,
CooldownRule,
TradingCost,
)
class MyStrategy(TradingStrategy):
symbols = ["BTC", "ETH"]
position_sizes = [
PositionSize(symbol="BTC", percentage_of_portfolio=20),
PositionSize(symbol="ETH", percentage_of_portfolio=20),
]
stop_losses = [
StopLossRule(symbol="BTC", percentage_threshold=5, trailing=True),
StopLossRule(symbol="ETH", percentage_threshold=5, trailing=True),
]
take_profits = [
TakeProfitRule(
symbol="BTC", percentage_threshold=10, sell_percentage=50,
),
TakeProfitRule(
symbol="ETH", percentage_threshold=10, sell_percentage=50,
),
]
scaling_rules = [
ScalingRule(
symbol="BTC", max_entries=3, scale_in_percentage=[50, 25],
),
ScalingRule(
symbol="ETH", max_entries=3, scale_in_percentage=[50, 25],
),
]
cooldowns = [
CooldownRule(symbol="BTC", trigger="sell", blocks="buy", bars=12),
CooldownRule(trigger="any", blocks="any", bars=2),
]
trading_costs = [
TradingCost(symbol="BTC", fee_percentage=0.1),
TradingCost(symbol="ETH", fee_percentage=0.1),
]
def generate_buy_signals(self, data):
...
def generate_sell_signals(self, data):
...
Backtesting Engines
Polars-powered vectorized signal evaluation. Compare thousands of strategies side by side, sweep parameter grids, run multi-window robustness checks, rank by key metrics and surface your top candidates in seconds
$ claude mcp add investing-algorithm-framework \
-- python -m otcore.mcp_server <graph>