Skip to main content

Rust-backed Python bindings for low-latency cross-exchange crypto trading.

Project description

dcex - DEX & CEX trading library

Important: No default broker tags are set. You may manually specify a broker tag within function arguments if needed.

Forked from krex, a simplified version of the ccxt Python library.

Originally created and maintained by the same contributor, this fork continues active development, building upon the original foundation with enhanced design, unified DEX + CEX support, and fixes for previously unresolved issues.

A high-performance and lightweight Python and Rust library for interacting with cryptocurrency exchanges. dcex offers synchronous and asynchronous Python clients backed by a Rust core, plus direct Rust APIs for low-level HTTP, signing, and exchange integrations.

Scope note: dcex focuses on market data, account queries, and trading/order APIs. External withdrawal creation endpoints are not currently wrapped, and options support is limited to exchange-specific APIs rather than the unified Product Table Manager.

Python Rust License PyPI Crates.io

Installation

Python:

pip install dcex

or use uv to manage the project:

uv add dcex

Rust:

cargo add dcex

or add it manually:

[dependencies]
dcex = "0.1.0"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

Quick Start

Python Synchronous Usage

import dcex

client = dcex.binance()

klines = client.get_klines(product_symbol="BTC-USDT-SWAP", interval="1m")
print(klines)

Python Asynchronous Usage

import os
import asyncio
import dcex.async_support as dcex
from dotenv import load_dotenv

load_dotenv()

BINANCE_API_KEY = os.getenv("BINANCE_API_KEY")
BINANCE_API_SECRET = os.getenv("BINANCE_API_SECRET")

async def main():
    client = await dcex.binance(
        api_key=BINANCE_API_KEY,
        api_secret=BINANCE_API_SECRET
    )

    try:
        result = await client.get_income_history()
        print(result)

    finally:
        await client.close()

if __name__ == "__main__":
    asyncio.run(main())

Rust Usage

use std::time::Duration;

use dcex::exchanges::binance::{BinanceClient, BinanceMarket};
use dcex::http::HttpMethod;

#[tokio::main]
async fn main() -> dcex::Result<()> {
    let client = BinanceClient::new(None, None, Duration::from_secs(10))?;
    let response = client
        .request_raw(
            HttpMethod::Get,
            BinanceMarket::Spot,
            "/api/v3/time",
            Vec::new(),
            false,
        )
        .await?;
    println!("{}", response.text()?);
    Ok(())
}

Supported Exchanges

Exchange Sync Support Async Support
Binance Yes Yes
Bybit Yes Yes
OKX Yes Yes
Bitget Yes Yes
Kraken Yes Yes
MEXC Yes Yes
BitMart Yes Yes
BitMEX Yes Yes
Gate.io Yes Yes
BingX Yes Yes
KuCoin Yes Yes
Hyperliquid Yes Yes
Lighter Yes Yes
Backpack Yes Yes
Aster Yes Yes

Key Features

  • Product Table Manager for unifying trading instruments across exchanges
  • Sync and async Python API clients with consistent interfaces where available
  • Native Rust core for exchange HTTP, signing, serialization, and response validation
  • Direct Rust crate (dcex) for applications that do not need the Python layer
  • Opt-in live test suites for public, private, stateful, and generated-report endpoints

What is Product Table Manager (PTM)?

PTM is a utility that standardizes and unifies trading instrument metadata across different exchanges, making cross-exchange strategy development easier.

It is a table that contains the following columns:

Column Description
exchange The exchange name
product_symbol The symbol we use to identify the product, it will be the same in different exchanges. For example, BTC-USDT-SWAP is the same product in Binance and Bybit, which named BTCUSDT in Binance and BTC-USDT-SWAP in OKX.
exchange_symbol The symbol that the exchange actually uses
product_type The normalized product type used by dcex, e.g. spot, swap, futures
exchange_type The exchange-specific product type, e.g. spot, linear, inverse, perpetual, delivery
base_currency The base currency, e.g. BTC
quote_currency The quote currency, e.g. USDT
price_precision The price precision, e.g. 0.000001
size_precision The size precision, e.g. 0.000001
min_size The minimum size, e.g. 0.000001
min_notional The minimum notional, e.g. 0.000001
size_per_contract The size per contract. Sometimes 1 contract is not the same as 1 unit in exchanges like OKX.

Options are not currently included in the unified PTM output. Some exchange-specific clients expose option-related parameters or market endpoints, but options are not normalized across exchanges.

How to use Product Table Manager?

In most cases, dcex handles product-symbol mapping internally. If you have a specific use case, you can use ptm to get the information you need.

from dcex.utils.common import Common
from dcex.product_table.manager import ProductTableManager

ptm = ProductTableManager.get_instance(Common.BINANCE)

product_symbol = ptm.get_product_symbol(
    exchange=Common.BINANCE,
    exchange_symbol="BTCUSDT",
    product_type="swap",
)

print(product_symbol)

rows = ptm.rows()
ptm.write_csv("binance_product_table.csv")

Contributing

Contributions are welcome through GitHub issues and pull requests. Run the default test suite before opening a pull request.

Testing

The default test suite is offline and does not require exchange API keys or network access:

uv run pytest

Live, private, stateful, and generated-report tests use the pytest markers configured in pyproject.toml. These tests are opt-in because they can require network access, exchange credentials, or account state.

Examples

Python examples are under examples/sync and examples/async. Rust examples are under crates/dcex/examples. See examples/README.md for the example conventions.

Benchmarking

Local CPU-bound benchmarks isolate Lighter signing and hashing hot paths. The baseline is the PyPI dcex==0.21.2 native Python implementation, fixed at 1.00x; this keeps the comparison reproducible after this branch is merged into main. Rust-backed Python is the current Python API calling the Rust core through PyO3. The baseline is identified by package source and version because the current working tree may still report the same Python package version until the next release bump.

Recorded sample (uv run python examples/benchmark_core_local.py --iterations 50 --warmup 5 --baseline-version 0.21.2, 2026-06-20):

Baseline: PyPI dcex==0.21.2 native Python implementation = 1.00x.

Operation Rust-backed Python Rust native
Cryptographic hash 135.87x 142.05x
Schnorr signature 648.68x 672.18x
Transaction payload signing 395.80x 595.90x

Public HTTP benchmarks install the same PyPI baseline and compare live Binance server-time calls against the current PyO3-backed Python wrapper and Rust native example. Treat those results as an end-to-end latency check, not as the primary evidence for CPU-bound signing speed, because exchange latency and local network conditions dominate the measurement.

Layer Command Output
Local CPU-bound PyPI baseline vs current core uv run python examples/benchmark_core_local.py --iterations 50 --warmup 5 --baseline-version 0.21.2 Speedup table
Rust native local CPU-bound only cargo run -p dcex --example core_local_benchmark --release Timing table
Public HTTP PyPI baseline vs current core uv run python examples/benchmark_public_http.py --iterations 20 --baseline-version 0.21.2 Markdown table
Rust native only cargo run -p dcex --example public_http_benchmark --release Markdown table
Optional local CPU-bound CSV output uv run python examples/benchmark_core_local.py --csv benchmark_core.csv Ignored local CSV file
Optional public HTTP CSV output uv run python examples/benchmark_public_http.py --csv benchmark_public.csv Ignored local CSV file

The Python benchmark scripts install the PyPI baseline into a temporary target directory with uv pip install --target; they do not mutate the current environment. Use --baseline-version when you need to compare against another published Python package version. Use DCEX_BENCH_ITERATIONS, DCEX_BENCH_WARMUP, DCEX_BENCH_INNER_LOOPS, and DCEX_BENCH_OUTPUT=json for Rust-only examples when needed.

Release Publishing

The release workflow detects Conventional Commit changes on main and plans Python and Rust releases independently. A bumped Python release builds wheels and publishes the Python package to PyPI. If no Python version bump is detected, PyPI is not updated.

The Rust crate has an independent version in crates/dcex/Cargo.toml and is published from rust-v* tags. For example, rust-v0.1.0 publishes crate version 0.1.0 to crates.io and creates a separate GitHub Release. The crates/dcex-python package is an internal PyO3 build crate and is not published to crates.io; the Python package version is managed only in pyproject.toml.

License

This project is licensed under the MIT License.

Support

Disclaimer

Cryptocurrency trading involves significant risk. This library is provided as-is without any warranty. Users are responsible for their own trading decisions and risk management.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dcex-0.22.0.tar.gz (412.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

dcex-0.22.0-cp312-cp312-win_amd64.whl (6.5 MB view details)

Uploaded CPython 3.12Windows x86-64

dcex-0.22.0-cp312-cp312-manylinux_2_34_x86_64.whl (6.6 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

dcex-0.22.0-cp312-cp312-macosx_11_0_arm64.whl (6.1 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

File details

Details for the file dcex-0.22.0.tar.gz.

File metadata

  • Download URL: dcex-0.22.0.tar.gz
  • Upload date:
  • Size: 412.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dcex-0.22.0.tar.gz
Algorithm Hash digest
SHA256 9b5c5ec3e87fe14e0a0b6c9db92b37ad5e26dd08c302494ffb0b4752c25b871a
MD5 c6dff2ab7f2ef50e2ddcc0e92fd23559
BLAKE2b-256 0d71a714ad7c6ab47d5d650d8a171e0c9cb1f57c2c566645f6bf854e6c7dc741

See more details on using hashes here.

File details

Details for the file dcex-0.22.0-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: dcex-0.22.0-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 6.5 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dcex-0.22.0-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 c2c7ce6e28aab10340a0c4064b829e03ca63f9966c0177eb75ca5247c02f9701
MD5 ad7606846f18ad809a8d9fb042988830
BLAKE2b-256 3aca6545dcf3040e6a5faef0effe68cd7cdf5c872e4df59b2c64a79d7b0c4f69

See more details on using hashes here.

File details

Details for the file dcex-0.22.0-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

  • Download URL: dcex-0.22.0-cp312-cp312-manylinux_2_34_x86_64.whl
  • Upload date:
  • Size: 6.6 MB
  • Tags: CPython 3.12, manylinux: glibc 2.34+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dcex-0.22.0-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 4a3c5b4559594f3699b727086e56314e9fc68acbc9ea911ffad3f914a3f22f0d
MD5 8ab052058d77cddbaddabcf6d551e11d
BLAKE2b-256 6b9c9f468df2e1aa471be6677d478da30e820f3baa464595bde5bd592f8323c7

See more details on using hashes here.

File details

Details for the file dcex-0.22.0-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

  • Download URL: dcex-0.22.0-cp312-cp312-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 6.1 MB
  • Tags: CPython 3.12, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.23 {"installer":{"name":"uv","version":"0.11.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dcex-0.22.0-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b0ff503f90df82c3c75234619b4547ce7448a26008d40bb1c88fbf0a355811d4
MD5 57823b6fe244618b130426c71f93b82e
BLAKE2b-256 de21d3383d40d5ba739635013bb736af1588784e16794b479ffca6c0c5da5193

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page