슬리피지란 무엇인가?
슬리피지(Slippage)는 주문 시점의 예상 체결가와 실제 체결가의 차이를 말합니다. 자동매매 시스템에서 백테스트 수익률과 실전 수익률의 괴리를 만드는 가장 큰 원인 중 하나이며, 고빈도 전략일수록 슬리피지가 수익을 잠식하는 비율이 급격히 커집니다.
슬리피지를 이해하고 최소화하는 것은 자동매매 시스템의 실전 수익성을 좌우하는 핵심 역량입니다.
슬리피지가 발생하는 3가지 원인
1. 유동성 부족
호가창에 충분한 물량이 없으면 주문이 여러 호가에 걸쳐 체결됩니다. 예를 들어 BTC를 시장가로 10개 매수하려는데 최우선 매도호가에 3개만 있다면, 나머지 7개는 더 높은 가격에 체결됩니다.
2. 네트워크 지연(Latency)
주문 신호 생성부터 거래소 서버 도달까지의 시간 동안 가격이 변합니다. 특히 변동성이 큰 구간에서는 수 밀리초의 지연도 체결가에 영향을 줍니다.
3. 시장 임팩트
큰 규모의 주문 자체가 가격을 움직입니다. 자동매매 봇이 대량 매수 주문을 넣으면 호가창의 매도 물량을 소진시키며 가격을 밀어올립니다.
슬리피지 측정 방법
슬리피지를 관리하려면 먼저 정확하게 측정해야 합니다.
import pandas as pd
def calculate_slippage(orders_df):
"""주문별 슬리피지 계산"""
# expected_price: 시그널 생성 시점의 가격
# filled_price: 실제 체결 가격
orders_df['slippage_pct'] = (
(orders_df['filled_price'] - orders_df['expected_price'])
/ orders_df['expected_price'] * 100
)
# 매도 주문은 부호 반전
sell_mask = orders_df['side'] == 'sell'
orders_df.loc[sell_mask, 'slippage_pct'] *= -1
avg = orders_df['slippage_pct'].mean()
median = orders_df['slippage_pct'].median()
p95 = orders_df['slippage_pct'].quantile(0.95)
print(f"평균 슬리피지: {avg:.4f}%")
print(f"중앙값: {median:.4f}%")
print(f"95퍼센타일: {p95:.4f}%")
return orders_df
평균값뿐 아니라 95퍼센타일을 확인하는 것이 중요합니다. 극단적인 슬리피지가 전체 수익을 날릴 수 있기 때문입니다.
슬리피지를 줄이는 7가지 실전 기법
1. 지정가 주문 활용
시장가 주문 대신 지정가(Limit) 주문을 사용하면 슬리피지를 원천 차단할 수 있습니다. 다만 체결되지 않을 위험이 있으므로, 체결률과 슬리피지 사이의 균형을 찾아야 합니다.
- 공격적 지정가: 현재가 ±0.01%에 지정가 → 높은 체결률, 약간의 슬리피지 허용
- 보수적 지정가: 현재가 정확히 또는 유리한 가격 → 낮은 체결률, 슬리피지 제로
2. 주문 분할(Order Splitting)
큰 주문을 여러 개의 작은 주문으로 나누어 실행합니다.
import asyncio
import time
async def split_order(exchange, symbol, side, total_qty, num_splits, interval_sec=1.0):
"""주문을 n등분하여 시간 간격을 두고 실행"""
split_qty = total_qty / num_splits
filled_prices = []
for i in range(num_splits):
order = await exchange.create_limit_order(
symbol=symbol,
side=side,
amount=split_qty,
price=await get_best_price(exchange, symbol, side)
)
filled_prices.append(order['average'])
if i < num_splits - 1:
await asyncio.sleep(interval_sec)
avg_price = sum(filled_prices) / len(filled_prices)
return avg_price, filled_prices
주문을 5~10개로 분할하면 시장 임팩트를 크게 줄일 수 있습니다. 단, 분할 간격 동안 가격이 불리하게 움직일 수도 있으므로 변동성이 낮은 시간대에 유리합니다.
3. TWAP/VWAP 알고리즘
| 알고리즘 | 방식 | 적합한 상황 |
|---|---|---|
| TWAP | 일정 시간 간격으로 균등 분할 주문 | 유동성이 일정한 시장 |
| VWAP | 거래량 비율에 맞춰 분할 주문 | 거래량 변동이 큰 시장 |
| Iceberg | 일부만 호가창에 노출, 체결되면 추가 주문 | 대량 주문 시 시장 임팩트 최소화 |
대부분의 거래소 API에서 아이스버그 주문을 지원하므로, 큰 포지션 진입 시 적극 활용해야 합니다.
4. 유동성 높은 시간대 거래
암호화폐 시장 기준으로 유동성이 가장 높은 시간대:
- UTC 13:00~21:00: 미국·유럽 시장 겹치는 시간
- UTC 00:00~02:00: 아시아 시장 개장
- 주말 새벽: 유동성 최저 → 슬리피지 최대, 가급적 회피
5. 호가창 깊이(Depth) 모니터링
주문 전에 호가창 깊이를 확인하여 예상 슬리피지를 사전 계산합니다.
def estimate_slippage(orderbook, side, quantity):
"""호가창 기반 예상 슬리피지 계산"""
levels = orderbook['asks'] if side == 'buy' else orderbook['bids']
remaining = quantity
total_cost = 0
mid_price = (orderbook['asks'][0][0] + orderbook['bids'][0][0]) / 2
for price, size in levels:
fill = min(remaining, size)
total_cost += fill * price
remaining -= fill
if remaining <= 0:
break
if remaining > 0:
return float('inf') # 유동성 부족
avg_price = total_cost / quantity
slippage = abs(avg_price - mid_price) / mid_price * 100
return slippage
예상 슬리피지가 임계값(예: 0.1%)을 초과하면 주문을 분할하거나 지연시키는 로직을 추가합니다.
6. 거래소 코로케이션
거래소 서버와 물리적으로 가까운 곳에 봇 서버를 배치하면 네트워크 지연을 최소화할 수 있습니다. 바이낸스는 도쿄·싱가포르, 업비트는 서울 리전의 클라우드 서버를 사용하면 수 밀리초의 지연을 줄일 수 있습니다.
7. 메이커 주문 인센티브 활용
대부분의 거래소에서 메이커(지정가) 주문은 테이커(시장가) 주문보다 수수료가 낮습니다. 슬리피지 절감과 수수료 절감을 동시에 달성할 수 있습니다.
백테스트에 슬리피지 반영하기
백테스트 신뢰도를 높이려면 현실적인 슬리피지 모델을 적용해야 합니다.
| 시장 상황 | 권장 슬리피지 설정 |
|---|---|
| BTC/USDT 고유동성 | 0.01~0.03% |
| 알트코인 중간 유동성 | 0.05~0.15% |
| 저유동성 소형 코인 | 0.2~0.5% |
| 급변동 구간 | 0.5~2.0% |
관련 글 더 보기
마무리
슬리피지는 자동매매의 숨겨진 비용입니다. 백테스트에서는 보이지 않지만 실전에서는 매 거래마다 수익을 깎아먹습니다. 지정가 주문 활용, 주문 분할, 호가창 모니터링, 유동성 높은 시간대 거래 등의 기법을 체계적으로 적용하면 슬리피지를 크게 줄일 수 있습니다.
0.1%의 슬리피지 절감이 연간 수백 회 거래에서 복리로 누적되면, 최종 수익률에 결정적인 차이를 만듭니다.