고-frequency 거래(HFT)와 정량 트레이딩에서 주문서(Order Book) 불균형은 가장 강력한 단기 Alpha 신호 중 하나입니다. 이 튜토리얼에서는 Tardis L2 시세 데이터를 기반으로 주문서 불균형 인자(Order Book Imbalance Factor)를 계산하고, 이를 AI 분석과 결합하여 트레이딩 신호로 변환하는 방법을 상세히 설명합니다. HolySheep AI의 글로벌 API 게이트웨이를 활용하면 단일 API 키로 다중 모델을 통한 신호 분석과 비용 최적화를 동시에 달성할 수 있습니다.
실제 오류 시나리오로 시작하기
실시간 주문서 데이터를 처리하는 과정에서 흔히 마주치는 오류들을 먼저 살펴보겠습니다:
# 오류 시나리오 1: Tardis API 연결 타임아웃
import requests
tardis_url = "https://api.tardis.dev/v1/l2/orderbook"
params = {"exchange": "binance", "symbol": "BTC-PERPETUAL"}
try:
response = requests.get(tardis_url, params=params, timeout=5)
orderbook = response.json()
except requests.exceptions.Timeout:
print("ConnectionError: timeout - 네트워크 지연이 5초를 초과했습니다")
# 재시도 로직 필요
except requests.exceptions.ConnectionError:
print("ConnectionError: Unable to connect to Tardis API")
# DNS 또는 네트워크 문제 점검 필요
# 오류 시나리오 2: 비동기 스트리밍 데이터 처리 오류
import asyncio
from tardis_client import TardisClient, TardisReplay
비동기 핸들러에서 예외 처리 누락으로 인한 크래시
async def on_orderbook_update(data):
bid_volume = data['bids'][0]['volume'] # KeyError 발생 가능
ask_volume = data['asks'][0]['volume']
imbalance = (bid_volume - ask_volume) / (bid_volume + ask_volume)
return imbalance
예외 처리가 없는 경우 스트리밍이 갑자기 중단됨
client = TardisClient()
await client.subscribe(
exchange="binance",
channels=["orderbook"],
symbols=["BTC-PERPETUAL"],
on_orderbook=on_orderbook_update
)
주문서 불균형 인자(Order Book Imbalance)란?
주문서 불균형은 특정 가격 수준에서 매수 주문량과 매도 주문량의 차이를 나타냅니다. 이 비율을 통해 시장의 단기 방향성을 예측할 수 있습니다:
- 양의 불균형 (Positive Imbalance): 매수 거래량이 매도 거래량보다 많음 → 가격 상승 압력 신호
- 음의 불균형 (Negative Imbalance): 매도 거래량이 매수 거래량보다 많음 → 가격 하락 압력 신호
- 중립 (Near Zero): 양쪽 주문량이 균형 → 방향성 없음
Tardis L2 데이터 구조 이해
import json
from dataclasses import dataclass
from typing import List, Dict
import numpy as np
@dataclass
class OrderBookLevel:
"""주문서 단일 수준 (Bid 또는 Ask)"""
price: float
volume: float
order_count: int = 1
@dataclass
class OrderBook:
"""전체 주문서 데이터 구조"""
exchange: str
symbol: str
timestamp: int
bids: List[OrderBookLevel] # 매수 주문 (가격 오름차순)
asks: List[OrderBookLevel] # 매도 주문 (가격 내림차순)
def calculate_imbalance(self, levels: int = 10, volume_weighted: bool = True) -> float:
"""
주문서 불균형 계산
Args:
levels: 분석에 사용할 가격 수준 수
volume_weighted: True면 거래량 가중 평균 사용
Returns:
float: -1 ~ +1 사이의 불균형 지표
"""
bid_volumes = [level.volume for level in self.bids[:levels]]
ask_volumes = [level.volume for level in self.asks[:levels]]
if volume_weighted:
# 거래량 가중 불균형: 큰 주문의 영향력 증대
total_bid = sum(bid_volumes)
total_ask = sum(ask_volumes)
else:
# 단순 개수 기반 불균형
total_bid = len(bid_volumes)
total_ask = len(ask_volumes)
total = total_bid + total_ask
if total == 0:
return 0.0
# -1 (완전 매도 우위) ~ +1 (완전 매수 우위)
imbalance = (total_bid - total_ask) / total
return imbalance
def calculate_depth_imbalance(self, depth_usd: float = 100000) -> float:
"""
특정 깊이(USDD 기준)에서의 불균형 계산
Args:
depth_usd: 분석할 주문 총 금액 (USD)
Returns:
float: 지정 깊이까지의 불균형 지표
"""
bid_accumulated = 0.0
ask_accumulated = 0.0