Build your first crypto trading bot in 15 minutes — in whichever language you already know

Connect to an exchange, read balances and prices, and place your first order — in JavaScript, Python, PHP, C#, Go, and Java, with safety rails on from the start.

By CCXT Team

Every trading bot starts with the same four moves: connect to an exchange, load its markets, read some data, place an order. This tutorial does exactly that — and because CCXT ships the same API in six languages, every step below is shown in all of them. Pick your tab and stay in it.

Rule zero: don't learn with real money

Before writing any code:

  • Use a testnet. Most major exchanges (Binance, Bybit, OKX, and others) offer sandbox or demo environments with play money. CCXT switches to them with a single call — setSandboxMode(true) — shown below.
  • Create API keys with withdrawals disabled and an IP allowlist. A trading bot never needs withdrawal permissions.
  • Start with the exchange's minimum order size, even on testnet, so the habits transfer.

Step 1 — install

npm install ccxt

Step 2 — connect and load markets

loadMarkets() downloads the exchange's tradable symbols, precision rules, and limits. Call it once at startup; everything else builds on it.

import ccxt from 'ccxt';

const exchange = new ccxt.binance({
    apiKey: process.env.API_KEY,
    secret: process.env.SECRET,
});
exchange.setSandboxMode(true); // testnet — remove only when you mean it

await exchange.loadMarkets();
console.log(`${exchange.id}: ${Object.keys(exchange.markets).length} markets`);

CCXT's rate limiter is on by default — requests are automatically spaced out to respect the exchange's limits, so a simple loop won't get your IP banned.

Step 3 — read the market and your balance

const ticker = await exchange.fetchTicker('BTC/USDT');
console.log('last price:', ticker.last);

const balance = await exchange.fetchBalance();
console.log('free USDT:', balance['USDT'].free);

Notice the symbol: BTC/USDT is CCXT's unified symbol format. You write the same symbol on every exchange — CCXT translates it to whatever the exchange calls it internally (BTCUSDT, XBTUSDT, BTC-USDT, ...).

Step 4 — place a limit order, then cancel it

We place a buy order 20% below the market so it won't fill while you experiment, then cancel it.

const price = exchange.priceToPrecision('BTC/USDT', ticker.last * 0.8);
const amount = 0.001;

const order = await exchange.createOrder('BTC/USDT', 'limit', 'buy', amount, price);
console.log('placed:', order.id);

await exchange.cancelOrder(order.id, 'BTC/USDT');
console.log('canceled');

Two details that separate toy scripts from real bots, both visible here:

  • Precision helpers. priceToPrecision / amountToPrecision round values to what the exchange actually accepts. Sending 26418.377777 raw gets your order rejected.
  • Always pass the symbol to cancelOrder. Many exchanges require it, and unified code should assume it's needed.

Where to go next

You now have the full loop: connect, read, act, undo. From here:

  • Never poll in a loop for live prices — use WebSockets instead, covered in Real-time market data with WebSockets.
  • Read Seven mistakes before putting real funds behind any of this.
  • The Manual documents everything the unified API offers — 100+ exchanges, spot and derivatives, public and private endpoints.