Wingfoil
Wingfoil is a blazingly fast, highly scalable stream processing framework designed for latency-critical use cases such as electronic trading and real-time AI systems.
Wingfoil simplifies receiving, processing and distributing streaming data across your entire stack.
Features
- Fast: Ultra-low latency and high throughput with an efficient DAG based execution engine.
- Simple and obvious to use: Define your graph of calculations; Wingfoil manages its execution.
- Multi-language: currently available as a Rust crate and as a beta release, python package with plans to add WASM/JavaScript/TypeScript support.
- Backtesting: Replay historical data to backtest and optimise strategies.
- Async/Tokio: seamless integration, allows you to leverage async at your graph edges.
- Multi-threading: distribute graph execution across cores.
- I/O Adapters: production-ready KDB+ integration for tick data, CSV, etcd key-value store, FIX protocol (FIX 4.4 with TLS), ZeroMQ pub/sub messaging (beta), Prometheus metrics exporter, OpenTelemetry OTLP push, etc.
Quick Start
In this example we build a simple, linear pipeline with all nodes ticking in lock-step.
use *;
use Duration;
This output is produced:
hello, world 1
hello, world 2
hello, world 3
Order Book Example
Wingfoil lets you easily wire up complex business logic, splitting and recombining streams, and altering the frequency of data. I/O adapters make it easy to plug in real data sources and sinks. In this example we load a CSV of AAPL limit orders, maintain an order book using the lobster crate, derive trades and two-way prices, and export back to CSV — all in a few lines:
let book = new;
let get_time = ;
let = csv_read
.map
.split;
let prices_export = prices
.filter_value
.map
.distinct
.csv_write;
let fills_export = fills.csv_write;
new
.print
.run
.unwrap;
This output is produced:
KDB+ Example
Define a typed struct, implement KdbDeserialize to map rows, and stream time-sliced queries directly into your graph:
.logged
.run?;
etcd Example
Watch a key prefix, transform values, and write results back — all in a declarative graph:
use *;
use *;
let conn = new;
let round_trip = etcd_sub
.map
.etcd_pub;
round_trip.run.unwrap;
ZeroMQ Example
Publish a stream over ZMQ and subscribe from another process — cross-language compatible with the Python bindings:
// publisher
use ZeroMqPub;
use *;
ticker
.count
.map
.zmq_pub
.run?;
// subscriber
use zmq_sub;
use *;
let = ?;
// See wingfoil-python/examples/zmq/ for a Python subscriber
data.print
.run?;
Service discovery via etcd is also supported — see the etcd examples for details.
FIX Protocol Example
Connect to a FIX 4.4 exchange (e.g. LMAX London Demo) over TLS, subscribe to market data, and process incoming messages — all as a streaming graph:
use fix_connect_tls;
use *;
let fix = fix_connect_tls;
// Subscribe to EUR/USD — waits for LoggedIn, then sends the request.
let sub = fix.fix_sub;
let data_node = fix.data.logged.as_node;
let status_node = fix.status.logged.as_node;
new
.run
.unwrap;
Run the self-contained loopback example (no external FIX engine needed):
RUST_LOG=info
Telemetry Example
Export stream metrics to Grafana via Prometheus scraping (pull) or OpenTelemetry OTLP push — or both simultaneously:
use PrometheusExporter;
use ;
use *;
let exporter = new;
exporter.serve?;
let config = OtlpConfig ;
let counter = ticker.count;
let prometheus_node = exporter.register;
let otlp_node = counter.otlp_push;
new.run?;
Links
- Checkout the examples
- Download from crates.io
- Read the documentation
- Review the benchmarks
- Download the wingfoil Python module from pypi.org
Get Involved!
We want to hear from you! Especially if you:
- are interested in contributing
- know of a project that wingfoil would be well-suited for
- would like to request a feature or report a bug
- have any feedback
Please do get in touch:
- ping us on discord
- email us at hello@wingfoil.io
- submit an issue
- get involved in the discussion