์๋ favorite(โฅ70%)์ด๋ ํ ํฐ์ด ์ ์ฌ/๋ฃจ๋จธ์ ๊ณตํฉ ํฌ๋งค๋ก 12%p ์ด์ ๊ธ๋ฝํ ๋ค, ๋ฐ๋ฅ ์์ ํ๊ฐ ํ์ธ๋๋ฉด ์ญ๋งค์ํด ๊ณผ์๋ฐ์์ ๋๋๋ฆผ(+10%)์ ์ํํ๋ค.
p = favorite์๋ ์ชฝ ํ ํฐ ๊ธฐ์ค ๊ฐ๊ฒฉ ref = ์ต๊ทผ 48h(๋จ ์ต๊ทผ 3h ์ ์ธ) ์ต๊ณ ๊ฐ, ref โฅ 0.70 BUY if ref - p โฅ 0.12 # ๊ณตํฉ ๋ํญ AND 0.35 โค p โค 0.75 # ๋ถ๊ดด ๋ฐฐ์ ๋ฐด๋ AND ์ต๊ทผ 45๋ถ: p โฅ min(์ง์ ์ค๋ ์ท) AND std โค 0.02 # ๋ฐ๋ฅ ์์ ํ AND hours_left โฅ 48h
์์ค ํํผ์ ๊ณผ์๋ฐ์. ์์ค ํํผ๋ ์ด๋ ๋๋น ์ฝ 2๋ฐฐ์ ์ฌ๋ฆฌ ๊ฐ์ค์ ๊ฐ๋๋ค (Kahneman & Tversky์ prospect theory). ์ ์ฌ/๋ฃจ๋จธ๊ฐ ํฐ์ง๋ฉด ๋ณด์ ์๋ค์ "๋ ์๊ธฐ ์ ์" ์ผ๋จ ๋์ง๊ณ , ๋งค์ ๋๊ธฐ์๋ ๊ด๋งํ๋ค โ ๊ฐ๊ฒฉ์ด ํ๋๋ฉํธ ์ดํ๋ก ์ค๋ฒ์ํ ํ๋ค. ๊ธ๋ฝ ์งํ๋ ์ ๋์ฑ ๊ณต๊ธ์๋ ์คํ๋ ๋๋ฅผ ๋ฒ๋ฆฌ๋ ๊ตฌ๊ฐ์ด๋ผ ์๋์ ํฌ๋งค๋ง์ผ๋ก๋ ๊ฐ๊ฒฉ์ด ๊ณผ๋ํ๊ฒ ๋ฐ๋ฆฐ๋ค. 24/7 3~5๋ถ ๊ฐ๊ฒฉ์ผ๋ก ๋๋ ๋ด์ ์ฌ๋๋ค์ด ์๋ ์๋ฒฝ์ ๊ณตํฉ๋ ์ก๋ ๊ตฌ์กฐ์ ์ฐ์๊ฐ ์๋ค.
๋ฆฌ์์น ๊ทผ๊ฑฐ. ๋ ํฌ์ momentum ๋ฆฌ์์น ๋ฌธ์(golden-cherry์ polymarket-strategy-momentum ๊ณ์ด)๊ฐ ์ง์ ๊ทผ๊ฑฐ๋ค: "10%+ ๊ธ๋ณ์ mean-revert" (์ํญ ๋๋ฆฌํํธ๋ ์ง์, ๊ธ๋ณ์ ํ๊ท). Panic Fade๋ ์ด ํ๊ท ์์ญ๋ง ์ ์กฐ์คํ๋ค.
์ ๋ง๊ฐ์ด ๋จผ(โฅ48h) ์์ฅ๋ง์ธ๊ฐ. ๋ง๊ฐ ์ง์ ๊ธ๋ฝ์ "์ง์ง ์ ๋ณด"(์ฌ๊ฑด ํ์ )์ผ ํ๋ฅ ์ด ๋๋ค. ํด๊ฒฐ๊น์ง 48์๊ฐ ์ด์ ๋จ์ ์์ฅ์ผ๋ก ํ์ ํด ์ ๋ณด์ ์ํ ๋ถ๊ดด์ ์ฌ๋ฆฌ์ ์ํ ์ค๋ฒ์ํ ์ ๋ถ๋ฆฌํ๋ค. ๊ธ๋ณ ์ด๋ฒคํธ์ ๋ฐ๋ ๊ฐ์ค(์ง์ง ์ ๋ณด + ๊ฑฐ๋๋ ํญ์ฆ = ํธ์น)์ ์๋งค ๋ด golden-lime์ด ๊ฒ์ฆํ๋ค โ ๊ฐ์ ์ด๋ฒคํธ ํด๋์ค์ ๋ํ ์๋์ A/B ์์ด๋ค.
๊ธฐ์กด ๋ด์์ ๋ฐฐ์ด ๊ฒ (STRATEGY_ANALYSIS ๋ฐ์):
| ๊ธฐ์กด ์ฝ์ | elderberry์ ์์ |
|---|---|
| banana: ์ค๋ ์ท "๊ฐ์" ๊ธฐ๋ฐ ์๋์ฐ โ Jenkins ์ค๋จ ์ 15๋ถ ์๋์ฐ๊ฐ ๋ช ์๊ฐ์ ์ปค๋ฒ | timestamp ๊ธฐ๋ฐ ์๋์ฐ + ์ปค๋ฒ๋ฆฌ์ง ๊ฒ์ฆ (is_window_valid), invalid๋ฉด ์ง์
์ ํจ |
| banana: ๊ด๋ํ cold-start ํด๋ฐฑ์ผ๋ก ์ฌ์ค์ ๋ฌด์ ๋ต ์ง์ | cold start๋ prices-history ๋ฐฑํ๋ก ํด๊ฒฐ, ๋ฐฑํ ์คํจ ์ ์ง์ ๊ธ์ง |
| cherry: rapid_jump ์๊ตฌ skip | skip์ reentry_cooldown_hours(24h) ๋์๋ง ์ ํจ |
| cherry: ํ ๋ฒ ๊ฑฐ๋ํ ์์ฅ ์๊ตฌ ์ฌ์ง์ ๊ธ์ง | HOLDING/์ฟจ๋ค์ด๋ง ์ฒดํฌํ๋ ์ฌ์ง์ ํ์ฉ ๊ตฌ์กฐ |
| cherry: ํด๊ฒฐ๋ ์์ฅ์ด ์๊ตฌ HOLDING ์ข๋น๋ก ๋จ์ | midpoint ์กฐํ ์คํจ + ํด๊ฒฐ 24h ๊ฒฝ๊ณผ ์ EXPIRED ๋ง๊ฐ + ์๋ redeem ๊ฒฝ๊ณ |
| cherry: TP ๋ชฉํ๊ฐ๊ฐ 1.0์ ๋์ด ๋๋ฌ ๋ถ๊ฐ | ๋ชฉํ๊ฐ 0.99 ์บก |
| cherry: ํธ๋ ์ผ๋ง ์คํ์ด ์คํจ ์์ ์ ์ ๋์ฒด (whipsaw) | ๊ธ๋ฝ ๋งค์๋ ์ง์ ์งํ ๋ณ๋์ด ํฌ๋ฏ๋ก trailing ์์ฒด๋ฅผ ์ ๊ฑฐ |
๊ณตํต: LOG_LEVEL env ๋ฌด์ | setup_logger๊ฐ LOG_LEVEL์ ์ฝ์ (--verbose๊ฐ ์ต์ฐ์ ) |
๋ชจ๋ AND. favorite์๋ ์ชฝ ํ ํฐ ๊ธฐ์ค ๊ฐ๊ฒฉ p๋ก ํ๊ฐํ๋ค.
| ์กฐ๊ฑด | ๊ฐ (๊ธฐ๋ณธ) | ์ด์ |
|---|---|---|
| ์ ๋์ฑ | liquidity โฅ $20,000 (gamma liquidity) | ๋์ ์คํ๋ ๋๊ฐ ๋ง๋๋ ๊ฐ์ง ๊ธ๋ฝ ๋ฐฉ์ด |
| ๊ฑฐ๋๋ | volume24hr โฅ $10,000 (gamma volume24hr) | ์ค๊ฑฐ๋๊ฐ ๋๋ฐ๋ ๊ธ๋ฝ๋ง ๋์ |
| ์์ฌ ์๊ฐ | hours_left โฅ 48h (gamma endDate) | ๋ง๊ฐ ์ง์ ๊ธ๋ฝ = ์ง์ง ์ ๋ณด์ผ ํ๋ฅ ์ด ๋์ ๋ฐฐ์ |
| ์๋์ฐ ์ ํจ์ฑ | 48h ์๋์ฐ์ โฅ 5 ํฌ์ธํธ, span โฅ 24h (is_window_valid) | invalid๋ฉด ๋ฐฑํ ์๋ ํ ์ฌ๊ฒ์ฆ, ๊ทธ๋๋ invalid๋ฉด ์ง์ ๊ธ์ง (banana ๊ตํ) |
| favorite ํ๋ณ | ref ์๋์ฐ์ YES ์ต๊ณ ๊ฐ โฅ 0.5๋ฉด YES์ชฝ, ์๋๋ฉด NO์ชฝ(1-p ํ์ฐ) ํ๊ฐ (evaluate_panic_fade) | YES/NO ์๋ฐฉํฅ ์์ฅ ์ปค๋ฒ |
| ๊ธฐ์ค๊ฐ | ref = ์ต๊ทผ 48h(๋จ ์ต๊ทผ 3h ์ ์ธ) ์ต๊ณ ๊ฐ, ref โฅ 0.70 | ์ต๊ทผ 3h ์ ์ธ = ๊ธ๋ฝ ์์ฒด๋ฅผ ref์ ๋ฃ์ง ์๊ธฐ ์ํจ |
| ๋ํญ | ref - p โฅ 0.12 | ๊ณตํฉ ๊ท๋ชจ ํํฐ |
| ๋ถ๊ดด ๋ฐฐ์ | 0.35 โค p โค 0.75 | 0.35 ๋ฏธ๋ง ๋ถ๊ดด๋ ์ง์ง ์ ๋ณด๋ก ๊ฐ์ฃผ |
| ๋ฐ๋ฅ ์์ ํ | ์ต๊ทผ 45๋ถ(โฅ 3 ์ค๋ ์ท): ํ์ฌ๊ฐ โฅ ์ง์ ์ค๋ ์ท๋ค(์ต์ ํฌ์ธํธ ์ ์ธ) min AND ๊ตฌ๊ฐ std โค 0.02 | ๋จ์ด์ง๋ ์นผ๋ ํํผ (์ ์ ๊ฐ ๊ธ์ง โ ํ์ฌ๊ฐ ์์ ์ Phase 0์์ ์ด๋ฏธ ์ค๋ ์ท์ผ๋ก ์ ์ฅ๋๋ฏ๋ก min ๊ณ์ฐ์์ ์ ์ธ) |
| ์ฌ์ง์ ์ฟจ๋ค์ด | HOLDING ์์ + ๋ง์ง๋ง ์ฒญ์ฐ/skip ํ 24h ๊ฒฝ๊ณผ (is_reentry_blocked) | ๋ฐ๋ณต ์์ ๋ฐฉ์ง |
๋งค์ ์ง์ CLOB midpoint ์ฌ๊ฒ์ฆ: ๊ฐ๊ฒฉ์ด current_max๋ฅผ ๋์์ผ๋ฉด(๋ฐ๋ฑ ์ด๋ฏธ ์๋ฃ) rebound_before_entry๋ก skip(์ฟจ๋ค์ด ์์), current_min ๋ฏธ๋ง์ด๋ฉด(๋ถ๊ดด ์งํ) ์ด๋ฒ ์ฌ์ดํด๋ง ๋ณด๋ฅํ๋ค.
์ฐ์ ์์ ์์ผ๋ก ๊ฒ์ฌํ๋ค. trailing stop์ ์๋ค.
| ์ฐ์ ์์ | ์กฐ๊ฑด | ๊ฐ | exit_reason |
|---|---|---|---|
| 1 | ์์ | P&L โค -10% | stop_loss |
| 2 | ์ต์ | ํ์ฌ๊ฐ โฅ min(์ง์ ๊ฐ ร 1.10, 0.99) | take_profit |
| 3 | ๋ณด์ ์๊ฐ ์ด๊ณผ | ๋ณด์ โฅ 48h (๋ฐ๋ฑ ์คํจ) | max_holding |
| 4 | ์๊ฐ ์ฒญ์ฐ | ํด๊ฒฐ๊น์ง < 24h | time_exit |
| - | ํด๊ฒฐ leak | midpoint ์กฐํ ์คํจ + ํด๊ฒฐ 24h ๊ฒฝ๊ณผ (EXPIRED, ์๋ redeem) | resolved_unredeemed |
์ฐ์ ์์: env > config.yaml > ์ฝ๋ ๊ธฐ๋ณธ๊ฐ
| env | ๊ธฐ๋ณธ๊ฐ | ์๋ฏธ |
|---|---|---|
POLYBOT_BUY_AMOUNT | 5.0 | 1ํ ๋งค์ USDC |
POLYBOT_MIN_LIQUIDITY | 20000 | ์ต์ ์ ๋์ฑ $ |
POLYBOT_MIN_VOLUME_24H | 10000 | ์ต์ 24h ๊ฑฐ๋๋ $ |
POLYBOT_TAKE_PROFIT | 0.10 | ์ต์ +10% (๋ชฉํ๊ฐ 0.99 ์บก) |
POLYBOT_STOP_LOSS | -0.10 | ์์ -10% |
POLYBOT_MAX_POSITIONS | -1 | ์ต๋ ๋์ ํฌ์ง์ (-1 ๋ฌด์ ํ) |
POLYBOT_REENTRY_COOLDOWN_HOURS | 24 | ์ฌ์ง์ ์ฟจ๋ค์ด |
POLYBOT_HISTORY_BACKFILL | true | prices-history ๋ฐฑํ |
POLYBOT_EXCLUDED_CATEGORIES | "" | ์ ์ธ ์นดํ ๊ณ ๋ฆฌ (comma ๊ตฌ๋ถ, ๋น ๊ฐ = ๋นํ์ฑ) |
POLYBOT_REF_WINDOW_HOURS | 48 | ๊ธฐ์ค๊ฐ ์ฐ์ถ ์๋์ฐ |
POLYBOT_REF_EXCLUDE_RECENT_HOURS | 3 | ref์์ ์ ์ธํ ์ต๊ทผ ๊ตฌ๊ฐ |
POLYBOT_REF_MIN | 0.70 | ref ์ต์๊ฐ (์๋ favorite) |
POLYBOT_DROP_MIN | 0.12 | ์ต์ ๋ํญ |
POLYBOT_CURRENT_MIN | 0.35 | ์ง์ ๋ฐด๋ ํํ (๋ถ๊ดด ๋ฐฐ์ ) |
POLYBOT_CURRENT_MAX | 0.75 | ์ง์ ๋ฐด๋ ์ํ |
POLYBOT_STAB_WINDOW_MINUTES | 45 | ์์ ํ ํ์ธ ์๋์ฐ (๋ถ) |
POLYBOT_STAB_MAX_STD | 0.02 | ์์ ํ ์ต๋ std |
POLYBOT_ENTRY_HOURS_MIN | 48 | ์ง์ ์ต์ ์์ฌ ์๊ฐ |
POLYBOT_MAX_HOLDING_HOURS | 48 | ์ต๋ ๋ณด์ ์๊ฐ |
POLYBOT_EXIT_HOURS | 24 | ํด๊ฒฐ ์ด ์๊ฐ ์ ์ฒญ์ฐ |
LOG_LEVEL | INFO | ๋ก๊ทธ ๋ ๋ฒจ |
max_holding์ผ๋ก ๋ณธ์ ๋ถ๊ทผ ์ฒญ์ฐ โ ์์๋ฃ/์คํ๋ ๋๋งํผ ์๋๋ค.1) ์๋ฎฌ๋ ์ด์
(1~2์ฃผ) โ uv run python main.py run --simulate --job sim-test๋ฅผ Jenkins 3~5๋ถ ๊ฐ๊ฒฉ์ผ๋ก ์คํ. data/sim-test/trades_sim.db ์ถ์ .
2) ์์ก ์ค์ (4์ฃผ) โ POLYBOT_BUY_AMOUNT=1๋ก ์์, ๋ฌธ์ ์์ผ๋ฉด ์ฆ์ก.
3) ํ๋จ ๊ธฐ์ค โ 4์ฃผ + 30๊ฑด ์ด์ ๊ฑฐ๋์์:
max_holding ์ฒญ์ฐ ๋น์จ < 40%resolved_unredeemed(EXPIRED) ๋ฐ์ ์ ์์ธ ๋ถ์ ์ฐ์ 4) ํ๋ผ๋ฏธํฐ ์กฐ์ โ ์๋ณ CSV(trades_YYYY-MM.csv)์ ref_price_at_buy/drop_at_buy/exit_reason์ผ๋ก ๋ํญ ๊ตฌ๊ฐ๋ณ ์น๋ฅ ์ ์ง๊ณํด ๋ฐ์ดํฐ๋ก ์กฐ์ ํ๋ค.
5) ํ๊ณ ๊ณตํต ์ปฌ๋ผ (A/B ํฌ์คํธ๋ชจํ
๊ณ์ฝ) โ trades์ CSV์ strategy_name("elderberry"), mode("live"/"sim"), volume_24h_at_buy(๋งค์ ์์ gamma volume24hr), stabilization_range_at_buy(์ง์
ํ์ ์ ์ด ์์ ํ ๊ตฌ๊ฐ ๊ณ ์ ํญ max-min)๋ฅผ ๊ธฐ๋กํ๋ค. ๊ต์ฐจ ๋ด UNION ์ฟผ๋ฆฌ ์ strategy_name์ผ๋ก ๊ตฌ๋ถํ๊ณ , sim/live ํผ์
์ mode๋ก ๊ฑธ๋ฌ๋ธ๋ค.
๋ฒ ๋ฆฌ์์ด์ ํ๋ณด:
| ์ | ๋ณ๊ฒฝ env | ๊ฐ์ค |
|---|---|---|
| A-1 (์์ ๋ํญยท๋น ๋ฅธ ํ์ ) | POLYBOT_DROP_MIN=0.08, POLYBOT_TAKE_PROFIT=0.06, POLYBOT_MAX_HOLDING_HOURS=24 | ์์ ๊ณผ์๋ฐ์์ด ๋ ์์ฃผ, ๋ ๋นจ๋ฆฌ ๋ณต์๋๋ค |
| A-2 (๊น์ ๋ํญ๋ง) | POLYBOT_DROP_MIN=0.18, POLYBOT_CURRENT_MIN=0.40 | ๊ทน๋จ์ ๊ณตํฉ์ผ์๋ก ๋๋๋ฆผ ํญ์ด ํฌ๋ค |
| A-3 (์๊ฒฉํ ์์ ํ) | POLYBOT_STAB_WINDOW_MINUTES=90, POLYBOT_STAB_MAX_STD=0.015 | ์์ ํ๋ฅผ ์ค๋ ํ์ธํ ์๋ก ๋จ์ด์ง๋ ์นผ๋ ํํผ์จ์ด ์ค๋ฅธ๋ค (์ง์ ํ์๋ ๊ฐ์) |
#!/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_DROP_MIN=0.12 export POLYBOT_REENTRY_COOLDOWN_HOURS=24 export POLYBOT_MAX_HOLDING_HOURS=48 cd ./golden-elderberry uv sync uv run python ./main.py run
3~5๋ถ ์ฃผ๊ธฐ cron ํธ๋ฆฌ๊ฑฐ๋ฅผ ๊ถ์ฅํ๋ค (์ค๋ ์ท ์ถ์ ์ด ์๊ทธ๋ ํ์ง์ ์ข์ฐ).