바이낸스 선물(Futures) API와 현물(Spot) API의 근본적인 차이는 베이스 도메인과 파라미터 세트입니다. 현물은 api.binance.com/api/v3/*를 사용하고, 선물 USDⓈ-M은 fapi.binance.com/fapi/v1/*, 선물 Coin-M은 dapi.binance.com/dapi/v1/*를 사용합니다. 서명 알고리즘은 HMAC-SHA256으로 동일하지만, 선물은 reduceOnly, positionSide, leverage 등의 추가 파라미터가 필요하며 가중치 규칙도 다릅니다. 본문에서는 10가지 차원에서의 비교표와 실제 코드를 제공하여 현물 양적 거래 전략을 선물로 매끄럽게 이전할 수 있도록 돕습니다. 바이낸스 계정이 없다면 먼저 바이낸스 공식 사이트에서 가입을 완료하세요. 신규 사용자는 무료 가입 통로를 통해 계정을 개설할 수 있습니다.
1. 기초 비교 개요표
| 항목 | 현물 (Spot) | 선물 USDⓈ-M | 선물 Coin-M |
|---|---|---|---|
| 베이스 URL | api.binance.com | fapi.binance.com | dapi.binance.com |
| 경로 접두사 | /api/v3/ | /fapi/v1/ 및 /fapi/v2/ | /dapi/v1/ |
| 증거금 코인 | — | USDT, USDC | BTC, ETH, BNB 등 (Coin-M) |
| 최대 레버리지 | 미지원 (마진 대출만 가능) | 125x | 125x |
| 양방향 포지션 | 미지원 | 지원 (HEDGE 모드) | 지원 |
| WebSocket URL | stream.binance.com:9443 | fstream.binance.com | dstream.binance.com |
| 최소 주문 금액 | 5 USDT (MIN_NOTIONAL) | 5 USDT | 명목 가치 기준 (코인별 상이) |
| 펀딩비 (Funding Rate) | 없음 | 8시간마다 정산 | 8시간마다 정산 |
| 분당 가중치 제한 | 6000 | 2400 | 2400 |
| listenKey 유효 기간 | 60분 | 60분 | 60분 |
핵심 포인트: USDⓈ-M 엔드포인트는 항상 fapi로 시작하고, Coin-M은 dapi로 시작합니다. 현물 코드를 URL만 바꿔서 사용하지 않도록 주의하세요.
2. 서명 메커니즘의 미세한 차이
서명 알고리즘은 HMAC-SHA256으로 완전히 동일하지만, 다음 두 가지를 주의해야 합니다:
1. recvWindow 기본값 차이
- 현물: 기본 5000ms, 최대 60000ms
- 선물: 기본 5000ms, 최대 60000ms이지만 공식적으로는 5000ms 이하를 강력히 권장
2. 수치 파라미터는 문자열 권장
선물 API는 수치 정밀도에 더 민감합니다. 주문 시 price와 quantity는 문자열(string) 형태로 전달하는 것이 좋습니다. 이는 부동 소수점 오차로 인한 -1111 Precision 오류를 방지하기 위함입니다:
# 비권장
{"price": 60000.123456789, "quantity": 0.001}
# 권장 (문자열 사용)
{"price": "60000.12", "quantity": "0.001"}
3. 포지션 및 잔액 조회 인터페이스 차이
현물 잔액 (Spot Balance)
# 현물: GET /api/v3/account
# balances 배열 반환
{
"balances": [{"asset": "USDT", "free": "1000", "locked": "0"}]
}
선물 USDⓈ-M 포지션 (Futures Position)
import hmac, hashlib, time, requests
from urllib.parse import urlencode
API_KEY = "YOUR_KEY"
SECRET_KEY = "YOUR_SECRET"
FAPI = "https://fapi.binance.com"
def _sign(params):
params["timestamp"] = int(time.time() * 1000)
query = urlencode(params)
params["signature"] = hmac.new(SECRET_KEY.encode(), query.encode(), hashlib.sha256).hexdigest()
return params
def get_positions():
"""V2 포지션 조회: 0이 아닌 모든 포지션 반환"""
params = _sign({})
r = requests.get(f"{FAPI}/fapi/v2/positionRisk", params=params,
headers={"X-MBX-APIKEY": API_KEY})
return [p for p in r.json() if float(p["positionAmt"]) != 0]
def get_futures_balance():
"""V2 선물 계정 잔액"""
params = _sign({})
r = requests.get(f"{FAPI}/fapi/v2/balance", params=params,
headers={"X-MBX-APIKEY": API_KEY})
return r.json()
positions = get_positions()
for p in positions:
print(f"{p['symbol']}: 수량 {p['positionAmt']}, 진입가 {p['entryPrice']}, 미실현 손익 {p['unRealizedProfit']}")
4. 주문 파라미터 비교
현물 주문은 보통 4~5개의 파라미터만 필요하지만, 선물은 포지션 방향, 감소 전용 여부, 자가 거래 방지 등의 추가 필드가 필요합니다:
| 파라미터 | 현물 (Spot) | 선물 (Futures) |
|---|---|---|
| symbol | 필수 | 필수 |
| side | BUY / SELL | BUY / SELL |
| type | LIMIT/MARKET/... | LIMIT/MARKET/STOP/TAKE_PROFIT/TRAILING_STOP_MARKET |
| quantity | 필수 | 필수 (또는 closePosition 사용) |
| positionSide | — | BOTH (단방향) / LONG / SHORT (양방향) |
| reduceOnly | — | true 설정 시 감소 전용 주문 |
| closePosition | — | true 설정 시 일괄 청산 |
| workingType | — | MARK_PRICE / CONTRACT_PRICE |
| newOrderRespType | ACK/RESULT/FULL | ACK/RESULT |
선물 지정가 주문 예시
def place_futures_limit(symbol, side, quantity, price, position_side="BOTH"):
params = _sign({
"symbol": symbol,
"side": side,
"type": "LIMIT",
"timeInForce": "GTC",
"quantity": str(quantity),
"price": str(price),
"positionSide": position_side,
})
r = requests.post(f"{FAPI}/fapi/v1/order", params=params,
headers={"X-MBX-APIKEY": API_KEY})
return r.json()
# BTC 0.01 롱 포지션 오픈, 지정가 60000
order = place_futures_limit("BTCUSDT", "BUY", 0.01, 60000)
print(order["orderId"])
5. 레버리지 및 증거금 모드 설정
선물 전용 설정 인터페이스:
# 레버리지 배수 설정
def set_leverage(symbol: str, leverage: int):
params = _sign({"symbol": symbol, "leverage": leverage})
r = requests.post(f"{FAPI}/fapi/v1/leverage", params=params,
headers={"X-MBX-APIKEY": API_KEY})
return r.json()
set_leverage("BTCUSDT", 10) # 10배 레버리지 설정
# 증거금 모드 설정: ISOLATED (격리) 또는 CROSSED (교차)
def set_margin_type(symbol: str, margin_type: str):
params = _sign({"symbol": symbol, "marginType": margin_type})
r = requests.post(f"{FAPI}/fapi/v1/marginType", params=params,
headers={"X-MBX-APIKEY": API_KEY})
return r.json()
set_margin_type("BTCUSDT", "ISOLATED")
주의: 해당 거래 페어에 포지션이 있는 상태에서는 증거금 모드를 변경할 수 없습니다. 먼저 포지션을 종료해야 합니다.
6. 펀딩비 (Funding Rate)
펀딩비는 선물 고유의 개념으로, 8시간마다 정산됩니다:
# 최신 펀딩비 조회
def get_funding_rate(symbol="BTCUSDT"):
r = requests.get(f"{FAPI}/fapi/v1/premiumIndex",
params={"symbol": symbol})
data = r.json()
return {
"markPrice": data["markPrice"],
"fundingRate": data["lastFundingRate"],
"nextFundingTime": data["nextFundingTime"]
}
# 과거 펀딩비 내역 조회
def funding_history(symbol, limit=100):
r = requests.get(f"{FAPI}/fapi/v1/fundingRate",
params={"symbol": symbol, "limit": limit})
return r.json()
차익거래 팁: 펀딩비가 양수(+)이면 롱 포지션이 숏 포지션에게 지급하고, 음수(-)이면 반대입니다. 고율의 양수 펀딩비가 지속될 때 '선물 숏 + 현물 롱'은 흔히 사용되는 펀딩비 차익거래 전략입니다.
7. 가중치 및 요청 제한 차이
# 현물 응답 헤더
X-MBX-USED-WEIGHT-1m: 45
X-MBX-ORDER-COUNT-10s: 3
# 선물 응답 헤더
X-MBX-USED-WEIGHT-1m: 12
X-MBX-ORDER-COUNT-1m: 5
X-MBX-ORDER-COUNT-10s: 3
선물은 1분당 주문 상한 필드가 하나 더 있으며(기본 1200회/분), 고주파 매매 전략 시 중점적으로 모니터링해야 합니다.
8. WebSocket 차이점
# 현물 시세 구독
import websocket, json
def on_message(ws, msg):
data = json.loads(msg)
print(data["s"], data["c"]) # symbol, close price
# 현물 (Spot)
ws_spot = websocket.WebSocketApp(
"wss://stream.binance.com:9443/ws/btcusdt@ticker",
on_message=on_message)
# 선물 USDⓈ-M
ws_fut = websocket.WebSocketApp(
"wss://fstream.binance.com/ws/btcusdt@markPrice", # 시장 평균가(Mark Price) 푸시
on_message=on_message)
선물 전용 구독 주제: @markPrice (시장 평균가), @forceOrder (강제 청산 알림), @liquidation.
9. 현물 + 선물 병행 조작 전략 코드
헤지 전략은 종종 현물 매수 + 선물 매도(숏)를 동시에 실행해야 합니다:
import asyncio, aiohttp
async def spot_buy(session, symbol, qty):
# 실제 구현 시 서명 과정 포함 필요
async with session.post("https://api.binance.com/api/v3/order",
params={"symbol": symbol, "side": "BUY",
"type": "MARKET", "quantity": qty}) as r:
return await r.json()
async def futures_short(session, symbol, qty):
async with session.post("https://fapi.binance.com/fapi/v1/order",
params={"symbol": symbol, "side": "SELL",
"type": "MARKET", "quantity": qty}) as r:
return await r.json()
async def hedge():
async with aiohttp.ClientSession() as s:
results = await asyncio.gather(
spot_buy(s, "BTCUSDT", 0.01),
futures_short(s, "BTCUSDT", 0.01)
)
print(results)
asyncio.run(hedge())
10. 자주 묻는 질문 FAQ
Q1: 하나의 API 키로 현물과 선물을 동시에 조작할 수 있나요?
A: 네, 가능합니다. API 키 관리 페이지에서 Enable Spot & Margin Trading과 Enable Futures 권한을 각각 체크하면 됩니다. 단, 선물은 웹 사이트에서 별도로 선물 계정을 활성화하고 퀴즈를 통과해야 합니다. 그렇지 않으면 API 호출 시 -2015 Invalid API-key, IP, or permissions 오류가 발생합니다.
Q2: fapi와 dapi의 계정 잔액은 독립적인가요?
A: 그렇습니다. USDⓈ-M 선물은 독립적인 USDT/USDC 지갑을 사용하고, Coin-M 선물은 독립적인 BTC/ETH 지갑을 사용하며, 현물 지갑 또한 완전히 독립적입니다. 자금은 /sapi/v1/futures/transfer를 통해 계정 간 이체해야 합니다.
Q3: 선물 API v1과 v2의 차이점은 무엇인가요?
A: v2는 강화된 버전으로 정밀도와 필드 명칭 등이 최적화되었습니다. 포지션 및 잔액 조회는 반드시 v2를 사용해야 하며 (/fapi/v2/positionRisk, /fapi/v2/balance), 주문 및 취소는 여전히 v1 (/fapi/v1/order)에서 이루어집니다.
Q4: 통합 계정(Portfolio Margin)을 사용하려면 코드를 수정해야 하나요?
A: 통합 계정은 papi.binance.com/papi/v1/*라는 독립 도메인을 사용하며, 엔드포인트는 fapi와 유사하지만 파라미터가 약간 다릅니다. VIP 또는 자산 규모가 큰 계정에서만 지원되므로 일반 사용자는 크게 신경 쓰지 않아도 됩니다.
Q5: 선물 API 주문 최소 금액은 얼마인가요?
A: USDⓈ-M 기준 기본적으로 5 USDT 명목 가치입니다 (예: BTC 가격이 60,000일 때 최소 수량은 약 0.0001 BTC). BNBUSDT, ETHUSDT 등 인기 종목은 최저 1 USDT까지 내려갈 수도 있습니다. 자세한 내용은 GET /fapi/v1/exchangeInfo의 MIN_NOTIONAL 필터를 확인하세요.
더 많은 선물 API 주제는 카테고리의 「API 연동」 메뉴에서 확인하실 수 있습니다.