Skip to content

QuantEx Documentation

QuantEx is a Python backtesting library for people who want to write trading rules and run them on historical OHLCV market data.

This documentation is written to match the current codebase, not an imagined future version. Where the library is intentionally small or has limitations, those limitations are stated explicitly.

What QuantEx is

At its core, QuantEx provides four main concepts:

  1. Strategy defines your trading logic.
  2. DataSource provides time-indexed market data.
  3. Broker manages orders, positions, and cash for each attached symbol.
  4. SimpleBacktester runs the bar-by-bar simulation and can search parameter combinations.

If you are new to the library, the usual workflow is:

  • load a CSV or Parquet file into a data source
  • attach that data source to a strategy
  • create indicator arrays if needed
  • place buy, sell, or close orders inside your strategy logic
  • run the strategy through the backtester
  • inspect the resulting BacktestReport

What QuantEx is not

The current codebase does not try to be all of the following:

  • a live-trading framework
  • a full portfolio accounting platform
  • a live execution stack or portfolio analytics platform beyond backtesting
  • a feature-complete execution simulator with slippage, partial fills, or order cancellation

Those distinctions matter because some older documentation implied broader functionality than the code currently implements.

Package contents

The public package exports are currently defined in src/quantex/__init__.py:

Quick start

Installation

pip install quantex

Python version support is declared in pyproject.toml as Python 3.10 or newer.

Smallest useful example

from quantex import Strategy, CSVDataSource, SimpleBacktester
import pandas as pd


class BuyAndHold(Strategy):
    def __init__(self):
        super().__init__()
        self.entered = False

    def init(self):
        self.add_data(CSVDataSource("data.csv"), "TEST")

    def next(self):
        if not self.entered and len(self.data["TEST"].Close) >= 2:
            self.positions["TEST"].buy(quantity=1.0)
            self.entered = True


strategy = BuyAndHold()
backtester = SimpleBacktester(strategy, cash=10_000)
report = backtester.run()

print(report)

This example works as follows:

How the backtest loop works

Understanding the backtest loop makes the rest of the library easier to use.

When you create SimpleBacktester, the provided strategy is deep-copied in SimpleBacktester.__init__(). When you call SimpleBacktester.run(), the following happens:

  1. Starting cash is split evenly across all registered brokers in SimpleBacktester.run().
  2. Every data source receives the current bar index by updating DataSource.current_index.
  3. Every broker processes pending and active orders through Broker._iterate().
  4. Every time-aware indicator is advanced by updating its visibility window in SimpleBacktester.run().
  5. Your Strategy.next() method is called.
  6. At the end, all brokers are asked to close open positions via Broker.close(), and the combined equity curve is returned inside BacktestReport.

Data model

Required input data

DataSource requires a pandas DataFrame with these columns:

  • Open
  • High
  • Low
  • Close
  • Volume

That validation happens in DataSource.__init__().

Current bar vs historical arrays

The library distinguishes between:

This is important because strategies normally make decisions using the current bar and recent history, not the entire future dataset.

Orders and execution behavior

The order system is defined around Order, OrderSide, OrderType, and OrderStatus.

The current implementation supports:

  • market orders
  • limit orders
  • optional stop-loss and take-profit levels attached to an order
  • long and short positions
  • percentage commissions and cash-per-lot commissions through CommissionType

Important implementation details from Broker._iterate():

  • market orders execute using the current bar open, via DataSource.COpen
  • buy limit orders trigger when the current open is less than or equal to the limit price
  • sell limit orders trigger when the current open is greater than or equal to the limit price
  • stop-loss and take-profit monitoring also uses the current open
  • slippage is not modeled in the current code
  • there is no public order cancellation API

Indicators

QuantEx ships a built-in indicator catalogue through quantex.indicators and the strategy-level convenience handle self.ta created in Strategy.__init__().

The indicator module includes common stock-trading studies such as moving averages, RSI, MACD, Bollinger Bands, ATR, stochastic oscillator, CCI, Williams %R, OBV, MFI, ADX, Keltner Channels, Donchian Channels, Aroon, and Vortex, plus more advanced tools such as Ichimoku Cloud, KAMA, TRIX, Fisher Transform, Hurst exponent, rolling Sharpe/Sortino ratios, Z-score, and linear regression slope.

Use Strategy.Indicator() to wrap any returned NumPy array in TimeNDArray. The wrapper makes only the currently visible portion of the array accessible during the backtest.

Optimization

QuantEx includes two optimization entry points:

Both perform grid search over candidate parameter values. The parallel version distributes combinations across worker processes and then reruns the best result locally to produce the full report.

Guides

API reference

Reference pages live under docs/reference/.

Project structure

The main source files in the current codebase are:

The test suite is also a useful source of truth for documented behavior:

License

See LICENSE.md.