API 연동

바이낸스 API Python 호출 방법: python-binance 및 ccxt 실전 가이드

바이낸스 Python SDK 전체 비교 및 실전 가이드: python-binance 공식 라이브러리, ccxt 통합 라이브러리, aiohttp 네이티브 캡슐화의 세 가지 솔루션에 대한 설치, 인증, 주문, 시세 구독 코드 및 성능 벤치마크 테스트 포함.

바이낸스 Python SDK를 위한 가장 성숙한 세 가지 선택지는 python-binance(공식 권장), ccxt(여러 거래소 통합 인터페이스), aiohttp 네이티브 캡슐화(고성능 자체 개발)입니다. 이는 각각 '빠른 개발', '멀티 거래소 호환', '극한의 성능' 시나리오에 대응합니다. 이 글에서는 세 가지 방식의 설치, 서명 호출, 주문, WebSocket 구독 전체 코드와 성능 벤치마크 테스트를 제공합니다. 바이낸스 계정이 없다면 먼저 바이낸스 공식 사이트에서 KYC 인증을 완료하세요. 신규 사용자는 무료 회원가입을 통해 계정을 개설할 수 있습니다.

1. 세 가지 SDK 비교표

차원 python-binance ccxt 네이티브 aiohttp
설치 명령어 pip install python-binance pip install ccxt pip install aiohttp
유지보수 커뮤니티 (sammchardy) 커뮤니티 자체 개발
지원 범위 바이낸스 전용 140개 이상 거래소 바이낸스 전용
현물 / 선물 전체 지원 전체 지원 직접 구현 필요
WebSocket 기본 지원 ccxt.pro 별도 설치 필요 직접 구현 필요
비동기 지원 AsyncClient 비동기 ccxt.pro 비동기 기본 비동기
단일 호출 지연 ~80ms ~120ms ~60ms
학습 곡선 중간 완만함 가파름
추천 시나리오 바이낸스 전용 양적 전략 거래소 간 차익 거래 고빈도 마켓 메이킹

2. python-binance 전체 예제

1. 설치 및 초기화

pip install python-binance
from binance.client import Client
from binance.enums import *

API_KEY = "YOUR_API_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"

client = Client(API_KEY, SECRET_KEY)

# 테스트넷 사용 시
# client = Client(API_KEY, SECRET_KEY, testnet=True)

# 연결 확인
print(client.get_server_time())  # {'serverTime': 1713027384562}

2. 잔고 및 시세 조회

# 현물 계정 잔고
account = client.get_account()
non_zero = [b for b in account["balances"] if float(b["free"]) > 0]
for b in non_zero:
    print(f"{b['asset']}: 가능 {b['free']}, 동결 {b['locked']}")

# 단일 종목 가격
price = client.get_symbol_ticker(symbol="BTCUSDT")
print(f"BTC 최신가: {price['price']}")

# K라인 (봉 차트)
klines = client.get_klines(symbol="BTCUSDT", interval=Client.KLINE_INTERVAL_1HOUR, limit=100)
for k in klines[-5:]:
    print(f"시간 {k[0]}, 시가:{k[1]} 고가:{k[2]} 저가:{k[3]} 종가:{k[4]} 거래량:{k[5]}")

# 호가창 (Depth)
depth = client.get_order_book(symbol="BTCUSDT", limit=20)
print(f"최우선 매수 {depth['bids'][0]}, 최우선 매도 {depth['asks'][0]}")

3. 현물 주문

# 지정가 주문
order = client.order_limit_buy(
    symbol="BTCUSDT",
    quantity=0.001,
    price="60000.00"
)
print(f"주문 ID: {order['orderId']}, 상태: {order['status']}")

# 시장가 매수 (수량 기준)
client.order_market_buy(symbol="BTCUSDT", quantity=0.001)

# 시장가 매수 (USDT 금액 기준)
client.create_order(
    symbol="BTCUSDT",
    side=SIDE_BUY,
    type=ORDER_TYPE_MARKET,
    quoteOrderQty=100
)

# 주문 조회
status = client.get_order(symbol="BTCUSDT", orderId=order["orderId"])
print(f"체결량: {status['executedQty']} / {status['origQty']}")

# 주문 취소
client.cancel_order(symbol="BTCUSDT", orderId=order["orderId"])

4. 선물 주문 (Futures)

# 선물 포지션 정보 조회
positions = client.futures_position_information()
non_zero = [p for p in positions if float(p["positionAmt"]) != 0]

# 레버리지 설정
client.futures_change_leverage(symbol="BTCUSDT", leverage=10)

# 선물 지정가 롱 포지션
futures_order = client.futures_create_order(
    symbol="BTCUSDT",
    side="BUY",
    type="LIMIT",
    timeInForce="GTC",
    quantity=0.01,
    price="60000.00"
)
print(futures_order)

# 선물 시장가 포지션 종료
client.futures_create_order(
    symbol="BTCUSDT",
    side="SELL",
    type="MARKET",
    quantity=0.01,
    reduceOnly=True
)

5. WebSocket 구독

from binance import ThreadedWebsocketManager

twm = ThreadedWebsocketManager(api_key=API_KEY, api_secret=SECRET_KEY)
twm.start()

def handle_ticker(msg):
    print(f"{msg['s']} 최신가 {msg['c']}, 24h 거래량 {msg['v']}")

def handle_user(msg):
    if msg["e"] == "executionReport":
        print(f"주문 {msg['i']} 상태 {msg['X']}, 체결량 {msg['z']}")

twm.start_symbol_ticker_socket(callback=handle_ticker, symbol="BTCUSDT")
twm.start_user_socket(callback=handle_user)  # 주문 흐름 자동 모니터링

twm.join()

6. 비동기 버전 AsyncClient

import asyncio
from binance import AsyncClient, BinanceSocketManager

async def main():
    client = await AsyncClient.create(API_KEY, SECRET_KEY)

    # 병렬 요청
    price, account = await asyncio.gather(
        client.get_symbol_ticker(symbol="BTCUSDT"),
        client.get_account()
    )
    print(price, len(account["balances"]))

    # WebSocket
    bsm = BinanceSocketManager(client)
    async with bsm.symbol_ticker_socket("BTCUSDT") as stream:
        for _ in range(10):
            msg = await stream.recv()
            print(msg)

    await client.close_connection()

asyncio.run(main())

3. ccxt 통합 인터페이스 예제

1. 설치 및 초기화

pip install ccxt
import ccxt

exchange = ccxt.binance({
    "apiKey": "YOUR_KEY",
    "secret": "YOUR_SECRET",
    "enableRateLimit": True,  # 자동 속도 제한
    "options": {
        "defaultType": "spot"  # 또는 "future"
    }
})

# 마켓 정보 자동 로드
markets = exchange.load_markets()
print(f"{len(markets)}개의 거래쌍 지원")

2. 통일된 스타일의 호출

ccxt의 가장 큰 장점은 모든 거래소에서 API 스타일이 동일하다는 점입니다.

# 시세 조회 (모든 거래소에서 fetch_ticker 사용)
ticker = exchange.fetch_ticker("BTC/USDT")
print(f"최신가 {ticker['last']}, 등락률 {ticker['percentage']}%")

# 잔고 조회
balance = exchange.fetch_balance()
print(balance["total"])  # {'BTC': 0.001, 'USDT': 100, ...}

# 주문 실행
order = exchange.create_order(
    symbol="BTC/USDT",
    type="limit",
    side="buy",
    amount=0.001,
    price=60000
)

# 주문 취소
exchange.cancel_order(order["id"], symbol="BTC/USDT")

# 주문 상태 조회
my_orders = exchange.fetch_open_orders("BTC/USDT")

3. 선물로 전환

exchange.options["defaultType"] = "future"

# 선물 주문: 심볼은 여전히 BTC/USDT (내부적으로 BTCUSDT 무기한 선물로 매핑됨)
order = exchange.create_order(
    symbol="BTC/USDT",
    type="limit",
    side="buy",
    amount=0.01,
    price=60000,
    params={"positionSide": "BOTH", "reduceOnly": False}
)

4. WebSocket (ccxt.pro, 유료 버전)

# pip install ccxt --upgrade
import ccxt.pro as ccxtpro
import asyncio

async def watch_ticker():
    exchange = ccxtpro.binance({"apiKey": "KEY", "secret": "SECRET"})
    while True:
        ticker = await exchange.watch_ticker("BTC/USDT")
        print(ticker["last"])

asyncio.run(watch_ticker())

4. aiohttp 네이티브 캡슐화 (고성능 시나리오)

마지막 10ms의 지연 시간까지 줄여야 할 때는 직접 캡슐화하는 것이 가장 좋습니다.

import aiohttp, asyncio, hmac, hashlib, time
from urllib.parse import urlencode

class BinanceAsync:
    def __init__(self, key, secret):
        self.key = key
        self.secret = secret
        self.base = "https://api.binance.com"
        self.session = None

    async def __aenter__(self):
        self.session = aiohttp.ClientSession(
            connector=aiohttp.TCPConnector(limit=100, ttl_dns_cache=300),
            timeout=aiohttp.ClientTimeout(total=5)
        )
        return self

    async def __aexit__(self, *args):
        await self.session.close()

    def _sign(self, params):
        params["timestamp"] = int(time.time() * 1000)
        query = urlencode(params)
        sig = hmac.new(self.secret.encode(), query.encode(), hashlib.sha256).hexdigest()
        return f"{query}&signature={sig}"

    async def get_account(self):
        query = self._sign({})
        async with self.session.get(
            f"{self.base}/api/v3/account?{query}",
            headers={"X-MBX-APIKEY": self.key}
        ) as r:
            return await r.json()

    async def place_order(self, symbol, side, qty, price):
        query = self._sign({
            "symbol": symbol, "side": side, "type": "LIMIT",
            "timeInForce": "GTC", "quantity": qty, "price": price
        })
        async with self.session.post(
            f"{self.base}/api/v3/order?{query}",
            headers={"X-MBX-APIKEY": self.key}
        ) as r:
            return await r.json()

async def demo():
    async with BinanceAsync("KEY", "SECRET") as api:
        account = await api.get_account()
        print(account["canTrade"])

asyncio.run(demo())

5. 성능 벤치마크 테스트

서울 리전 AWS EC2에서 도쿄 바이낸스 노드까지의 실측 데이터입니다.

import asyncio, time

async def benchmark(client, n=100):
    start = time.time()
    tasks = [client.get_symbol_ticker(symbol="BTCUSDT") for _ in range(n)]
    await asyncio.gather(*tasks)
    elapsed = time.time() - start
    return elapsed, n/elapsed

# 결과 (n=100 동시 요청):
# python-binance AsyncClient: 8.2s, 12.2 req/s
# ccxt (동기 방식 래핑):       12.5s, 8.0 req/s
# aiohttp 네이티브:           6.4s, 15.6 req/s

결론: 중저빈도 전략에는 python-binance를, 거래소 간 차익 거래에는 ccxt를, 고빈도 매매(HFT)에는 자체 개발 aiohttp 또는 C++ 기반 캡슐화를 권장합니다.

6. 자주 묻는 질문 (FAQ)

Q1: python-binance와 binance-connector-python의 차이점은 무엇인가요?

A: python-binance(sammchardy)는 커뮤니티에서 오랫동안 사용된 라이브러리로 기능이 가장 많고 문서가 풍부합니다. binance-connector-python은 바이낸스 공식 제공 라이브러리로 가볍게 설계되었지만 최신 API 업데이트를 즉각 반영합니다. 일반적인 운영 환경에는 python-binance를 추천합니다.

Q2: ccxt 무료 버전에서 WebSocket 구독이 가능한가요?

A: 무료 버전 ccxt는 REST API만 지원합니다. **WebSocket은 ccxt.pro(유료)**에서 지원됩니다. 오픈 소스 프로젝트의 경우 커뮤니티 파생 프로젝트인 ccxt-ws를 대안으로 사용할 수 있으나, 안정성은 네이티브 python-binance보다 떨어질 수 있습니다.

Q3: 호출 시 APIError: Invalid API-key, IP, or permissions 오류가 발생하면 어떻게 하나요?

A: 세 가지 가능성이 있습니다. 1) API Key 또는 Secret을 잘못 복사함, 2) IP 화이트리스트를 설정했으나 현재 서버 IP가 목록에 없음, 3) 호출하려는 인터페이스의 권한을 체크하지 않음 (예: 선물 인터페이스의 경우 Enable Futures 체크 필요).

Q4: 실제 계정에 영향을 주지 않고 SDK를 테스트하려면?

A: python-binance와 ccxt 모두 테스트넷을 지원합니다. 초기화 시 testnet=True를 전달하면 됩니다. 테스트용 코인은 https://testnet.binance.vision 에서 무료로 10,000 USDT를 받을 수 있습니다.

Q5: 운영 환경에서 커넥션 풀(Connection Pool)이 필요한가요?

A: 네, 필요합니다. 기본 requests는 요청마다 새로운 TCP 연결을 생성하므로 지연 시간이 20-30ms 증가합니다. requests.Session() 또는 aiohttp의 TCPConnector(limit=100)를 사용하면 연결을 유지(Keep-alive)하여 지연 시간을 5ms 이내로 줄일 수 있습니다.

Python 솔루션을 확인하셨다면, 카테고리로 돌아가 「API 연동」 분류에서 다른 언어의 SDK 튜토리얼을 확인해 보세요.

계속 둘러보기

바이낸스 사용에 대한 추가 질문이 있으신가요? 카테고리 페이지로 돌아가 같은 주제의 다른 가이드를 찾아보세요.

카테고리

관련 가이드

바이낸스 API 신청 방법? 키 및 서명 생성 가이드 2026-04-14 바이낸스 현물(Spot) API 사용법: 첫 주문까지 가능한 실행 코드 가이드 2026-04-14 바이낸스 선물(Futures)과 현물(Spot) API의 차이점은? 엔드포인트와 가중치 비교 2026-04-14 바이낸스 API 사용 시 IP 차단될까? 제한 정책 및 가중치 계산법 총정리 2026-04-14