digdigdig3 0.1.3

Multi-exchange connector library — unified async Rust API for 40+ crypto exchanges, stock brokers, forex providers, and 88 intelligence feeds
Documentation

digdigdig3

Multi-exchange connector library for Rust — unified async trait API covering crypto exchanges, stock brokers, forex providers, aggregators, and 88 intelligence feeds.

Crates.io docs.rs License: MIT OR Apache-2.0

Features

  • 26 crypto venues — 17 CEX + 2 derivatives platforms + 7 DEX
  • 14 stock market connectors — US, India, Japan, Korea, Russia
  • 3 forex providers — broker and historical data
  • 4 multi-asset aggregators — DeFi, crypto, global equities
  • 88 intelligence feeds — economic, geopolitical, aviation, maritime, cyber, space, and more
  • Unified async trait APIMarketData, Trading, Account, Positions across all venues
  • AnyConnector enum — store heterogeneous connectors in collections without dyn Trait
  • ConnectorFactory — create any connector by ExchangeId with one call
  • WebSocket streaming — real-time klines, trades, orderbook, ticker, private events
  • Built-in rate limiting — per-exchange weight limiters and simple request-count limiters
  • Testnet support — Binance, Bybit, OKX, Kraken, Phemex, Deribit, and others

Quick Start

[dependencies]
digdigdig3 = "0.1"
tokio = { version = "1", features = ["full"] }
use digdigdig3::{
    connector_manager::{ConnectorFactory, AnyConnector},
    ExchangeId, AccountType, Symbol, MarketData,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a public Binance connector — no API key required
    let connector = ConnectorFactory::create_public(ExchangeId::Binance).await?;

    let symbol = Symbol::new("BTC", "USDT");
    let price = connector.get_price(symbol.clone(), AccountType::Spot).await?;
    println!("BTC/USDT: {price}");

    let klines = connector
        .get_klines(symbol, "1h", Some(10), AccountType::Spot, None)
        .await?;
    println!("Got {} candles", klines.len());

    Ok(())
}

Supported Venues

Crypto — CEX

Exchange Spot Futures WebSocket Testnet
Binance yes yes yes yes
Bybit yes yes yes yes
OKX yes yes yes yes
KuCoin yes yes yes no
Kraken yes yes yes yes
Coinbase yes no yes no
Gate.io yes yes yes no
Bitfinex yes yes yes yes
Bitstamp yes no yes no
Gemini yes no yes no
MEXC yes yes yes no
HTX yes yes yes yes
Bitget yes yes yes no
BingX yes yes yes yes
Phemex yes yes yes yes
Crypto.com yes yes yes yes
Upbit yes no yes no

Crypto — Derivatives

Exchange Type WebSocket Testnet
Deribit Options / Perpetuals yes yes
HyperLiquid Perpetuals (hybrid CEX/DEX) yes yes

Crypto — DEX

Exchange Chain WebSocket
Uniswap Ethereum no
Lighter Ethereum L2 yes
dYdX v4 Cosmos yes
Paradex Starknet yes
Jupiter Solana no
Raydium Solana yes
GMX Arbitrum no

Prediction Markets

Provider Description
Polymarket Probability-based trading on real-world events

Stocks — US

Provider Type Trading
Polygon Data (NYSE, NASDAQ) no
Finnhub Data (global coverage) no
Tiingo Data (stocks, forex, crypto) no
Twelvedata Data (100+ indicators, ETFs) no
Alpaca Broker (commission-free) yes

Stocks — India

Provider Exchanges Trading
AngelOne NSE, BSE, MCX, CDS yes
Zerodha NSE, BSE, NFO, BFO, MCX yes
Fyers NSE, BSE, MCX, NCDEX yes
Dhan NSE, BSE, MCX (200-level depth) yes
Upstox NSE, BSE, MCX yes

Stocks — Other Regions

Provider Market Type
JQuants Japan (TSE / JPX) Data
Tinkoff Russia (MOEX) Broker
MOEX ISS Russia Data
KRX Korea (KOSPI, KOSDAQ, KONEX) Data

Forex

Provider Type Trading
OANDA Broker (REST + streaming) yes
Alpha Vantage Data (forex, stocks, crypto) no
Dukascopy Historical tick data (2003+) no

Multi-Asset Aggregators

Provider Coverage
Yahoo Finance Stocks, crypto, forex, options, fundamentals
CryptoCompare 5,700+ coins, 170+ exchanges, CCCAGG index
DefiLlama DeFi TVL, protocols, yields
Interactive Brokers Stocks, forex, futures, options (multi-market)

Architecture

Trait System

All connectors implement a minimal core trait stack:

ExchangeIdentity   — id(), exchange_name(), is_testnet(), supported_account_types()
     │
     ├── MarketData — get_price(), get_orderbook(), get_klines(), get_ticker(), ping()
     ├── Trading    — market_order(), limit_order(), cancel_order(), get_order(), open_orders()
     ├── Account    — get_balance(), get_account_info()
     └── Positions  — get_positions(), get_funding_rate(), set_leverage()

The CoreConnector supertrait combines all five:

pub trait CoreConnector:
    ExchangeIdentity + MarketData + Trading + Account + Positions + Send + Sync {}

Exchange-specific extensions (modify_order, cancel_all, TP/SL orders, sub-accounts, etc.) live directly on each connector struct — not in core traits — keeping the shared interface lean and guaranteed across all venues.

AnyConnector and ConnectorFactory

AnyConnector is an enum with one variant per connector. It implements all core traits via delegation and is cheaply clonable via Arc wrapping:

// All of these have the same type: Arc<AnyConnector>
let binance = ConnectorFactory::create_public(ExchangeId::Binance).await?;
let bybit   = ConnectorFactory::create_public(ExchangeId::Bybit).await?;

// Store in a Vec, pass to generic functions — same type, no dyn
let connectors: Vec<Arc<AnyConnector>> = vec![binance, bybit];

ConnectorRegistry provides O(1) metadata lookup by ExchangeId: name, category, feature flags (market_data, trading, websocket, etc.).

Intelligence Feed Registry

FeedId (88 variants) and FeedRegistry follow the same pattern for intelligence feeds. FeedMetadata carries category, auth type, endpoint base URL, and a human-readable description.

Usage Examples

Public Market Data (no API key)

use digdigdig3::{
    connector_manager::ConnectorFactory,
    ExchangeId, AccountType, Symbol, MarketData,
};

let conn = ConnectorFactory::create_public(ExchangeId::Bybit).await?;
let symbol = Symbol::new("ETH", "USDT");

// Current price
let price = conn.get_price(symbol.clone(), AccountType::Spot).await?;

// Order book (20 levels)
let book = conn.get_orderbook(symbol.clone(), Some(20), AccountType::Spot).await?;

// Last 100 hourly candles
let candles = conn
    .get_klines(symbol.clone(), "1h", Some(100), AccountType::Spot, None)
    .await?;

// 24-hour ticker
let ticker = conn.get_ticker(symbol, AccountType::Spot).await?;
println!("24h volume: {}", ticker.volume);

Authenticated Trading

use digdigdig3::{
    connector_manager::ConnectorFactory,
    Credentials, ExchangeId, AccountType, Symbol, OrderSide, MarketData, Trading, Account,
};

let creds = Credentials::new("YOUR_API_KEY", "YOUR_API_SECRET");
let conn = ConnectorFactory::create_authenticated(ExchangeId::Binance, creds).await?;

// Account balance
let balance = conn.get_balance(None, AccountType::Spot).await?;

// Place a limit order
let symbol = Symbol::new("BTC", "USDT");
let order = conn
    .limit_order(symbol.clone(), OrderSide::Buy, 0.001, 60_000.0, AccountType::Spot)
    .await?;
println!("Order id: {}", order.id);

// Cancel it
conn.cancel_order(symbol, &order.id, AccountType::Spot).await?;

WebSocket Streaming

use digdigdig3::{
    ExchangeId, AccountType, Symbol, StreamType, SubscriptionRequest,
};
use digdigdig3::exchanges::binance::BinanceConnector;
use digdigdig3::WebSocketConnector;
use futures_util::StreamExt;

let mut ws = BinanceConnector::public(false).await?;
ws.connect(AccountType::Spot).await?;

let req = SubscriptionRequest {
    stream_type: StreamType::Kline { interval: "1m".to_string() },
    symbol: Symbol::new("BTC", "USDT"),
    account_type: AccountType::Spot,
};
ws.subscribe(req).await?;

let mut stream = ws.event_stream();
while let Some(event) = stream.next().await {
    match event? {
        digdigdig3::StreamEvent::Kline(k) => {
            println!("open={} close={} volume={}", k.open, k.close, k.volume);
        }
        _ => {}
    }
}

Intelligence Feeds

Intelligence feeds are separate from exchange connectors and live under digdigdig3::intelligence_feeds. Each feed has its own typed connector in src/intelligence_feeds/<category>/<feed>/.

// Example: fetch earthquake data from USGS
use digdigdig3::intelligence_feeds::feed_manager::{FeedId, FeedRegistry};

let meta = FeedRegistry::get(FeedId::UsgsEarthquake);
println!("Feed: {} — auth required: {:?}", meta.name, meta.auth_type);

Query Available Connectors

use digdigdig3::connector_manager::{ConnectorRegistry, ConnectorCategory};

// All crypto CEX connectors
let cex = ConnectorRegistry::by_category(ConnectorCategory::CryptoExchangeCex);
for meta in cex {
    println!("{} — ws={} trading={}", meta.name, meta.features.websocket, meta.features.trading);
}

// All connectors that support WebSocket
let ws_capable = ConnectorRegistry::all()
    .filter(|m| m.features.websocket)
    .collect::<Vec<_>>();
println!("{} connectors support WebSocket", ws_capable.len());

Intelligence Feed Categories

88 feeds across 22 categories:

Category Count Examples
Economic 12 FRED, ECB, IMF, World Bank, OECD, BIS, Eurostat
Cyber 9 Shodan, VirusTotal, NVD, AbuseIPDB, Censys, RIPE NCC
US Government 9 SEC EDGAR, BLS, EIA, Census, Congress.gov, BEA
Environment 9 USGS Earthquake, NOAA, NASA EONET/FIRMS, OpenWeatherMap
Conflict 5 ACLED, GDELT, UCDP, ReliefWeb, UNHCR
Space 5 NASA, SpaceX, Space-Track, Launch Library 2, Sentinel Hub
Aviation 4 ADS-B Exchange, OpenSky, AviationStack, Wingbits
Maritime 4 AISStream, Datalastic AIS, IMF PortWatch, NGA Warnings
Demographics 4 WHO, World Bank Population, UN OCHA, Wikipedia
Financial 4 Alpha Vantage, Finnhub, NewsAPI, OpenFIGI
Crypto 5 CoinGecko, Coinglass, Whale Alert, Etherscan, Bitquery
Sanctions 3 OFAC, OpenSanctions, INTERPOL
Corporate 3 GLEIF, OpenCorporates, UK Companies House
Trade 2 UN COMTRADE, EU TED
Governance 2 EU Parliament, UK Parliament
Academic 2 arXiv, Semantic Scholar
C2 Intel 1 C2 Intel Feeds
FAA 1 FAA Status
Feodo 1 Feodo Tracker (botnet C2 blocklist)
Hacker News 1 Hacker News
Prediction 1 PredictIt
RSS 1 RSS Proxy

Error Handling

All fallible operations return ExchangeResult<T> = Result<T, ExchangeError>:

use digdigdig3::ExchangeError;

match connector.get_price(symbol, AccountType::Spot).await {
    Ok(price) => println!("Price: {price}"),
    Err(ExchangeError::RateLimit) => eprintln!("Rate limited — back off"),
    Err(ExchangeError::Auth(msg)) => eprintln!("Auth failed: {msg}"),
    Err(ExchangeError::Api { code, message }) => eprintln!("API {code}: {message}"),
    Err(e) => eprintln!("Error: {e}"),
}

Crate Features

Feature Default Description
websocket no Enable WebSocket streaming support

Contributing

New exchange connectors follow the Agent Carousel pipeline documented in contributing/. Each connector lives in:

src/exchanges/<name>/
├── mod.rs         # public exports
├── endpoints.rs   # URL constants, symbol formatting
├── auth.rs        # request signing
├── parser.rs      # JSON deserialization
├── connector.rs   # trait implementations
└── websocket.rs   # WebSocket (optional)

Reference implementation: src/exchanges/kucoin/

Support the Project

If you find this library useful, consider supporting development:

Currency Network Address
USDT TRC20 TNxMKsvVLYViQ5X5sgCYmkzH4qjhhh5U7X
USDC Arbitrum 0xEF3B94Fe845E21371b4C4C5F2032E1f23A13Aa6e
ETH Ethereum 0xEF3B94Fe845E21371b4C4C5F2032E1f23A13Aa6e
BTC Bitcoin bc1qjgzthxja8umt5tvrp5tfcf9zeepmhn0f6mnt40
SOL Solana DZJjmH8Cs5wEafz5Ua86wBBkurSA4xdWXa3LWnBUR94c

License

Licensed under either of:

at your option.