Phase C→B 배포 문서·dry-run 검증을 추가하고 운영 env를 동기화한다.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
42
.env
42
.env
@@ -142,3 +142,45 @@ GA_PIVOT_ORDER=3
|
|||||||
GA_PSAR_AF_START=0.02
|
GA_PSAR_AF_START=0.02
|
||||||
GA_PSAR_AF_STEP=0.02
|
GA_PSAR_AF_STEP=0.02
|
||||||
GA_PSAR_AF_MAX=0.2
|
GA_PSAR_AF_MAX=0.2
|
||||||
|
|
||||||
|
# --- .env.example 누락 키 추가 (2026-06-01) ---
|
||||||
|
GT_MIN_ORDER_KRW=5000
|
||||||
|
GT_BUY_PCT_LARGE_LEG=1.0
|
||||||
|
GT_BUY_PCT_SMALL_LEG=0.05
|
||||||
|
GT_LARGE_LEG_TOP_PCT=0.2
|
||||||
|
GT_SIGNAL_CAUSAL=1
|
||||||
|
SIM_CAUSAL_TIER=1
|
||||||
|
CAUSAL_GT_PEAK_MODE=local
|
||||||
|
CAUSAL_GT_MIN_LEG_PCT=5.0
|
||||||
|
CAUSAL_GT_MIN_BARS_BETWEEN_LEGS=60
|
||||||
|
CAUSAL_GT_USE_LOCAL_TROUGH=1
|
||||||
|
CAUSAL_GT_DD_LARGE_PCT=5.0
|
||||||
|
CAUSAL_GT_DD_MEDIUM_PCT=2.0
|
||||||
|
GT_BUY_PCT_MEDIUM_LEG=0.25
|
||||||
|
SIM_TIER_CONVICTION_DD_PCT=10.0
|
||||||
|
SIM_PRIMARY_SIZING=auto
|
||||||
|
SIM_HYBRID_MIN_HOLDOUT_PNL_PCT=0.0
|
||||||
|
SIM_HYBRID_MAX_MDD_PCT=30.0
|
||||||
|
SIM_OPTION_C_TARGET_PNL_PCT=300.0
|
||||||
|
SIM_OPTION_C_PHASE2_TARGET_PNL_PCT=1000.0
|
||||||
|
SIM_OPTION_C_PHASE2_FEE_STRESS_RATIO=0.85
|
||||||
|
SIM_OPTION_C_MIN_GT_CAPTURE=0.23
|
||||||
|
SIM_HYBRID_PORTFOLIO_WF_MIN_RATIO=0.5
|
||||||
|
GT_BUY_WEIGHT_RULE=inverse_price_normalized
|
||||||
|
GT_SELL_SPLIT_WEIGHTS=0.65,0.35
|
||||||
|
MATCH_LABEL_MODE=leg_gt
|
||||||
|
MATCH_HOLDOUT_RATIO=0.15
|
||||||
|
MATCH_MONITOR_MAX_PER_SIDE=1
|
||||||
|
SIM_GO_WF_POSITIVE_RATIO=0.5
|
||||||
|
SIM_FEE_STRESS_MULT=2.0
|
||||||
|
MONITOR_ALERT_COOLDOWN_MIN=180
|
||||||
|
MONITOR_ALERT_KRW_AMOUNT=100000
|
||||||
|
LIVE_TRADING_ENABLED=0
|
||||||
|
LIVE_ORDER_KRW=100000
|
||||||
|
LIVE_BUY_PCT_LARGE=1.0
|
||||||
|
LIVE_BUY_PCT_SMALL=0.05
|
||||||
|
LIVE_DAILY_KRW_MAX=300000
|
||||||
|
LIVE_COOLDOWN_MIN=180
|
||||||
|
LIVE_MAX_TRADES_PER_DAY=10
|
||||||
|
LIVE_DAILY_LOSS_LIMIT_KRW=50000
|
||||||
|
LIVE_SLIPPAGE_PCT=0.05
|
||||||
|
|||||||
13
.env.example
13
.env.example
@@ -21,8 +21,8 @@ CAUSAL_GT_PEAK_MODE=local
|
|||||||
CAUSAL_GT_MIN_LEG_PCT=5.0
|
CAUSAL_GT_MIN_LEG_PCT=5.0
|
||||||
CAUSAL_GT_MIN_BARS_BETWEEN_LEGS=60
|
CAUSAL_GT_MIN_BARS_BETWEEN_LEGS=60
|
||||||
CAUSAL_GT_USE_LOCAL_TROUGH=1
|
CAUSAL_GT_USE_LOCAL_TROUGH=1
|
||||||
CAUSAL_GT_DD_LARGE_PCT=8.0
|
CAUSAL_GT_DD_LARGE_PCT=5.0
|
||||||
CAUSAL_GT_DD_MEDIUM_PCT=4.0
|
CAUSAL_GT_DD_MEDIUM_PCT=2.0
|
||||||
GT_BUY_PCT_MEDIUM_LEG=0.25
|
GT_BUY_PCT_MEDIUM_LEG=0.25
|
||||||
SIM_TIER_CONVICTION_DD_PCT=10.0
|
SIM_TIER_CONVICTION_DD_PCT=10.0
|
||||||
# hybrid tier 승격 (auto=검증 통과 시 hybrid)
|
# hybrid tier 승격 (auto=검증 통과 시 hybrid)
|
||||||
@@ -46,11 +46,15 @@ MATCH_MONITOR_MAX_PER_SIDE=1
|
|||||||
SIM_GO_WF_POSITIVE_RATIO=0.5
|
SIM_GO_WF_POSITIVE_RATIO=0.5
|
||||||
SIM_FEE_STRESS_MULT=2.0
|
SIM_FEE_STRESS_MULT=2.0
|
||||||
|
|
||||||
# 05 알림
|
# 05 알림 (Phase C: MONITOR_LOOP_SLEEP_SEC=180 권장)
|
||||||
MONITOR_ALERT_COOLDOWN_MIN=180
|
MONITOR_ALERT_COOLDOWN_MIN=180
|
||||||
MONITOR_ALERT_KRW_AMOUNT=100000
|
MONITOR_ALERT_KRW_AMOUNT=100000
|
||||||
|
MONITOR_LOOP_SLEEP_SEC=180
|
||||||
|
|
||||||
# 3 실거래 (오픈 시에만 1) — 아래 한도는 06_live 전용, 시뮬(04)은 GT tier 복리 사용
|
# 3 실거래 — Phase별 권장값: docs/05_ops/env.recommended.md
|
||||||
|
# Phase C (알림만): LIVE_TRADING_ENABLED=0
|
||||||
|
# Phase B-1 (소액 live): LIVE_TRADING_ENABLED=1, LIVE_DAILY_KRW_MAX=1000000
|
||||||
|
# Phase B-2 (sim 근접): LIVE_DAILY_KRW_MAX=5000000
|
||||||
LIVE_TRADING_ENABLED=0
|
LIVE_TRADING_ENABLED=0
|
||||||
LIVE_ORDER_KRW=100000
|
LIVE_ORDER_KRW=100000
|
||||||
LIVE_BUY_PCT_LARGE=1.0
|
LIVE_BUY_PCT_LARGE=1.0
|
||||||
@@ -59,3 +63,4 @@ LIVE_DAILY_KRW_MAX=300000
|
|||||||
LIVE_COOLDOWN_MIN=180
|
LIVE_COOLDOWN_MIN=180
|
||||||
LIVE_MAX_TRADES_PER_DAY=10
|
LIVE_MAX_TRADES_PER_DAY=10
|
||||||
LIVE_DAILY_LOSS_LIMIT_KRW=50000
|
LIVE_DAILY_LOSS_LIMIT_KRW=50000
|
||||||
|
LIVE_SLIPPAGE_PCT=0.05
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class LiveTrader(Monitor):
|
|||||||
"""
|
"""
|
||||||
총자산·현금·EV/WF·leg 티어로 매수 원화 산출.
|
총자산·현금·EV/WF·leg 티어로 매수 원화 산출.
|
||||||
|
|
||||||
GT_SIGNAL_CAUSAL=1 이면 시뮬 sim_tier_enhanced와 동일 인과 tier·weight.
|
GT_SIGNAL_CAUSAL=1 이면 시뮬 sim_primary(hybrid, enhanced=False)와 동일 tier·weight.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
hit: evaluate_live_rules 항목.
|
hit: evaluate_live_rules 항목.
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1521,6 +1521,7 @@
|
|||||||
"hybrid_max_mdd_pct": 30.0,
|
"hybrid_max_mdd_pct": 30.0,
|
||||||
"option_c_target_pnl_pct": 300.0,
|
"option_c_target_pnl_pct": 300.0,
|
||||||
"option_c_phase2_target_pnl_pct": 1000.0,
|
"option_c_phase2_target_pnl_pct": 1000.0,
|
||||||
|
"option_c_phase2_fee_stress_ratio": 0.85,
|
||||||
"option_c_min_gt_capture": 0.23
|
"option_c_min_gt_capture": 0.23
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
270
docs/05_ops/DEPLOYMENT_CHECKLIST.md
Normal file
270
docs/05_ops/DEPLOYMENT_CHECKLIST.md
Normal file
@@ -0,0 +1,270 @@
|
|||||||
|
# DeepCoin 배포 체크리스트 (C → B)
|
||||||
|
|
||||||
|
- **목표:** 초기 ₩1,000,000 → **+1,000% 이상** (인과적 hybrid primary 경로)
|
||||||
|
- **일정:** **금요일까지 Phase C** (알림·dry-run 사전 테스트) → **토요일부터 Phase B-1** (소액 실거래)
|
||||||
|
- **기준일:** 2026-06-01 (월) 작성 · C 종료 2026-06-05 (금) · B-1 시작 2026-06-06 (토)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. 현재 설계 (한 장 요약)
|
||||||
|
|
||||||
|
```text
|
||||||
|
[Ground Truth] 사후 ZigZag 타점 → +4,291% (벤치마크·미래 허용)
|
||||||
|
↓
|
||||||
|
[Monitor 규칙] buy_compound_tight + sell_mtf_cross_all_tf (과거 지표만)
|
||||||
|
↓
|
||||||
|
[배분 hybrid] DD tier + past-leg tier (enhanced=False) → sim +1,121%
|
||||||
|
↓
|
||||||
|
[06 live_trader] LIVE_TRADING_ENABLED=1 일 때만 빗썸 주문
|
||||||
|
```
|
||||||
|
|
||||||
|
| 리포트 경로 | PnL | 배포 |
|
||||||
|
|-------------|-----|------|
|
||||||
|
| GT oracle | +4,291% | 아님 (상한) |
|
||||||
|
| **sim_primary (hybrid)** | **+1,121%** | **예** |
|
||||||
|
| sim_sized | +75% | 아님 |
|
||||||
|
| sim_causal_gt | +15% | 아님 |
|
||||||
|
| sim_tier_enhanced (conviction) | -51% | **금지** |
|
||||||
|
| sim_fixed_order | -94% | 비교용 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 요청 항목 대비 달성 현황
|
||||||
|
|
||||||
|
### A. Ground Truth · 매수 배분
|
||||||
|
|
||||||
|
| # | 요청 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| A1 | GT 재생성 | 완료 |
|
||||||
|
| A2 | 1회 10만 캡 제거 | 완료 |
|
||||||
|
| A3 | 총자산×배분, 한도=보유 현금 | 완료 |
|
||||||
|
| A4 | GT HTML | 완료 |
|
||||||
|
|
||||||
|
### B. 시뮬 개선
|
||||||
|
|
||||||
|
| # | 요청 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| B1 | GT 일반화 | 부분 (monitor 규칙이 primary) |
|
||||||
|
| B2 | sim 매수 상한 제거 | 완료 (hybrid) |
|
||||||
|
| B3 | 전기간 복리 carry | 완료 |
|
||||||
|
| B4 | GT 배분 분석·DD 캘리브 | 완료 (large 5%, medium 2%) |
|
||||||
|
| B5 | sim 상한 제거 | hybrid 완료 |
|
||||||
|
| B6 | LIVE_DAILY_KRW_MAX sim 제거 | sim hybrid 완료 / **live는 Phase B에서 조정** |
|
||||||
|
| B7 | GT식 large leg | 완료 |
|
||||||
|
| B8 | 복리 구조 | hybrid 완료 / conviction 실패 |
|
||||||
|
|
||||||
|
### C. 인과성
|
||||||
|
|
||||||
|
| # | 요청 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| C1 | GT=미래 OK, sim=과거만 | 완료 |
|
||||||
|
| C2 | 인과 sim 재실행 | 완료 |
|
||||||
|
| C3 | 복리 총자산 배분 | 완료 |
|
||||||
|
| C4 | HTML 비교 | 완료 |
|
||||||
|
|
||||||
|
### D. +1,000% 목표
|
||||||
|
|
||||||
|
| # | 요청 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| D1 | 1000% 설계 | 완료 |
|
||||||
|
| D2 | Option C 300% | 완료 (+1,121%) |
|
||||||
|
| D3 | Phase2 +1000% Go | **시뮬 Go** |
|
||||||
|
| D4 | holdout/fee/WF | 완료 |
|
||||||
|
| D5 | 슬리피지 | Go이나 +28%로 급감 (주의) |
|
||||||
|
| D6 | 실현=sim | **미달** (mark·슬리피지·live 한도) |
|
||||||
|
|
||||||
|
### E. 배포·운영
|
||||||
|
|
||||||
|
| # | 요청 | 상태 |
|
||||||
|
|---|------|------|
|
||||||
|
| E1 | live_trader hybrid 정합 | 완료 |
|
||||||
|
| E2 | conviction 배포 | 금지 |
|
||||||
|
| E3 | git push | 완료 |
|
||||||
|
| E4 | Phase A dry-run | 완료 |
|
||||||
|
| E5 | Phase C (알림) | **진행 중** |
|
||||||
|
| E6 | Phase B (live) | 토요일 예정 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Phase 로드맵 (C → B-1 → B-2)
|
||||||
|
|
||||||
|
```text
|
||||||
|
Phase C (월~금) 알림만 · 주문 없음 · 신호·슬리피지 관찰
|
||||||
|
↓ 금요일 Go 판정
|
||||||
|
Phase B-1 (토~ ) LIVE ON · 소~중간 한도 · hybrid tier 부분 체결
|
||||||
|
↓ 2~4주 검증
|
||||||
|
Phase B-2 (검증 후) sim에 근접한 한도 · +1000% 경로 추격 (리스크↑)
|
||||||
|
```
|
||||||
|
|
||||||
|
| Phase | 기간 | 스크립트 | LIVE_TRADING | 목적 |
|
||||||
|
|-------|------|----------|--------------|------|
|
||||||
|
| **C** | ~금 6/5 | `05_run_monitor.py` | **0** | 신호 품질·빈도·텔레그램 |
|
||||||
|
| **B-1** | 토 6/6~ | `06_execute_live.py` | **1** | 소액 실체결·tier·로그 검증 |
|
||||||
|
| **B-2** | B-1 Go 후 | `06_execute_live.py` | **1** | sim hybrid에 근접한 배분 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Phase C — 금요일까지 사전 테스트
|
||||||
|
|
||||||
|
### 4.1 `.env` (Phase C)
|
||||||
|
|
||||||
|
`.env`에 아래를 적용하세요. 전체 예시는 `docs/05_ops/env.recommended.md` 참고.
|
||||||
|
|
||||||
|
```env
|
||||||
|
# === Phase C: 알림만 (금~금) ===
|
||||||
|
LIVE_TRADING_ENABLED=0
|
||||||
|
GT_SIGNAL_CAUSAL=1
|
||||||
|
SIM_PRIMARY_SIZING=auto
|
||||||
|
MONITOR_ALERT_COOLDOWN_MIN=180
|
||||||
|
MONITOR_LOOP_SLEEP_SEC=180
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 매일 실행
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 프로젝트 루트, xavis conda
|
||||||
|
python scripts/01_download.py # 1일 1회 (봉 갱신)
|
||||||
|
python scripts/06_verify_live_dryrun.py # tier·설정 점검 (1일 1회)
|
||||||
|
python scripts/05_run_monitor.py # 상시 알림 (또는 --once 수동)
|
||||||
|
python scripts/06_execute_live.py --once # dry-run (주문 없음, 선택)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 Phase C 일별 기록 (금요일까지)
|
||||||
|
|
||||||
|
| 날짜 | download | verify | monitor | 발화 buy | 발화 sell | 메모 |
|
||||||
|
|------|----------|--------|---------|----------|-----------|------|
|
||||||
|
| 6/1 (월) | | PASS | | | | Phase A 완료 |
|
||||||
|
| 6/2 (화) | | | | | | |
|
||||||
|
| 6/3 (수) | | | | | | |
|
||||||
|
| 6/4 (목) | | | | | | |
|
||||||
|
| 6/5 (금) | | | | | | **C Go/No-Go** |
|
||||||
|
|
||||||
|
기록 파일: `docs/05_ops/live_verification_20260601.md` (매일 갱신)
|
||||||
|
|
||||||
|
### 4.4 Phase C 금요일 Go/No-Go 기준
|
||||||
|
|
||||||
|
**GO (토요일 B-1 진행)** — 아래 **전부** 충족:
|
||||||
|
|
||||||
|
- [ ] 5일간 `05` 크래시·API 오류 없음
|
||||||
|
- [ ] monitor 규칙 2개만 발화 (`buy_compound_tight`, `sell_mtf_cross_all_tf`)
|
||||||
|
- [ ] `06_verify_live_dryrun.py` PASS
|
||||||
|
- [ ] 텔레그램 알림 수신 정상
|
||||||
|
- [ ] 발화 빈도가 비정상적으로 과다/과소 아님 (참고: sim 전기간 buy ~1,608 / 365일)
|
||||||
|
- [ ] 빗썸 API 키·잔고 조회 정상
|
||||||
|
|
||||||
|
**NO-GO** — 하나라도 해당 시 토요일 live 연기:
|
||||||
|
|
||||||
|
- API/DB 장애 지속
|
||||||
|
- 규칙 외 신호
|
||||||
|
- verify FAIL
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Phase B-1 — 토요일부터 소액 실거래
|
||||||
|
|
||||||
|
### 5.1 `.env` (Phase B-1)
|
||||||
|
|
||||||
|
```env
|
||||||
|
# === Phase B-1: 소액 live (토~) ===
|
||||||
|
LIVE_TRADING_ENABLED=1
|
||||||
|
GT_SIGNAL_CAUSAL=1
|
||||||
|
SIM_PRIMARY_SIZING=auto
|
||||||
|
|
||||||
|
# hybrid tier: large 구간 일부 체결 가능, sim보다 보수적
|
||||||
|
LIVE_ORDER_KRW=100000
|
||||||
|
LIVE_DAILY_KRW_MAX=1000000
|
||||||
|
LIVE_MAX_TRADES_PER_DAY=15
|
||||||
|
LIVE_COOLDOWN_MIN=180
|
||||||
|
LIVE_DAILY_LOSS_LIMIT_KRW=100000
|
||||||
|
LIVE_SLIPPAGE_PCT=0.05
|
||||||
|
```
|
||||||
|
|
||||||
|
| 변수 | B-1 값 | 의미 |
|
||||||
|
|------|--------|------|
|
||||||
|
| `LIVE_DAILY_KRW_MAX` | **1,000,000** | 일 100만 (sim full tier보다 낮음) |
|
||||||
|
| `LIVE_DAILY_LOSS_LIMIT_KRW` | **100,000** | 일 -10만 시 당일 중단 |
|
||||||
|
| `LIVE_MAX_TRADES_PER_DAY` | 15 | sim 거래 빈도 대비 여유 |
|
||||||
|
|
||||||
|
### 5.2 토요일 오픈 당일
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/06_verify_live_dryrun.py
|
||||||
|
python scripts/06_execute_live.py --once # 1회 수동 확인
|
||||||
|
python scripts/06_execute_live.py # 상시 (systemd/cron)
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] `data/ops/live_trades.jsonl` 체결·dry_run 기록
|
||||||
|
- [ ] `data/ops/live_sizing_state.json` leg 상태 갱신
|
||||||
|
- [ ] Kill switch: `LIVE_TRADING_ENABLED=0` + 프로세스 중지
|
||||||
|
|
||||||
|
### 5.3 Phase B-1 Go/No-Go (2~4주 후)
|
||||||
|
|
||||||
|
**B-2 승격 후보:**
|
||||||
|
|
||||||
|
- [ ] 일 손실 한도 위반 없음
|
||||||
|
- [ ] hybrid planned vs 실체결 금액 오차 허용 범위
|
||||||
|
- [ ] 슬리피지·스킵 사유 기록
|
||||||
|
- [ ] 실계좌 PnL이 sim 대비 **완전히 다르더라도** tier 동작이 의도대로
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Phase B-2 — sim hybrid 근접 (검증 후)
|
||||||
|
|
||||||
|
> +1,000% 경로 추격. **본인 리스크 허용 범위에서만** 적용.
|
||||||
|
|
||||||
|
```env
|
||||||
|
# === Phase B-2: sim 정합 (B-1 Go 후) ===
|
||||||
|
LIVE_TRADING_ENABLED=1
|
||||||
|
LIVE_DAILY_KRW_MAX=5000000
|
||||||
|
LIVE_MAX_TRADES_PER_DAY=30
|
||||||
|
LIVE_DAILY_LOSS_LIMIT_KRW=300000
|
||||||
|
LIVE_COOLDOWN_MIN=120
|
||||||
|
```
|
||||||
|
|
||||||
|
- large tier 1회 ~총자산 100% 매수 가능 → **MDD sim 19%·슬리피지 +28% 스트레스 참고**
|
||||||
|
- conviction tier(`enhanced=True`) **절대 사용 금지**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Kill switch
|
||||||
|
|
||||||
|
| 방법 | 동작 |
|
||||||
|
|------|------|
|
||||||
|
| `.env` | `LIVE_TRADING_ENABLED=0` 후 프로세스 재시작 |
|
||||||
|
| 프로세스 | `06_execute_live.py` 중지 |
|
||||||
|
| 빗썸 | 앱/웹 수동 청산 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. +1,000% 목표 현실 점검
|
||||||
|
|
||||||
|
| 항목 | sim | live (B-1) | live (B-2) |
|
||||||
|
|------|-----|------------|------------|
|
||||||
|
| hybrid large tier | 대부분 체결 | **일한도로 일부 스킵** | sim에 근접 |
|
||||||
|
| 복리 | 전기간 | 동일 로직 | 동일 |
|
||||||
|
| 슬리피지 | 5% 스트레스 +28% | **실측 필요** | 실측 필요 |
|
||||||
|
| 미청산 mark | +1,121%에 포함 | **실현 PnL 별도** | 동일 |
|
||||||
|
|
||||||
|
**+1,000%는 B-2까지 올라가도 보장되지 않습니다.** B-1에서 tier·슬리피지·PnL을 먼저 검증하세요.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 관련 문서·스크립트
|
||||||
|
|
||||||
|
| 경로 | 용도 |
|
||||||
|
|------|------|
|
||||||
|
| `docs/05_ops/env.recommended.md` | Phase별 `.env` 전체 예시 |
|
||||||
|
| `docs/05_ops/live_verification_*.md` | 일별 검증 기록 |
|
||||||
|
| `docs/reference/LIVE_TRADING.md` | 06 실거래 가이드 |
|
||||||
|
| `docs/reference/RISK.md` | 리스크·한도 |
|
||||||
|
| `scripts/06_verify_live_dryrun.py` | Phase A/C 점검 |
|
||||||
|
| `scripts/05_run_monitor.py` | Phase C 알림 |
|
||||||
|
| `scripts/06_execute_live.py` | Phase B 주문 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. 변경 이력
|
||||||
|
|
||||||
|
| 날짜 | 내용 |
|
||||||
|
|------|------|
|
||||||
|
| 2026-06-01 | C→B-1→B-2 로드맵·체크리스트 최초 작성 |
|
||||||
158
docs/05_ops/env.recommended.md
Normal file
158
docs/05_ops/env.recommended.md
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
# Phase별 `.env` 권장값
|
||||||
|
|
||||||
|
프로젝트 루트 `.env`에 **해당 Phase 블록만** 반영하세요. API 키·토큰은 기존 값 유지.
|
||||||
|
|
||||||
|
**일정:** Phase C ~2026-06-05 (금) → Phase B-1 ~2026-06-06 (토)부터
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 공통 (C·B 모두 동일)
|
||||||
|
|
||||||
|
```env
|
||||||
|
SYMBOL=WLD
|
||||||
|
CHART_LOOKBACK_DAYS=365
|
||||||
|
|
||||||
|
# 인과 sim · hybrid live sizing (필수)
|
||||||
|
GT_SIGNAL_CAUSAL=1
|
||||||
|
SIM_CAUSAL_TIER=1
|
||||||
|
SIM_PRIMARY_SIZING=auto
|
||||||
|
|
||||||
|
# hybrid DD (캘리브 결과 — 변경 시 04_hybrid_dd_calibrate 재실행)
|
||||||
|
# docs/04_matching/hybrid_dd_calibration.json 과 동기
|
||||||
|
CAUSAL_GT_DD_LARGE_PCT=5.0
|
||||||
|
CAUSAL_GT_DD_MEDIUM_PCT=2.0
|
||||||
|
|
||||||
|
# GT tier (sim·live hybrid)
|
||||||
|
GT_BUY_PCT_LARGE_LEG=1.0
|
||||||
|
GT_BUY_PCT_SMALL_LEG=0.05
|
||||||
|
GT_BUY_PCT_MEDIUM_LEG=0.25
|
||||||
|
GT_LARGE_LEG_TOP_PCT=0.2
|
||||||
|
GT_MIN_ORDER_KRW=5000
|
||||||
|
|
||||||
|
# monitor 규칙 (04 matched_rules — 코드에서 로드, env 변경 불필요)
|
||||||
|
MATCH_MONITOR_MAX_PER_SIDE=1
|
||||||
|
|
||||||
|
# conviction tier — 코드 기본 enhanced=False 유지, env로 켜지 않음
|
||||||
|
SIM_TIER_CONVICTION_DD_PCT=10.0
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase C — 알림만 (월~금, 주문 없음)
|
||||||
|
|
||||||
|
**적용 기간:** ~2026-06-05
|
||||||
|
**실행:** `python scripts/05_run_monitor.py`
|
||||||
|
|
||||||
|
```env
|
||||||
|
# === Phase C ===
|
||||||
|
LIVE_TRADING_ENABLED=0
|
||||||
|
|
||||||
|
# 05 알림
|
||||||
|
MONITOR_ALERT_COOLDOWN_MIN=180
|
||||||
|
MONITOR_ALERT_KRW_AMOUNT=100000
|
||||||
|
MONITOR_LOOP_SLEEP_SEC=180
|
||||||
|
|
||||||
|
# 06 dry-run용 (C에서도 06 --once 가능, 주문 없음)
|
||||||
|
LIVE_ORDER_KRW=100000
|
||||||
|
LIVE_DAILY_KRW_MAX=300000
|
||||||
|
LIVE_COOLDOWN_MIN=180
|
||||||
|
LIVE_MAX_TRADES_PER_DAY=10
|
||||||
|
LIVE_DAILY_LOSS_LIMIT_KRW=50000
|
||||||
|
LIVE_SLIPPAGE_PCT=0.05
|
||||||
|
LIVE_BUY_PCT_LARGE=1.0
|
||||||
|
LIVE_BUY_PCT_SMALL=0.05
|
||||||
|
```
|
||||||
|
|
||||||
|
### Phase C 확인 명령
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/06_verify_live_dryrun.py
|
||||||
|
python scripts/05_run_monitor.py --once
|
||||||
|
python scripts/06_execute_live.py --once
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase B-1 — 소액 실거래 (토요일~)
|
||||||
|
|
||||||
|
**적용 시점:** 2026-06-06 (토) 00:00 이후 (금요일 C Go 후)
|
||||||
|
**실행:** `python scripts/06_execute_live.py`
|
||||||
|
|
||||||
|
```env
|
||||||
|
# === Phase B-1 ===
|
||||||
|
LIVE_TRADING_ENABLED=1
|
||||||
|
|
||||||
|
LIVE_ORDER_KRW=100000
|
||||||
|
LIVE_DAILY_KRW_MAX=1000000
|
||||||
|
LIVE_MAX_TRADES_PER_DAY=15
|
||||||
|
LIVE_COOLDOWN_MIN=180
|
||||||
|
LIVE_DAILY_LOSS_LIMIT_KRW=100000
|
||||||
|
LIVE_SLIPPAGE_PCT=0.05
|
||||||
|
LIVE_BUY_PCT_LARGE=1.0
|
||||||
|
LIVE_BUY_PCT_SMALL=0.05
|
||||||
|
|
||||||
|
MONITOR_ALERT_COOLDOWN_MIN=180
|
||||||
|
MONITOR_LOOP_SLEEP_SEC=180
|
||||||
|
```
|
||||||
|
|
||||||
|
| 항목 | 값 | 설명 |
|
||||||
|
|------|-----|------|
|
||||||
|
| 초기 자금 | ₩1,000,000 | 빗썸 가용 KRW |
|
||||||
|
| 일 매수 한도 | ₩1,000,000 | large tier 일부 가능, sim(무한)보다 보수 |
|
||||||
|
| 일 손실 중단 | ₩100,000 | -10% 일손실 시 당일 추가 주문 중단 |
|
||||||
|
| 1회 참고 | ₩100,000 | 매도 시 참고; **매수는 hybrid tier가 산출** |
|
||||||
|
|
||||||
|
### B-1 오픈 당일
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/06_verify_live_dryrun.py
|
||||||
|
python scripts/06_execute_live.py --once
|
||||||
|
python scripts/06_execute_live.py
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase B-2 — sim hybrid 근접 (B-1 Go 후, 2~4주)
|
||||||
|
|
||||||
|
> +1,000% 경로. **리스크·MDD·슬리피지 감수 가능할 때만.**
|
||||||
|
|
||||||
|
```env
|
||||||
|
# === Phase B-2 ===
|
||||||
|
LIVE_TRADING_ENABLED=1
|
||||||
|
|
||||||
|
LIVE_ORDER_KRW=100000
|
||||||
|
LIVE_DAILY_KRW_MAX=5000000
|
||||||
|
LIVE_MAX_TRADES_PER_DAY=30
|
||||||
|
LIVE_COOLDOWN_MIN=120
|
||||||
|
LIVE_DAILY_LOSS_LIMIT_KRW=300000
|
||||||
|
LIVE_SLIPPAGE_PCT=0.05
|
||||||
|
LIVE_BUY_PCT_LARGE=1.0
|
||||||
|
LIVE_BUY_PCT_SMALL=0.05
|
||||||
|
```
|
||||||
|
|
||||||
|
| sim 대비 | B-1 | B-2 |
|
||||||
|
|----------|-----|-----|
|
||||||
|
| 일한도 | 100만 | 500만 |
|
||||||
|
| large tier 1회 ~100% | 종종 스킵 | 대부분 가능 |
|
||||||
|
| +1000% 가능성 | 낮음 | sim에 근접 (보장 없음) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 절대 변경하지 말 것
|
||||||
|
|
||||||
|
```env
|
||||||
|
# conviction tier 배포 금지 — live_trader는 enhanced=False 고정
|
||||||
|
# GT_SIGNAL_CAUSAL=0 ← hybrid sizing 꺼짐, sim과 불일치
|
||||||
|
# SIM_PRIMARY_SIZING=causal_tier ← 구 +75% 경로
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 전환 체크
|
||||||
|
|
||||||
|
| 전환 | 조건 | `.env` 변경 |
|
||||||
|
|------|------|-------------|
|
||||||
|
| C → B-1 | 금요일 C Go | `LIVE_TRADING_ENABLED=1`, B-1 한도 |
|
||||||
|
| B-1 → B-2 | 2~4주 검증 Go | `LIVE_DAILY_KRW_MAX` 등 B-2 값 |
|
||||||
|
|
||||||
|
상세: [DEPLOYMENT_CHECKLIST.md](./DEPLOYMENT_CHECKLIST.md)
|
||||||
57
docs/05_ops/live_verification_20260601.md
Normal file
57
docs/05_ops/live_verification_20260601.md
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# Live Phase A — dry-run 검증
|
||||||
|
|
||||||
|
- 일시: 2026-06-01 16:37:13
|
||||||
|
- 결과: **PASS**
|
||||||
|
- **배포 일정:** Phase C ~6/5 (금) → Phase B-1 ~6/6 (토)
|
||||||
|
- **체크리스트:** [DEPLOYMENT_CHECKLIST.md](./DEPLOYMENT_CHECKLIST.md)
|
||||||
|
- **`.env` 권장:** [env.recommended.md](./env.recommended.md)
|
||||||
|
|
||||||
|
## Plan (목적)
|
||||||
|
|
||||||
|
- hybrid primary(`enhanced=False`) live_trader 경로가 시뮬과 정합인지 확인
|
||||||
|
- conviction tier(`enhanced=True`) 미사용 확인
|
||||||
|
- 실거래 한도가 hybrid tier와 어떻게 상호작용하는지 기록
|
||||||
|
|
||||||
|
## Do (실행)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/06_verify_live_dryrun.py
|
||||||
|
python scripts/06_execute_live.py --once
|
||||||
|
```
|
||||||
|
|
||||||
|
## Check (점검 결과)
|
||||||
|
|
||||||
|
- GT_SIGNAL_CAUSAL=True · live_sizing=ON · LIVE_TRADING_ENABLED=False
|
||||||
|
- monitor_rules: buy_compound_tight, sell_mtf_cross_all_tf
|
||||||
|
- hybrid DD: dd_large=5.0%, dd_medium=2.0%
|
||||||
|
- 현재 발화: 없음 (신호 대기)
|
||||||
|
- 06 dry-run: 주문 없음, live=OFF
|
||||||
|
|
||||||
|
### hybrid tier 사이징 (시나리오)
|
||||||
|
|
||||||
|
| 시나리오 | hybrid | conviction (배포 금지) |
|
||||||
|
|----------|--------|------------------------|
|
||||||
|
| 신규·DD 1% | ₩50,000 | ₩50,000 |
|
||||||
|
| 신규·DD 6% | ₩999,500 | ₩999,500 |
|
||||||
|
| 복리 500만·large leg | ₩4,997,501 | ₩4,997,501 |
|
||||||
|
|
||||||
|
- live_trader는 `enhanced=False` → hybrid primary와 동일 경로
|
||||||
|
- conviction은 DD 10% 이상·weight 분할 생략 시 시뮬과 크게 괴리 (별도 경로)
|
||||||
|
|
||||||
|
### 실거래 한도 (중요)
|
||||||
|
|
||||||
|
- 현재 시장 DD 구간에서 hybrid 1회 매수액 ≈ **₩999,500** (현금 100만 기준)
|
||||||
|
- `LIVE_DAILY_KRW_MAX=300,000` → **일 주문 한도 초과로 매수 스킵**
|
||||||
|
- 파일럿 단계에서는 한도가 의도적으로 시뮬(+1121%)보다 보수적임
|
||||||
|
|
||||||
|
## Act (다음 단계)
|
||||||
|
|
||||||
|
1. **Phase C (월~6/5 금):** `05_run_monitor.py` 상시 · `06_verify_live_dryrun.py` 1일 1회
|
||||||
|
2. **금요일 C Go/No-Go** — [DEPLOYMENT_CHECKLIST.md](./DEPLOYMENT_CHECKLIST.md) §4.4
|
||||||
|
3. **토 6/6~ Phase B-1:** [env.recommended.md](./env.recommended.md) 적용 후 `LIVE_TRADING_ENABLED=1`
|
||||||
|
4. 2~4주 후 B-2 승격 검토
|
||||||
|
|
||||||
|
## Kill switch
|
||||||
|
|
||||||
|
- `LIVE_TRADING_ENABLED=0` + 06 프로세스 중지
|
||||||
|
- 빗썸 앱 수동 청산
|
||||||
@@ -7,12 +7,16 @@
|
|||||||
## 선행 조건
|
## 선행 조건
|
||||||
|
|
||||||
1. `python scripts/04_simulation_report.py` → **Go/No-Go: GO**
|
1. `python scripts/04_simulation_report.py` → **Go/No-Go: GO**
|
||||||
2. 본 문서·`RISK.md`·`OPERATIONS.md` 숙지
|
2. [DEPLOYMENT_CHECKLIST.md](../05_ops/DEPLOYMENT_CHECKLIST.md) — Phase C 완료 후 B-1
|
||||||
3. `.env` 한도 값 확정
|
3. [env.recommended.md](../05_ops/env.recommended.md) — Phase별 `.env`
|
||||||
|
4. 본 문서·`RISK.md`·`OPERATIONS.md` 숙지
|
||||||
|
|
||||||
## 실행
|
## 실행
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# Phase A: hybrid tier·한도 점검 (주문 없음)
|
||||||
|
python scripts/06_verify_live_dryrun.py
|
||||||
|
|
||||||
# 반드시 LIVE_TRADING_ENABLED=1 일 때만 주문
|
# 반드시 LIVE_TRADING_ENABLED=1 일 때만 주문
|
||||||
python scripts/06_execute_live.py --once # 1회 점검
|
python scripts/06_execute_live.py --once # 1회 점검
|
||||||
python scripts/06_execute_live.py # 상시 (알림+주문)
|
python scripts/06_execute_live.py # 상시 (알림+주문)
|
||||||
|
|||||||
@@ -33,6 +33,8 @@
|
|||||||
|
|
||||||
## 오픈 체크리스트 (3단계 당일)
|
## 오픈 체크리스트 (3단계 당일)
|
||||||
|
|
||||||
|
- [ ] [DEPLOYMENT_CHECKLIST.md](../05_ops/DEPLOYMENT_CHECKLIST.md) Phase C Go
|
||||||
|
- [ ] [env.recommended.md](../05_ops/env.recommended.md) Phase B-1 적용
|
||||||
- [ ] 시뮬 Go/No-Go **GO**
|
- [ ] 시뮬 Go/No-Go **GO**
|
||||||
- [ ] `.env` 한도 확인
|
- [ ] `.env` 한도 확인
|
||||||
- [ ] `LIVE_TRADING_ENABLED=1` 의도적 설정
|
- [ ] `LIVE_TRADING_ENABLED=1` 의도적 설정
|
||||||
|
|||||||
278
scripts/06_verify_live_dryrun.py
Normal file
278
scripts/06_verify_live_dryrun.py
Normal file
@@ -0,0 +1,278 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Phase A: live_trader dry-run·hybrid tier 사이징·한도 점검."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import runpy
|
||||||
|
from datetime import datetime
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
runpy.run_path(str(Path(__file__).resolve().parent / "_bootstrap.py"))
|
||||||
|
|
||||||
|
from config import ( # noqa: E402
|
||||||
|
CHART_LOOKBACK_DAYS,
|
||||||
|
GT_SIGNAL_CAUSAL,
|
||||||
|
LIVE_COOLDOWN_MIN,
|
||||||
|
LIVE_DAILY_KRW_MAX,
|
||||||
|
LIVE_DAILY_LOSS_LIMIT_KRW,
|
||||||
|
LIVE_MAX_TRADES_PER_DAY,
|
||||||
|
LIVE_TRADING_ENABLED,
|
||||||
|
MATCH_PRIMARY_INTERVAL,
|
||||||
|
SIM_PRIMARY_SIZING,
|
||||||
|
SYMBOL,
|
||||||
|
TRADING_FEE_RATE,
|
||||||
|
)
|
||||||
|
from deepcoin.data.mtf_bb import load_frames_from_db
|
||||||
|
from deepcoin.ground_truth.hybrid_dd_calibrate import load_hybrid_dd_params
|
||||||
|
from deepcoin.matching.live_eval import evaluate_live_rules
|
||||||
|
from deepcoin.ground_truth.causal_gt_hybrid import _close_series_from_df, hybrid_tier_scale
|
||||||
|
from deepcoin.ground_truth.gt_model import leg_entry_weights
|
||||||
|
from deepcoin.matching.position_sizing import compute_buy_amount_krw
|
||||||
|
from deepcoin.matching.load_rules import load_monitor_rules
|
||||||
|
from deepcoin.matching.live_sizing import LivePositionState, live_sizing_enabled
|
||||||
|
from deepcoin.ops.live_trader import LiveTrader
|
||||||
|
from deepcoin.ops.monitor import Monitor
|
||||||
|
|
||||||
|
|
||||||
|
def _plan_with_dd(
|
||||||
|
cash: float,
|
||||||
|
qty: float,
|
||||||
|
price: float,
|
||||||
|
dd_pct: float,
|
||||||
|
*,
|
||||||
|
enhanced: bool,
|
||||||
|
completed_leg_ret: dict[int, float] | None = None,
|
||||||
|
leg_id: int = 1,
|
||||||
|
) -> float:
|
||||||
|
"""drawdown %를 고정한 tier 매수 원화 (검증용)."""
|
||||||
|
weights = leg_entry_weights([price])
|
||||||
|
trade: dict = {"leg_id": leg_id, "drawdown_pct": dd_pct}
|
||||||
|
dd_params = load_hybrid_dd_params()
|
||||||
|
scale = hybrid_tier_scale(
|
||||||
|
trade,
|
||||||
|
completed_leg_ret=completed_leg_ret or {},
|
||||||
|
enhanced=enhanced,
|
||||||
|
dd_large_pct=dd_params.get("dd_large_pct"),
|
||||||
|
dd_medium_pct=dd_params.get("dd_medium_pct"),
|
||||||
|
)
|
||||||
|
return compute_buy_amount_krw(
|
||||||
|
cash,
|
||||||
|
qty,
|
||||||
|
price,
|
||||||
|
weights[0],
|
||||||
|
weights[0],
|
||||||
|
asset_pct_scale=scale,
|
||||||
|
fee_rate=TRADING_FEE_RATE,
|
||||||
|
ignore_weight_split=bool(trade.get("conviction_buy")),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _print_header(title: str) -> None:
|
||||||
|
print(f"\n=== {title} ===")
|
||||||
|
|
||||||
|
|
||||||
|
def check_config() -> list[str]:
|
||||||
|
"""필수 설정 확인. 문제 목록 반환."""
|
||||||
|
issues: list[str] = []
|
||||||
|
_print_header("1. 설정")
|
||||||
|
print(f" SYMBOL={SYMBOL}")
|
||||||
|
print(f" GT_SIGNAL_CAUSAL={GT_SIGNAL_CAUSAL} (live_sizing={live_sizing_enabled()})")
|
||||||
|
print(f" LIVE_TRADING_ENABLED={LIVE_TRADING_ENABLED}")
|
||||||
|
print(f" SIM_PRIMARY_SIZING={SIM_PRIMARY_SIZING}")
|
||||||
|
dd = load_hybrid_dd_params()
|
||||||
|
print(f" hybrid DD: large={dd.get('dd_large_pct')}% medium={dd.get('dd_medium_pct')}%")
|
||||||
|
print(
|
||||||
|
f" LIVE 한도: daily_max={LIVE_DAILY_KRW_MAX:,} "
|
||||||
|
f"max_trades={LIVE_MAX_TRADES_PER_DAY} "
|
||||||
|
f"loss_limit={LIVE_DAILY_LOSS_LIMIT_KRW:,} "
|
||||||
|
f"cooldown={LIVE_COOLDOWN_MIN}min"
|
||||||
|
)
|
||||||
|
rules = load_monitor_rules()
|
||||||
|
print(f" monitor_rules={[r['rule_id'] for r in rules]}")
|
||||||
|
if not GT_SIGNAL_CAUSAL:
|
||||||
|
issues.append("GT_SIGNAL_CAUSAL=0 — hybrid live sizing 비활성")
|
||||||
|
if LIVE_TRADING_ENABLED:
|
||||||
|
issues.append("LIVE_TRADING_ENABLED=1 — dry-run 점검 시 0 권장")
|
||||||
|
if len(rules) != 2:
|
||||||
|
issues.append(f"monitor_rules {len(rules)}개 (기대 2)")
|
||||||
|
expected = {"buy_compound_tight", "sell_mtf_cross_all_tf"}
|
||||||
|
got = {r["rule_id"] for r in rules}
|
||||||
|
if got != expected:
|
||||||
|
issues.append(f"monitor_rules 불일치: {got}")
|
||||||
|
return issues
|
||||||
|
|
||||||
|
|
||||||
|
def check_tier_sizing(df) -> list[str]:
|
||||||
|
"""hybrid vs conviction tier 금액 비교 (enhanced=False가 primary)."""
|
||||||
|
issues: list[str] = []
|
||||||
|
_print_header("2. hybrid tier 사이징 (시나리오)")
|
||||||
|
price = 487.0
|
||||||
|
scenarios = [
|
||||||
|
("신규·소형DD(1%)", 1_000_000, 0.0, 1.0, {}),
|
||||||
|
("신규·대형DD(6%)", 1_000_000, 0.0, 6.0, {}),
|
||||||
|
("복리·과거large leg", 5_000_000, 2000.0, 3.0, {"completed_leg_ret": {1: 25.0}}),
|
||||||
|
]
|
||||||
|
for label, cash, qty, dd, extra in scenarios:
|
||||||
|
hybrid_amt = _plan_with_dd(
|
||||||
|
cash,
|
||||||
|
qty,
|
||||||
|
price,
|
||||||
|
dd,
|
||||||
|
enhanced=False,
|
||||||
|
completed_leg_ret=extra.get("completed_leg_ret"),
|
||||||
|
)
|
||||||
|
conv_amt = _plan_with_dd(
|
||||||
|
cash,
|
||||||
|
qty,
|
||||||
|
price,
|
||||||
|
dd,
|
||||||
|
enhanced=True,
|
||||||
|
completed_leg_ret=extra.get("completed_leg_ret"),
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f" [{label}] cash={cash:,} hybrid={hybrid_amt:,} "
|
||||||
|
f"conviction={conv_amt:,} (conviction 배포 금지)"
|
||||||
|
)
|
||||||
|
if hybrid_amt <= 0:
|
||||||
|
issues.append(f"hybrid 금액 0: {label}")
|
||||||
|
return issues
|
||||||
|
|
||||||
|
|
||||||
|
def check_live_limits() -> None:
|
||||||
|
"""시뮬 대비 실거래 일한도 영향 안내."""
|
||||||
|
_print_header("3. 실거래 한도 vs hybrid tier")
|
||||||
|
st = LivePositionState()
|
||||||
|
mon = Monitor(cooldown_file=None)
|
||||||
|
frames = load_frames_from_db(mon, SYMBOL, lookback_days=CHART_LOOKBACK_DAYS)
|
||||||
|
df = frames.get(MATCH_PRIMARY_INTERVAL)
|
||||||
|
price = 487.0
|
||||||
|
if df is not None and not df.empty:
|
||||||
|
close_s = _close_series_from_df(df)
|
||||||
|
if not close_s.empty:
|
||||||
|
price = float(close_s.iloc[-1])
|
||||||
|
planned = st.plan_buy_amount_krw(
|
||||||
|
str(df.index[-1]) if df is not None and not df.empty else "2026-06-01 12:00:00",
|
||||||
|
price,
|
||||||
|
1_000_000,
|
||||||
|
0.0,
|
||||||
|
df,
|
||||||
|
enhanced=False,
|
||||||
|
fee_rate=TRADING_FEE_RATE,
|
||||||
|
)
|
||||||
|
trader = LiveTrader()
|
||||||
|
ok, reason = trader._can_trade("buy_compound_tight", planned)
|
||||||
|
print(f" 현재가={price:,.0f} · hybrid planned={planned:,}")
|
||||||
|
print(f" LIVE_DAILY_KRW_MAX={LIVE_DAILY_KRW_MAX:,} → _can_trade={ok} ({reason or 'OK'})")
|
||||||
|
if planned > LIVE_DAILY_KRW_MAX:
|
||||||
|
print(
|
||||||
|
" WARN: hybrid 1회 매수액이 일한도 초과 가능 — "
|
||||||
|
"파일럿은 의도적 제한, 시뮬(+1121%)과 괴리 발생"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def check_live_eval() -> None:
|
||||||
|
"""현재 시점 규칙 발화."""
|
||||||
|
_print_header("4. 현재 발화 (live_eval)")
|
||||||
|
fired = evaluate_live_rules(force_refresh=True)
|
||||||
|
if not fired:
|
||||||
|
print(" 발화 없음 (정상 — 신호 대기)")
|
||||||
|
return
|
||||||
|
for hit in fired:
|
||||||
|
print(f" {hit['side']} {hit['rule_id']} @ {hit['dt']} close={hit['close']}")
|
||||||
|
|
||||||
|
|
||||||
|
def run_dryrun_once() -> None:
|
||||||
|
"""06 1회 dry-run."""
|
||||||
|
_print_header("5. 06_execute_live --once (dry-run)")
|
||||||
|
LiveTrader().run_once()
|
||||||
|
|
||||||
|
|
||||||
|
def write_verification_report(issues: list[str], out_path: Path) -> None:
|
||||||
|
"""Phase A 결과를 docs/05_ops에 기록."""
|
||||||
|
out_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
status = "PASS" if not issues else "WARN"
|
||||||
|
lines = [
|
||||||
|
"# Live Phase A — dry-run 검증",
|
||||||
|
"",
|
||||||
|
f"- 일시: {datetime.now():%Y-%m-%d %H:%M:%S}",
|
||||||
|
f"- 결과: **{status}**",
|
||||||
|
"",
|
||||||
|
"## Plan (목적)",
|
||||||
|
"",
|
||||||
|
"- hybrid primary(`enhanced=False`) live_trader 경로가 시뮬과 정합인지 확인",
|
||||||
|
"- conviction tier(`enhanced=True`) 미사용 확인",
|
||||||
|
"- 실거래 한도가 hybrid tier와 어떻게 상호작용하는지 기록",
|
||||||
|
"",
|
||||||
|
"## Do (실행)",
|
||||||
|
"",
|
||||||
|
"```bash",
|
||||||
|
"python scripts/06_verify_live_dryrun.py",
|
||||||
|
"python scripts/06_execute_live.py --once",
|
||||||
|
"```",
|
||||||
|
"",
|
||||||
|
"## Check (점검 결과)",
|
||||||
|
"",
|
||||||
|
f"- GT_SIGNAL_CAUSAL={GT_SIGNAL_CAUSAL}",
|
||||||
|
f"- LIVE_TRADING_ENABLED={LIVE_TRADING_ENABLED}",
|
||||||
|
f"- monitor_rules: buy_compound_tight, sell_mtf_cross_all_tf",
|
||||||
|
f"- hybrid DD: {load_hybrid_dd_params()}",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
if issues:
|
||||||
|
lines.append("### 이슈")
|
||||||
|
lines.append("")
|
||||||
|
for i in issues:
|
||||||
|
lines.append(f"- {i}")
|
||||||
|
lines.append("")
|
||||||
|
lines.extend(
|
||||||
|
[
|
||||||
|
"## Act (다음 단계)",
|
||||||
|
"",
|
||||||
|
"1. `05_run_monitor.py` 1~2일 병행 (알림만)",
|
||||||
|
"2. `.env` 파일럿 한도 확정 후 `LIVE_TRADING_ENABLED=1`",
|
||||||
|
"3. 1~2주 실계좌 PnL·슬리피지 기록 (본 문서 갱신)",
|
||||||
|
"",
|
||||||
|
"## Kill switch",
|
||||||
|
"",
|
||||||
|
"- `LIVE_TRADING_ENABLED=0` + 06 프로세스 중지",
|
||||||
|
"- 빗썸 앱 수동 청산",
|
||||||
|
"",
|
||||||
|
]
|
||||||
|
)
|
||||||
|
out_path.write_text("\n".join(lines), encoding="utf-8")
|
||||||
|
print(f"\n[저장] {out_path}")
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
"""Phase A 검증 실행."""
|
||||||
|
print("[06_verify] Phase A dry-run 검증 시작")
|
||||||
|
issues = check_config()
|
||||||
|
mon = Monitor(cooldown_file=None)
|
||||||
|
frames = load_frames_from_db(mon, SYMBOL, lookback_days=CHART_LOOKBACK_DAYS)
|
||||||
|
df = frames.get(MATCH_PRIMARY_INTERVAL)
|
||||||
|
if df is None or df.empty:
|
||||||
|
issues.append("3m OHLC 없음 — 01_download 필요")
|
||||||
|
else:
|
||||||
|
issues.extend(check_tier_sizing(df))
|
||||||
|
check_live_limits()
|
||||||
|
check_live_eval()
|
||||||
|
run_dryrun_once()
|
||||||
|
out = (
|
||||||
|
Path(__file__).resolve().parents[1]
|
||||||
|
/ "docs"
|
||||||
|
/ "05_ops"
|
||||||
|
/ f"live_verification_{datetime.now():%Y%m%d}.md"
|
||||||
|
)
|
||||||
|
write_verification_report(issues, out)
|
||||||
|
_print_header("요약")
|
||||||
|
if issues:
|
||||||
|
for i in issues:
|
||||||
|
print(f" WARN: {i}")
|
||||||
|
print(" → 이슈 확인 후 Phase B(소액 파일럿) 진행")
|
||||||
|
return 1
|
||||||
|
print(" Phase A PASS — Phase B(소액 LIVE_TRADING_ENABLED=1) 준비 완료")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -10,6 +10,7 @@ python scripts/03_analyze_trades.py
|
|||||||
python scripts/04_match_rules.py
|
python scripts/04_match_rules.py
|
||||||
python scripts/04_simulation_report.py # 1단계 Go/No-Go
|
python scripts/04_simulation_report.py # 1단계 Go/No-Go
|
||||||
python scripts/05_run_monitor.py # 알림만
|
python scripts/05_run_monitor.py # 알림만
|
||||||
|
python scripts/06_verify_live_dryrun.py # Phase A dry-run·tier 점검
|
||||||
python scripts/06_execute_live.py # 3단계 실거래
|
python scripts/06_execute_live.py # 3단계 실거래
|
||||||
python scripts/05_chart_truth.py
|
python scripts/05_chart_truth.py
|
||||||
python scripts/05_chart_bb.py
|
python scripts/05_chart_bb.py
|
||||||
|
|||||||
Reference in New Issue
Block a user