StructureX

Home › Guides › Trading bots & code

Crypto trading bot with CCXT: a safe first build in Python

CCXT is a free Python library that talks to about 100 crypto exchanges with the same commands. That makes a first bot surprisingly short. Here's one — with the safety parts written first.

Beginner guide · 10-minute read · Updated 2026-10-21

What CCXT is

Every crypto exchange has its own API (the door programs use to read prices and send orders). Each one is a little different.

CCXT smooths that out. You learn one set of commands — fetch_ohlcv for candles, fetch_balance for your balance, create_order for orders — and they work across many exchanges.

It's free, open source, and available for Python and JavaScript. Install it with pip install ccxt pandas.

Before any code: 4 safety steps

  1. Use a test version if you can. Some exchanges run a test network (sandbox) with fake funds. CCXT can switch to it with one line. Not every exchange has one.
  2. Make API keys with trading only — withdrawals OFF. Then a stolen key can't move your coins out.
  3. Turn on IP whitelisting if the exchange offers it, so the key only works from your server.
  4. Keep keys out of the code. Put them in environment variables. Never paste them into a script, a chat or a shared file.

More: API key security for trading bots.

Step 1: Connect and read candles

Example code for learning — test it on paper first; it is not a ready-made trading system.

import os
import ccxt
import pandas as pd
exchange = ccxt.binance({
    "apiKey": os.environ["EXCHANGE_API_KEY"],      # keys live in the environment
    "secret": os.environ["EXCHANGE_API_SECRET"],
    "enableRateLimit": True,                       # wait between requests
})
exchange.set_sandbox_mode(True)                    # test version; errors if none
exchange.load_markets()
SYMBOL = "BTC/USDT"
candles = exchange.fetch_ohlcv(SYMBOL, "1h", limit=200)
df = pd.DataFrame(candles, columns=["time", "open", "high", "low", "close", "volume"])
df["time"] = pd.to_datetime(df["time"], unit="ms", utc=True)
df = df.iloc[:-1]                                  # drop the candle still forming
print(df.tail(3))

Line by line:

Step 2: Size from the stop

Crypto moves fast, and it trades 24/7, weekends included. Size matters even more here.

import logging
logging.basicConfig(filename="bot.log", level=logging.INFO, format="%(asctime)s %(message)s")
DRY_RUN = True                                     # True = log only, no orders
def size_from_stop(equity, risk_pct, entry, stop):
    risk_money = equity * risk_pct / 100
    per_coin = entry - stop                        # loss per 1 BTC if stopped
    if per_coin <= 0:
        return 0.0
    amount = float(exchange.amount_to_precision(SYMBOL, risk_money / per_coin))
    min_amount = exchange.market(SYMBOL)["limits"]["amount"]["min"] or 0
    return amount if amount >= min_amount else 0.0

In plain words:

Example: 10,000 USDT account, 1% risk = 100. Entry 60,000, stop 59,000: 100 ÷ 1,000 = 0.1 BTC. A math example, not a promise — fast moves can fill a stop worse than planned. Our position size calculator does the same math.

If you're using Leverage on crypto futures, know your liquidation price before anything else — see the crypto liquidation calculator. Many beginners skip leverage entirely while learning.

Step 3: Place orders — carefully

def buy(amount):
    if DRY_RUN:
        logging.info("DRY RUN buy %s %s", amount, SYMBOL)
        return None
    try:
        order = exchange.create_order(SYMBOL, "market", "buy", amount)
        logging.info("ORDER %s", order["id"])
        return order
    except ccxt.InsufficientFunds as e:
        logging.error("Not enough funds: %s", e)
    except ccxt.NetworkError as e:
        logging.error("Network problem, check open orders before retrying: %s", e)
    except ccxt.ExchangeError as e:
        logging.error("Exchange said no: %s", e)
    return None

In plain words:

The stop: don't leave it in your head

A market buy on a spot exchange has no stop attached. You need one placed at the exchange, not just watched by your script — scripts crash and servers lose internet.

How stops work differs by exchange. Some support stop orders, some support take-profit and stop-loss together, some neither on spot. Check exchange.has in CCXT and the exchange's own docs, then test placing and cancelling a stop on the test network. If an exchange can't hold a stop for you, think hard before running a bot there.

The loop and the safety switches

Wrap it all in a loop that runs once per finished candle. Before each decision, check:

Crypto never closes, so the bot can run while you sleep. That's exactly why these limits need to be in the code, not in your head. More: trading bot risk controls.

Test before you trust it

  1. Backtest the rule on past candles first, watching for look-ahead bias (using a candle before it's finished) and overfitting (tuning until the past looks perfect). See how to backtest in Python.
  2. Dry run on live prices for weeks, reading the log daily.
  3. Test network orders, including stops and cancels.
  4. Only then consider small real orders. Losses are possible at any size.

"Crypto bot" sellers are a classic trap. A bot promising steady daily returns is a red flag, not a feature. If you can't read the rules, you can't know how it loses. See AI trading bots explained.

Questions

What is CCXT?

A free, open-source library for Python and JavaScript that connects to many crypto exchanges with one set of commands, such as fetch_ohlcv for candles and create_order for orders.

Is CCXT safe to use?

The library itself is widely used and open source. The risk is in how you use it: protect your API keys, turn off withdrawal permission, start on a test network or dry run, and add stops and loss limits.

Does CCXT support paper trading?

CCXT can switch to an exchange's test network with set_sandbox_mode(True), but only if that exchange offers one. Otherwise, run your bot in a dry-run mode that logs orders instead of sending them.

Which exchanges work with CCXT?

About 100, including many large exchanges. Which ones you can legally use depends on where you live, so check the exchange's terms for your country.

Want the next step? We'll walk you through it.

Four free lessons by email, one every few days — each with a 10-minute exercise on a real chart.

Send Me the Free Lessons 4 short emails · No spam · Unsubscribe anytime

Or see the whole method, step by step:

See What’s Inside the Course Try everything free first. Decide when you're ready. · Open the free chart tool (works in the TradingView phone app)

One chart idea a day, in plain English. Follow along:

Follow on XFollow on TradingView