마켓 메이킹 자동매매 전략

마켓 메이킹이란?

마켓 메이킹(Market Making)은 매수 호가와 매도 호가를 동시에 제출하여 스프레드(bid-ask spread) 차이로 수익을 추구하는 자동매매 전략입니다. 전통 금융에서는 증권사·HFT 펌이 독점하던 영역이지만, 암호화폐 시장에서는 개인 트레이더도 API를 통해 마켓 메이킹 봇을 운영할 수 있습니다.

마켓 메이킹의 핵심은 유동성 공급입니다. 시장에 유동성을 제공하는 대가로 스프레드 수익을 얻고, 일부 거래소에서는 메이커 수수료 리베이트까지 받을 수 있습니다.

마켓 메이킹의 수익 구조

마켓 메이킹 봇의 수익은 세 가지 요소로 구성됩니다:

  • 스프레드 수익: 매수·매도 호가 차이에서 발생하는 기본 수익
  • 메이커 리베이트: 거래소가 유동성 공급자에게 돌려주는 수수료 (보통 0.01~0.025%)
  • 재고 수익/손실: 보유 포지션의 가격 변동에 따른 손익

이 중 재고 리스크(Inventory Risk)가 마켓 메이킹의 가장 큰 위험 요소입니다. 한쪽 방향으로만 체결이 쏠리면 포지션이 누적되어 큰 손실로 이어질 수 있습니다.

기본 마켓 메이킹 봇 구현

파이썬과 ccxt를 활용한 기본적인 마켓 메이킹 봇 구조입니다. 중간 가격(mid price) 기준으로 양쪽에 주문을 배치합니다.

import ccxt
import time

exchange = ccxt.binance({
    'apiKey': 'YOUR_API_KEY',
    'secret': 'YOUR_SECRET_KEY',
})

SYMBOL = 'BTC/USDT'
SPREAD = 0.002       # 스프레드 0.2%
ORDER_SIZE = 0.001   # 주문 수량 (BTC)
REFRESH_SEC = 5      # 주문 갱신 주기

def get_mid_price():
    """오더북 중간 가격 계산"""
    book = exchange.fetch_order_book(SYMBOL, limit=5)
    best_bid = book['bids'][0][0]
    best_ask = book['asks'][0][0]
    return (best_bid + best_ask) / 2

def place_orders():
    """매수·매도 주문 동시 배치"""
    mid = get_mid_price()
    buy_price = round(mid * (1 - SPREAD / 2), 2)
    sell_price = round(mid * (1 + SPREAD / 2), 2)

    buy_order = exchange.create_limit_buy_order(
        SYMBOL, ORDER_SIZE, buy_price
    )
    sell_order = exchange.create_limit_sell_order(
        SYMBOL, ORDER_SIZE, sell_price
    )
    print(f"매수: {buy_price} | 매도: {sell_price} | 스프레드: {SPREAD*100}%")
    return buy_order, sell_order

def cancel_all():
    """미체결 주문 전량 취소"""
    orders = exchange.fetch_open_orders(SYMBOL)
    for order in orders:
        exchange.cancel_order(order['id'], SYMBOL)

def run_bot():
    """메인 루프"""
    while True:
        try:
            cancel_all()
            place_orders()
            time.sleep(REFRESH_SEC)
        except Exception as e:
            print(f"에러: {e}")
            time.sleep(10)

재고 관리 전략

마켓 메이킹에서 가장 중요한 것은 재고(포지션) 관리입니다. 포지션이 한쪽으로 쏠리면 방향성 리스크에 노출됩니다.

전략 원리 장단점
호가 비대칭 조정 롱 포지션 ↑ → 매도 호가를 더 가깝게 자연스러운 재고 해소, 구현 간단
주문 수량 조정 롱 포지션 ↑ → 매도 수량 증가 빠른 재고 해소, 스프레드 유지
헤지 주문 선물 반대 포지션으로 헤지 리스크 제거, 비용 발생
포지션 한도 설정 최대 보유량 초과 시 한쪽 주문 중단 단순하고 안전, 기회 상실

아래는 재고 기반으로 호가를 비대칭 조정하는 코드입니다:

MAX_INVENTORY = 0.01  # 최대 보유량 (BTC)

def inventory_skew(current_inventory):
    """재고 기반 스프레드 비대칭 조정"""
    skew = current_inventory / MAX_INVENTORY  # -1 ~ +1
    mid = get_mid_price()

    # 재고가 많으면 매도 호가를 중간가에 가깝게
    buy_offset = SPREAD / 2 * (1 + skew)
    sell_offset = SPREAD / 2 * (1 - skew)

    buy_price = round(mid * (1 - buy_offset), 2)
    sell_price = round(mid * (1 + sell_offset), 2)
    return buy_price, sell_price

변동성 기반 동적 스프레드

시장 변동성이 높아지면 스프레드를 넓혀 리스크를 줄이고, 변동성이 낮으면 스프레드를 좁혀 체결 확률을 높이는 것이 핵심입니다.

import numpy as np

def dynamic_spread(ohlcv_data, base_spread=0.002, lookback=24):
    """변동성 기반 동적 스프레드 계산"""
    closes = [d[4] for d in ohlcv_data[-lookback:]]
    returns = [np.log(closes[i]/closes[i-1]) for i in range(1, len(closes))]
    volatility = np.std(returns) * np.sqrt(24)  # 일간 변동성

    # 변동성에 비례하여 스프레드 조정 (최소 0.1%, 최대 1%)
    spread = max(0.001, min(0.01, base_spread * (1 + volatility * 10)))
    return round(spread, 4)

def fetch_volatility_and_trade():
    """변동성 반영 마켓 메이킹"""
    ohlcv = exchange.fetch_ohlcv(SYMBOL, '1h', limit=48)
    spread = dynamic_spread(ohlcv)
    print(f"현재 스프레드: {spread*100:.2f}%")
    # spread를 적용하여 주문 배치
    mid = get_mid_price()
    buy_price = round(mid * (1 - spread / 2), 2)
    sell_price = round(mid * (1 + spread / 2), 2)
    return buy_price, sell_price

실전 운영 시 핵심 주의사항

마켓 메이킹 봇을 실전에서 운영할 때 반드시 고려해야 할 사항들입니다:

1. 거래소 선택

메이커 수수료가 낮거나 리베이트가 있는 거래소를 선택해야 합니다. 테이커 수수료 0.1%인 거래소에서 0.2% 스프레드로 마켓 메이킹을 하면 수수료만으로 수익이 사라집니다.

2. 급등락 대응

뉴스·이벤트로 가격이 급변할 때는 주문이 한쪽으로만 체결되는 역선택(Adverse Selection) 위험이 큽니다. 변동성 급등 감지 시 즉시 모든 주문을 취소하는 킬 스위치(Kill Switch)가 필수입니다.

3. API 레이트 리밋

주문 갱신 주기가 너무 짧으면 거래소 API 제한에 걸립니다. 바이낸스 기준 분당 1,200개 요청이 한도이므로, 주문 갱신 주기를 3~5초 이상으로 설정하는 것이 안전합니다.

4. 킬 스위치 구현

def kill_switch(current_pnl, max_loss=-50):
    """일일 최대 손실 도달 시 전량 청산"""
    if current_pnl <= max_loss:
        cancel_all()
        # 보유 포지션 시장가 청산
        balance = exchange.fetch_balance()
        btc = balance['BTC']['free']
        if btc > 0.0001:
            exchange.create_market_sell_order(SYMBOL, btc)
        print(f"[킬스위치] 손실 ${current_pnl} → 전량 청산")
        return True
    return False

마켓 메이킹 vs 다른 자동매매 전략

마켓 메이킹은 방향성을 예측하지 않는 시장 중립(Market Neutral) 전략입니다. 변동성 돌파 전략처럼 추세를 따라가는 전략과는 성격이 다르며, 횡보장에서 더 유리합니다.

자동매매 봇 만들기 실전 가이드에서 ccxt 기반 봇 아키텍처를 먼저 이해하면 마켓 메이킹 봇 구현이 훨씬 수월합니다.

정리

마켓 메이킹은 스프레드 수익 + 수수료 리베이트를 노리는 고급 자동매매 전략입니다. 핵심 포인트를 정리하면:

  • 매수·매도 호가를 동시에 제출하여 스프레드 차익 확보
  • 재고(포지션) 관리가 수익의 핵심 — 호가 비대칭 조정 필수
  • 변동성에 따라 스프레드를 동적으로 조정
  • 킬 스위치로 급등락 시 자동 청산
  • 메이커 리베이트가 있는 거래소 선택이 중요

마켓 메이킹은 진입 장벽이 높지만, 제대로 구현하면 시장 방향에 관계없이 꾸준한 수익을 기대할 수 있는 전략입니다.

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