바이비트 자동매매 봇
V5 API 맞춤 제작
바이비트(Bybit)의 Linear·Inverse 선물, 현물, 옵션을 모두 다루는 자동매매 봇을 맞춤 제작합니다.
Bybit V5 API는 모든 상품을 category 파라미터 하나로 통합한 현대적 구조로, 한 봇에서 여러 상품 동시 운영도 가능합니다.
알고랩(AlgoLab) 누적 바이비트 자동매매 35건+ 제작 경험 반영.
category를 명시해야 합니다. 인증은 헤더 넷(X-BAPI-API-KEY·X-BAPI-TIMESTAMP·X-BAPI-RECV-WINDOW·X-BAPI-SIGN)이고, 서명은 타임스탬프 + API키 + recv_window + (쿼리 또는 본문)을 HMAC-SHA256으로 해시한 값입니다. 실무에서 막히는 곳은 늘 셋입니다 — ① retCode 10004(서명 불일치: 서명한 본문과 보낸 본문이 다름), ② retCode 10002(서버 시계 어긋남·recv_window 부족), ③ category 누락(BTCUSDT는 linear, BTCUSD는 inverse). 그리고 HTTP 200이어도 retCode가 0이 아니면 실패입니다.
바이비트 자동매매 주요 유형
- USDT 무기한 선물(Linear Perpetual) 트렌드 추종 — BTC·ETH 등 대형주 기반 추세 매매
- 그리드 봇 — 횡보장 심볼에 일정 간격 매수·매도 반복, 수수료 캐시백 최적화
- Inverse 선물(코인 증거금) 롱숏 — USDT 대신 코인 자체로 증거금 운영하는 고급 전략
- 옵션 전략 — Short Strangle, Iron Condor 등 옵션 조합 자동 관리
- 트레이딩뷰 웹훅 연동 — Pine Script 시그널 → Bybit 실거래 자동 전달
- 바이낸스·업비트와 차익거래 — 김치프리미엄·거래소 간 가격차 자동 실행
기술 구조
| 항목 | 사양 |
|---|---|
| API 문서 | bybit-exchange.github.io/docs/v5/intro (V5 통합) |
| 인증 | API Key + Secret + 타임스탬프 서명 (HMAC-SHA256) |
| 언어 | Python 3.10+ 64bit, 또는 pybit / ccxt 라이브러리 |
| 카테고리 파라미터 | linear (USDT 선물), inverse (코인 선물), spot (현물), option (옵션) |
| Rate Limit | API Key 당 초당 10~50회 (엔드포인트별 상이) |
| WebSocket | Public: 실시간 시세 / Private: 체결·잔고·주문 이벤트 |
| 테스트넷 | testnet.bybit.com (실거래와 동일 API, 별도 키) |
| REST 주소 | 실거래 https://api.bybit.com / 테스트넷 https://api-testnet.bybit.com — 웹 화면 주소(testnet.bybit.com)와 API 주소가 다릅니다 |
| 인증 헤더 | X-BAPI-API-KEY · X-BAPI-TIMESTAMP(밀리초) · X-BAPI-RECV-WINDOW · X-BAPI-SIGN |
| 성공 판정 | HTTP 200이 아니라 응답 본문의 retCode == 0 |
V5 API 핵심: category 파라미터: 모든 요청에 category=linear|inverse|spot|option 을 명시해야 합니다. 빠뜨리면 400 에러. 알고랩에서 제작한 봇은 심볼에 따라 자동으로 카테고리를 선택합니다.
수치 확인 캐치 — 위 표의 호출 제한(초당 10~50회)은 엔드포인트·계정 등급·시기에 따라 달라집니다. 설계 전에 Bybit 공식 API 문서에서 현재 값을 확인하시고, 코드에는 숫자를 박기보다 응답 헤더의 잔여 한도를 읽어 스스로 속도를 줄이는 구조를 두십시오.
Bybit V5 API는 실제로 어떻게 호출하나
아래는 pybit·ccxt 같은 라이브러리 없이 requests만으로 호출할 때의 최소 구조입니다. 라이브러리를 쓰더라도 인증이 막혔을 때 어디를 봐야 하는지는 이 구조를 알아야 판단할 수 있습니다.
1) 서명 만들기 — X-BAPI-SIGN
서명 대상 문자열은 네 조각을 순서대로 이어 붙인 것입니다: timestamp + api_key + recv_window + (GET이면 쿼리 문자열, POST면 본문 JSON). 이걸 API Secret을 키로 HMAC-SHA256 해시한 뒤 16진수 문자열로 만듭니다.
import time, hmac, hashlib, json, requests
BASE = "https://api.bybit.com" # 테스트넷: https://api-testnet.bybit.com
KEY = "YOUR_API_KEY"
SECRET = "YOUR_API_SECRET"
RECV = "5000" # 밀리초
def _sign(payload: str, ts: str) -> str:
raw = ts + KEY + RECV + payload # ← 순서가 중요하다
return hmac.new(SECRET.encode(), raw.encode(), hashlib.sha256).hexdigest()
def private_post(path: str, body: dict) -> dict:
ts = str(int(time.time() * 1000)) # 밀리초 (초 단위로 주면 10002)
# ⚠️ 본문 문자열을 '한 번만' 만들어 서명과 전송에 같은 값을 쓴다
payload = json.dumps(body, separators=(",", ":"))
headers = {
"X-BAPI-API-KEY" : KEY,
"X-BAPI-TIMESTAMP" : ts,
"X-BAPI-RECV-WINDOW" : RECV,
"X-BAPI-SIGN" : _sign(payload, ts),
"Content-Type" : "application/json",
}
r = requests.post(BASE + path, headers=headers, data=payload, timeout=10)
return r.json()
json.dumps()를 두 번 부르지 마십시오. 서명할 때 한 번, 전송할 때 또 한 번 직렬화하면 키 순서나 공백이 달라져 서버가 계산한 서명과 어긋납니다. 증상은 retCode 10004 하나뿐이라 "코드는 문서와 똑같은데 왜 안 되지"로 몇 시간을 쓰게 되는, 가장 흔한 함정입니다. 위 코드처럼 문자열을 먼저 만들어 두고 data=payload로 그대로 보내는 것이 정답입니다.
2) 잔고 조회 — GET /v5/account/wallet-balance
GET은 서명 대상의 마지막 조각이 본문이 아니라 쿼리 문자열입니다.
def private_get(path: str, params: dict) -> dict:
ts = str(int(time.time() * 1000))
query = "&".join(f"{k}={v}" for k, v in params.items()) # 순서 그대로
headers = {
"X-BAPI-API-KEY" : KEY,
"X-BAPI-TIMESTAMP" : ts,
"X-BAPI-RECV-WINDOW" : RECV,
"X-BAPI-SIGN" : _sign(query, ts),
}
r = requests.get(f"{BASE}{path}?{query}", headers=headers, timeout=10)
return r.json()
res = private_get("/v5/account/wallet-balance", {"accountType": "UNIFIED"})
print(res["retCode"], res["retMsg"])
정상이면 이런 형태로 돌아옵니다.
{
"retCode": 0,
"retMsg": "OK",
"result": { "list": [ { "accountType": "UNIFIED", "coin": [ ... ] } ] },
"time": 1754600000000
}
3) 주문 — POST /v5/order/create
여기서 category가 등장합니다. 같은 BTC라도 BTCUSDT는 linear, BTCUSD는 inverse입니다.
# USDT 무기한 선물 지정가 매수
res = private_post("/v5/order/create", {
"category" : "linear", # spot | linear | inverse | option
"symbol" : "BTCUSDT",
"side" : "Buy",
"orderType" : "Limit",
"qty" : "0.001", # 문자열로 보내는 편이 안전
"price" : "60000",
"timeInForce": "GTC",
})
# ⚠️ HTTP 200이어도 실패일 수 있다 — retCode 를 반드시 본다
if res["retCode"] != 0:
raise RuntimeError(f"주문 실패 {res['retCode']}: {res['retMsg']}")
order_id = res["result"]["orderId"]
4) 인증이 막혔을 때 — 확인 순서
| retCode | 뜻 | 먼저 볼 곳 |
|---|---|---|
10004 | 서명 불일치 | 서명한 문자열과 실제 전송 본문이 같은 값인지 → 이어 붙인 순서 → 시크릿 오타 |
10002 | 타임스탬프 범위 초과 | 서버 시계 NTP 동기화 → recv_window 값을 늘려 볼 것 → 초 단위로 보내고 있지 않은지 |
| 파라미터 계열 | 요청 값 오류 | category 누락 여부 → 심볼과 카테고리 조합 → 수량·호가 단위 |
타임스탬프를 초 단위로 넣는 것은 다른 거래소 코드를 옮겨 올 때 특히 자주 나옵니다. Bybit는 밀리초입니다. 서명 규칙이 거래소마다 미묘하게 다른 이유와 대응은 HTX 서명 오류 정리에서, 바이낸스 쪽 -1022·-1021 사례는 바이낸스 API 키 발급 가이드에서 함께 보실 수 있습니다.
5) WebSocket — Public과 Private이 분리돼 있다
시세는 Public 스트림, 체결·잔고·주문 상태는 Private 스트림으로 나뉘고 Private만 인증이 필요합니다. 종목이 늘어날수록 REST 폴링은 호출 제한에 먼저 부딪히므로, 시세는 구독으로 옮기고 REST는 주문·조회에만 쓰는 구조가 기본입니다.
// Public 시세 구독 (인증 불필요)
{ "op": "subscribe", "args": ["publicTrade.BTCUSDT", "orderbook.50.BTCUSDT"] }
// Private 은 인증 후 체결·주문·지갑 이벤트 구독
{ "op": "subscribe", "args": ["order", "execution", "wallet"] }
재연결과 재구독은 반드시 한 쌍입니다. 세션이 끊기면 구독도 함께 사라지므로, 재접속만 하고 재구독을 빠뜨리면 봇은 살아 있는데 시세만 안 들어오는 상태가 됩니다. 알고랩이 제작하는 봇은 재연결·재구독·하트비트와 "N초간 데이터 없음" 경고를 기본으로 넣습니다.
핵심 기능 구성 요소
- Multi-category 라우팅: 심볼에 따라 자동 카테고리 결정 (BTCUSDT → linear, BTCUSD → inverse)
- WebSocket 실시간 시세: kline / orderbook / trade 스트림, 재연결 로직
- Private WebSocket 이벤트: 체결·잔고·주문 상태 실시간 수신
- 포지션 모드 관리: One-Way / Hedge 모드 자동 전환
- 레버리지·마진 타입: Isolated/Cross 자동 설정
- 리스크 관리: 포지션당 최대 손실, 일일 최대 손실, 레버리지 상한
- 알림: 텔레그램 실시간 체결/청산/에러 알림, 일일 손익 리포트
제작 비용·기간 가이드
| 유형 | 예상 비용 | 제작 기간 |
|---|---|---|
| 단일 심볼 지표 기반 봇 | 80~150만원 | 7~10일 |
| 다중 심볼 + 리스크 관리 + 알림 | 150~250만원 | 10~14일 |
| 그리드 봇 (카테고리 복수) | 200~350만원 | 14~20일 |
| 옵션 전략 봇 (스트래들·아이언콘도르 등) | 300~500만원 | 21~30일 |
| 트레이딩뷰 웹훅 단독 연동 | 60~120만원 | 5~7일 |
📖 더 자세히: 바이비트(Bybit) 자동매매 완전 가이드 — API 발급부터 선물·그리드 전략, 실제 봇 구조까지 입문자 눈높이로 정리한 글입니다.
자주 묻는 질문
retCode 10004가 계속 나옵니다. 어떻게 고치나요?
서명 불일치입니다. 서명에 쓴 문자열과 실제로 전송한 본문이 다른 경우가 압도적으로 많으므로, json.dumps()를 한 번만 호출해 그 결과를 서명과 전송에 함께 쓰십시오. 그다음 확인할 것은 이어 붙이는 순서(timestamp → api_key → recv_window → 쿼리/본문)와 시크릿 오타입니다. 타임스탬프 문제라면 코드는 10004가 아니라 10002로 나옵니다.
테스트넷 API 주소가 왜 안 되나요?
웹 화면 주소와 API 주소가 다르기 때문입니다. 화면은 testnet.bybit.com이지만 API 호출은 https://api-testnet.bybit.com으로 보내야 합니다. 실거래 주소(https://api.bybit.com)와 키도 서로 호환되지 않으므로 테스트넷 계정에서 키를 따로 발급받아야 합니다.
바이낸스와 비교하면 뭐가 나은가요?
바이비트 V5 API는 전 상품(선물·현물·옵션)이 통합된 단일 API여서 멀티 상품 봇 구현이 간결합니다. 수수료·출금 수수료도 바이낸스 대비 경쟁력 있고, 한국 계정 지원도 상대적으로 안정적입니다. 유동성·상장 코인 수는 바이낸스가 더 많습니다.
테스트넷은 어떻게 쓰나요?
testnet.bybit.com 에서 별도 계정 생성 + 가상 자금 신청 → API 키 발급. 실거래 코드를 엔드포인트만 바꿔서 검증 가능. 알고랩 봇은 설정 파일의 testnet: true 하나로 전환되게 제작합니다.
옵션 자동매매는 실제로 수익 가능한가요?
옵션은 프리미엄 수령·숏 감마·변동성 아비트라지 등 전략이 다양합니다. 알고랩은 매매 실행을 자동화하는 프로그램 제작 서비스이며, 전략 자체의 수익성은 보장하지 않습니다. 전략 아이디어가 있으시면 구현 가능성과 리스크 포인트를 상담에서 함께 검토해드립니다.
김치프리미엄 차익거래도 가능한가요?
업비트·바이낸스 등과 함께 운영 가능합니다. 체결 지연 대비 타임아웃 + 양방향 자동 취소 로직 필수. 제작 견적은 양쪽 거래소 API 구현까지 포함해서 산출됩니다.
제작 사례
바이비트 자동매매 제작 사례는 포트폴리오에서 확인하실 수 있습니다.