TWAP 자동매매란?
TWAP(Time-Weighted Average Price)은 대량 주문을 일정 시간 간격으로 균등 분할하여 체결하는 알고리즘 매매 전략입니다. 기관 투자자와 퀀트 트레이더가 시장 충격(Market Impact)을 최소화하면서 대규모 포지션을 진입·청산할 때 핵심적으로 사용합니다.
VWAP이 거래량 가중 평균을 추종한다면, TWAP은 시간 축을 기준으로 균등 분배하므로 거래량 데이터가 불안정한 암호화폐 시장이나 유동성이 낮은 종목에서 특히 유리합니다.
TWAP vs VWAP 차이점
| 구분 | TWAP | VWAP |
|---|---|---|
| 분배 기준 | 시간 균등 분할 | 거래량 가중 분할 |
| 필요 데이터 | 시간 정보만 | 실시간 거래량 필요 |
| 적합 시장 | 저유동성, 암호화폐 | 고유동성 주식 |
| 구현 난이도 | 낮음 | 중간 |
| 시장 충격 | 균등 분산 | 거래량 집중 시간대 분산 |
TWAP 알고리즘 핵심 로직
TWAP 전략의 핵심은 단순합니다. 총 주문 수량을 N개의 슬라이스로 나누고, 일정 간격마다 한 슬라이스씩 시장가 또는 지정가로 체결시킵니다.
총_주문량 = 10 BTC
실행_시간 = 60분
슬라이스_수 = 12 (5분 간격)
슬라이스_수량 = 10 / 12 ≈ 0.833 BTC
타이머:
매 5분마다 → 0.833 BTC 시장가 매수 실행
미체결 시 → 다음 슬라이스에 잔량 합산
파이썬 TWAP 봇 구현
아래는 ccxt 라이브러리를 활용한 암호화폐 TWAP 자동매매 봇의 핵심 코드입니다. 바이낸스, 업비트 등 주요 거래소에서 바로 사용할 수 있습니다.
import ccxt
import time
import math
from datetime import datetime
class TWAPBot:
def __init__(self, exchange_id, api_key, secret):
exchange_class = getattr(ccxt, exchange_id)
self.exchange = exchange_class({
'apiKey': api_key,
'secret': secret,
'options': {'defaultType': 'spot'}
})
def execute_twap(self, symbol, side, total_qty,
duration_min, num_slices):
"""
TWAP 주문 실행
:param symbol: 거래쌍 (예: 'BTC/USDT')
:param side: 'buy' 또는 'sell'
:param total_qty: 총 주문 수량
:param duration_min: 실행 시간(분)
:param num_slices: 분할 횟수
"""
slice_qty = total_qty / num_slices
interval_sec = (duration_min * 60) / num_slices
executed = 0
results = []
for i in range(num_slices):
remaining = total_qty - executed
qty = min(slice_qty, remaining)
if qty <= 0:
break
try:
order = self.exchange.create_market_order(
symbol, side, qty
)
filled = order.get('filled', qty)
avg_price = order.get('average', 0)
executed += filled
results.append({
'slice': i + 1,
'time': datetime.now().isoformat(),
'filled': filled,
'price': avg_price
})
print(f"[슬라이스 {i+1}/{num_slices}] "
f"{filled} {symbol} @ {avg_price}")
except Exception as e:
print(f"[오류] 슬라이스 {i+1}: {e}")
# 미체결 잔량은 다음 슬라이스에 합산
slice_qty += qty / (num_slices - i - 1)
if i < num_slices - 1 else 0
if i < num_slices - 1:
time.sleep(interval_sec)
return self._calculate_summary(results, side)
def _calculate_summary(self, results, side):
if not results:
return None
total_filled = sum(r['filled'] for r in results)
twap_price = (
sum(r['filled'] * r['price'] for r in results)
/ total_filled
)
return {
'side': side,
'total_filled': total_filled,
'twap_price': twap_price,
'num_executions': len(results),
'slices': results
}
실전 TWAP 최적화 기법
기본 TWAP에 아래 기법을 추가하면 체결 품질을 크게 높일 수 있습니다.
1. 랜덤 지터(Jitter) 추가
정확히 같은 간격으로 주문하면 알고리즘 감지(algo detection)에 노출됩니다. 실행 간격에 ±10~20% 랜덤 편차를 넣으면 패턴을 숨길 수 있습니다.
import random
# 기본 간격 300초에 ±20% 지터
base_interval = 300
jitter = random.uniform(-0.2, 0.2)
actual_interval = base_interval * (1 + jitter)
2. 지정가 주문 + 폴백
시장가 대신 현재가 기준 약간의 슬리피지 허용 범위 내에서 지정가 주문을 먼저 시도하고, 미체결 시 시장가로 전환하면 체결 비용을 줄일 수 있습니다.
def smart_order(self, symbol, side, qty,
slippage_pct=0.05):
ticker = self.exchange.fetch_ticker(symbol)
mid_price = (ticker['bid'] + ticker['ask']) / 2
if side == 'buy':
limit_price = mid_price * (1 + slippage_pct / 100)
else:
limit_price = mid_price * (1 - slippage_pct / 100)
order = self.exchange.create_limit_order(
symbol, side, qty, limit_price
)
time.sleep(5) # 5초 대기
status = self.exchange.fetch_order(order['id'], symbol)
if status['remaining'] > 0:
self.exchange.cancel_order(order['id'], symbol)
# 잔량 시장가 체결
self.exchange.create_market_order(
symbol, side, status['remaining']
)
return status
3. 최소 주문 수량 처리
거래소마다 최소 주문 수량이 있습니다. 슬라이스 수량이 최소 수량 미만이면 슬라이스를 합치거나 총 분할 수를 줄여야 합니다.
market = self.exchange.market(symbol)
min_qty = market['limits']['amount']['min']
if slice_qty < min_qty:
num_slices = math.floor(total_qty / min_qty)
slice_qty = total_qty / num_slices
TWAP 성과 측정 지표
TWAP 봇의 성과는 단순 수익률이 아니라 실행 품질(Execution Quality)로 평가합니다.
| 지표 | 계산 방법 | 목표 |
|---|---|---|
| TWAP Slippage | (실제 평균가 - 이론 TWAP) / 이론 TWAP | 0에 가까울수록 좋음 |
| Implementation Shortfall | 결정 시점 가격 대비 실제 체결 비용 차이 | 최소화 |
| Fill Rate | 체결 수량 / 목표 수량 × 100 | 100% |
| Market Impact | 주문 전후 가격 변동 폭 | 최소화 |
실전 운영 체크리스트
TWAP 봇을 프로덕션에 배포하기 전 반드시 확인해야 할 항목들입니다.
- API Rate Limit 확인 — 거래소별 초당 요청 제한을 넘지 않도록 슬라이스 간격 조정
- 네트워크 장애 대비 — 연결 끊김 시 미완료 슬라이스 복구 로직 구현
- 가격 급변 서킷브레이커 — 실행 중 가격이 일정 비율 이상 급변하면 자동 중단
- 슬리피지 모니터링 — 슬라이스별 체결가와 이론가 편차를 실시간 추적
- 잔고 사전 확인 — 전체 주문을 체결할 충분한 잔고가 있는지 시작 전 검증
- 로그 기록 — 모든 슬라이스의 체결 시간, 가격, 수량을 파일/DB에 저장
TWAP 전략이 효과적인 상황
TWAP은 만능이 아닙니다. 다음 상황에서 가장 효과적입니다.
- 대량 포지션 진입/청산 — 일일 거래량의 10% 이상 매매 시
- 유동성 낮은 시장 — 알트코인, 소형주 등 호가 스프레드가 넓은 종목
- 시장 방향성 불확실 — 트렌드 예측 없이 평균 가격에 수렴하고 싶을 때
- 규제 준수 필요 — 기관 투자자가 Best Execution 의무를 충족해야 할 때
반면, 강한 트렌드가 진행 중이거나 시간 압박이 있는 매매에서는 TWAP보다 적극적인 전략이 적합합니다.
관련 글
- 파이썬 VWAP 자동매매 전략 — TWAP과 비교되는 거래량 가중 알고리즘
- 자동매매 슬리피지 최적화 전략 — 체결 비용을 줄이는 실전 기법
- 거래소 API 장애 대응 전략 — TWAP 실행 중 API 장애 처리법