6 releases (breaking)
| 0.5.1 | Mar 10, 2026 |
|---|---|
| 0.5.0 | Mar 8, 2026 |
| 0.4.0 | Feb 23, 2026 |
| 0.3.0 | Jan 20, 2026 |
| 0.1.0 | Feb 6, 2025 |
#169 in Finance
315KB
7.5K
SLoC
dukascopy-fx
Library-first Rust crate for Dukascopy historical market data (FX, metals, indices, equities).
30-Second Quickstart
[dependencies]
dukascopy-fx = "0.5.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
use dukascopy_fx::{Ticker, time::now};
#[tokio::main]
async fn main() -> dukascopy_fx::Result<()> {
let ticker = Ticker::try_new("EUR", "USD")?;
let rate = ticker.rate_at(now()).await?;
println!("{} @ {}", rate.rate, rate.timestamp);
Ok(())
}
Why teams choose this crate
- yfinance-like ergonomics (
Ticker,history,rate_at) - unified request model (
RateRequest) for pair/symbol flows - strict + explicit parse modes (
RequestParseMode) - typed period API (
Period) and tuned batch concurrency - deduplicated concurrent fetches + parsed-tick cache reuse for better throughput
- checkpoint-driven incremental updates
- CLI fetcher for repeatable data jobs
- dataframe-friendly interop helpers (
flatten_rows,FlatExchangeRow)
What's New in 0.5.1
- Faster hot paths (request parsing, pair construction, mixed high-load scenarios).
- Safer cache-miss concurrency via singleflight with cancellation-safe wakeups.
- New client tuning knobs:
parsed_tick_cache_size(...)andmax_decompression_jobs(...). - Added controlled HTTP load/stress testing guide (
docs/LOAD_TESTING.md) andk6script.
Copy-Paste Workflows
1) Live fetch (library)
cargo run --example live_fetch
2) Incremental sync with checkpoints (library)
cargo run --example incremental_checkpoint
3) CSV/Parquet pipeline
# CSV (default features)
cargo run --example csv_parquet_pipeline
# Parquet sink enabled
cargo run --example csv_parquet_pipeline --features sinks-parquet
Feature Matrix
| Capability | Default build | --features sinks-parquet |
|---|---|---|
Library fetch API (Ticker, get_rate*) |
Yes | Yes |
CSV sink (CsvSink) |
Yes | Yes |
Parquet sink (ParquetSink) |
No | Yes |
fx_fetcher backfill/update to CSV |
Yes | Yes |
fx_fetcher backfill/update to Parquet |
No | Yes |
fx_fetcher export CSV -> Parquet |
No | Yes |
CLI Quickstart (fx_fetcher)
# discover/update universe
cargo run --bin fx_fetcher -- sync-universe --dry-run
# initial backfill
cargo run --bin fx_fetcher -- backfill \
--symbols EURUSD,GBPUSD \
--period 30d \
--interval 1h \
--out data/fx.csv
# incremental update
cargo run --bin fx_fetcher -- update \
--symbols EURUSD,GBPUSD \
--lookback 7d \
--interval 1h \
--checkpoint .state/checkpoints.json \
--out data/fx.csv
# machine-readable output for automation
cargo run --bin fx_fetcher -- --json list-instruments
# config-driven defaults
cargo run --bin fx_fetcher -- --config config/fx_fetcher.example.toml backfill --symbols EURUSD
fx_fetcher global flags:
--config PATH.toml: load command defaults from TOML file--json: emit JSON summary/errors for CI scripts and wrappers
API Highlights
Most-used functions:
get_rate(from, to, timestamp)get_rate_for_request(&RateRequest, timestamp)get_rate_for_input(input, timestamp)get_rate_for_input_with_mode(input, RequestParseMode, timestamp)get_rate_for_symbol(symbol, timestamp)get_rate_in_quote(symbol, quote, timestamp)get_rates_range(from, to, start, end, interval)
Most-used Ticker methods:
Ticker::try_new(from, to)Ticker::parse("EUR/USD")rate(),rate_at(timestamp)history("1w"),history_period(Period::Weeks(1))interval(Duration::minutes(30))fetch_incremental(&store, lookback)
Advanced client configuration:
DukascopyClientBuilder::new()default_quote_currency("USD")pair_resolution_mode(...)conversion_mode(...),bridge_currencies(...)code_alias("AAPL", "AAPLUS")max_in_flight_requests(...),max_download_concurrency(...)parsed_tick_cache_size(...),max_decompression_jobs(...)max_at_or_before_backtrack_hours(...)
FAQ (common issues)
Missing command / Unknown option
- run
cargo run --bin fx_fetcher -- --help - commands use strict flag validation (unknown flags are errors)
backfill/update fails with output-mode error
- pass exactly one mode:
--out PATH(persist) or--no-output(dry fetch, no checkpoint advance)
Parquet sink requires feature
- build with
--features sinks-parquet
Invalid currency code
- accepted code format is alphanumeric, length
2..12 - prefer checked constructors:
Ticker::try_new,CurrencyPair::try_new
DataNotFound / sparse timestamps
- timestamp may be outside available history
- weekends/market closure can require earlier timestamp
Testing
Default:
cargo test --lib
cargo test --test public_api_offline_test
cargo test --bin fx_fetcher
Live integration (opt-in):
LIVE_TESTS=1 cargo test --test integration_test
Project docs
- Changelog (release history):
CHANGELOG.md - API stability policy:
docs/API_STABILITY.md - Benchmark methodology:
docs/BENCHMARKS.md - CLI config reference:
docs/CLI_CONFIG.md - Dataframe integrations:
docs/INTEGRATIONS.md - Roadmap:
ROADMAP.md
License
MIT
Dependencies
~14–35MB
~493K SLoC