polars_bt
polars_bt is a Rust-backed Polars expression plugin with two deliberately
separate backtesting engines.
| Engine | Model | State axis | Output |
|---|---|---|---|
pulse |
T0 quote/signal matching | time rows | scalar summary |
mosaic |
cross-sectional portfolio | dense daily panels | daily portfolio rows |
Both engines execute inside the Polars process. They do not serialize a DataFrame through Arrow IPC to call Rust.
Requirements and installation
- CPython 3.10, 3.11, or 3.12
- Polars 1.43.x
pip install polars_bt
For a local release build:
uv venv --python 3.12 .venv
uv pip install --python .venv/bin/python 'polars>=1.43,<1.44' maturin pytest
.venv/bin/maturin develop --release
Pulse: T0 quote matching
pulse retains the original quote-by-quote T0 matcher and returns one Struct
summary.
import polars as pl
from polars_bt import pulse
quotes = pl.DataFrame(
{
"ask": [100.0, 101.0, 102.0],
"bid": [99.5, 100.5, 101.5],
"long": [1, 0, 0],
"short": [0, 1, 0],
"close_long": [0, 0, 0],
"close_short": [0, 0, 0],
"time": [1000, 2000, 3000],
"limit_down": [90.0] * 3,
"limit_up": [110.0] * 3,
}
)
summary = quotes.select(
pulse(
"ask",
"bid",
"long",
"short",
"close_long",
"close_short",
"time",
"limit_down",
"limit_up",
).alias("pulse")
)
Set LOFIEX_MATCHER=easy to use the relaxed matcher; the default matcher keeps
the original limit-price checks.
Mosaic: cross-sectional portfolios
mosaic scans a dense, date-major panel in fixed asset_num row blocks. It
returns one daily Struct row containing date, cash, nav, turnover, and
holding_count.
import polars as pl
from polars_bt import mosaic
panel = pl.DataFrame(
{
"date": ["2024-01-02", "2024-01-02", "2024-01-03", "2024-01-03"],
"weight": [0.4, 0.4, 0.0, 0.5],
"ovn_ret": [0.0, 0.0, 0.01, -0.01],
"ind_ret": [0.0, 0.0, 0.0, 0.0],
"buyable": [True] * 4,
"sellable": [True] * 4,
"prev_close": [10.0] * 4,
"vwap": [10.0] * 4,
"is_rebalance": [True] * 4,
}
)
daily = panel.select(
mosaic(
date="date",
weight="weight",
ovn_ret="ovn_ret",
ind_ret="ind_ret",
buyable="buyable",
sellable="sellable",
prev_close="prev_close",
vwap="vwap",
is_rebalance="is_rebalance",
asset_num=2,
).alias("daily")
).unnest("daily")
Mosaic's input contract is intentionally narrow:
- rows are already sorted by
(date, asset)and every date has exactlyasset_numrows; - the asset row order is stable across dates, so the engine uses row offsets and performs no joins or asset hashing;
- preprocessing materializes a complete panel before the call;
- use it as an eager whole-table expression; it changes the output length;
- fees default to
st_fee=6e-4andlg_fee=1e-4.
Development
make install-release
make pre-commit
.venv/bin/python benchmarks/benchmark_mosaic.py
The accepted benchmark is 2,500 days by 5,000 assets (12.5 million rows), with a five-second hard limit measured only around the Mosaic expression call.
License
MIT. See LICENSE.
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 polars_bt-0.2.0.tar.gz.
File metadata
- Download URL: polars_bt-0.2.0.tar.gz
- Upload date:
- Size: 67.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7348f37e78f9e395bccc4dbe23451082805435e8d28425d7392b9ae46ded28b9
|
|
| MD5 |
0555d1c051e1fa72dd4c8c73d869ed0c
|
|
| BLAKE2b-256 |
c411bcdad93b277260f499e436bb8034478c55f42dd8a751dd6bbd27fe08d812
|
Provenance
The following attestation bundles were made for polars_bt-0.2.0.tar.gz:
Publisher:
release.yml on huangbogeng/polars_bt_extension
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
polars_bt-0.2.0.tar.gz -
Subject digest:
7348f37e78f9e395bccc4dbe23451082805435e8d28425d7392b9ae46ded28b9 - Sigstore transparency entry: 2216986000
- Sigstore integration time:
-
Permalink:
huangbogeng/polars_bt_extension@ee65da0db3401bd580ae8b8f9bfb185cc399f795 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/huangbogeng
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ee65da0db3401bd580ae8b8f9bfb185cc399f795 -
Trigger Event:
release
-
Statement type:
File details
Details for the file polars_bt-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: polars_bt-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 5.5 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7eca2b5904286d32d817bfa1016199895f0ca66fb4c749df5bee5d5be2aebefe
|
|
| MD5 |
b92c911c6bae57b4d11185060c7f0a72
|
|
| BLAKE2b-256 |
bde5b440d2eb677fd96dd4553e93c2cf94e150b27e5b493a5056a1345361c2c6
|
Provenance
The following attestation bundles were made for polars_bt-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on huangbogeng/polars_bt_extension
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
polars_bt-0.2.0-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
7eca2b5904286d32d817bfa1016199895f0ca66fb4c749df5bee5d5be2aebefe - Sigstore transparency entry: 2216986076
- Sigstore integration time:
-
Permalink:
huangbogeng/polars_bt_extension@ee65da0db3401bd580ae8b8f9bfb185cc399f795 -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/huangbogeng
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@ee65da0db3401bd580ae8b8f9bfb185cc399f795 -
Trigger Event:
release
-
Statement type: