Polymarket Bot Tutorial · 32개 중 13장
Polymarket에서의 market making: bid와 ask를 어떻게 quote하고, spread를 포착하며, maker rebate(taker fee의 20-25%)를 얻는지, inventory risk 수학은 어떻게 되는지, 그리고 prediction markets에서 MM이 언제 작동하는지.
이 장에서 다루는 내용
Polymarket에서의 market making은 market book의 양쪽을 지속적으로 quote하고, 각 round trip마다 spread를 수익으로 가져가는 것을 의미합니다. 이 전략은 전통적인 금융에서 잘 알려져 있지만, Polymarket 특유의 차이는 maker-rebate 프로그램과 prediction markets의 adverse-selection 특성입니다. 이는 CFD venue보다 더 높습니다. 이 장에서는 솔직한 수학을 다룹니다.
- 쉽게 설명한 market making
- spread + rebate edge
- inventory risk와 skew
- Polymarket에서 MM이 작동하는 경우와 그렇지 않은 경우
- Code skeleton: 양쪽을 +/- N cents로 quote하기
- 뉴스 흐름에 따른 quote 조정
- adverse selection이 급증할 때 bot 종료하기
쉽게 설명한 market making
market maker는 buy price(bid)와 sell price(ask)를 둘 다, mid보다 고정 spread만큼 넓게 지속적으로 quote합니다. 누군가 bid를 치면 maker는 싸게 사고, 누군가 ask를 올리면 maker는 비싸게 팝니다. bid와 ask의 차이가 maker의 round trip당 수익입니다.
이 전략은 방향성보다는 order-flow 기반입니다. maker는 YES가 이길지에 대해 의견을 갖지 않습니다. 대신 flow가 계속되고 spread가 계속 지급될 것이라는 전제를 취합니다.
리스크는 adverse selection입니다. 당신의 bid를 치는 사람들은 당신이 알지 못하는 정보를 가지고 있습니다. 시간이 지남에 따라 MM 수익은 spread가 정보 우위를 가진 트레이더로 인한 slippage를 충분히 상쇄할 만큼 넓은지에 달려 있습니다.
spread + rebate edge
Polymarket maker의 수익원은 두 가지입니다.
Spread capture: 0.46 mid를 기준으로 bid 0.45, ask 0.47을 quote합니다. 나중에 ask에서 청산할 수 있는 bid 체결 하나마다 2 cents를 얻습니다. 순수 edge는 fill의 불균형과 가격 drift에 따라 달라집니다.
Maker rebate: Polymarket의 liquidity-rewards program은 eligible market에서 maker fill에 대해 share당 rebate를 지급합니다. 수치는 바뀔 수 있으니 현재 값은 공식 rewards 페이지를 확인하세요. rebate는 거래 자체와 별개로 pUSD로 주기적으로 지급됩니다.
대부분의 시장에서는 spread capture가 더 큰 수익원입니다. 선거 연도나 주요 스포츠 플레이오프처럼 Polymarket가 유동성을 끌어오기 위해 rebate를 높이는 넓은 시장에서는 rebate도 의미가 있습니다.
inventory risk와 skew
bid에서 반복적으로 체결되는 MM은 long position을 축적합니다. 리스크는 inventory가 long인 상태에서 mid가 하락하는 것이며, maker는 spread 수익을 얻었더라도 포지션에서 손실을 실현할 수 있습니다.
방어책: quote skew(inventory가 long이면 bid를 더 낮추고, short이면 ask를 더 높여 한쪽으로 치우친 fill을 억제); inventory cap(이미 너무 long인 side에서는 quote를 중단); active rebalancing(inventory가 한계에 도달했을 때 가끔 spread를 가로질러 position을 줄이기).
수학적으로, bid fill의 60%가 가격이 2 cents 불리하게 움직이기 전에 청산되지 않는다면, 그 fill들만으로도 전략은 손실입니다. fill imbalance가 65/35를 넘으면 공격적으로 skew하세요.
Polymarket에서 MM이 작동하는 경우와 그렇지 않은 경우
다음 세 가지 조건이 충족될 때 Polymarket에서 MM이 작동합니다.
- Liquid book: quote 경쟁이 충분해 spread는 경쟁력 있지만 0은 아닌 경우. 2024년 대선 market, 주요 NFL/NBA 경기, BTC up/down 5m 등이 해당됩니다.
- Two-sided flow: 매수자와 매도자가 모두 활발한 경우. 한쪽으로만 치우친 시장(0.95+로 거의 resolution된 상태)은 maker가 가져갈 것이 없습니다.
- Bounded price moves: spread capture를 5-cent 점프가 먹어치우는 경우를 피해야 합니다. 안정적인 mid-range market(0.40-0.60)이 가장 유리합니다.
MM이 실패하는 경우: mid가 quote를 다시 낼 속도보다 더 빨리 움직이는 뉴스-driven market, 다음 trade가 5단계를 훑고 지나갈 정도로 유동성이 낮은 book, 한쪽이 0 또는 1로 수렴하는 resolution-imminent market입니다.
Code skeleton: 양쪽을 +/- N cents로 quote하기
가장 단순하게 동작하는 maker를 위한 pseudocode입니다.
SPREAD_CENTS = 2
INVENTORY_CAP_SHARES = 50
def make_loop(token_id):
while True:
book = fetch_book(token_id)
mid = (book.best_bid + book.best_ask) / 2
inv = chain_balance(token_id)
# Skew: pull the side we are too long on
bid_px = mid - SPREAD_CENTS/200 - (0.005 if inv > INVENTORY_CAP_SHARES * 0.6 else 0)
ask_px = mid + SPREAD_CENTS/200 + (0.005 if inv < -INVENTORY_CAP_SHARES * 0.6 else 0)
cancel_my_existing_quotes(token_id)
if inv < INVENTORY_CAP_SHARES:
place_gtc(token_id, side="BUY", price=bid_px, size=5)
if inv > -INVENTORY_CAP_SHARES:
place_gtc(token_id, side="SELL", price=ask_px, size=min(5, inv))
time.sleep(2)
Production maker에는 다음이 추가됩니다: side별 inventory 추적, cancel-before-place 순서, 예측 가능성을 줄이기 위한 re-quote 간격의 jitter, adverse selection 시 kill-switch(다음 섹션).
뉴스 흐름에 따른 quote 조정
뉴스 이벤트가 발생하면 공정가치는 당신의 quote보다 먼저 움직입니다. 뉴스 흐름 동안 quote를 내리지 않는 MM은 picked off됩니다.
신호: 30초 이내에 incoming fill의 cancel rate가 baseline 대비 약 3배 이상 급증하거나, 더 넓게는 event-stream 교차 확인(Polymarket Twitter/Discord, Bloomberg headline feed). 이를 감지하면 maker는 모든 quote를 60-120초 동안 철회하고, 새로운 mid가 안정될 때까지 기다린 뒤 새로운 중심을 기준으로 다시 quote합니다.
가장 단순한 구현은 token의 last-trade-price stream을 봅니다. rolling-window 평균에서 2 standard deviation 이상 벗어나는 점프가 발생하면 pause를 트리거합니다. 가격이 30초 이상 안정되면 bot이 다시 참여합니다.
adverse selection이 급증할 때 bot 종료하기
강제 종료 조건입니다. bot의 최근 50개 fill에 대한 fill PnL이 급격히 음수로 돌아서면, 문제가 있다는 뜻입니다. 시장이 이제 news-driven 상태이므로 더 이상 making을 해서는 안 되거나, 현재 adverse-selection 수준에 비해 spread가 너무 좁게 설정된 것입니다.
코드에 넣어야 할 종료 조건:
- 연속 5번의 bid fill 후 ask fill이 없고, 첫 fill 이후 mid가 1c 이상 하락.
- 최근 25개 round-trip fill의 realized PnL이 기대치의 -25% 이하.
- WebSocket disconnect 또는 stale book 감지.
- 양쪽 어느 side든 inventory가 cap에 도달한 상태가 5분 이상 지속.
트리거되면 모든 주문을 취소하고, 시장가로 inventory를 정리한 뒤 15분 이상 중단합니다. kill switch가 없는 market maker는 변동성이 큰 기간에 수동으로 trader가 알아차릴 때까지 계속 손실을 내게 됩니다. 항상 생각보다 더 오래 걸립니다.





