---
name: 키움 REST 통합 설계 결정
description: 관리자님이 확정한 키움증권 REST 통합 설계 — owner 그룹 "본인(일반/ISA) + 가희(가희_일반/가희_ISA)", portfolio.json B안(accounts 중첩) v2 스키마, 표시는 owner 블록. 엔드포인트·TR 매핑 확정.
type: project
---
키움 REST API 통합 설계 확정 사항 (2026-04-23 수립 → 2026-04-24 실연동 → 2026-04-25 가희 명의 2계좌 추가로 owner 그룹 도입).

**1. 계좌 라벨**: `일반`, `ISA`, `가희_일반`, `가희_ISA`. credentials·snapshot·메시지 모두 이 라벨 사용. owner 그룹은 라벨 prefix로 자동 도출(`가희_*` → 가희, 그 외 → 본인). 향후 가족 계좌 추가 시 동일한 `<이름>_<상품>` 패턴 사용.

**2. portfolio.json v2 스키마 (B안 — 2026-04-24 실데이터 마이그레이션, 2026-04-25 4계좌로 확장)**:
```json
{
  "schema_version": 2,
  "last_update": "...",
  "source": "kiwoom-rest",
  "accounts": {
    "일반":      {"positions": {"종목명": {"code","qty","avgPrice"}, ...}},
    "ISA":       {"positions": {"종목명": {"code","qty","avgPrice"}, ...}},
    "가희_일반": {"positions": {...}},
    "가희_ISA":  {"positions": {...}}
  }
}
```
- 같은 종목을 여러 계좌에 분산 보유해도 평단·수량이 안 섞임
- iMessage 체결 누적으로 쌓인 기존 v1 데이터는 믿지 않는다 — 키움 REST `kt00018` 응답이 ground truth
- `memory/portfolio.json`은 참고용 스냅샷. 리포트 숫자는 항상 REST 실시간 조회

**3. 표시 방식 (owner 블록)**:
- 평소 브리핑·리포트: owner 그룹별 블록(본인 / 가희) 표시. 그룹 내에서만 같은 종목 가중평단 합산. 본인 자금과 가희 자금은 절대 한 칸에 합산하지 않음 (회계상 분리)
- `--by-account` 옵션: owner 블록 안에서 4계좌별 상세까지 추가 분리
- 텔레그램 요약: owner별 합계 + (그룹 ≥2개일 때) 전체 합계 + 당일 매매에 owner/계좌 태그

**4. API 엔드포인트·TR 매핑 (실연동 확정)**:
- Base: `https://api.kiwoom.com`
- 토큰: `POST /oauth2/token` — body `{grant_type:"client_credentials", appkey, secretkey}` → `{token, expires_dt:"YYYYMMDDHHmmss"}`
- 계좌 API 공통: `POST /api/dostk/acnt` — header `api-id:<TR_ID>`, `Authorization: Bearer <token>`, `cont-yn:N`, `next-key:""`
  - `kt00001` 예수금상세현황: body `{qry_tp:"3"}` → `entr`(예수금), `ord_alow_amt`, `d2_entra`, `repl_amt`(대용금)
  - `kt00004` 계좌평가현황: body `{qry_tp:"0", dmst_stex_tp:"KRX"}` → `acnt_nm`, `brch_nm`, `tot_est_amt`, `aset_evlt_amt`, `stk_acnt_evlt_prst[]`
  - `kt00018` 계좌평가잔고내역: body `{qry_tp:"1", dmst_stex_tp:"KRX"}` → `tot_pur_amt`, `tot_evlt_amt`, `tot_evlt_pl`, `tot_prft_rt`, `acnt_evlt_remn_indv_tot[]`(종목별)
- 종목별 필드 (kt00018 acnt_evlt_remn_indv_tot): `stk_cd`(A prefix 붙음), `stk_nm`, `rmnd_qty`, `pur_pric`(평단), `cur_prc`, `pur_amt`, `evlt_amt`, `evltv_prft`, `prft_rt`, `poss_rt`, `tdy_buyq`, `tdy_sellq`
- 모든 숫자는 zero-padded string (음수는 `-` prefix). 클라이언트가 int로 파싱.
- **NXT(NextTrade) 거래소 지정**: 시세 TR(`ka10001` 등)은 종목코드 접미사로 거래소 선택. `005930`=KRX 단독, `005930_NX`=NXT 단독, `005930_AL`=KRX+NXT 통합. body의 `stex_tp` 파라미터는 stkinfo 경로에서 무시됨 — 접미사가 유일한 방법. 통합(`_AL`)은 가장 늦은 체결가 + 통합 거래량(KRX+NXT 합계). NXT 미상장 종목(서남 등)은 `_AL` 호출 시 KRX 값 fallback. `kiwoom_client.get_stock_quote(code, exchange='AL')` 기본값 통합. 단, 잔고 평가(stock_portfolio_report day_change 보정)는 kt00018의 KRX 종가와 일관성 유지하려 `exchange='KRX'` 명시.

**Why:** 본인 + 가희 다명의 4계좌 기준으로 가장 실용적·안전한 조합. B안은 종목 중복 시 데이터 무결성 보장. owner 블록 표시는 자금 주체를 시각적으로 분리하면서도 필요 시 계좌 단위까지 드릴다운 가능. 엔드포인트는 실호출로 확정 (키움 공식 문서가 SPA라 정적 크롤링 불가 → probe 스크립트로 검증).

**How to apply:**
- 모든 키움 관련 스크립트·스킬에서 계좌 라벨은 `일반`, `ISA`, `가희_일반`, `가희_ISA` 문자열 사용 (영문 alias 불필요)
- 새 코드 작성 시 portfolio v2 스키마(B안) 가정. v1 스키마 읽는 코드 있으면 즉시 v2로 포팅
- 리포트·알림 출력 함수는 기본 owner 블록, `--by-account` 또는 동등한 옵션으로 계좌 분리 출력 지원
- 신규 계좌(가족 등) 추가 시 `<이름>_<상품>` 라벨 컨벤션 유지 — 그래야 prefix 분기가 자동 동작
- 엔드포인트 추가 필요 시 `kt00018` 패턴(TR_ID + body) 그대로 재사용 가능. 주문 TR(kt1000x)은 절대 호출·함수 작성 금지
