๐ŸŒฐ

golden-fig โ€” Hope Crusher

"D์ผ๊นŒ์ง€ X๊ฐ€ ์ผ์–ด๋‚ ๊นŒ" ๋กฑ์ƒท(YES 5~25%) ์‹œ์žฅ์—์„œ NO ํ† ํฐ(75~95%)์„ ๋งค์ˆ˜ํ•ด, ํฌ๋ง ๋ณด์œ ์ž๋“ค์ด ๋Šฆ๊ฒŒ ๋†“๋Š” ์‹œ๊ฐ„ ๊ฐ€์น˜ ์†Œ๋ฉธ(theta)์„ ์ˆ˜ํ™•ํ•œ๋‹ค.

์œ ํ˜• ํŽ˜์ด๋“œ์ƒํƒœ ์‹ ๊ทœ ยท ๊ฒ€์ฆ ๋Œ€๊ธฐํ•ต์‹ฌ ํŽธํ–ฅ favorite-longshot bias

ํ•ต์‹ฌ ์ˆ˜์‹

์‹œ์žฅ ํ˜•ํƒœ: "D์ผ๊นŒ์ง€ X๊ฐ€ ์ผ์–ด๋‚ ๊นŒ"

BUY NO(clobTokenIds[1]) if
    0.05 โ‰ค YES โ‰ค 0.25                    # ๋กฑ์ƒท ๋ฐด๋“œ (NO = 0.75~0.95)
    AND 24h โ‰ค ํ•ด๊ฒฐ๊นŒ์ง€ โ‰ค 240h
    AND YES 24h ๋ณ€ํ™” โ‰ค +0.02              # ์‚ฌ๊ฑด ์ง„ํ–‰ ๋ฐฐ์ œ โ‘ 
    AND ์ตœ๊ทผ 6h YES ๊ธ‰๋“ฑ < 0.05           # ์‚ฌ๊ฑด ์ง„ํ–‰ ๋ฐฐ์ œ โ‘ก

์™œ ์ด ์ „๋žต์ธ๊ฐ€

Favorite-longshot bias. ์˜ˆ์ธก์‹œ์žฅ/๋ฒ ํŒ… ๋ฌธํ—Œ์—์„œ ๊ฐ€์žฅ ์ž˜ ๋ฌธ์„œํ™”๋œ ํŽธํ–ฅ์ด๋‹ค. ๋ณต๊ถŒ ์‹ฌ๋ฆฌ(์ž‘์€ ๋ˆ์œผ๋กœ ํฐ ๋ณด์ƒ ๊ธฐ๋Œ€)๋Š” ๋‚ฎ์€ ํ™•๋ฅ  ๊ตฌ๊ฐ„์—์„œ YES๋ฅผ ์ฒด๊ณ„์ ์œผ๋กœ ๊ณผ๋Œ€ํ‰๊ฐ€ํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค โ€” 1%๋กœ ํ‘œ์‹œ๋œ ์‚ฌ๊ฑด์˜ ์‹ค์ œ ํ™•๋ฅ ์€ 0.3% ์ˆ˜์ค€์ด๋‹ค. ๋ฐ˜๋Œ€๋กœ favorite์€ ๊ณผ์†Œํ‰๊ฐ€๋œ๋‹ค.

Theta decay + ์•ต์ปค๋ง. "D์ผ๊นŒ์ง€ X๊ฐ€ ์ผ์–ด๋‚ ๊นŒ" ํ˜•ํƒœ์˜ ์‹œ์žฅ์€ ์‹œ๊ฐ„์ด ์ง€๋‚ ์ˆ˜๋ก X๊ฐ€ ์ผ์–ด๋‚  ์‹œ๊ฐ„ ์ž์ฒด๊ฐ€ ์†Œ์ง„๋˜์–ด YES์˜ ์ •๋‹น ๊ฐ€์น˜๊ฐ€ ๊ธฐ๊ณ„์ ์œผ๋กœ ํ•˜๋ฝํ•œ๋‹ค(theta decay). ๊ทธ๋Ÿฌ๋‚˜ YES ๋ณด์œ ์ž๋Š” ์•ต์ปค๋ง(๋งค์ˆ˜๊ฐ€ ๊ธฐ์ค€ ์‚ฌ๊ณ )๊ณผ ํฌ๋ง์  ์‚ฌ๊ณ  ๋•Œ๋ฌธ์— ํฌ์ง€์…˜์„ ๋Šฆ๊ฒŒ ๋†“๋Š”๋‹ค โ†’ NO ๊ฐ€๊ฒฉ์ด ์ •๋‹น ๊ฐ€์น˜๋ณด๋‹ค ๋‚ฎ๊ฒŒ ์œ ์ง€๋˜๋Š” ๊ตฌ๊ฐ„์ด ์ƒ๊ธด๋‹ค. ์ฆ‰ NO ๋งค์ˆ˜๋Š” "์‹œ๊ฐ„์˜ ํ๋ฆ„"์ด๋ผ๋Š” ํ™•์‹คํ•œ ๋ฐฉํ–ฅ์„ฑ์— ๋ฒ ํŒ…ํ•˜๋ฉด์„œ, ๋Œ€์ค‘ ์‹ฌ๋ฆฌ๊ฐ€ ๋งŒ๋“  ํ• ์ธ๊นŒ์ง€ ์–ป๋Š” ๊ตฌ์กฐ๋‹ค.

cherry์˜ ๋ฏธ๋Ÿฌ. cherry๋Š” ๊ฐ™์€ ํŽธํ–ฅ์˜ favorite ์ชฝ(75~92% favorite ๋งค์ˆ˜)์„ ์ˆ˜ํ™•ํ•ด ์™”๋‹ค. fig๋Š” ๊ฐ™์€ ํŽธํ–ฅ์˜ ๋ฏธ๋Ÿฌ๋‹ค: cherry๊ฐ€ "favorite ์ €ํ‰๊ฐ€"๋ฅผ ์‚ฌ๋ฉด, fig๋Š” "longshot ๊ณผ๋Œ€ํ‰๊ฐ€"๋ฅผ ํŒ๋‹ค(= NO ๋งค์ˆ˜). ๋‘ ๋ด‡์˜ ์„ฑ๊ณผ ๋น„๊ต๊ฐ€ ์ด ํŽธํ–ฅ์˜ ์–ด๋А ์ชฝ์ด ๋” ๋‘ํ„ฐ์šด์ง€์— ๋Œ€ํ•œ A/B ๊ฒ€์ฆ์ด ๋œ๋‹ค. ๋˜ cherry์˜ --yes-only ์šด์˜์€ NO-favorite ์‹œ์žฅ ์ ˆ๋ฐ˜์„ ๋ฒ„๋ ธ๋Š”๋ฐ(STRATEGY_ANALYSIS ํ™•์ธ ์‚ฌํ•ญ), fig๋Š” ๋ฐฉํ–ฅ์„ ์ „๋žต์— ๋‚ด์žฅ(ํ•ญ์ƒ NO)ํ•ด์„œ ์ด ๋‚ญ๋น„ ์ž์ฒด๊ฐ€ ์—†๋‹ค.

banana์—์„œ ๋ฐฐ์šด ๊ฒƒ. ๊ฐœ์ˆ˜ ๊ธฐ๋ฐ˜ ์Šค๋ƒ…์ƒท ์œˆ๋„์šฐ ๋ฒ„๊ทธ(Jenkins ์ค‘๋‹จ ์‹œ 15๋ถ„ ์œˆ๋„์šฐ๊ฐ€ ์ˆ˜ ์‹œ๊ฐ„์„ ์ปค๋ฒ„), ๊ด€๋Œ€ํ•œ cold-start ํด๋ฐฑ(์Šค๋ƒ…์ƒท 6๊ฐœ ๋ฏธ๋งŒ์ด๋ฉด ์‚ฌ์‹ค์ƒ ๋ฌด์ „๋žต ์ง„์ž…), ์˜๊ตฌ one-shot(์žฌ์ง„์ž… ๊ธˆ์ง€) ๋ฌธ์ œ๋ฅผ ๋ชจ๋‘ ์ˆ˜์ •ํ•ด ๋ฐ˜์˜ํ–ˆ๋‹ค.

์ง„์ž… ๊ทœ์น™

๋ชจ๋‘ ์ถฉ์กฑํ•ด์•ผ ๋งค์ˆ˜ํ•œ๋‹ค.

์กฐ๊ฑด๊ฐ’ (๊ธฐ๋ณธ)์ด์œ 
์œ ๋™์„ฑliquidity โ‰ฅ $10,000 (Gamma liquidity)์ฒด๊ฒฐ ๊ฐ€๋Šฅ์„ฑ ํ™•๋ณด
(์˜ต์…˜) 24h ๊ฑฐ๋ž˜๋Ÿ‰volume24hr โ‰ฅ $0 (0 = ๋น„ํ™œ์„ฑ, Gamma volume24hr)ํ•„์š” ์‹œ env๋กœ ํ™œ์„ฑํ™”
์‹œ๊ฐ„ ์œˆ๋„์šฐ24h โ‰ค ํ•ด๊ฒฐ๊นŒ์ง€ โ‰ค 240h (endDate ๊ธฐ์ค€)theta ์ˆ˜ํ™• ๊ตฌ๊ฐ„ ํ•œ์ •
YES ๋กฑ์ƒท ๋ฐด๋“œ0.05 โ‰ค YES โ‰ค 0.25 (์–‘๋ ํฌํ•จ, outcomePrices[0])๋ณต๊ถŒ ์‹ฌ๋ฆฌ ๊ณผ๋Œ€ํ‰๊ฐ€ ๊ตฌ๊ฐ„๋งŒ ํŽ˜์ด๋“œ
์œˆ๋„์šฐ ์œ ํšจ์„ฑ24h ์œˆ๋„์šฐ์— โ‰ฅ 5 ํฌ์ธํŠธ, ์ปค๋ฒ„๋ฆฌ์ง€ โ‰ฅ 12h. invalid โ†’ ๋ฐฑํ•„ ์‹œ๋„ โ†’ ๊ทธ๋ž˜๋„ invalid๋ฉด ์ง„์ž… ๊ธˆ์ง€ (is_window_valid)banana์˜ ๊ด€๋Œ€ํ•œ cold-start ํด๋ฐฑ ๊ธˆ์ง€
์‚ฌ๊ฑด ์ง„ํ–‰ ๋ฐฐ์ œ โ‘ YES 24h ๋ณ€ํ™” โ‰ค +0.02 (์œˆ๋„์šฐ ์ตœ๊ณ (ๆœ€ๅค) ์Šค๋ƒ…์ƒท ๋Œ€๋น„, change_from_oldest)์ง„์งœ ์ •๋ณด๋กœ ์˜ค๋ฅด๋Š” YES ๋ฐฐ์ œ
์‚ฌ๊ฑด ์ง„ํ–‰ ๋ฐฐ์ œ โ‘ก์ตœ๊ทผ 6h YES ๊ธ‰๋“ฑ < 0.05 (6h ์œˆ๋„์šฐ ์ €์  ๋Œ€๋น„, rise_from_low)๊ธ‰๋“ฑ ์ง„ํ–‰ ์ค‘ ์ง„์ž… ์ฐจ๋‹จ
์žฌ์ง„์ž… ์ •์ฑ…HOLDING ์—†์Œ AND ๋งˆ์ง€๋ง‰ ์ฒญ์‚ฐ/skip ํ›„ 24h ๊ฒฝ๊ณผ (is_in_reentry_cooldown)์˜๊ตฌ one-shot ๋Œ€์‹  ์ฟจ๋‹ค์šด ๊ธฐ๋ฐ˜ ์žฌ์ง„์ž… ํ—ˆ์šฉ

์ง„์ž… ์‹œ NO ํ† ํฐ(clobTokenIds[1])์„ ๋งค์ˆ˜ํ•œ๋‹ค. NO ๊ฐ€๊ฒฉ์€ 0.75~0.95 ๊ตฌ๊ฐ„. ์ฃผ๋ฌธ์€ midpoint ๊ฐ€๊ฒฉ GTC limit BUY, POLYBOT_BUY_AMOUNT(USDC) รท ๊ฐ€๊ฒฉ = ์ฃผ์ˆ˜ (์ตœ์†Œ 5์ฃผ).

trader์˜ ๋งค์ˆ˜ ์ง์ „ ์žฌ๊ฒ€์ฆ: NO midpoint > 0.95(๋ฐด๋“œ ์ƒ๋‹จ)๋ฉด rapid_jump๋กœ skip ๊ธฐ๋ก(์ฟจ๋‹ค์šด 24h), < 0.75๋ฉด ์ด๋ฒˆ ์‚ฌ์ดํด๋งŒ skip.

์ฒญ์‚ฐ ๊ทœ์น™

์šฐ์„ ์ˆœ์œ„ ์ˆœ์œผ๋กœ ๊ฒ€์‚ฌํ•œ๋‹ค. trailing stop์€ ์—†๋‹ค.

์šฐ์„ ์ˆœ์œ„์กฐ๊ฑดํŒŒ๋ผ๋ฏธํ„ฐ (๊ธฐ๋ณธ๊ฐ’)exit_reason
1P&L โ‰ค -10%stop_loss_percent -0.10stop_loss (NO ํ•˜๋ฝ = YES ๊ธ‰๋“ฑ = ์‚ฌ๊ฑด ๋ฐœ์ƒ ์‹ ํ˜ธ)
2ํ˜„์žฌ๊ฐ€ โ‰ฅ min(๋งค์ˆ˜๊ฐ€ ร— 1.06, 0.99)take_profit_percent +0.06take_profit
3ํ•ด๊ฒฐ๊นŒ์ง€ < 2hexit_hours 2time_exit
-midpoint ์กฐํšŒ ๋ถˆ๊ฐ€ + ํ•ด๊ฒฐ 24h ๊ฒฝ๊ณผ-resolved_unredeemed (status=EXPIRED, ์ˆ˜๋™ redeem ํ•„์š”)

NO๋Š” ๋งŒ๊ธฐ ์ˆ˜๋ ด์ด ๋ณธ์งˆ์ด๋ฏ€๋กœ TP๊ฐ€ +6%๋กœ ์ž‘์•„๋„ ํšŒ์ „์œจ๋กœ ์ˆ˜์ต์„ ์Œ“๋Š”๋‹ค. ๋งค์ˆ˜๊ฐ€ 0.934 ์ด์ƒ์ด๋ฉด ์›๋ชฉํ‘œ๊ฐ€๊ฐ€ 0.99๋ฅผ ๋„˜์œผ๋ฏ€๋กœ 0.99 ๋„๋‹ฌ ์‹œ ์ต์ ˆ(์บก).

ํŒŒ๋ผ๋ฏธํ„ฐ (ํ™˜๊ฒฝ๋ณ€์ˆ˜)

์šฐ์„ ์ˆœ์œ„: env > config.yaml > ์ฝ”๋“œ ๊ธฐ๋ณธ๊ฐ’

env๊ธฐ๋ณธ๊ฐ’์˜๋ฏธ
POLYBOT_BUY_AMOUNT5.01ํšŒ ๋งค์ˆ˜ USDC
POLYBOT_MIN_LIQUIDITY10000์ตœ์†Œ ์œ ๋™์„ฑ $
POLYBOT_MIN_VOLUME_24H0์ตœ์†Œ 24h ๊ฑฐ๋ž˜๋Ÿ‰ $ (0 = ๋น„ํ™œ์„ฑ)
POLYBOT_TAKE_PROFIT0.06์ต์ ˆ % (๋ชฉํ‘œ๊ฐ€ 0.99 ์บก)
POLYBOT_STOP_LOSS-0.10์†์ ˆ %
POLYBOT_MAX_POSITIONS-1์ตœ๋Œ€ ๋™์‹œ ํฌ์ง€์…˜ (-1 ๋ฌด์ œํ•œ)
POLYBOT_REENTRY_COOLDOWN_HOURS24์žฌ์ง„์ž… ์ฟจ๋‹ค์šด
POLYBOT_HISTORY_BACKFILLtrueprices-history ๋ฐฑํ•„
POLYBOT_EXCLUDED_CATEGORIES""์ œ์™ธ ์นดํ…Œ๊ณ ๋ฆฌ (comma ๊ตฌ๋ถ„, ๋นˆ ๊ฐ’ = ๋น„ํ™œ์„ฑ)
POLYBOT_YES_MIN0.05YES ๋กฑ์ƒท ๋ฐด๋“œ ํ•˜ํ•œ
POLYBOT_YES_MAX0.25YES ๋กฑ์ƒท ๋ฐด๋“œ ์ƒํ•œ
POLYBOT_YES_RISE_BLOCK_24H0.0224h YES ์ƒ์Šน ์ฐจ๋‹จ ์ž„๊ณ„
POLYBOT_YES_SPIKE_BLOCK_6H0.056h YES ๊ธ‰๋“ฑ ์ฐจ๋‹จ ์ž„๊ณ„
POLYBOT_RISE_LOOKBACK_HOURS2424h ๊ฒŒ์ดํŠธ lookback
POLYBOT_SPIKE_LOOKBACK_HOURS66h ๊ฒŒ์ดํŠธ lookback
POLYBOT_ENTRY_HOURS_MIN24์ง„์ž… ์ตœ์†Œ ์ž”์—ฌ ์‹œ๊ฐ„
POLYBOT_ENTRY_HOURS_MAX240์ง„์ž… ์ตœ๋Œ€ ์ž”์—ฌ ์‹œ๊ฐ„
POLYBOT_EXIT_HOURS2ํ•ด๊ฒฐ N์‹œ๊ฐ„ ์ „ ์ฒญ์‚ฐ
LOG_LEVELINFO๋กœ๊ทธ ๋ ˆ๋ฒจ (--verbose๊ฐ€ ์ตœ์šฐ์„ )

์ด ์ „๋žต์ด ์‹คํŒจํ•˜๋Š” ๊ฒฝ์šฐ

A/B ๊ฒ€์ฆ ๊ณ„ํš

1) ์‹œ๋ฎฌ๋ ˆ์ด์…˜ (1~2์ฃผ) โ€” uv run python main.py run --simulate --job fig-sim์„ Jenkins 3~5๋ถ„ ์ฃผ๊ธฐ๋กœ ์‹คํ–‰. data/fig-sim/trades_sim.db ์ถ•์ .

2) ์†Œ์•ก ์‹ค์ „ (4์ฃผ) โ€” POLYBOT_BUY_AMOUNT๋ฅผ ์ตœ์†Œ ์ˆ˜์ค€์œผ๋กœ ์‹คํ–‰ (๋ฐด๋“œ ํŠน์„ฑ์ƒ 5์ฃผ ์ตœ์†Œ ์ฃผ๋ฌธ ์ถฉ์กฑ ํ•„์š”, NO 0.95 ๊ธฐ์ค€ ์•ฝ $4.75 ์ด์ƒ).

3) ํŒ๋‹จ ๊ธฐ์ค€ โ€” 4์ฃผ ๊ฒฝ๊ณผ + 30๊ฑด ์ด์ƒ ์™„๊ฒฐ ๊ฑฐ๋ž˜์—์„œ:

4) cherry์™€์˜ A/B โ€” ๊ฐ™์€ ํŽธํ–ฅ์˜ favorite ์ชฝ์ธ cherry์™€ ๋™์ผ ๊ธฐ๊ฐ„ ์ˆ˜์ต๋ฅ  ๋น„๊ต โ†’ ํŽธํ–ฅ์˜ ์–ด๋А ์ชฝ์ด ๋” ์ˆ˜ํ™• ๊ฐ€๋Šฅํ•œ์ง€ ํŒ๋‹จ.

๋ฒ ๋ฆฌ์—์ด์…˜ ํ›„๋ณด (๊ฐ๊ฐ --job fig-1 ์‹์œผ๋กœ job์„ ๋ถ„๋ฆฌํ•˜๋ฉด DB๊ฐ€ ๋ถ„๋ฆฌ๋˜์–ด ๋™์‹œ A/B ์šด์˜ ๊ฐ€๋Šฅ):

์‹คํ–‰ (Jenkins)

#!/bin/bash
export POLYBOT_BUY_AMOUNT=20
export POLYMARKET_PRIVATE_KEY=<Jenkins credential>
export POLYMARKET_FUNDER_ADDRESS=<Jenkins credential>
export LOG_LEVEL=INFO
# ์ „๋žต ํŒŒ๋ผ๋ฏธํ„ฐ ์˜ˆ์‹œ (๊ธฐ๋ณธ๊ฐ’๊ณผ ๋‹ค๋ฅด๊ฒŒ ์šด์˜ํ•  ๋•Œ๋งŒ)
export POLYBOT_YES_MAX=0.25
export POLYBOT_TAKE_PROFIT=0.06
export POLYBOT_REENTRY_COOLDOWN_HOURS=24

cd ./golden-fig
uv sync
uv run python ./main.py run

3~5๋ถ„ ์ฃผ๊ธฐ cron ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ๊ถŒ์žฅํ•œ๋‹ค (์Šค๋ƒ…์ƒท ์ถ•์ ์ด ์‹œ๊ทธ๋„ ํ’ˆ์งˆ์„ ์ขŒ์šฐ).