diff --git a/DEPLOYMENT_CHECKLIST.md b/DEPLOYMENT_CHECKLIST.md new file mode 100644 index 0000000..822bf6e --- /dev/null +++ b/DEPLOYMENT_CHECKLIST.md @@ -0,0 +1,292 @@ +# ๐Ÿš€ Quant Engine v9 Deployment Checklist + +**์ƒํƒœ**: 2026-06-25 ๋ฐฐํฌ ์ค€๋น„ ์™„๋ฃŒ +**๋ชฉํ‘œ**: honest_proof_score 56.57 โ†’ 95.0 +**๊ธฐ๊ฐ„**: 6์ฃผ (2026-06-25 ~ 2026-08-10) + +--- + +## โœ… Phase 0: ์‚ฌ์ „ ์ค€๋น„ (์™„๋ฃŒ) + +### ์ฝ”๋“œ ๊ตฌํ˜„ +- [x] **P3 ์†์ ˆ ์ฒด๊ณ„** โ€” `spec/exit/stop_loss.yaml` + - calcAbsoluteRiskStopV1_ + - calcRelativeUnderperfAlertV1_ + - calcStopActionLadderV1_ + +- [x] **P4 ๋ผ์šฐํŒ…** โ€” `spec/xx_routing_contract.yaml` + - buildRoutePacket_ (SCALP/SWING/MOMENTUM/POSITION) + +- [x] **P5 ๋’ท๋ถ ์ฐจ๋‹จ** โ€” `spec/exit/pre_distribution_gate.yaml` + - calcAlphaLeadV1_ + - calcDistributionRiskV1_ + +- [x] **P6 ํ˜„๊ธˆํ™•๋ณด** โ€” `spec/exit/cash_recovery.yaml` + - calcCashRecoveryOptimizerV1_ + +### UI/UX +- [x] MudBlazor 6.10.0 ์ถ”๊ฐ€ (QuantEngine.Web.csproj) +- [x] Dashboard.razor โ€” Material Design ๋ ˆ์ด์•„์›ƒ +- [x] MainLayout.razor โ€” ๋ฐ˜์‘ํ˜• AppBar + Drawer +- [x] NavMenu.razor โ€” Material Icons ๋„ค๋น„๊ฒŒ์ด์…˜ +- [x] App.razor โ€” MudThemeProvider ํ†ตํ•ฉ + +### ๋นŒ๋“œ +- [x] Release ๋นŒ๋“œ: `dotnet publish -c Release` +- [x] ๊ฒฐ๊ณผ: `src/dotnet/QuantEngine.Web/publish/` (24MB, 172๊ฐœ ํŒŒ์ผ) +- [x] ๋ชจ๋“  ์ปดํŒŒ์ผ ์—๋Ÿฌ ํ•ด๊ฒฐ + +--- + +## ๐Ÿš€ Phase 1: ๋ฐฐํฌ (์ง€๊ธˆ ์ง„ํ–‰) + +### 1.1 ์›น ์„œ๋ฒ„ ๋ฐฐํฌ + +```bash +# ์‹คํ–‰ ๋ฐฉ๋ฒ• +chmod +x deploy.sh +./deploy.sh +``` + +**๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ ๋‹จ๊ณ„:** +- [ ] SSH ์—ฐ๊ฒฐ ํ™•์ธ (178.104.200.7) +- [ ] ์›๊ฒฉ ๋ฐฑ์—… ์ƒ์„ฑ (`/var/www/quant_backup_*`) +- [ ] ํŒŒ์ผ ์ „์†ก (rsync, 24MB) +- [ ] ๊ถŒํ•œ ์„ค์ • (www-data:www-data) +- [ ] nginx ์žฌ์‹œ์ž‘ +- [ ] HTTP ์ƒํƒœ ํ™•์ธ (200 OK) + +**ํ™•์ธ URL:** +``` +http://178.104.200.7/quant/ +``` + +### 1.2 GAS ๋ฐฐํฌ + +#### Step 1: Google Apps Script ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ +``` +1. Google Drive โ†’ ์ƒˆ๋กœ ๋งŒ๋“ค๊ธฐ โ†’ Google Apps Script +2. ํ”„๋กœ์ ํŠธ๋ช…: "Quant Engine Data Feed" +3. ์Šคํฌ๋ฆฝํŠธ ์ €์žฅ +``` + +#### Step 2: ํ•จ์ˆ˜ ์ถ”๊ฐ€ +```javascript +// ๋‹ค์Œ ํŒŒ์ผ๋“ค์˜ ๋‚ด์šฉ์„ ๋ณต์‚ฌํ•ด์„œ GAS์— ๋ถ™์—ฌ๋„ฃ๊ธฐ: +// - src/google_apps_script/gas_data_feed.gs (P3~P6 ํ•จ์ˆ˜) +// - src/google_apps_script/live_outcome_ledger.gs (์‹ ํ˜ธ ์ถ”์ ) +``` + +#### Step 3: ์Šคํ”„๋ ˆ๋“œ์‹œํŠธ ์—ฐ๋™ +``` +1. ์ƒˆ ์Šคํ”„๋ ˆ๋“œ์‹œํŠธ ์ƒ์„ฑ: "live_outcome_ledger" +2. LEDGER_SHEET_ID ๋ณ€์ˆ˜ ์—…๋ฐ์ดํŠธ (live_outcome_ledger.gs) +3. initializeLedger_() ์‹คํ–‰ โ†’ ํ—ค๋” ์ž๋™ ์ƒ์„ฑ +``` + +#### Step 4: ํ…Œ์ŠคํŠธ +```javascript +// GAS ์ฝ˜์†”์—์„œ ์‹คํ–‰ +testLiveOutcomeLedger(); + +// ๋˜๋Š” ๊ฐœ๋ณ„ ํ…Œ์ŠคํŠธ +testP3Functions(); +``` + +**์ฒดํฌ๋ฆฌ์ŠคํŠธ:** +- [ ] GAS ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ์™„๋ฃŒ +- [ ] gas_data_feed.gs ํŒŒ์ผ ์ถ”๊ฐ€ (7๊ฐœ ํ•จ์ˆ˜) +- [ ] live_outcome_ledger.gs ํŒŒ์ผ ์ถ”๊ฐ€ (์‹ ํ˜ธ ์ถ”์ ) +- [ ] LEDGER_SHEET_ID ์„ค์ • (์Šคํ”„๋ ˆ๋“œ์‹œํŠธ ID) +- [ ] initializeLedger_() ์‹คํ–‰ +- [ ] ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ํ†ต๊ณผ + +### 1.3 ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ™•์ธ + +```bash +# SSH ์ ‘์† ํ›„ +ssh kjh2064@178.104.200.7 + +# PostgreSQL ์—ฐ๊ฒฐ ํ™•์ธ +psql -h 127.0.0.1 -U gitea -d giteadb +``` + +**์ฒดํฌ๋ฆฌ์ŠคํŠธ:** +- [ ] PostgreSQL ์‹คํ–‰ ์ค‘ +- [ ] giteadb ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์กด์žฌ +- [ ] quantengine schema ์กด์žฌ + +--- + +## ๐Ÿ“Š Phase 2: ์‹ค์ „ ์šด์˜ (6์ฃผ) + +### Week 1-2: ๊ธฐ์ดˆ ๊ตฌ์ถ• (2026-06-25 ~ 2026-07-08) + +**๋ชฉํ‘œ**: 6-8๊ฐœ ์‹ ํ˜ธ ์ˆ˜์ง‘ + +**๋งค์ผ ํ•ด์•ผ ํ•  ์ผ:** +- [ ] ์‹ ํ˜ธ ๋ฐœ์ƒ โ†’ `addSignal_(signal)` ํ˜ธ์ถœ +- [ ] ๋˜๋Š” ์Šคํ”„๋ ˆ๋“œ์‹œํŠธ "live_outcome_ledger"์— ์ง์ ‘ ์ž…๋ ฅ + +**์ฃผ๊ฐ„ ๊ธˆ์š”์ผ (๋งค์ฃผ):** +- [ ] `calculateStats_()` ์‹คํ–‰ +- [ ] win_rate ํ™•์ธ (๋ชฉํ‘œ: >= 60%) +- [ ] ์ฃผ๊ฐ„ ๋ฆฌํฌํŠธ ์ž‘์„ฑ (docs/DAILY_SIGNAL_TRACKING.md ์ฐธ๊ณ ) + +**์ฒดํฌ๋ฆฌ์ŠคํŠธ:** +- [ ] Week 1: 3-4๊ฐœ ์‹ ํ˜ธ +- [ ] Week 2: 3-4๊ฐœ ์‹ ํ˜ธ (๋ˆ„์  6-8๊ฐœ) +- [ ] ์Šน๋ฅ  >= 50% ์œ ์ง€ + +### Week 3-4: T+20 ์ˆ˜์ง‘ (2026-07-09 ~ 2026-07-22) + +**๋ชฉํ‘œ**: ์ถ”๊ฐ€ 8-10๊ฐœ ์‹ ํ˜ธ + T+20 ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ์‹œ์ž‘ + +**๋งค์ผ:** +- [ ] ์‹ ๊ทœ ์‹ ํ˜ธ ๊ธฐ๋ก +- [ ] T+20 ๋„๋‹ฌํ•œ ์‹ ํ˜ธ `updatePriceT20_(signalId, priceT20)` ํ˜ธ์ถœ + +**T+20 ๊ฐ€๊ฒฉ ์ˆ˜์ง‘:** +```python +# KIS API, Yahoo Finance ๋“ฑ์—์„œ ์ž๋™ ์ˆ˜์ง‘ +# ๋˜๋Š” ์ˆ˜๋™์œผ๋กœ ์Šคํ”„๋ ˆ๋“œ์‹œํŠธ ์ž…๋ ฅ + +# ์ž๋™์œผ๋กœ ๊ณ„์‚ฐ๋จ: +# - return_pct_t20 +# - outcome (WIN/LOSS/BREAKEVEN) +# - win_margin +# - validation_status: PROVISIONAL +``` + +**์ฒดํฌ๋ฆฌ์ŠคํŠธ:** +- [ ] Week 3: 4-5๊ฐœ ์‹ ํ˜ธ +- [ ] Week 4: 4-5๊ฐœ ์‹ ํ˜ธ (๋ˆ„์  14-18๊ฐœ) +- [ ] T+20 ๋ฐ์ดํ„ฐ 6-8๊ฐœ ์ˆ˜์ง‘ +- [ ] ์™„๋ฃŒ๋œ ์‹ ํ˜ธ ์Šน๋ฅ  >= 60% + +### Week 5-6: ๋ฐ์ดํ„ฐ ์ˆ˜๋ ด (2026-07-23 ~ 2026-08-05) + +**๋ชฉํ‘œ**: ์ถ”๊ฐ€ 8-10๊ฐœ ์‹ ํ˜ธ + 30๊ฐœ ๊ทผ์ฒ˜ + +**๋งค์ผ:** +- [ ] ์‹ ๊ทœ ์‹ ํ˜ธ ๊ธฐ๋ก +- [ ] T+20 ๋ฐ์ดํ„ฐ ์ž…๋ ฅ (์™„๋ฃŒ) + +**๋Œ€๋Ÿ‰ ์ˆ˜๋ ด:** +```javascript +// ์ฃผ๊ฐ„ ์‹คํ–‰ +stats = calculateStats_(); +Logger.log(`์Šน๋ฅ : ${stats.win_rate}%, ์™„๋ฃŒ: ${stats.completed}/30`); +``` + +**์ฒดํฌ๋ฆฌ์ŠคํŠธ:** +- [ ] Week 5: 4-5๊ฐœ ์‹ ํ˜ธ +- [ ] Week 6: 4-5๊ฐœ ์‹ ํ˜ธ (๋ˆ„์  22-28๊ฐœ) +- [ ] ์ „์ฒด ์Šน๋ฅ  >= 60% + +### Week 7: CALIBRATED ์ „ํ™˜ (2026-08-06 ~ 2026-08-10) + +**๋ชฉํ‘œ**: 30๊ฐœ ์™„๋ฃŒ + CALIBRATED ์ „ํ™˜ + +**์ตœ์ข… ์‹ ํ˜ธ:** +- [ ] ๋งˆ์ง€๋ง‰ 2-8๊ฐœ ์‹ ํ˜ธ ์ˆ˜์ง‘ +- [ ] T+20 ๋ฐ์ดํ„ฐ ์™„๋ฃŒ + +**CALIBRATED ์ „ํ™˜ ์‹คํ–‰:** +```javascript +// ์กฐ๊ฑด ํ™•์ธ +check = checkCalibrationReady_(); +Logger.log(JSON.stringify(check, null, 2)); + +// ์กฐ๊ฑด ์ถฉ์กฑ ์‹œ +calibrateIfReady_(); +``` + +**์ฒดํฌ๋ฆฌ์ŠคํŠธ:** +- [ ] ์‹ ํ˜ธ ๋ˆ„์ : 30๊ฐœ ์™„๋ฃŒ +- [ ] ์Šน๋ฅ : >= 60% (30๊ฐœ ์ค‘ ์ตœ์†Œ 18๊ฐœ WIN) +- [ ] avg_win_margin >= 2.0% +- [ ] PROVISIONAL โ†’ CALIBRATED ์ „ํ™˜ +- [ ] honest_proof_score ์—…๋ฐ์ดํŠธ (95.0 ๋‹ฌ์„ฑ) + +--- + +## ๐ŸŽฏ ์ตœ์ข… ๋ชฉํ‘œ + +### honest_proof_score ๊ฐœ์„  + +``` +ํ˜„์žฌ: 56.57 +โ”œโ”€ P0 ์™„๋ฃŒ: +10์  โ†’ 66.57 +โ”œโ”€ P2 ์ƒ˜ํ”Œ: +20์  โ†’ 86.57 +โ””โ”€ P3~P6: +8์  โ†’ 94.57 โ‰ˆ 95.0 โœ… +``` + +### ๋ฐฐํฌ ์™„๋ฃŒ ์กฐ๊ฑด + +- [x] Release ๋นŒ๋“œ ์„ฑ๊ณต +- [x] ๋ช…์„ธ ํŒŒ์ผ (P3~P6 YAML) +- [x] GAS ํ•จ์ˆ˜ ๊ตฌํ˜„ (7๊ฐœ) +- [x] ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ ์ž‘์„ฑ +- [x] ์‹ ํ˜ธ ์ถ”์  ์‹œ์Šคํ…œ (GAS) +- [ ] ์›น ์„œ๋ฒ„ ๋ฐฐํฌ ์‹คํ–‰ +- [ ] GAS ํ”„๋กœ์ ํŠธ ๋ฐฐํฌ ์‹คํ–‰ +- [ ] 30๊ฐœ ์‹ ํ˜ธ ์ˆ˜์ง‘ (6์ฃผ) +- [ ] CALIBRATED ์ „ํ™˜ +- [ ] honest_proof_score 95.0 ๋‹ฌ์„ฑ + +--- + +## ๐Ÿ“ ์ถ”๊ฐ€ ์ž‘์—… + +### ๋ฐฐํฌ ํ›„ ํ™•์ธ + +```bash +# ์›น์‚ฌ์ดํŠธ ์ ‘์† +curl -I http://178.104.200.7/quant/ + +# ๋กœ๊ทธ ๋ชจ๋‹ˆํ„ฐ๋ง +ssh kjh2064@178.104.200.7 +sudo tail -f /var/log/nginx/error.log +sudo tail -f /var/log/nginx/access.log + +# ๋ฐฑ์—… ์œ„์น˜ +/var/www/quant_backup_YYYYMMDD_HHMMSS/ +``` + +### ๋ฌธ์ œ ํ•ด๊ฒฐ + +| ๋ฌธ์ œ | ํ•ด๊ฒฐ๋ฒ• | +|------|--------| +| HTTP 503 | ์•ฑ์ด ์‹œ์ž‘ ์ค‘. ๋ช‡ ์ดˆ ํ›„ ์žฌ์‹œ๋„ | +| HTTP 404 | nginx ์„ค์ • ํ™•์ธ (`/etc/nginx/sites-available/quant`) | +| SSH ์—ฐ๊ฒฐ ์‹คํŒจ | SSH ํ‚ค ํ™•์ธ (`~/.ssh/id_ed25519`) | +| ์„ฑ๋Šฅ ์ €ํ•˜ | ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ™•์ธ, ๋กœ๊ทธ ๋ถ„์„ | + +### ๋ชจ๋‹ˆํ„ฐ๋ง + +```bash +# ์ผ์ผ ํ—ฌ์Šค ์ฒดํฌ (cron) +0 9 * * * curl http://178.104.200.7/quant/ > /dev/null 2>&1 + +# ์ฃผ๊ฐ„ ๋ฆฌํฌํŠธ (GAS ์ž๋™ํ™”) +# ๋งค์ฃผ ๊ธˆ์š”์ผ 18:00 ์‹คํ–‰: +# - calculateStats_() +# - ์ด๋ฉ”์ผ ๋ฐœ์†ก +``` + +--- + +## ๐Ÿ”— ๊ด€๋ จ ๋ฌธ์„œ + +- `V9_HARDENING_IMPLEMENTATION_ROADMAP.md` โ€” ์ „์ฒด ๋กœ๋“œ๋งต +- `docs/DAILY_SIGNAL_TRACKING.md` โ€” ์ผ์ผ ์ถ”์  ๊ฐ€์ด๋“œ +- `deploy.sh` โ€” ๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ +- `src/google_apps_script/gas_data_feed.gs` โ€” GAS ํ•จ์ˆ˜ +- `src/google_apps_script/live_outcome_ledger.gs` โ€” ์‹ ํ˜ธ ์ถ”์  + +--- + +**์ž‘์„ฑ์ผ**: 2026-06-25 +**์ตœํ›„ ์ˆ˜์ •**: 2026-06-25 +**๋‹ค์Œ ์ฒดํฌ**: 2026-07-04 (Phase 2 Week 1 ๋งˆ๊ฐ)