이 문서는 Polymarket 15분 Up/Down 마켓에서 자동 거래를 실행하는 방법을 설명합니다.
Note: 이 가이드는 거래 실행 자동화에 집중합니다.
매매 전략(시그널 생성 로직)은 별도로 커스터마이징하세요.
- Python 3.10+
- Polygon 지갑 (USDC 보유)
- Polymarket 계정 (지갑 연동 완료)
# ===== 필수 (지갑) =====
PRIVATE_KEY=0x... # EOA 개인키 (Polygon)
SIGNATURE_TYPE=2 # EOA=0, POLY_PROXY=1, POLY_GNOSIS=2
FUNDER_ADDRESS=0x... # 지갑 주소
# ===== 거래 설정 =====
TRADE_AMOUNT=1 # 거래당 금액 ($)
DRY_RUN=false # true = 모의 거래
MAX_DAILY_TRADES=500 # 일일 최대 거래 수
# ===== 텔레그램 알림 (선택) =====
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=https://clob.polymarket.com
GET /markets?tag=crypto-15m-up-down&closed=falseResponse:
{
"data": [{
"condition_id": "0xabc123...",
"question": "Bitcoin Up or Down - February 5, 6:00AM-6:15AM ET",
"market_slug": "btc-updown-15m-1707127200",
"tokens": [
{"token_id": "111...", "outcome": "Up", "price": 0.51},
{"token_id": "222...", "outcome": "Down", "price": 0.49}
],
"end_date_iso": "2024-02-05T11:15:00Z"
}]
}핵심 필드:
| 필드 | 설명 |
|---|---|
condition_id |
마켓 고유 ID |
market_slug |
슬러그 (타임스탬프 포함) |
tokens[].token_id |
Up/Down 토큰 ID |
tokens[].price |
현재 가격 (0.0-1.0) |
end_date_iso |
마켓 종료 시간 |
POST /order
Content-Type: application/json
Headers:
POLY-ADDRESS: {지갑주소}
POLY-SIGNATURE: {서명}
POLY-TIMESTAMP: {타임스탬프}
POLY-NONCE: {논스}Request Body:
{
"order": {
"tokenID": "111...",
"price": "0.51",
"size": "2",
"side": "BUY",
"feeRateBps": "0",
"nonce": "0",
"expiration": "0",
"signatureType": 2
},
"signature": "0x..."
}Response (성공):
{
"success": true,
"orderID": "0xdef456...",
"status": "matched",
"takingAmount": "2",
"makingAmount": "1",
"transactionsHashes": ["0x..."]
}Polymarket은 EIP-712 서명을 사용합니다.
from eth_account import Account
from eth_account.messages import encode_typed_data
def sign_order(order_data: dict, private_key: str) -> str:
"""
EIP-712 타입 데이터 서명
"""
domain = {
"name": "Polymarket CTF Exchange",
"version": "1",
"chainId": 137, # Polygon
}
types = {
"Order": [
{"name": "tokenId", "type": "uint256"},
{"name": "price", "type": "uint256"},
{"name": "size", "type": "uint256"},
{"name": "side", "type": "uint8"},
# ... 추가 필드
]
}
message = encode_typed_data(domain, types, order_data)
signed = Account.sign_message(message, private_key)
return signed.signature.hex()┌─────────────────────────────────────────────────────────────┐
│ 1. 마켓 조회 │
│ GET /markets?tag=crypto-15m-up-down&closed=false │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. 거래 결정 (YOUR STRATEGY) │
│ - 방향: "up" or "down" │
│ - 토큰 선택: tokens[0] (Up) or tokens[1] (Down) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. 주문 생성 │
│ - size = TRADE_AMOUNT / price │
│ - 최소 5 shares 이상 (Polymarket 최소 단위) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 4. 서명 (EIP-712) │
│ - PRIVATE_KEY로 주문 데이터 서명 │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 5. 주문 제출 │
│ POST /order │
│ - Headers: POLY-ADDRESS, POLY-SIGNATURE, ... │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 6. 결과 확인 │
│ - success: true → 체결 완료 │
│ - transactionsHashes로 Polygonscan 확인 가능 │
└─────────────────────────────────────────────────────────────┘
import asyncio
import aiohttp
from eth_account import Account
CLOB_URL = "https://clob.polymarket.com"
PRIVATE_KEY = "0x..."
WALLET = "0x..."
async def get_markets():
"""15분 마켓 조회"""
async with aiohttp.ClientSession() as session:
url = f"{CLOB_URL}/markets?tag=crypto-15m-up-down&closed=false"
async with session.get(url) as resp:
data = await resp.json()
return data.get("data", [])
async def execute_trade(token_id: str, price: float, amount: float):
"""
거래 실행
Args:
token_id: Up 또는 Down 토큰 ID
price: 현재 가격 (0.0-1.0)
amount: 거래 금액 ($)
"""
size = amount / price # shares 계산
order = {
"tokenID": token_id,
"price": str(int(price * 1e6)), # 6 decimals
"size": str(int(size * 1e6)),
"side": "BUY",
"feeRateBps": "0",
"nonce": "0",
"expiration": "0",
"signatureType": 2
}
# 서명 생성 (실제로는 EIP-712 필요)
signature = sign_order(order, PRIVATE_KEY)
headers = {
"POLY-ADDRESS": WALLET,
"POLY-SIGNATURE": signature,
"POLY-TIMESTAMP": str(int(time.time())),
"POLY-NONCE": "0"
}
async with aiohttp.ClientSession() as session:
async with session.post(
f"{CLOB_URL}/order",
json={"order": order, "signature": signature},
headers=headers
) as resp:
return await resp.json()
async def main():
# 1. 마켓 조회
markets = await get_markets()
for market in markets:
# 2. BTC 마켓 찾기
if "Bitcoin" not in market["question"]:
continue
up_token = market["tokens"][0]
down_token = market["tokens"][1]
# 3. 거래 결정 (YOUR STRATEGY HERE)
direction = "up" # 또는 "down"
# 4. 토큰 선택
token = up_token if direction == "up" else down_token
# 5. 거래 실행
result = await execute_trade(
token_id=token["token_id"],
price=float(token["price"]),
amount=1.0 # $1
)
print(f"Trade result: {result}")
if __name__ == "__main__":
asyncio.run(main())| 항목 | 값 | 설명 |
|---|---|---|
| 최소 거래 | ~$1 | 5+ shares 필요 |
| 수수료 | 0% | Maker 수수료 없음 |
| 체인 | Polygon | USDC 필요 |
| Rate Limit | 50 req/sec | API 호출 제한 |
- CLOB API: https://docs.polymarket.com/
- Python SDK: https://github.com/Polymarket/py-clob-client
- Order Signing: https://docs.polymarket.com/#signing-orders
- USDC Contract:
0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174 - Explorer: https://polygonscan.com/
→ Polygon 지갑에 USDC 충전
→ SIGNATURE_TYPE 확인 (EOA=0, POLY_GNOSIS=2)
→ 최소 5 shares 이상 필요 ($1 at 20¢ = 5 shares)