Managing crypto orders through raw exchange APIs is a noisy experience. If you’ve worked with REST endpoints like createOrders, fetchOpenOrders, or cancelOrders, you know the drill: every exchange has different parameters, symbols, limits, and quirks.
That’s why we created Crypto-Pandas — an open-source Python library that brings order management into the comfort of Pandas, powered by the battle-tested exchange integration library CCXT.
In this short guide, we’ll walk through how you can:
Let’s get started.
First, install the library:
pip install crypto-pandas
Then set up your CCXT exchange instance (e.g., for Binance).
import ccxt
from crypto_pandas import CCXTPandasExchange
exchange = CCXTPandasExchange(exchange=ccxt.binance({
“apiKey”: “your-key”,
“secret”: “your-secret”,
“proxy”: “possible-need-to-set-proxy”,
}))
Instead of looping through orders manually, just define a DataFrame:
orders = pd.DataFrame([
{
“symbol”: “BTC/USDT:USDT”,
“side”: “buy”,
“type”: “limit”,
“notional”: 300,
“price”: 105000,
“reduceOnly”: False,
},
{
“symbol”: “ETH/USDT:USDT”,
“side”: “sell”,
“type”: “market”,
“notional”: 400,
“price”: 2000,
}
])
Send them in one line:
response = exchange.create_orders(orders=orders)
print(response.to_markdown(index=False))
| id | clientOrderId | timestamp | datetime | lastTradeTimestamp | lastUpdateTimestamp | symbol | type | timeInForce | postOnly | reduceOnly | side | price | triggerPrice | amount | cost | average | filled | remaining | status | fee | trades | fees | stopPrice | takeProfitPrice | stopLossPrice | |-----------:|:---------------------------------|:---------------------------------|:---------------------------------|---------------------:|----------------------:|:--------------|:-------|:--------------|:-----------|:-------------|:-------|----------:|:---------------|---------:|--------:|----------:|---------:|------------:|:---------|:------|:---------|:-------|:------------|:------------------|:----------------| | 5188236127 | x-cvBPrNm91fc1e919c01e4897e12cae | 2025-07-03 09:17:22.299000+00:00 | 2025-07-03 09:17:22.299000+00:00 | nan | 1751534242299 | BTC/USDT:USDT | limit | GTC | False | False | buy | 105000 | | 0.003 | 0 | nan | 0 | 0.003 | open | | [] | [] | | | | | 4781793614 | x-cvBPrNm99b077cd6fbbb52a99e44b | 2025-07-03 09:17:22.299000+00:00 | 2025-07-03 09:17:22.299000+00:00 | 1.75153e+12 | 1751534242299 | ETH/USDT:USDT | market | GTC | False | False | sell | 2597.49 | | 0.2 | 519.498 | 2597.49 | 0.2 | 0 | closed | | [] | [] | | | |
That’s it. Notice that crypto-pandas also allows providing a notional field rather than amount if you want to trade a specific amount in quote quantity.
You can retrieve your existing orders and trades like this:
open_orders = exchange.fetch_open_orders()
closed_orders = exchange.fetch_closed_orders(symbol=”BTC/USDT:USDT”)
trades = exchange.fetch_my_trades(symbol=”BTC/USDT:USDT”)
print(open_orders.to_markdown(index=False))
print(trades.to_markdown(index=False))
| id | clientOrderId | timestamp | datetime | lastTradeTimestamp | lastUpdateTimestamp | symbol | type | timeInForce | postOnly | reduceOnly | side | price | triggerPrice | amount | cost | average | filled | remaining | status | fee | trades | fees | stopPrice | takeProfitPrice | stopLossPrice | |-----------:|:---------------------------------|:---------------------------------|:---------------------------------|:---------------------|----------------------:|:--------------|:-------|:--------------|:-----------|:-------------|:-------|--------:|:---------------|---------:|-------:|----------:|---------:|------------:|:---------|:------|:---------|:-------|:------------|:------------------|:----------------| | 5188234563 | x-cvBPrNm9bcca946b20444708610ef6 | 2025-07-03 09:16:43.896000+00:00 | 2025-07-03 09:16:43.896000+00:00 | | 1751534203896 | BTC/USDT:USDT | limit | GTC | False | False | buy | 105000 | | 0.003 | 0 | nan | 0 | 0.003 | open | | [] | [] | | | | | 5188236127 | x-cvBPrNm91fc1e919c01e4897e12cae | 2025-07-03 09:17:22.299000+00:00 | 2025-07-03 09:17:22.299000+00:00 | | 1751534242299 | BTC/USDT:USDT | limit | GTC | False | False | buy | 105000 | | 0.003 | 0 | nan | 0 | 0.003 | open | | [] | [] | | | |
Need to modify an existing order? Do it as such:
orders_to_edit = open_orders[[“id”, “symbol”, “amount”, “type”, “price”, “side”]].copy()
# Double amount
orders_to_edit[“amount”] /= 2
response = exchange.edit_orders(orders=orders_to_edit)
print(response.to_markdown(index=False))
| id | symbol | amount | type | price | side | notional | precision_amount | precision_price | limits_price.min | limits_price.max | limits_amount.min | limits_amount.max | |-----------:|:--------------|---------:|:-------|--------:|:-------|-----------:|-------------------:|------------------:|------------------:|------------------:|-------------------:|-------------------:| | 5188234563 | BTC/USDT:USDT | 0.0015 | limit | 105000 | buy | 157.5 | 0.001 | 0.1 | 261.1 | 809484 | 0.001 | 1000 | | 5188236127 | BTC/USDT:USDT | 0.0015 | limit | 105000 | buy | 157.5 | 0.001 | 0.1 | 261.1 | 809484 | 0.001 | 1000 |
You can cancel individual orders:
response = exchange.cancel_orders(ids=open_orders[“id”].tolist(), symbol=”BTC/USDT:USDT”)
print(response)
| id | clientOrderId | timestamp | datetime | lastTradeTimestamp | lastUpdateTimestamp | symbol | type | timeInForce | postOnly | reduceOnly | side | price | triggerPrice | amount | cost | average | filled | remaining | status | fee | trades | fees | stopPrice | takeProfitPrice | stopLossPrice | |-----------:|:----------------------------------------|:----------------------------------|:----------------------------------|:--------------------|---------------------:|:---------------|:------|:------------|:---------|:------------|:-----|--------:|:--------------|--------:|-----:|---------:|--------:|----------:|:---------|:----|:--------|:------|:----------|:------------------|:---------------| | 5188234563 | x-cvBPrNm9bcca946b20444708610ef6 | 2025-07-03 09:24:01.760000+00:00 | 2025-07-03 09:24:01.760000+00:00 | | 1751534641760 | BTC/USDT:USDT | limit | GTC | False | False | buy | 105000 | | 0.002 | 0 | nan | 0 | 0.002 | canceled | | [] | [] | | | | | 5188236127 | x-cvBPrNm91fc1e919c01e4897e12cae | 2025-07-03 09:24:01.760000+00:00 | 2025-07-03 09:24:01.760000+00:00 | | 1751534641760 | BTC/USDT:USDT | limit | GTC | False | False | buy | 105000 | | 0.002 | 0 | nan | 0 | 0.002 | canceled | | [] | [] | | | |
response = exchange.cancel_all_orders(symbol=”BTC/USDT:USDT”)
print(response)
| fees | id | clientOrderId | timestamp | datetime | symbol | type | side | lastTradeTimestamp | lastUpdateTimestamp | price | amount | cost | average | filled | remaining | timeInForce | postOnly | trades | reduceOnly | stopPrice | triggerPrice | takeProfitPrice | stopLossPrice | status | fee | |:-------|:-----|:----------------|:------------|:-----------|:---------|:-------|:-------|:---------------------|:----------------------|:--------|:---------|:-------|----------:|:---------|:------------|:--------------|:-----------|:---------|:-------------|:------------|:---------------|:------------------|:----------------|:---------|:------| | [] | | | NaT | NaT | | | | | | | | | nan | | | | | [] | | | | | | | |
We built Crypto-Pandas to make algorithmic trading workflows cleaner, faster, and more maintainable. It’s more intuitive and less prone to bugs for quants who enjoy working with Pandas.
Rather than writing dozens of lines of glue code for each exchange, you can now create strategies with just a few Pandas operations — and keep your entire pipeline readable and testable.
If you prefer visual guides, here’s the full video tutorial:
Copyright © 2025 Sigma Quantiphi. All rights reserved.