GT 총자산 비율 매수·leg 티어 배분과 시뮬/실거래 포지션 사이징을 통합한다.

타점·비중을 gt_model로 일반화하고, amount_krw 시각순 배분·EV/WF·상위 leg 대형 매수를
position_sizing과 시뮬 HTML(고정 ₩/회 비교)에 반영한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-31 16:11:49 +09:00
parent 2cb67c42b3
commit 5842cc9fa3
14 changed files with 2073 additions and 182 deletions

View File

@@ -1,35 +1,78 @@
# 정답 타점 (Ground Truth)
1(기본 45일) 3분봉 구간에서 **사후 최적 스윙** 매수·매도 라벨을 만듭니다.
실시간 매매 전략이 아니라, 이후 전략 검증·학습용 **정답 데이터**입니다.
1(기본 `CHART_LOOKBACK_DAYS=365`) 3분봉에서 **사후 최적 스윙** 매수·매도 라벨.
실시간 전략이 아니라 규칙·시뮬 검증용 **벤치마크**입니다.
## Plan
JSON 필드 `model`에 타점·비중·자본 배분 규칙이 일반화되어 있습니다 (`deepcoin/ground_truth/gt_model.py`).
- **목적**: 차트 상 의미 있는 저점 매수·고점 매도를 JSON으로 고정
- **방법**: 고점(major swing)에서 1~2회 매도 · 저점(ZigZag+BB)에서 분할 매수 · 삼각형 크기=비중
- **체결 순서**: JSON 저장·포트폴리오 시뮬은 **leg별 매수 전량 → 매도 전량** (시각순 아님). 차트 표는 시각순 정렬.
- **HTML 카드**: 초기 금액, 총보유자산, 초기 대비 증감율(종가 평가 포함). 기간말 leg는 **종가 청산** 포함.
## Plan — 타점 구조 (일반화)
## Do
### Leg (라운드트립 구간)
```bash
python scripts/02_ground_truth.py # ground_truth_trades.json
python scripts/05_chart_truth.py # JSON + HTML 차트
- **leg_id**: 이전 **고점 매도** 시각 ~ 다음 **고점 매도** 직전까지.
- 마지막 구간: 마지막 major peak 이후 ~ 기간 말 → **기간말 leg** (종가 청산 1회).
### 매수 타점 (Entry)
| 항목 | 규칙 |
|------|------|
| 피벗 | ZigZag **저점(trough)**, `GT_BUY_MIN_SWING_PCT` |
| 가격 | 해당 봉 **Low** |
| 후보 | leg 구간 내 trough, `GT_BUY_MIN_BARS` 간격, BB (`bb_pos <= GT_BUY_BB_MAX`) |
| **비중 weight** | `w_i = (1/price_i) / Σ(1/price_j)`**저가일수록 큰 비중** |
| leg당 상한 | `GT_MAX_BUYS_PER_LEG` (초과 시 저가 순 유지) |
### 매도 타점 (Exit)
| 항목 | 규칙 |
|------|------|
| 피벗 | **major swing 고점(peak)** |
| 가격 | 해당 봉 **High** |
| **비중 weight** | 1회 매도: **100%** · 2회 분할: **65% + 35%** (`GT_SELL_SPLIT_GAP_PCT`) |
| 수량 | leg 보유 수량 × 매도 비중 (마지막 매도 = leg 전량) |
## Do — 자본 배분 (amount_krw)
시각순 체결. **매도 후 현금**이 다음 매수에 반영됩니다.
```
총보유자산 = 현금 + 보유×체결가
최적매수율 = (이번 weight / leg 남은 weight 합) × leg티어스케일
목표매수액 = 총보유자산 × 최적매수율
실제매수액 = min(목표, 가용현금/(1+수수료)), 최소 GT_MIN_ORDER_KRW
```
## Check
| leg 티어 | 조건 | 스케일 (`.env`) |
|----------|------|-----------------|
| 대형 | leg 수익률 상위 `GT_LARGE_LEG_TOP_PCT` | `GT_BUY_PCT_LARGE_LEG` (기본 1.0) |
| 소형 | 그 외 | `GT_BUY_PCT_SMALL_LEG` (기본 0.05) |
| 환경 변수 | 기본 | 설명 |
|-----------|------|------|
| `CHART_LOOKBACK_DAYS` | 365 | 조회 일수 (`.env` 기본 1년) |
| `GT_MIN_SWING_PCT` | 4.0 | ZigZag 최소 스윙(%) |
| `GT_PIVOT_ORDER` | 20 | 국소 극값 반경(봉) |
| `GT_MIN_BARS_BETWEEN` | 30 | 체결 간격(3분봉 30봉=90분) |
| `GT_MIN_LEG_PCT` | 8.0 | 한 구간 최소 수익(%) |
| `GT_MAX_ROUND_TRIPS` | 24 | 최대 라운드트립 |
| `GT_SELECTION_MODE` | split_buy_peak_sell | `split_buy_peak_sell` 등 (`.env` 참고) |
**summary.pnl_pct**: 위 배분으로 **시각순** 시뮬 + 기간말 **종가 평가**.
**JSON 저장 순서**: leg별 매수 전량 → 매도 전량 (`leg_block`, 차트·테이블 정합).
## 실행
```bash
python scripts/02_ground_truth.py # ground_truth_trades.json (+ model)
python scripts/05_chart_truth.py # HTML 차트
```
## Check — 주요 환경 변수
| 변수 | 기본 | 설명 |
|------|------|------|
| `GT_MIN_SWING_PCT` | 4.0 | 매도 피벗 ZigZag(%) |
| `GT_BUY_MIN_SWING_PCT` | 3.0 | 매수 피벗 ZigZag(%) |
| `GT_PIVOT_ORDER` | 20 | 국소 극값 반경 |
| `GT_MIN_BARS_BETWEEN` | 30 | 체결 최소 간격(봉) |
| `GT_MIN_LEG_PCT` | 8.0 | major leg 최소 수익(%) |
| `GT_BUY_PCT_LARGE_LEG` | 1.0 | 상위 leg 총자산 배분 스케일 |
| `GT_BUY_PCT_SMALL_LEG` | 0.05 | 소형 leg 스케일 |
| `GT_LARGE_LEG_TOP_PCT` | 0.2 | 대형 leg 상위 비율 |
| `GT_MIN_ORDER_KRW` | 5000 | 최소 체결 원화 |
## Act
- JSON 수동 수정 후 `scripts/05_chart_truth.py` 재실행으로 차트 갱신
- 파라미터 조정으로 타점 수·크기 튜닝
- JSON·`model` 수정 후 `02` / `05` 재실행
- 시뮬 비교: `04_simulation_report.py` (GT vs 시뮬·총자산% vs 고정 ₩/회)