SignalFlow is a Polars-backed framework for algorithmic trading research that takes a strategy from idea to backtest to live with one object you can save and ship. The public surface is six nouns:
| Noun | What it is |
|---|---|
| Dataset | One lazy, immutable market-data container. sf.data(...) builds it; the same object feeds backtest, paper, and live. |
| Transform | A column-producing step - features (SMA in core; RSI, ATR, ZScore, … via the signalflow-ta plugin) and detectors (SmaCrossDetector, ThresholdDetector) share one contract. |
| Models | ForecastModel (trainable predictor → probability column) plus validator combinators. |
| Flow | The central, deployable, tradeable unit: forecasts → detectors → validator → strategy → risk. |
| Engine | The decision/execution loop and brokers (SimBroker for backtest/paper, BinanceBroker for armed live). |
| Run | The result of executing a Flow - equity curve, fills, and a standard .scorecard(). |
Install
pip install signalflow-trading
| Extra | Installs | For |
|---|---|---|
signalflow-trading[ta] |
signalflow-ta | 248 technical-indicator features + 21 detectors |
signalflow-trading[labs] |
signalflow-labs[rl] | neural encoders, RL strategy, torch backends |
signalflow-trading[live] |
mlflow, huggingface_hub | model artifact tracking / deploy |
signalflow-trading[llm] |
httpx, pydantic | LLM-assisted strategy (any OpenAI-compatible server) |
signalflow-trading[all] |
ta + labs + live + llm | everything |
signalflow-trading[dev] |
pytest, ruff, mypy | development |
Idea → first backtest
import signalflow as sf
ds = sf.data("memory", pairs=["BTCUSDT"], start="2023-01-01", interval="1h")
model = sf.ForecastModel(target=sf.FixedHorizon(bars=12),
features=sf.FeaturePipe(sf.SMA(10), sf.SMA(20), sf.SMA(50)))
model.fit(ds) # train tier-1 forecaster
flow = sf.Flow(name="sma_rise",
forecasts={"rise": model},
detectors=[sf.ThresholdDetector(forecast="rise", p_min=0.6)],
strategy=sf.RulesStrategy())
run = flow.backtest(ds, capital=50_000)
print(run.scorecard()) # total_return, sharpe, max_drawdown, ...
Backtest → paper → live
One decision core drives all three modes. Backtest and paper replay a finished
Dataset; live consumes a streaming feed (PollingFeed polls Binance for each
closed bar) and routes orders to a real venue when armed=True.
flow.paper(ds, capital=50_000) # sim fills over a Dataset
feed = sf.PollingFeed(sf.BinanceSource(), pairs=["BTCUSDT"], interval="1m")
flow.live(feed, capital=50_000) # live data, SimBroker (paper)
flow.live(feed, capital=50_000, armed=True, # real orders on Binance
broker=sf.BinanceBroker(api_key=..., api_secret=...),
state_path="book.json") # book persists across restarts
CLI
sf list # registry snapshot grouped by type
sf list transform # one type, with one-line summaries
sf run flow.yaml --source memory --pairs BTCUSDT --start 2023-01-01 --interval 1h --capital 50000
sf promote flow.yaml --to shadow # validate + show the registry op (real promotion: sf-prod)
sf version
Three invariants worth knowing
WoE/IV encoding is the default. Features flow through Weight-of-Evidence
encoding against the target, and IVSelector keeps only columns whose Information
Value clears a threshold. Encoding is monotone, leak-aware, and fit out-of-fold.
A Flow is inference-only. Every forecast slot (and the optional validator
slot) must hold a trained model. Constructing a Flow around an unfitted model
raises UntrainedModelError - you cannot accidentally deploy something untrained.
The same Flow object runs backtest and paper over a Dataset and live over a
streaming feed - one decision core, no separate execution path to drift.
Deploy is data. flow.save(path) serializes the whole stack (config +
trained artifacts) to YAML plus a model directory; sf.Flow.load(path) brings it
back byte-for-byte. There is no code to redeploy - promoting a strategy is moving
a file. Model artifacts can live on the local filesystem, MLflow, or the Hugging
Face Hub (model.save("mlflow://..."), model.save("hf://...")).
flow.save("flows/rsi_rise.yaml", model_dir="flows/models") # yaml + trained artifacts
same = sf.Flow.load("flows/rsi_rise.yaml")
assert same.backtest(ds, capital=50_000).final_equity == run.final_equity
Registry
Every core class registers under a name - that name is what flow.yaml
serializes and sf list enumerates. Seven ComponentTypes: SOURCE, TRANSFORM,
MODEL, STRATEGY, SAMPLER, BROKER, METRIC.
sf.registry.snapshot() # {type: [names]}
sf.registry.list(sf.ComponentType.TRANSFORM) # core: ['sma', 'woe', ...]; +248 features with [ta]
Installing a plugin (signalflow-ta, signalflow-labs) auto-registers its
components via entry points - no imports or wiring needed.
Ecosystem
| Package | Description |
|---|---|
| signalflow-ta | Technical-indicator plugin: 248 features + 21 detectors ([ta] extra) |
| signalflow-labs | Neural encoders, RL strategy, torch backends ([labs] extra) |
| sf-prod | Promotion, shadow/live rollout, monitoring |
License: MIT · Author: pathway2nothing · Docs: signalflow-trading.com
Metadata
Release files for signalflow-trading 0.8.5
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 | Actions |
|---|---|---|---|---|
| signalflow_trading-0.8.5.tar.gz | 132.5 kB | Without provenance | Details for signalflow_trading-0.8.5.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| signalflow_trading-0.8.5-py3-none-any.whl | Python 3 | none | any | Details for signalflow_trading-0.8.5-py3-none-any.whl |
Total release size: 292.5 kB
Release files / signalflow_trading-0.8.5.tar.gz
| Download URL | signalflow_trading-0.8.5.tar.gz |
|---|---|
| Size | 132.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dbfdb5a41a093e19057394642d83af6cc65e7c815db18e45e2017fd3a7e36310
|
|
BLAKE2b-256 checksum How to use checksums |
00b8c328dabe16420a58883831053bcd31639de50b9c11a86eeccee4973b2ad0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Release files / signalflow_trading-0.8.5-py3-none-any.whl
| Download URL | signalflow_trading-0.8.5-py3-none-any.whl |
|---|---|
| Size | 160.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
293f4ecbded1e55123606c7be97fcd91a5aa98892a451a52bb1da3def8ea120d
|
|
BLAKE2b-256 checksum How to use checksums |
7f9e1291632860468dff30639f665e9c9fb5135d42e7bf72a7e016657a0999b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Security for signalflow-trading 0.8.5
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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.