Single Blog

How to Create, Fetch, Edit, and Cancel Crypto Orders in Pandas

programmatic trading using Crypto-Panda

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:

    • Create new orders from a DataFrame
    • Fetch your open and closed orders
    • Edit existing orders
    • Cancel orders individually or in bulk

Let’s get started.

Setup

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”,
}))

Create Orders from a DataFrame

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.

Fetch Orders (Open + Closed)

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     |       | []       | []     |             |                   |                 |
Everything is returned as a clean, typed DataFrame — ready for filtering, analysis, or exporting.

Edit Orders

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 |

Cancel Orders

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 |     | []     | []   |           |                  |                |
Or cancel everything for a given symbol:

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 |          |             |               |            | []       |              |             |                |                   |                 |          |       |

Why We Built This

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.

Watch the Full Walkthrough

If you prefer visual guides, here’s the full video tutorial:

Create, Fetch, Edit, Cancel Orders with Crypto-Pandas