알고리즘 주문 집행이란?
대량 주문을 한 번에 시장에 내면 시장 충격(Market Impact)으로 불리한 가격에 체결됩니다. 알고리즘 주문 집행은 대량 주문을 잘게 쪼개어 최적의 타이밍과 수량으로 나누어 체결하는 기법입니다. 기관 투자자뿐 아니라 자동매매 봇을 운영하는 개인 트레이더에게도 핵심 기술입니다.
대표적인 알고리즘으로 VWAP(Volume Weighted Average Price)과 TWAP(Time Weighted Average Price)이 있습니다. 이 글에서는 두 전략의 원리, 구현 방법, 실전 적용 노하우를 정리합니다.
VWAP 전략: 거래량 가중 평균가 추종
VWAP은 하루 동안의 거래량 가중 평균 가격을 의미합니다. VWAP 주문 집행의 목표는 내 체결 평균가가 시장 VWAP에 최대한 가깝도록 만드는 것입니다.
VWAP 계산 공식
VWAP = Σ(가격 × 거래량) / Σ(거래량)
# 파이썬 구현
import pandas as pd
def calc_vwap(df):
"""df에 price, volume 컬럼 필요"""
cumulative_pv = (df['price'] * df['volume']).cumsum()
cumulative_vol = df['volume'].cumsum()
return cumulative_pv / cumulative_vol
VWAP 주문 집행 로직
과거 거래량 패턴(보통 20~60일 평균)으로 시간대별 거래량 비율을 예측합니다. 거래량이 많은 시간대에 더 많은 수량을 배분하고, 적은 시간대에는 줄입니다.
import numpy as np
def vwap_schedule(total_qty, volume_profile):
"""
volume_profile: 시간대별 예상 거래량 비율 (합계=1.0)
반환: 시간대별 주문 수량
"""
schedule = np.round(total_qty * volume_profile).astype(int)
# 반올림 오차 보정
diff = total_qty - schedule.sum()
schedule[np.argmax(volume_profile)] += diff
return schedule
# 예시: 10분 단위 39슬롯 (9:00~15:30)
profile = get_historical_volume_profile(symbol, days=20)
order_schedule = vwap_schedule(10000, profile)
VWAP 전략의 장단점
| 장점 | 단점 |
|---|---|
| 시장 충격 최소화 | 거래량 예측이 빗나가면 효과 감소 |
| 벤치마크 대비 성과 측정 용이 | 급등·급락장에서 뒤처짐 |
| 기관 수준의 체결 품질 | 유동성 낮은 종목에는 부적합 |
TWAP 전략: 시간 균등 분할 집행
TWAP은 정해진 시간 동안 균등한 간격으로 동일 수량을 주문하는 방식입니다. VWAP보다 단순하지만, 거래량 데이터가 부족하거나 24시간 운영되는 암호화폐 시장에서 특히 유용합니다.
TWAP 구현 코드
import time
import math
def twap_execute(total_qty, duration_sec, interval_sec, place_order_fn):
"""
total_qty: 총 주문 수량
duration_sec: 전체 집행 시간(초)
interval_sec: 주문 간격(초)
place_order_fn: 실제 주문 함수
"""
num_slices = math.ceil(duration_sec / interval_sec)
slice_qty = total_qty // num_slices
remainder = total_qty % num_slices
for i in range(num_slices):
qty = slice_qty + (1 if i < remainder else 0)
place_order_fn(qty)
if i < num_slices - 1:
time.sleep(interval_sec)
# 예시: 1000개를 1시간 동안 1분 간격으로
twap_execute(1000, 3600, 60, my_order_function)
TWAP에 랜덤성 추가하기
고정 간격 TWAP은 패턴이 노출되어 다른 알고리즘에 이용당할 수 있습니다. 실전에서는 ±20~30% 범위의 랜덤 지터(Jitter)를 추가합니다.
import random
def randomized_interval(base_interval, jitter_pct=0.25):
jitter = base_interval * jitter_pct
return base_interval + random.uniform(-jitter, jitter)
VWAP vs TWAP: 언제 무엇을 쓸까?
| 기준 | VWAP | TWAP |
|---|---|---|
| 거래량 패턴 | 뚜렷한 거래량 프로필 존재 시 | 거래량 예측 어려울 때 |
| 시장 유형 | 주식 시장 (개장·마감 거래량 집중) | 암호화폐·외환 (24시간 운영) |
| 구현 복잡도 | 높음 (거래량 프로필 필요) | 낮음 (시간만 분할) |
| 벤치마크 | 시장 VWAP 대비 슬리피지 | 단순 평균가 대비 슬리피지 |
| 시장 충격 | 거래량에 맞춰 분산 → 매우 낮음 | 균등 분할 → 낮음 |
실전 최적화 기법 4가지
1. 참여율(Participation Rate) 제한
각 슬라이스의 주문량이 해당 시간대 전체 거래량의 5~15%를 넘지 않도록 제한합니다. 참여율이 너무 높으면 시장 충격이 발생하고, 너무 낮으면 집행이 완료되지 않습니다.
2. 가격 제한(Price Limit) 적용
현재가 대비 불리한 방향으로 일정 틱 이상 벌어지면 해당 슬라이스를 스킵하고 다음 슬라이스에 합산합니다. 급등·급락 구간에서의 불리한 체결을 방지합니다.
3. 잔량 가속(Catch-Up) 로직
스킵된 물량이 누적되면 뒤쪽 슬라이스에 부담이 몰립니다. 잔량이 예정 대비 20% 이상 밀리면 다음 슬라이스 수량을 1.5배까지 확대하되, 참여율 상한은 유지합니다.
4. 슬리피지 실시간 모니터링
집행 중 실시간으로 체결 평균가 vs 벤치마크(VWAP/TWAP)를 비교합니다. 슬리피지가 임계값(예: 0.3%)을 초과하면 집행 속도를 조절하거나 일시 중단합니다. 자동매매 슬리피지 관리 전략에서 더 자세한 방법을 확인하세요.
자동매매 봇에 통합하기
시그널 생성과 주문 집행을 분리하는 것이 좋은 아키텍처입니다. 시그널 모듈이 "삼성전자 1000주 매수"를 결정하면, 집행 모듈이 VWAP 또는 TWAP 알고리즘으로 최적 체결을 수행합니다.
- 소형 주문 (일평균 거래량의 1% 미만): 즉시 시장가 체결이 효율적
- 중형 주문 (1~5%): TWAP으로 30분~1시간 분할
- 대형 주문 (5% 초과): VWAP으로 장 전체에 걸쳐 분산
자동매매 봇 리스크 관리와 함께 적용하면 체결 품질과 리스크 관리를 동시에 달성할 수 있습니다.
성과 측정: Implementation Shortfall
주문 집행의 품질을 측정하는 핵심 지표는 Implementation Shortfall(IS)입니다. 주문 의사결정 시점의 가격과 실제 체결 평균가의 차이를 측정합니다.
def implementation_shortfall(decision_price, exec_avg_price, side='buy'):
if side == 'buy':
return (exec_avg_price - decision_price) / decision_price * 100
else:
return (decision_price - exec_avg_price) / decision_price * 100
# IS가 낮을수록 좋은 집행
is_pct = implementation_shortfall(50000, 50150, 'buy')
print(f"IS: {is_pct:.2f}%") # 0.30%
마무리
VWAP과 TWAP은 자동매매에서 시장 충격을 줄이고 체결 품질을 높이는 핵심 알고리즘입니다. 주식처럼 거래량 패턴이 뚜렷한 시장에서는 VWAP이, 암호화폐처럼 24시간 균등한 시장에서는 TWAP이 유리합니다.
단순히 시장가로 던지는 것과 알고리즘 집행의 체결 품질 차이는 주문 규모가 클수록 극적으로 벌어집니다. 참여율 제한, 가격 제한, 잔량 가속, 슬리피지 모니터링까지 적용하면 기관급 주문 집행을 자동매매 봇에서도 구현할 수 있습니다.