Skip to content

Exchange Connectivity

How TradAI connects to cryptocurrency exchanges for market data and trading.

Supported Exchanges

TradAI uses CCXT as a unified exchange abstraction layer. Any CCXT-supported exchange can be configured, though the platform is primarily tested with:

Exchange Trading Modes Auth Type Notes
Binance Spot, Futures API key/secret Primary exchange; perpetual swaps via futures mode
Hyperliquid Futures Private key (EVM wallet) DEX; uses wallet signing instead of API keys

Trading Modes

The TradingMode enum controls which markets are queried:

  • SPOT -- Spot trading markets
  • MARGIN -- Margin trading markets
  • FUTURES -- Perpetual swaps and delivery futures (maps to CCXT types swap and future)
from tradai.common import ExchangeConfig, TradingMode

# Binance futures (default)
config = ExchangeConfig(name="binance", trading_mode=TradingMode.FUTURES)

# Binance spot
config = ExchangeConfig(name="binance", trading_mode=TradingMode.SPOT)

Credential Management

Exchange credentials are stored in AWS Secrets Manager and loaded at runtime via ExchangeConfig.from_secret().

Secret Format

CEX (centralized exchange) secrets:

{
    "auth_type": "api_key",
    "api_key": "your-api-key",
    "api_secret": "your-api-secret",
    "passphrase": ""
}

DEX (decentralized exchange) secrets:

{
    "auth_type": "private_key",
    "private_key": "0x...",
    "wallet_address": "0x..."
}

Loading Credentials

from tradai.common import ExchangeConfig

# Load from Secrets Manager
config = ExchangeConfig.from_secret(
    secret_name="tradai/prod/exchange/binance",
    name="binance",
)

# Validate credentials work (calls fetch_balance)
config.validate_credentials(timeout=10)

The get_secret() function in tradai.common.aws.secrets_manager is thread-safe (uses explicit locking) and retrieves the secret as a parsed JSON dictionary.

Credential Rotation

Credentials must be rotated manually:

  1. Generate new API key/secret on the exchange.
  2. Update the secret in AWS Secrets Manager:
    aws secretsmanager update-secret \
        --secret-id tradai/prod/exchange/binance \
        --secret-string '{"auth_type":"api_key","api_key":"NEW_KEY","api_secret":"NEW_SECRET","passphrase":""}'
    
  3. Restart affected ECS services so they pick up the new credentials:
    aws ecs update-service --cluster tradai-dev --service data-collection --force-new-deployment
    
  4. Verify connectivity by checking service health logs.
  5. Revoke the old API key on the exchange.

No automatic rotation

AWS Secrets Manager rotation lambdas are not configured for exchange credentials. Rotation is a manual process.

Rate Limiting

CCXT provides built-in rate limiting (enableRateLimit: true is set by default in create_ccxt_client). Each exchange class in CCXT enforces its own rate limits based on the exchange's documented API limits.

No additional application-level rate limiting is applied. CCXT's rate limiter is sufficient for the platform's data fetching patterns (sequential symbol iteration with pagination).

Failover Behavior

ResilientDataRepository

The ResilientDataRepository wraps any DataRepository with a circuit breaker:

from tradai.data.infrastructure.repositories import CCXTRepository, ResilientDataRepository

config = ExchangeConfig(name="binance", trading_mode=TradingMode.FUTURES)
repo = CCXTRepository(config)
resilient = ResilientDataRepository(repo, name="binance")

# Use exactly like a normal repository
data = resilient.fetch_ohlcv(symbols, date_range, timeframe)

Circuit breaker behavior:

  • Tracks consecutive failures from retriable exceptions (ExternalServiceError, ConnectionError, TimeoutError).
  • When the failure threshold is reached, the circuit opens and subsequent requests fail immediately with CircuitOpenError.
  • After a recovery timeout, the circuit enters half-open state and allows a probe request.
  • A successful probe closes the circuit; a failed probe re-opens it.

Partial Success Handling

CCXTRepository.fetch_ohlcv() fetches symbols sequentially. If some symbols fail:

  • The repository logs a warning and continues with remaining symbols.
  • Only raises DataFetchError if all symbols fail.
  • Partial results are returned for the symbols that succeeded.

Current Limitations

Multi-exchange failover (falling back to a secondary exchange when the primary is down) is not implemented. The ResilientDataRepository operates on a single exchange. Multi-exchange failover is tracked as a separate initiative.

Configuration Reference

Environment Variable Description Example
EXCHANGE_SECRET_NAME Secrets Manager secret name tradai/prod/exchange/binance
EXCHANGE_NAME CCXT exchange identifier binance
TRADING_MODE Market type futures, spot

Source Files

File Description
libs/tradai-common/src/tradai/common/entities/exchange.py ExchangeConfig, TradingMode, AuthType
libs/tradai-common/src/tradai/common/aws/secrets_manager.py get_secret() for credential retrieval
libs/tradai-data/src/tradai/data/infrastructure/repositories/ccxt_repository.py CCXTRepository
libs/tradai-data/src/tradai/data/infrastructure/repositories/resilient.py ResilientDataRepository
libs/tradai-data/src/tradai/data/infrastructure/repositories/ccxt_shared.py Shared CCXT client creation and utilities