오더플로우 자동매매 분석

오더플로우(Order Flow)란?

오더플로우는 실시간 매수·매도 주문의 흐름을 분석하여 시장 참여자의 의도를 파악하는 기법입니다. 캔들 차트나 이동평균 같은 가격 기반 지표와 달리, 오더플로우는 체결 데이터와 호가창(Order Book)을 직접 분석하여 가격 변동의 원인을 추적합니다.

퀀트 자동매매에서 오더플로우 분석을 활용하면, 단순 기술적 지표보다 한 발 앞선 매매 신호를 포착할 수 있습니다. 대형 기관의 매집·분배 패턴, 유동성 불균형, 아이스버그 주문 등을 감지하여 더 정밀한 진입·청산 타이밍을 잡을 수 있습니다.

핵심 개념: 델타·CVD·호가 불균형

오더플로우 분석의 세 가지 핵심 지표를 살펴보겠습니다.

1. 델타(Delta)

델타는 특정 기간 동안 시장가 매수(Ask에서 체결)와 시장가 매도(Bid에서 체결)의 차이입니다. 양의 델타는 공격적 매수 우세, 음의 델타는 공격적 매도 우세를 나타냅니다.

import pandas as pd
import numpy as np

def calculate_delta(trades_df):
    """체결 데이터에서 델타 계산"""
    # side: 'buy' = 시장가 매수(taker buy), 'sell' = 시장가 매도(taker sell)
    trades_df['signed_qty'] = np.where(
        trades_df['side'] == 'buy',
        trades_df['quantity'],
        -trades_df['quantity']
    )
    
    # 1분봉 기준 델타 집계
    delta_1m = trades_df.resample('1min', on='timestamp').agg(
        delta=('signed_qty', 'sum'),
        volume=('quantity', 'sum'),
        buy_vol=('signed_qty', lambda x: x[x > 0].sum()),
        sell_vol=('signed_qty', lambda x: abs(x[x < 0].sum())),
        trade_count=('quantity', 'count')
    )
    return delta_1m

2. CVD(Cumulative Volume Delta)

CVD는 델타의 누적값입니다. 가격과 CVD의 다이버전스를 관찰하면 추세 전환 신호를 포착할 수 있습니다. 예를 들어 가격은 신고가를 갱신하는데 CVD는 하락한다면, 매수 동력이 약화되고 있음을 의미합니다.

def calculate_cvd(delta_series):
    """CVD 계산 및 다이버전스 감지"""
    cvd = delta_series.cumsum()
    return cvd

def detect_divergence(price, cvd, lookback=20):
    """가격-CVD 다이버전스 감지"""
    signals = []
    for i in range(lookback, len(price)):
        window_price = price[i-lookback:i]
        window_cvd = cvd[i-lookback:i]
        
        # 베어리시 다이버전스: 가격 ↑ but CVD ↓
        if (price[i] > window_price.max() * 0.998 and 
            cvd[i] < window_cvd.mean()):
            signals.append(('bearish_div', i))
        
        # 불리시 다이버전스: 가격 ↓ but CVD ↑
        elif (price[i] < window_price.min() * 1.002 and
              cvd[i] > window_cvd.mean()):
            signals.append(('bullish_div', i))
    
    return signals

3. 호가 불균형(Order Book Imbalance)

호가창의 매수·매도 대기 물량 비율을 분석합니다. 불균형이 클수록 가격이 해당 방향으로 움직일 확률이 높습니다.

def order_book_imbalance(bids, asks, levels=10):
    """호가창 불균형 비율 계산 (-1 ~ +1)"""
    bid_volume = sum(qty for _, qty in bids[:levels])
    ask_volume = sum(qty for _, qty in asks[:levels])
    
    if bid_volume + ask_volume == 0:
        return 0
    
    imbalance = (bid_volume - ask_volume) / (bid_volume + ask_volume)
    return imbalance  # +1에 가까우면 매수벽, -1에 가까우면 매도벽

파이썬 실시간 오더플로우 수집

바이낸스 WebSocket API를 사용하여 실시간 체결 데이터와 호가창을 수집하는 방법입니다.

import asyncio
import websockets
import json
from collections import deque
from datetime import datetime

class OrderFlowCollector:
    """실시간 오더플로우 데이터 수집기"""
    
    def __init__(self, symbol='btcusdt', depth_levels=20):
        self.symbol = symbol
        self.depth_levels = depth_levels
        self.trades = deque(maxlen=10000)
        self.current_book = {'bids': [], 'asks': []}
        self.delta_window = deque(maxlen=60)  # 최근 60초
    
    async def collect_trades(self):
        """실시간 체결 데이터 수집"""
        uri = f"wss://stream.binance.com:9443/ws/{self.symbol}@aggTrade"
        async with websockets.connect(uri) as ws:
            async for msg in ws:
                trade = json.loads(msg)
                parsed = {
                    'timestamp': datetime.fromtimestamp(trade['T'] / 1000),
                    'price': float(trade['p']),
                    'quantity': float(trade['q']),
                    'side': 'sell' if trade['m'] else 'buy'
                }
                self.trades.append(parsed)
                self._update_delta(parsed)
    
    async def collect_depth(self):
        """실시간 호가창 수집"""
        uri = f"wss://stream.binance.com:9443/ws/{self.symbol}@depth{self.depth_levels}@100ms"
        async with websockets.connect(uri) as ws:
            async for msg in ws:
                data = json.loads(msg)
                self.current_book = {
                    'bids': [(float(p), float(q)) for p, q in data.get('bids', [])],
                    'asks': [(float(p), float(q)) for p, q in data.get('asks', [])]
                }
    
    def _update_delta(self, trade):
        """1초 단위 델타 갱신"""
        signed = trade['quantity'] if trade['side'] == 'buy' else -trade['quantity']
        self.delta_window.append(signed)
    
    def get_rolling_delta(self):
        """최근 60초 누적 델타"""
        return sum(self.delta_window)

오더플로우 기반 자동매매 전략

오더플로우 지표들을 종합하여 자동매매 신호를 생성하는 전략을 구현합니다. 핵심은 다중 오더플로우 신호의 합류(confluence)입니다.

class OrderFlowStrategy:
    """오더플로우 기반 매매 전략"""
    
    def __init__(self, delta_threshold=100, imbalance_threshold=0.3):
        self.delta_threshold = delta_threshold
        self.imbalance_threshold = imbalance_threshold
        self.position = 0
    
    def generate_signal(self, rolling_delta, book_imbalance, 
                        cvd_slope, large_trade_ratio):
        """
        다중 오더플로우 신호 합류 기반 매매 신호
        
        Parameters:
            rolling_delta: 최근 N초 누적 델타
            book_imbalance: 호가 불균형 (-1 ~ +1)
            cvd_slope: CVD 기울기 (상승/하락 추세)
            large_trade_ratio: 대량 체결 비율
        
        Returns:
            signal: 1(롱), -1(숏), 0(관망)
        """
        score = 0
        
        # 델타 신호 (가중치 0.3)
        if rolling_delta > self.delta_threshold:
            score += 0.3
        elif rolling_delta < -self.delta_threshold:
            score -= 0.3
        
        # 호가 불균형 신호 (가중치 0.25)
        if book_imbalance > self.imbalance_threshold:
            score += 0.25
        elif book_imbalance < -self.imbalance_threshold:
            score -= 0.25
        
        # CVD 추세 신호 (가중치 0.25)
        if cvd_slope > 0:
            score += 0.25
        elif cvd_slope < 0:
            score -= 0.25
        
        # 대량 체결 비율 (가중치 0.2)
        if large_trade_ratio > 0.4:
            score += 0.2 * (1 if rolling_delta > 0 else -1)
        
        # 합류 점수 기반 신호
        if score >= 0.6:
            return 1   # 롱 진입
        elif score <= -0.6:
            return -1  # 숏 진입
        return 0       # 관망
    
    def detect_large_trades(self, trades, percentile=95):
        """대량 체결(고래 주문) 감지"""
        quantities = [t['quantity'] for t in trades]
        if not quantities:
            return 0, []
        
        threshold = np.percentile(quantities, percentile)
        large = [t for t in trades if t['quantity'] >= threshold]
        ratio = len(large) / len(trades) if trades else 0
        return ratio, large

아이스버그 주문 탐지

아이스버그 주문은 대형 주문을 소량으로 분할하여 시장 충격을 줄이는 기법입니다. 이를 탐지하면 기관의 숨겨진 매매 의도를 파악할 수 있습니다.

def detect_iceberg(trades, price_tolerance=0.001, 
                    min_count=5, time_window_sec=30):
    """
    아이스버그 주문 패턴 탐지
    - 동일 가격대에서 비슷한 크기의 반복 체결
    - 짧은 시간 내 동일 방향 연속 체결
    """
    from collections import defaultdict
    
    price_groups = defaultdict(list)
    
    for trade in trades:
        # 가격을 tolerance 범위로 그룹핑
        price_key = round(trade['price'] / trade['price'] 
                         / price_tolerance) * price_tolerance
        price_groups[price_key].append(trade)
    
    icebergs = []
    for price_key, group in price_groups.items():
        if len(group) < min_count:
            continue
        
        # 동일 방향 체결만 필터
        buy_trades = [t for t in group if t['side'] == 'buy']
        sell_trades = [t for t in group if t['side'] == 'sell']
        
        for direction, dir_trades in [('buy', buy_trades), ('sell', sell_trades)]:
            if len(dir_trades) < min_count:
                continue
            
            qtys = [t['quantity'] for t in dir_trades]
            cv = np.std(qtys) / np.mean(qtys) if np.mean(qtys) > 0 else 999
            
            # 변동계수가 낮으면 = 비슷한 크기 반복 = 아이스버그 의심
            if cv < 0.3:
                icebergs.append({
                    'price': dir_trades[0]['price'],
                    'direction': direction,
                    'count': len(dir_trades),
                    'avg_qty': np.mean(qtys),
                    'total_qty': sum(qtys),
                    'cv': cv
                })
    
    return icebergs

리스크 관리와 실전 적용 팁

오더플로우 자동매매를 실전에 적용할 때 반드시 고려해야 할 사항들입니다.

레이턴시(Latency) 관리

오더플로우 데이터는 밀리초 단위로 변합니다. WebSocket 연결 지연, 데이터 처리 시간이 전략 성과에 직접 영향을 미칩니다. 거래소 서버와 가까운 위치에 봇을 배포하고, 데이터 처리 파이프라인을 최적화해야 합니다.

스푸핑(Spoofing) 필터링

호가창에 대량 주문을 올려놓고 체결 직전에 취소하는 스푸핑은 오더플로우 분석을 교란합니다. 호가 데이터의 생존 시간을 추적하고, 자주 취소되는 가격대의 주문은 분석에서 제외해야 합니다.

지표 용도 주의점
델타 매수·매도 압력 측정 횡보장에서 노이즈 많음
CVD 추세 강도·다이버전스 거래소별 데이터 차이
호가 불균형 단기 방향성 예측 스푸핑에 취약
대량 체결 고래 활동 감지 OTC 거래 미반영

포지션 사이징 연동

오더플로우 신호의 강도(합류 점수)에 따라 포지션 크기를 조절하세요. 강한 합류 신호에는 기본 포지션의 100%, 중간 강도에는 50%를 배분하는 방식이 효과적입니다.

백테스트 시 주의사항

오더플로우 전략의 백테스트는 일반 가격 기반 전략보다 까다롭습니다. 반드시 틱 단위 체결 데이터가 필요하며, 호가창 스냅샷 데이터까지 있어야 정확한 검증이 가능합니다. 바이낸스는 과거 체결 데이터를 공개하므로 이를 활용할 수 있습니다.

또한 오더플로우 전략은 슬리피지에 민감하므로, 백테스트에서 현실적인 슬리피지 모델을 반드시 적용해야 합니다. 시장가 주문의 체결 가격은 호가 깊이에 따라 달라지기 때문입니다.

마무리

오더플로우 분석은 퀀트 자동매매의 알파(초과수익)를 창출할 수 있는 강력한 도구입니다. 델타, CVD, 호가 불균형, 아이스버그 탐지를 조합하면 가격 지표만으로는 얻을 수 없는 깊이 있는 시장 인사이트를 확보할 수 있습니다. 다만 레이턴시 관리, 스푸핑 필터링, 데이터 품질 확보 등 기술적 난관도 함께 해결해야 합니다. 실전 적용 전에 충분한 페이퍼 트레이딩으로 검증하는 것을 권장합니다.

위로 스크롤
WordPress Appliance - Powered by TurnKey Linux