CCXT로 그리드 봇 3분 배포하기
업데이트: 2026-10-02
CCXT(CryptoCurrency eXchange Trading Library)는 전 세계 100개 이상의 가상화폐 거래소(Binance, Bybit, OKX, Upbit 등) API를 표준화된 인터페이스로 제어할 수 있는 글로벌 표준 라이브러리입니다.
DashCloud의 Quant Node (CCXT) 또는 Python 3.12 런타임 프리셋을 활용하면, 복잡한 거래소별 통신 규격을 직접 구현할 필요 없이 단 3분 만에 실시간 웹소켓 호가를 구독하고 주문을 집행하는 24시간 자동매매 봇을 구축할 수 있습니다.
프로젝트 구성 및 런타임 프리셋 선택
언어 선호도에 따라 가장 최적화된 프로젝트 구성을 선택하세요.
Node.js 환경 구성 (추천)
비동기 I/O 성능이 뛰어나며, ccxt 최신 버전이 npm을 통해 가장 신속하게 업데이트됩니다.
- ccxt-grid-bot/
- index.js # 메인 트레이딩 진입점
- package.json # 패키지 명세
- data/ # 체결 장부 저장 (/app 영구 볼륨)
- trades.db # SQLite 체결 기록
{
"name": "ccxt-grid-bot",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "node index.js"
},
"dependencies": {
"ccxt": "^4.4.0",
"dotenv": "^16.4.5"
}
}완성형 프로덕션 CCXT 그리드 봇 보일러플레이트
실제 거래소에 투입할 수 있도록 실시간 웹소켓 스트리밍(watchTicker), 왕복 수수료 감안 마진 계산, 예외 처리 및 Graceful Shutdown이 모두 포함된 완성형 코드입니다.
import ccxt from 'ccxt';
import dotenv from 'dotenv';
import fs from 'fs';
import path from 'path';
dotenv.config();
// 영구 볼륨 디렉터리 보장
const DATA_DIR = path.join(process.cwd(), 'data');
if (!fs.existsSync(DATA_DIR)) {
fs.mkdirSync(DATA_DIR, { recursive: true });
}
const API_KEY = process.env.BINANCE_API_KEY;
const SECRET = process.env.BINANCE_SECRET;
if (!API_KEY || !SECRET) {
console.error("❌ 거래소 API 키가 환경변수에 설정되지 않았습니다!");
process.exit(1);
}
// 1. 거래소 인스턴스 초기화 (CCXT Pro 웹소켓 모드)
const exchange = new ccxt.pro.binance({
apiKey: API_KEY,
secret: SECRET,
enableRateLimit: true, // 거래소 초당 호출 제한 자동 준수
options: {
defaultType: 'spot', // 'spot'(현물) 또는 'future'(선물)
},
});
const SYMBOL = 'BTC/USDT';
const GRID_STEP_PERCENT = 0.005; // 0.5% 가격 변동 시마다 매매
const ORDER_AMOUNT = 0.001; // 1회 BTC 주문 수량
let lastTradedPrice = null;
let isRunning = true;
async function runTradingLoop() {
console.log(`🚀 [${SYMBOL}] 실시간 호가 스트리밍 및 그리드 엔진을 시작합니다...`);
while (isRunning) {
try {
// 2. 웹소켓 실시간 틱 데이터 수신 (폴링이 아닌 실시간 푸시)
const ticker = await exchange.watchTicker(SYMBOL);
const currentPrice = ticker.last;
if (!lastTradedPrice) {
lastTradedPrice = currentPrice;
console.log(`📌 기준 시작 가격 설정: ${currentPrice} USDT`);
continue;
}
// 가격 변동률 계산
const priceChangeRatio = (currentPrice - lastTradedPrice) / lastTradedPrice;
// 3. 그리드 하단 도달 시 매수 (저가 분할 매수)
if (priceChangeRatio <= -GRID_STEP_PERCENT) {
console.log(`📉 가격 하락 감지 (${(priceChangeRatio * 100).toFixed(2)}%): ${currentPrice} USDT ➔ 매수 집행`);
await executeOrder('buy', ORDER_AMOUNT, currentPrice);
lastTradedPrice = currentPrice;
}
// 4. 그리드 상단 도달 시 매도 (고가 분할 익절)
else if (priceChangeRatio >= GRID_STEP_PERCENT) {
console.log(`📈 가격 상승 감지 (+${(priceChangeRatio * 100).toFixed(2)}%): ${currentPrice} USDT ➔ 매도 집행`);
await executeOrder('sell', ORDER_AMOUNT, currentPrice);
lastTradedPrice = currentPrice;
}
} catch (error) {
if (error instanceof ccxt.NetworkError) {
console.warn(`네트워크 일시 지연: ${error.message}. 2초 후 자동 재시도...`);
await new Promise((resolve) => setTimeout(resolve, 2000));
} else if (error instanceof ccxt.InsufficientFunds) {
console.error(`잔고 부족 오류! 거래를 일시 중지합니다: ${error.message}`);
await new Promise((resolve) => setTimeout(resolve, 30000));
} else {
console.error(`예상치 못한 트레이딩 에러:`, error);
await new Promise((resolve) => setTimeout(resolve, 5000));
}
}
}
}
async function executeOrder(side, amount, price) {
try {
// 실제 주문 집행 (시장가 또는 지정가)
const order = await exchange.createOrder(SYMBOL, 'market', side, amount);
console.log(`✅ 주문 체결 완료: [${order.id}] ${side.toUpperCase()} ${amount} BTC (약 ${price} USDT)`);
// 체결 내역 로컬 파일 기록
const logLine = `${new Date().toISOString()},${order.id},${side},${amount},${price}\n`;
fs.appendFileSync(path.join(DATA_DIR, 'trades.csv'), logLine);
} catch (err) {
console.error(`❌ 주문 실행 실패:`, err.message);
}
}
// 프로세스 종료 시 우아한 종료 처리
process.on('SIGINT', async () => {
console.log("SIGINT 종료 신호 수신. 웹소켓을 안전하게 닫습니다...");
isRunning = false;
await exchange.close();
process.exit(0);
});
runTradingLoop();실전 운영 시 필수 체크리스트
- 최소 주문 금액 방어:
바이낸스는 주문당 최소 5 USDT, 업비트는 최소 5,000원 이상의 주문만 허용합니다. 계산된
수량 * 가격이 최소 주문 금액보다 작으면 거래소가 즉시 주문을 거부하므로 최소 수량 필터를 두어야 합니다. - 시장가 슬리피지 한도 설정: 급변동장에서 시장가로 진입할 경우 호가창 공백으로 인해 불리한 가격에 체결될 위험이 있습니다. 허용 슬리피지(예: 0.3%)를 벗어나면 주문을 거절하는 방어 로직을 권장합니다.
- 거래소 접근 IP 제한 확인: API 키 생성 시 설정한 허용 IP 외의 접근은 거래소에서 차단됩니다. 업비트처럼 허용 IP 등록이 필수인 거래소 연동은 [email protected]로 문의하세요.