/new-exchange
Scaffold a new CCXT exchange integration in TypeScript, following the certified-exchange template. Walks through describe(), required unified methods, parsers, capability flags, sandbox setup, and static fixtures. Use when adding support for an exchange that does not exist yet
Claude Code
$ npx -y skills add ccxt/ccxt --skill new-exchange --agent claude-code
Codex
$ npx skills add ccxt/ccxt --skill new-exchange -a codex -y
Cursor
$ npx skills add ccxt/ccxt --skill new-exchange -a cursor -y
Gemini CLI
$ npx skills add ccxt/ccxt --skill new-exchange -a gemini-cli -y
GitHub Copilot
$ npx skills add ccxt/ccxt --skill new-exchange -a github-copilot -y
OpenCode
$ npx skills add ccxt/ccxt --skill new-exchange -a opencode -y
Windsurf
$ npx skills add ccxt/ccxt --skill new-exchange -a windsurf -y
SKILL.md
new-exchange.SKILL.mdname: new-exchange
description: Scaffold a new CCXT exchange integration in TypeScript, following the certified-exchange template. Walks through describe(), required unified methods, parsers, capability flags, sandbox setup, and static fixtures. Use when adding support for an exchange that does not exist yet under ts/src/.
New Exchange Integration
Scaffold a new exchange in `ts/src/<id>.ts` (REST) and optionally `ts/src/pro/<id>.ts` (WebSocket).
> **Read first:** `wiki/Requirements.md` (mandatory unified methods) and `CONTRIBUTING.md` (transpiler rules). The CCXT root `CLAUDE.md` is the contributor guide.
Inputs
- `<id>`: lowercase exchange id, no separators (e.g. `mynewex`)
- `<Name>`: human-readable name (e.g. `My New Exchange`)
- API docs URL(s)
- Whether the exchange has a testnet/sandbox
Step 1 — Pick a reference exchange
Don't write from scratch. Copy a similar exchange that's already certified and adapt it.
| Style | Reference | |---|---| | Spot + futures, signed REST | `ts/src/binance.ts`, `ts/src/okx.ts` | | Spot only | `ts/src/kraken.ts`, `ts/src/coinbase.ts` | | Derivatives focus | `ts/src/bybit.ts`, `ts/src/hyperliquid.ts` | | Decentralised / on-chain signing | `ts/src/hyperliquid.ts`, `ts/src/dydx.ts` | | WebSocket reference | `ts/src/pro/binance.ts`, `ts/src/pro/okx.ts` |
Open the reference next to your new file and pattern-match — never invent new conventions.
Step 2 — Create `ts/src/<id>.ts`
Skeleton:
import Exchange from './abstract/<id>.js';
import { /* errors needed */ } from './base/errors.js';
import { Precise } from './base/Precise.js';
import type { /* types needed */ } from './base/types.js';
export default class <id> extends Exchange {
describe (): any {
return this.deepExtend (super.describe (), {
'id': '<id>',
'name': '<Name>',
'countries': [ 'XX' ],
'rateLimit': 1000, // ms between requests
'version': 'v1',
'certified': false,
'pro': false, // flip to true when pro/<id>.ts exists
'has': {
// start everything false; flip to true as you implement
'CORS': undefined,
'spot': true,
'margin': false,
'swap': false,
'future': false,
'option': false,
'fetchMarkets': true,
'fetchCurrencies': true,
'fetchTicker': true,
'fetchTickers': false,
'fetchOrderBook': true,
'fetchTrades': true,
'fetchOHLCV': false,
'fetchBalance': true,
'createOrder': true,
'cancelOrder': true,
'fetchOrder': true,
'fetchOpenOrders': true,
'fetchOrders': false,
'fetchClosedOrders': false,
'fetchMyTrades': true,
'fetchDeposits': false,
'fetchWithdrawals': false,
'withdraw': false,
},
'urls': {
'logo': 'https://...',
'api': {
'public': 'https://api.<id>.com',
'private': 'https://api.<id>.com',
},
'test': { // OPTIONAL — only if testnet exists
'public': 'https://testnet.<id>.com',
'private': 'https://testnet.<id>.com',
},
'www': 'https://<id>.com',
'doc': [ 'https://docs.<id>.com' ],
'fees': 'https://<id>.com/fees',
},
'api': {
'public': {
'get': [
'symbols',
'ticker/{pair}',
'orderbook/{pair}',
],
},
'private': {
'get': [ 'account', 'orders' ],
'post': [ 'order' ],
'delete': [ 'order/{id}' ],
},
},
'requiredCredentials': {
'apiKey': true,
'secret': true,
// 'password': true, // for passphrase-based exchanges
// 'walletAddress': true, // for on-chain
// 'privateKey': true,
},
'fees': {
'trading': {
'tierBased': false,
'percentage': true,
'maker': 0.001,
'taker': 0.001,
},
},
'precisionMode': /* TICK_SIZE | DECIMAL_PLACES | SIGNIFICANT_DIGITS */,
'options': {
// exchange-specific defaults
},
'exceptions': {
'exact': {
// 'ERROR_CODE': BadRequest,
},
'broad': {
// 'invalid signature': AuthenticationError,
},
},
});
}
// implement the unified methods you flipped on in `has`
async fetchMarkets (params = {}): Promise<Market[]> { /* ... */ }
parseMarket (market: Dict): Market { /* ... */ }
async fetchTicker (symbol: string, params = {}): Promise<Ticker> { /* ... */ }
parseTicker (ticker: Dict, market: Market = undefined): Ticker { /* ... */ }
// ...
sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
// build URL, sign request — use this.hmac, this.jwt, this.ecdsa, never external libs
}
handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
// throw the right exception based on response
}
}Step 3 — Define implicit API methods
URLs in the `api` block become methods automatically:
- `'symbols'` → `this.publicGetSymbols(params)`
- `'ticker/{pa
Read more
name: new-exchange description: Scaffold a new CCXT exchange integration in TypeScript, following the certified-exchange template. Walks through describe(), required unified methods, parsers, capability flags, sandbox setup, and static fixtures. Use when adding support for an exchange that does not exist yet under ts/src/.
New Exchange Integration
Scaffold a new exchange in `ts/src/<id>.ts` (REST) and optionally `ts/src/pro/<id>.ts` (WebSocket).
> **Read first:** `wiki/Requirements.md` (mandatory unified methods) and `CONTRIBUTING.md` (transpiler rules). The CCXT root `CLAUDE.md` is the contributor guide.
Inputs
- `<id>`: lowercase exchange id, no separators (e.g. `mynewex`)
- `<Name>`: human-readable name (e.g. `My New Exchange`)
- API docs URL(s)
- Whether the exchange has a testnet/sandbox
Step 1 — Pick a reference exchange
Don't write from scratch. Copy a similar exchange that's already certified and adapt it.
| Style | Reference | |---|---| | Spot + futures, signed REST | `ts/src/binance.ts`, `ts/src/okx.ts` | | Spot only | `ts/src/kraken.ts`, `ts/src/coinbase.ts` | | Derivatives focus | `ts/src/bybit.ts`, `ts/src/hyperliquid.ts` | | Decentralised / on-chain signing | `ts/src/hyperliquid.ts`, `ts/src/dydx.ts` | | WebSocket reference | `ts/src/pro/binance.ts`, `ts/src/pro/okx.ts` |
Open the reference next to your new file and pattern-match — never invent new conventions.
Step 2 — Create `ts/src/<id>.ts`
Skeleton:
import Exchange from './abstract/<id>.js';
import { /* errors needed */ } from './base/errors.js';
import { Precise } from './base/Precise.js';
import type { /* types needed */ } from './base/types.js';
export default class <id> extends Exchange {
describe (): any {
return this.deepExtend (super.describe (), {
'id': '<id>',
'name': '<Name>',
'countries': [ 'XX' ],
'rateLimit': 1000, // ms between requests
'version': 'v1',
'certified': false,
'pro': false, // flip to true when pro/<id>.ts exists
'has': {
// start everything false; flip to true as you implement
'CORS': undefined,
'spot': true,
'margin': false,
'swap': false,
'future': false,
'option': false,
'fetchMarkets': true,
'fetchCurrencies': true,
'fetchTicker': true,
'fetchTickers': false,
'fetchOrderBook': true,
'fetchTrades': true,
'fetchOHLCV': false,
'fetchBalance': true,
'createOrder': true,
'cancelOrder': true,
'fetchOrder': true,
'fetchOpenOrders': true,
'fetchOrders': false,
'fetchClosedOrders': false,
'fetchMyTrades': true,
'fetchDeposits': false,
'fetchWithdrawals': false,
'withdraw': false,
},
'urls': {
'logo': 'https://...',
'api': {
'public': 'https://api.<id>.com',
'private': 'https://api.<id>.com',
},
'test': { // OPTIONAL — only if testnet exists
'public': 'https://testnet.<id>.com',
'private': 'https://testnet.<id>.com',
},
'www': 'https://<id>.com',
'doc': [ 'https://docs.<id>.com' ],
'fees': 'https://<id>.com/fees',
},
'api': {
'public': {
'get': [
'symbols',
'ticker/{pair}',
'orderbook/{pair}',
],
},
'private': {
'get': [ 'account', 'orders' ],
'post': [ 'order' ],
'delete': [ 'order/{id}' ],
},
},
'requiredCredentials': {
'apiKey': true,
'secret': true,
// 'password': true, // for passphrase-based exchanges
// 'walletAddress': true, // for on-chain
// 'privateKey': true,
},
'fees': {
'trading': {
'tierBased': false,
'percentage': true,
'maker': 0.001,
'taker': 0.001,
},
},
'precisionMode': /* TICK_SIZE | DECIMAL_PLACES | SIGNIFICANT_DIGITS */,
'options': {
// exchange-specific defaults
},
'exceptions': {
'exact': {
// 'ERROR_CODE': BadRequest,
},
'broad': {
// 'invalid signature': AuthenticationError,
},
},
});
}
// implement the unified methods you flipped on in `has`
async fetchMarkets (params = {}): Promise<Market[]> { /* ... */ }
parseMarket (market: Dict): Market { /* ... */ }
async fetchTicker (symbol: string, params = {}): Promise<Ticker> { /* ... */ }
parseTicker (ticker: Dict, market: Market = undefined): Ticker { /* ... */ }
// ...
sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
// build URL, sign request — use this.hmac, this.jwt, this.ecdsa, never external libs
}
handleErrors (httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody) {
// throw the right exception based on response
}
}Step 3 — Define implicit API methods
URLs in the `api` block become methods automatically:
- `'symbols'` → `this.publicGetSymbols(params)`
- `'ticker/{pa
A crypto trading API with more than 100 exchanges and prediction markets in JavaScript / TypeScript / Python / C# / PHP / Go / Java / Rust.
Other skills on ccxt.
More skills from other plugins.
3-statement-model
Complete, populate and fill out 3-statement financial model templates (Income Statement, Balance Sheet, Cash Flow Statement) .…
3-statement-model
Complete, populate and fill out 3-statement financial model templates (Income Statement, Balance Sheet, Cash Flow Statement) .…
eli5
Explain a topic like I'm a 5 year old. Use when the user types /eli5 <topic> or asks for a dead-simple picture explainer of how…
Questions about new-exchange.
- Which coding agents can use new-exchange?
- new-exchange installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

