Rust
Rust market data API: the finzdata crate
Point-in-time market data in idiomatic Rust. One crate, typed results, async or blocking: stocks since 2000 with every delisted name, every futures contract since 2007, point-in-time dealer gamma, FX, indexes, crypto, COT and macro exactly as it was known.
cargo add finzdata
cargo add tokio --features macros,rt-multi-threadcrates.io/crates/finzdata · docs.rs/finzdata · API docs · Shop
Quickstart
#[tokio::main]
async fn main() -> finzdata::Result<()> {
let fz = finzdata::Client::new()?; // reads FINZDATA_API_KEY
let aapl = fz.prices("AAPL", Some("2020-01-01"), None, None).await?; // daily, delisted-aware
let es = fz.futures_bars("ES", None, true, None, Some("1min"), Some("2024-01-02"), None).await?;
let gex = fz.gex("SPX", Some("2020-01-01"), None).await?; // point-in-time dealer gamma
let eur = fz.fx_bars("EURUSD", Some("1hour"), Some("2025-01-01"), None).await?;
let btc = fz.crypto_bars("BTC-USD", Some("1day"), Some("2015-01-01"), None).await?;
let cpi = fz.macro_obs("CPIAUCSL", None, None, None, Some("2022-06-30")).await?; // CPI as known that day
println!("{} {} {} {} {} {}", aapl.len(), es.len(), gex.len(), eur.len(), btc.len(), cpi.len());
Ok(())
}No async runtime? finzdata::blocking::Client has the same methods. Any other endpoint: fz.get::<finzdata::Row>("/v1/...", ¶ms).
What the crate covers
| US stocks | 16,000+ stocks that have traded on NYSE and Nasdaq since January 2000, 9,000+ delisted, and 5,100+ ETFs: prices, minutes (1, 5, 15, 30-minute, hourly) |
|---|---|
| Futures | 139 markets, every contract since 2007, continuous series and the roll calendar: futures_daily, futures_bars, futures_contracts |
| Options gamma (GEX) | Point-in-time dealer gamma for 11,200+ stocks, ETFs and the major indexes since 2010: gex, gex_strikes |
| FX, indexes, crypto | 79 currency pairs, 123 indexes (SPX, NDX, VIX term structure, DXY), 512 crypto pairs: fx_bars, index_bars, crypto_bars |
| Positioning and macro | CFTC COT since 1986, 22,700+ macro series with every vintage, SEC fundamentals as filed, 13F holders: cot, macro_obs, fundamentals, holders |
| Tick data and Global Macro Pulse | Tick trades for 1,100+ stocks and ETFs; shipping chokepoints, ports, air and toll traffic: ticks, pulse |
Built for Rust backtesters and trading systems
Use the crate to feed a backtester written in Rust, a low-latency research pipeline, or an AI agent's tools. Results deserialize into typed structs (Bar, FuturesDay, GexDay, MacroObs), requests are gzip-compressed over rustls, and every dataset is point in time, so what your strategy sees is what the market knew on that date.
Prefer Python? pip install finzdata. Working in Claude, ChatGPT or Cursor? Connect the FinzData MCP server.
Questions
Is there a Rust crate for historical stock and futures data?
Yes. cargo add finzdata installs FinzData's official Rust client. It covers 16,000+ US stocks since 2000 with 9,000+ delisted names, every contract of 139 futures markets since 2007, point-in-time GEX, 79 FX pairs, 123 indexes, 512 crypto pairs, COT since 1986 and 22,700+ macro series.
Does the finzdata crate support async and blocking code?
Both. finzdata::Client is async on tokio; finzdata::blocking::Client has the same methods for code without an async runtime.
What bar sizes does the Rust client return?
Tick trades, 1-minute, 5-minute, 15-minute, 30-minute, hourly and daily bars, for stocks, futures, FX, indexes and crypto.
Is the data point in time?
Yes. Delisted companies stay in the history, SEC fundamentals are as filed, and macro series keep every vintage, so a backtest only sees what was known on each date.
How do I get an API key?
A free key needs only an email at https://finzdata.com. Set FINZDATA_API_KEY and finzdata::Client::new() reads it.
Our commitment: the best breadth and depth of market data at the best value. Get a free API key.