[go: up one dir, main page]

Module exchange

Module exchange 

Source
Expand description

§Unified Exchange Trait

This module defines the core Exchange trait that all exchange implementations must implement. It provides a unified, polymorphic interface for interacting with cryptocurrency exchanges.

§Overview

The Exchange trait is the central abstraction in CCXT-Rust. It enables:

  • Polymorphic Exchange Usage: Write exchange-agnostic trading code using dyn Exchange
  • Capability Discovery: Query exchange features at runtime via ExchangeCapabilities
  • Type Safety: Leverage Rust’s type system for compile-time guarantees
  • Thread Safety: All implementations are Send + Sync for async runtime compatibility

§Architecture

┌─────────────────────────────────────────────────────────────┐
│                      Exchange Trait                         │
├─────────────────────────────────────────────────────────────┤
│  Metadata Methods                                           │
│  ├── id(), name(), version(), certified()                   │
│  ├── capabilities(), timeframes(), rate_limit()             │
│  └── has_websocket()                                        │
├─────────────────────────────────────────────────────────────┤
│  Market Data Methods (Public API)                           │
│  ├── fetch_markets(), load_markets()                        │
│  ├── fetch_ticker(), fetch_tickers()                        │
│  ├── fetch_order_book(), fetch_trades()                     │
│  └── fetch_ohlcv()                                          │
├─────────────────────────────────────────────────────────────┤
│  Trading Methods (Private API)                              │
│  ├── create_order(), cancel_order(), cancel_all_orders()    │
│  └── fetch_order(), fetch_open_orders(), fetch_closed_orders()│
├─────────────────────────────────────────────────────────────┤
│  Account Methods (Private API)                              │
│  └── fetch_balance(), fetch_my_trades()                     │
└─────────────────────────────────────────────────────────────┘

§Key Types

  • Exchange: The core trait defining the unified exchange interface
  • ExchangeCapabilities: Describes which features an exchange supports
  • BoxedExchange: Type alias for Box<dyn Exchange> (owned trait object)
  • ArcExchange: Type alias for Arc<dyn Exchange> (shared trait object)

§Usage Examples

§Basic Exchange Usage

use ccxt_core::exchange::{Exchange, ExchangeCapabilities};

async fn print_exchange_info(exchange: &dyn Exchange) {
    println!("Exchange: {} ({})", exchange.name(), exchange.id());
    println!("Version: {}", exchange.version());
    println!("Certified: {}", exchange.certified());
    println!("Rate Limit: {} req/s", exchange.rate_limit());
}

§Checking Capabilities Before Calling Methods

use ccxt_core::exchange::{Exchange, ExchangeCapabilities};

async fn safe_fetch_ticker(
    exchange: &dyn Exchange,
    symbol: &str,
) -> ccxt_core::Result<ccxt_core::Ticker> {
    // Always check capability before calling
    if !exchange.capabilities().fetch_ticker {
        return Err(ccxt_core::Error::not_implemented("fetch_ticker"));
    }
    exchange.fetch_ticker(symbol).await
}

§Using Multiple Exchanges Polymorphically

use ccxt_core::exchange::{Exchange, BoxedExchange};
use ccxt_core::types::Price;

async fn fetch_best_price(
    exchanges: &[BoxedExchange],
    symbol: &str,
) -> ccxt_core::Result<Price> {
    let mut best_price: Option<Price> = None;
     
    for exchange in exchanges {
        if exchange.capabilities().fetch_ticker {
            if let Ok(ticker) = exchange.fetch_ticker(symbol).await {
                if let Some(last) = ticker.last {
                    best_price = Some(match best_price {
                        None => last,
                        Some(current) => if current < last { current } else { last },
                    });
                }
            }
        }
    }
     
    best_price.ok_or_else(|| ccxt_core::Error::market_not_found("symbol"))
}

§Thread-Safe Shared Exchange

use ccxt_core::exchange::{Exchange, ArcExchange};
use std::sync::Arc;

async fn spawn_ticker_tasks(
    exchange: ArcExchange,
    symbols: Vec<String>,
) {
    let handles: Vec<_> = symbols
        .into_iter()
        .map(|symbol| {
            let ex = Arc::clone(&exchange);
            tokio::spawn(async move {
                ex.fetch_ticker(&symbol).await
            })
        })
        .collect();
     
    for handle in handles {
        let _ = handle.await;
    }
}

§ExchangeCapabilities

The ExchangeCapabilities struct provides runtime feature discovery:

use ccxt_core::exchange::ExchangeCapabilities;

// Create capabilities for public-only access
let public_caps = ExchangeCapabilities::public_only();
assert!(public_caps.fetch_ticker);
assert!(!public_caps.create_order);

// Create capabilities with all features
let all_caps = ExchangeCapabilities::all();
assert!(all_caps.create_order);
assert!(all_caps.websocket);

// Check capability by name (CCXT-style camelCase)
assert!(all_caps.has("fetchTicker"));
assert!(all_caps.has("createOrder"));

§Error Handling

All exchange methods return Result<T> with comprehensive error types:

  • NotImplemented: Method not supported by this exchange
  • Authentication: API credentials missing or invalid
  • RateLimit: Too many requests
  • Network: Connection or timeout errors
  • Exchange: Exchange-specific errors

§Thread Safety

The Exchange trait requires Send + Sync bounds, ensuring:

  • Exchanges can be sent across thread boundaries (Send)
  • Exchanges can be shared across threads via Arc (Sync)
  • Compatible with Tokio and other async runtimes

§See Also

Structs§

ExchangeCapabilities
Exchange capabilities - describes what features an exchange supports

Traits§

Exchange
Core Exchange trait - the unified interface for all exchanges

Type Aliases§

ArcExchange
Type alias for an Arc-wrapped Exchange trait object
BoxedExchange
Type alias for a boxed Exchange trait object