Crypto · 10/29/2025
Adaptateur exchange (CCXT)

Espace publicitaire (in-article 1)
// src/broker/ccxt-adapter.ts
import ccxt from 'ccxt'
export type OrderParams = { symbol: string; side: 'buy' | 'sell'; amount: number; price?: number; type?: 'market'|'limit'; clientOrderId?: string }
export type OrderInfo = { id: string; status: string; filled: number; price?: number }
export class CcxtAdapter {
private ex: ccxt.Exchange
constructor(opts: { id: string; apiKey: string; secret: string; testnet?: boolean }) {
const { id, apiKey, secret, testnet } = opts
const cls = (ccxt as any)[id]
if (!cls) throw new Error(`Exchange ${id} non supporté par CCXT`)
this.ex = new cls({
apiKey, secret,
enableRateLimit: true,
options: testnet ? { defaultType: 'future' } : {},
})
if (id.includes('binance') && testnet) {
// endpoints testnet (ex: binance futures)
;(this.ex as any).urls['api'] = { public: 'https://testnet.binancefuture.com/fapi', private: 'https://testnet.binancefuture.com/fapi' }
}
}
async fetchOHLCV(symbol: string, timeframe: string, limit = 200) {
return this.ex.fetchOHLCV(symbol, timeframe, undefined, limit) // [t,o,h,l,c,v]
}
async balanceUSDT(): Promise<number> {
const b = await this.ex.fetchBalance()
return (b['USDT']?.free ?? 0) + (b['USDT']?.total ?? 0) - (b['USDT']?.used ?? 0)
}
async createOrder(p: OrderParams): Promise<OrderInfo> {
const type = p.type || 'market'
const order = await this.ex.createOrder(p.symbol, type, p.side, p.amount, p.price, { newClientOrderId: p.clientOrderId })
return { id: order.id, status: order.status ?? 'open', filled: order.filled ?? 0, price: order.price }
}
}
Espace publicitaire (in-article 2)



