rustrade-execution 0.3.0

Stream private account data from financial venues, and execute (live or mock) orders.
Documentation
[package]
name = "rustrade-execution"
version = "0.3.0"
edition.workspace = true
rust-version.workspace = true
license.workspace = true
repository.workspace = true
keywords.workspace = true
categories.workspace = true
documentation = "https://docs.rs/rustrade-execution/"
readme = "README.md"
description = "Stream private account data from financial venues, and execute (live or mock) orders."

# Every connector module (alpaca/binance/ibkr/hyperliquid) is feature-gated and `default = []`, so a
# default-feature docs.rs build would publish a crate documenting zero connectors and break the
# connector-comparison intra-doc links in `client/mod.rs`. Build the full surface for published docs.
[package.metadata.docs.rs]
all-features = true


[features]
default = []
alpaca = [
    "dep:reqwest",
    "dep:serde_json",
    "serde_json/raw_value", # RawValue borrow for zero-copy WS data field parsing
    "dep:lru",
    "dep:parking_lot",
    "dep:indexmap",
]
binance = [
    "dep:binance-sdk",
    "dep:serde_json",
    "serde_json/raw_value", # RawValue borrow for zero-copy WS user-data frame parsing
    "dep:anyhow",
    "dep:lru",
    "dep:parking_lot",
    # Only to name `reqwest::Method` for the hand-rolled userListenToken POST, which reuses the
    # SDK's `common::utils::send_request` (and its own reqwest client). No new crate enters the
    # graph — reqwest is already a workspace dep and a binance-sdk transitive dep.
    "dep:reqwest",
]
ibkr = ["dep:ibapi", "dep:parking_lot", "dep:chrono-tz", "rustrade-instrument/ibkr"]
hyperliquid = [
    "dep:hyperliquid_rust_sdk",
    "dep:ethers",
    "dep:tokio-util",
    "dep:uuid",
]

[dependencies]
# Rustrade Ecosystem
rustrade-integration = { workspace = true, features = [
    "collection",
    "error",
    "stream",
] }
rustrade-instrument = { workspace = true }

# Logging
tracing = { workspace = true }

# Async
tokio = { workspace = true, features = ["sync", "macros", "rt-multi-thread"] }
tokio-stream = { workspace = true, features = ["sync"] }
futures = { workspace = true }

# Data Structures
smol_str = { workspace = true }
fnv = { workspace = true }
indexmap = { workspace = true, optional = true }
rust_decimal = { workspace = true }

# Error
thiserror = { workspace = true }

# SerDe
serde = { workspace = true, features = ["derive"] }

# Misc
rand = { workspace = true }
chrono = { workspace = true, features = ["serde"] }
itertools = { workspace = true }
derive_more = { workspace = true, features = [
    "constructor",
    "from",
    "display",
] }

# Alpaca (optional, behind "alpaca" feature)
reqwest = { workspace = true, optional = true } # HTTP client for Alpaca REST API

# Binance (optional, behind "binance" feature)
# `margin_trading` is bundled with `spot` under the single `binance` feature (one feature per
# exchange, matching alpaca/ibkr/hyperliquid). It ships ahead of the BinanceMargin client being
# fully wired so spot + margin compile together; spot-only users pay the margin module's build cost.
binance-sdk = { version = "=52.0.0", features = ["spot", "margin_trading"], optional = true }
anyhow = { workspace = true, optional = true }                              # Required: binance-sdk's public API returns anyhow::Result

# Shared between "alpaca" and "binance" features
serde_json = { workspace = true, optional = true }
lru = { workspace = true, optional = true }         # Event deduplication cache for reconnect resilience
parking_lot = { workspace = true, optional = true } # Lighter mutex for dedup cache (no poisoning, no OS thread park)

# IBKR (optional, behind "ibkr" feature)
ibapi = { version = "=3.0.1", optional = true, default-features = false, features = [
    "sync",
] }
chrono-tz = { workspace = true, optional = true }

# Hyperliquid (optional, behind "hyperliquid" feature)
hyperliquid_rust_sdk = { version = "0.6", optional = true }
ethers = { version = "2.0", optional = true, default-features = false }
tokio-util = { version = "0.7", optional = true }
uuid = { version = "1.0", optional = true }

[dev-dependencies]
# test-util enables tokio::time::pause() and advance() for behavioral timing tests
tokio = { workspace = true, features = ["test-util"] }
# Mock HTTP server for testing REST pagination and truncation logic (H-1, H-3)
wiremock = { workspace = true }
# Tracing for examples
tracing-subscriber = { workspace = true, features = ["env-filter"] }
# Decimal literals for examples
rust_decimal_macros = { workspace = true }
# Serde round-trip tests (L2)
serde_json = { workspace = true }
# Serial test execution for integration tests that share exchange state
serial_test = { workspace = true }

# Examples that depend on optional features. Without `required-features`,
# `cargo check --all-targets` (default features) fails to compile them.

[[example]]
name = "hyperliquid_execution"
required-features = ["hyperliquid"]

[[example]]
name = "hyperliquid_spot_execution"
required-features = ["hyperliquid"]

[[example]]
name = "ibkr_execution"
required-features = ["ibkr"]