ํ๋ฅ 80~90% ๊ตฌ๊ฐ์ favorite์ ๋งค์ํ๊ณ 90% ๋๋ฌ ์ ๋งค๋ โ ๊ฑฐ๋๋น ์ฝ 10% ํ์ ์์ต์ ๋ ธ๋ฆฌ๋ ๋จ์ threshold ์ ๋ต.
BUY : 0.80 โค p < 0.90 # p = Yes/No ์ค ๋์ ์ชฝ(favorite) ํ๋ฅ
AND liquidity โฅ 50,000 AND volume โฅ 100,000 AND NOT sports
AND condition_id๋น ํ์ 1ํ (์ฌ๊ฑฐ๋ ๊ธ์ง)
SELL: p โฅ 0.90 โ ๋ณด์ ์ ๋ ๋งค๋ # ์ ์ผํ ์ฒญ์ฐ ์กฐ๊ฑด โ ์์ ยท์๊ฐ ์ฒญ์ฐยท๋ง๊ธฐ ์ฒ๋ฆฌ ์์
SKIP: ๋งค์ ์ง์ p โฅ 0.90 โ rapid_jump, ์๊ตฌ ์ ์ธGolden Apple์ Polymarket ๋ฐ์ด๋๋ฆฌ ์์ธก์์ฅ์์ ํ๋ฅ (๊ฐ๊ฒฉ)์ด 80% ์ด์ 90% ๋ฏธ๋ง์ธ outcome(Yes/No ์ค ๋์ ์ชฝ)์ ๋งค์ํ๊ณ , 90% ๋๋ฌ ์ ๋งค๋ํด ๊ฑฐ๋๋น ์ฝ 10%์ ํ์ ์์ต์ ๋ ธ๋ฆฌ๋ ๋จ์ threshold ์ ๋ต ๋ด์ด๋ค. ํต์ฌ ๊ฐ์ ์ ๋ ๊ฐ์ง โ "์ ๋ณด์ ํ์ฐ ์๋๋ก ์ธํด 80%๋ฅผ ๋ํํ ์์ธก์ ์ธ์ ๊ฐ 90%์ ๋๋ฌํ๋ค", "์๊ฐ์ด ์ง๋ ์๋ก ์์ฅ ํ๋ฅ ์ด ์ค์ ์ฌ๊ฑด ํ๋ฅ ๋ก ์๋ ดํ๋ค".
์์ (stop loss)์ ์๋์ ์ผ๋ก ์๊ณ , ํ ๋ฒ ๊ฑฐ๋(๋๋ ๊ธ๋ฑ์ผ๋ก skip)ํ ์์ฅ์ ์๊ตฌํ ์ฌ๊ฑฐ๋ํ์ง ์์ผ๋ฉฐ, ๋๋ค์ฑ์ด ํฐ ์คํฌ์ธ ์์ฅ์ ์ ๋ฉด ์ ์ธํ๋ค. Jenkins๊ฐ 5๋ถ ์ฃผ๊ธฐ๋ก polybot run์ ์คํํ๋ stateless one-shot ๊ตฌ์กฐ์ด๊ณ , ์ํ๋ job๋ณ ๋ก์ปฌ SQLite(data/{job}/trades.db)์๋ง ์ ์ฅ๋๋ค. ๋์ผ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ์์๋ง ๋ฌ๋ฆฌํ 2๊ฐ Jenkins job์ผ๋ก ๋๋ ค ๋์๋ณด๋์ GOLDEN-APPLE (1), (2) ๊ณ์ ์ ์ด์ํ๋ค.
๋งค์ ํ์ดํ๋ผ์ธ โ Gamma API ์ ์ฒด ์์ฅ ํ์ด์ง๋ค์ด์ (100๊ฐ์ฉ, offset ์ต๋ 5,000) ํ ์๋ ์กฐ๊ฑด์ ๋ชจ๋ ํต๊ณผํด์ผ ๋งค์ํ๋ค.
| ์กฐ๊ฑด | ๊ฐ (yaml ํ์ฌ๊ฐ) | ๋น๊ณ |
|---|---|---|
| ํ๋ฅ ๊ตฌ๊ฐ | 0.80 โค p < 0.90 | outcomePrices ์ค ํฐ ์ชฝ(favorite) ์ ํ. 90% ์ด์์ ํ๋ณด ์ ์ธ(๊ธ๋ฑ์ฅ ์ง์
๋ฐฉ์ง) |
| ์ ๋์ฑ | liquidity โฅ 50,000 | Gamma liquidity ํ๋. ์ฝ๋ ๊ธฐ๋ณธ๊ฐ 100,000 |
| ๊ฑฐ๋๋ | volume โฅ 100,000 | Gamma volume(๋์ ). ์ฝ๋ ๊ธฐ๋ณธ๊ฐ 0(๋นํ์ฑ) |
| ์นดํ ๊ณ ๋ฆฌ | ์คํฌ์ธ ์ ์ธ | tags(slug/label) + question/slug ํ
์คํธ์ SPORTS_KEYWORDS(์ฝ 60๊ฐ) ๋งค์นญ ์ ์ ์ธ |
| ์ค๋ณต ์ฒดํฌ | condition_id๋น ํ์ 1ํ | trades ๋๋ skipped_markets์ ์์ผ๋ฉด skip |
| ๋งค์ ์ง์ ์ฌ๊ฒ์ฆ | CLOB midpoint ์ฌ์กฐํ | p โฅ 0.90 โ rapid_jump ์๊ตฌ ์ ์ธ / p < 0.80 โ ์ด๋ฒ ์ฌ์ดํด๋ง skip |
| ์ต์ ์๋ | shares = 5 USDC รท midpoint โฅ 5์ฃผ | Polymarket ์ต์ ์ฃผ๋ฌธ ์๋ MIN_ORDER_SIZE=5 |
| ์ฃผ๋ฌธ | GTC limit BUY @ midpoint | 0.01 tick ๋ฐ์ฌ๋ฆผ, [0.01, 0.99] clamp. ์๋ต์ orderID๊ฐ ์์ผ๋ฉด ์ฆ์ HOLDING ๊ธฐ๋ก(์ฒด๊ฒฐ ํ์ธ ์์) |
๋งค๋ ํ์ดํ๋ผ์ธ โ ๋งค์๋ณด๋ค ๋จผ์ (Phase 1) ์คํ๋๋ฉฐ, ์ฒญ์ฐ ์กฐ๊ฑด์ ๋จ ํ๋๋ค.
| ์ฐ์ ์์ | ์กฐ๊ฑด | ์ฒ๋ฆฌ |
|---|---|---|
| 1 (์ ์ผ) | CLOB midpoint โฅ 0.90 (sell_threshold) | ์ ๋ midpoint limit SELL GTC โ realized_pnl = (sell - buy) ร shares ๊ธฐ๋ก ํ COMPLETED |
| - | midpoint < 0.90 | ๋ฌด์กฐ๊ฑด ๋ณด์ ์ ์ง. ์์ ยท์๊ฐ ๊ธฐ๋ฐ ์ฒญ์ฐยท๋ง๊ธฐ ์ฒ๋ฆฌ ๋ก์ง ์์ |
(์ค์บ) --[0.80โคp<0.90 & ํํฐ ํต๊ณผ]--> HOLDING --[pโฅ0.90]--> COMPLETED (์ค์บ) --[๋งค์ ์ง์ pโฅ0.90]--> SKIPPED(rapid_jump, ์๊ตฌ ์ ์ธ) HOLDING --[p ํ๋ฝ/๋ง๊ธฐ]--> HOLDING (์์ํ; redeem ๋ก์ง ์์)
ํ๋ผ๋ฏธํฐ (์ฐ์ ์์: env var > config.yaml > ์ฝ๋ ๊ธฐ๋ณธ๊ฐ)
| ํ๋ผ๋ฏธํฐ | env var | yaml ํ์ฌ๊ฐ | ์ฝ๋ ๊ธฐ๋ณธ๊ฐ | ์๋ฏธ |
|---|---|---|---|---|
buy_threshold | POLYBOT_BUY_THRESHOLD | 0.80 | 0.80 | ๋งค์ ์ต์ ํ๋ฅ |
sell_threshold | POLYBOT_SELL_THRESHOLD | 0.90 | 0.90 | ๋งค๋ ํธ๋ฆฌ๊ฑฐ ํ๋ฅ = ๋งค์ ์ํ(๋ฏธ๋ง) |
buy_amount_usdc | POLYBOT_BUY_AMOUNT | 5.0 | 10.0 | 1ํ ๋งค์ ๊ธ์ก(USDC) |
min_liquidity | POLYBOT_MIN_LIQUIDITY | 50,000 | 100,000 | Gamma liquidity ํ๋ ์ต์๊ฐ($) |
min_volume | POLYBOT_MIN_VOLUME | 100,000 | 0 (๋นํ์ฑ) | Gamma volume(๋์ ) ์ต์๊ฐ($) |
max_positions | POLYBOT_MAX_POSITIONS | -1 (๋ฌด์ ํ) | -1 | ๋์ HOLDING ์ ์ํ |
excluded_categories | (env ์์, yaml๋ง) | Sports/NFL/NBA ๋ฑ 10์ข | ๋์ผ | ์ ์ธ ์นดํ ๊ณ ๋ฆฌ(ํ๊ทธ+ํค์๋) |
simulation_mode | (CLI --simulate๊ฐ override) | false | false | true๋ฉด ์ฃผ๋ฌธ ๋ฏธ์ ์ก, trades_sim.db ์ฌ์ฉ |
MIN_ORDER_SIZE | ํ๋์ฝ๋ฉ (trader) | - | 5.0 (์ฃผ) | Polymarket ์ต์ ์ฃผ๋ฌธ ์๋ |
| tick size | ํ๋์ฝ๋ฉ (clob client) | - | 0.01 | ๊ฐ๊ฒฉ ๋ฐ์ฌ๋ฆผ ๋จ์, [0.01, 0.99]๋ก clamp |
ํ์ credential์ POLYMARKET_PRIVATE_KEYยทPOLYMARKET_FUNDER_ADDRESS(์์ผ๋ฉด ์ฆ์ ์ข
๋ฃ, private key์ hex prefix๋ ์๋ ์ ๊ฑฐ). SLACK_WEBHOOK_URL์ ํ์ฌ ๋งค๋งค ํ๋ก์ฐ์์ ์ฌ์ฉ๋์ง ์๋๋ค. Jenkins์์ job๋ง๋ค env var๋ง ๋ฌ๋ฆฌ ์ฃผ๋ฉด ๊ฐ์ ์ฝ๋๋ก ์์ดํ ์ ๋ต ์ธ์คํด์ค๋ฅผ ์ด์ํ ์ ์๋ค โ GOLDEN-APPLE (1)/(2)์ ๊ตฌํ ๋ฐฉ์.
trades_sim.db๋ก ์ค๊ฑฐ๋ DB ์ค์ผ ์์.orderID๋ง ์์ผ๋ฉด ๋งค์๋ ์ฆ์ HOLDING, ๋งค๋๋ ์ฆ์ COMPLETED. midpoint ๊ฐ๊ฒฉ BUY limit์ best ask๋ณด๋ค ๋ฎ์ ์ฒด๊ฒฐ๋์ง ์์ ์ฑ ์ด๋ ค ์์ ๊ฐ๋ฅ์ฑ์ด ๋๊ณ , ์ด ๊ฒฝ์ฐ DB์ ํฌ์ง์
ยทrealized_pnl์ ํ๊ตฌ๊ฐ ๋๋ค. PENDING_BUY/PENDING_SELLยทcancel_orderยทget_open_orders๊ฐ ๊ตฌํ๋ผ ์์์๋ ๋ฏธ์ฌ์ฉ.max_positions=-1 + ํ๋ณด 50๊ฐ(๋ก๊ทธ ํ์ธ) + ์ฌ์ดํด๋น ์ ํ๋ณด ๋งค์ โ ํ ์ฌ์ดํด์ ์๊ณ ์์ง ๊ฐ๋ฅ. USDC ์๊ณ ์กฐํยทํ๋ณด ์ฐ์ ์์ ์ ๋ ฌ ์์.volume24hr ๊ฐ์ ์ต๊ทผ ํ๋์ฑ ์งํ ๋ฏธ์ฌ์ฉ.total_pnl์ realized๋ง ํฉ์ฐ. MarketSnapshot ํ
์ด๋ธ์ ์ ์๋ง ์๊ณ ์ ์ฅ ํธ์ถ์ด ์์ด ์ฌํ ๊ฒ์ฆ์ฉ ์๊ณ์ด์ด ์ ์์ธ๋ค.utcnow(), ์ฃผ๋ฌธ ์ฑ๊ณต ํ์ ์ด API ์๋ต ํํ ๋ณํ์ ์ทจ์ฝ, buy_probability์ ์ฌ์กฐํ ๊ฐ๊ฒฉ ์ ์ฅ(์ค์บโ์ฃผ๋ฌธ ๊ฐ๊ฒฉ ๋ณํ ๋ถ์ ๋ถ๊ฐ), ํ
์คํธ 0๊ฐ.์ ํ์ ๋ค์ ์ ๊ท ๋ด ์ค๊ณ์ ๋ค์๊ณผ ๊ฐ์ด ๋ฐ์๋๋ค.
โ ์๋ฎฌ๋ ์ด์
: --simulate๋ก ์ฃผ๋ฌธ ์ ์ก๋ง mock, ์ค์บ~DB ๊ธฐ๋ก์ ์ค๊ฑฐ๋์ ๋์ผ ๊ฒฝ๋ก(trades_sim.db ๋ถ๋ฆฌ). ๋จ, midpoint ์ฆ์ ์ฒด๊ฒฐ ๊ฐ์ ์ด๋ผ ์๋ฎฌ P&L์ ๊ณผ๋ํ๊ฐ ๊ฒฝํฅ(์ฝ์ 7)์ ๊ฐ์ํ๋ค. โก ์์ก ์ค๊ฑฐ๋: yaml buy_amount_usdc: 5.0(USDC)์ผ๋ก ๊ฑด๋น ์์ค์ ์ ํ. โข ๋ณํ ๋น๊ต ํ ์ฆ์ก: ๊ฐ์ ์ฝ๋๋ฅผ env๋ง ๋ฌ๋ฆฌํ 2๊ฐ Jenkins job(GOLDEN-APPLE (1)/(2))์ผ๋ก ๋ณํ ์ด์ํ๊ณ ๋์๋ณด๋์์ ์๊ณ ยท์์ต๋ฅ ์ ๋น๊ตํ๋ค. ํ๋จ ์ DB realized P&L์ ์ฒด๊ฒฐ ํ์ธ ๋ถ์ฌ(์ฝ์ 1)๋ก ์ค์๊ณ ์ ์ด๊ธ๋ ์ ์์ผ๋ฏ๋ก ์ง๊ฐ ์๊ณ ๊ธฐ์ค์ผ๋ก ๊ต์ฐจ ํ์ธํ๋ค.
# Jenkins job ร 2 (5๋ถ cron, one-shot) โ ๊ฐ์ ์ฝ๋, env๋ง ์์ด โ GOLDEN-APPLE (1)/(2)
cd ./golden-apple
export POLYMARKET_PRIVATE_KEY=<Jenkins credential>
export POLYMARKET_FUNDER_ADDRESS=<Jenkins credential>
export POLYBOT_BUY_THRESHOLD=0.80 # job๋ณ๋ก ์๊ณ๊ฐยท๊ธ์ก๋ง ๋ฌ๋ฆฌ ์ง์
export POLYBOT_SELL_THRESHOLD=0.90
uv sync --frozen
uv run polybot run --job apple-1 # ์ํ๋ data/{job}/trades.db ์ ๊ฒฉ๋ฆฌ