Skip to main content
SignalFlow

SignalFlow

Real-time-first framework for trading signal research and execution

Version Python 3.12+ License: MIT Code style: ruff


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)

Source distribution for signalflow-trading 0.8.5
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)

Table of built distributions (wheels) for signalflow-trading 0.8.5
File Interpreter ABI Platform Actions
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.

Release history Release notifications | RSS feed

This release

0.8.5 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page