docs(dcy-035): 멀티데이 WAC 실현PnL 운영리포트 — discovery confirmed + REQ-109/110/111 approved
- dcy-035 confirm-discovery: OQ-1=전 인스턴스 WAC 통일, OQ-5=섹션 에러 degrade - REQ-109 portfolio-hub /pnl/realized read 어댑터(포트+HTTP+stub) - REQ-110 운영리포트 WAC 실현손익 통합(전 인스턴스, 매수일 수수료, completeness, 일중 net 회귀) - REQ-111 portfolio-hub 미가용 시 실현손익 섹션 에러 degrade(폴백 없음) - srs/index register 갱신 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
# 0. 문서 상태
|
||||
- 상태: confirmed
|
||||
- 문서 ID: dcy-035_20260626_multiday-realized-pnl-report-wac
|
||||
- 이슈명: 중장기 운영 리포트 — portfolio-hub WAC 실현PnL(/pnl/realized) 연동 (멀티데이 정확 실현손익)
|
||||
- 작성 시각(KST): 2026-06-26 (KST)
|
||||
- 마지막 갱신 시각(KST): 2026-06-26 (KST)
|
||||
- 대체됨: 없음
|
||||
- 후속 Discovery 참조: 없음
|
||||
- 생성된 REQ 참조: REQ-109, REQ-110, REQ-111
|
||||
|
||||
# 1. 계획 상태 요약
|
||||
- 연계 문서 현황:
|
||||
- 관련 TODO/메모: GitHub 보드 #7 "중장기 운영 리포트 — portfolio-hub WAC 실현PnL API(/pnl/realized) 연동 (멀티데이, M3)". M3 중장기 인스턴스 운영 도구(슬롯 동기화 dcy-034의 리포트 짝).
|
||||
- 선행: dcy-029(운영 관측성·실현 PnL 뷰, REQ-088 operator report), dcy-032(체결가 누락→cost basis 오염), portfolio-hub dcy-007/REQ-040(WAC 실현 PnL API).
|
||||
- 해석:
|
||||
- 현행 trex-core 운영 리포트(`application/operator_report.py`, REQ-088/dcy-029)는 실현 PnL을 **당일 net 매매 현금흐름**(`Σ매도(qty·price−fee−tax) − Σ매수(qty·price+fee)`)으로 계산한다. **일중 진입·청산 전략에선 net ≈ 실현손익**이라 충분했으나(M1/M2 단기), **중장기(수일~수개월 보유)에선 cost basis(WAC)를 무시한 당일 net이 실현손익과 다르다**.
|
||||
- portfolio-hub는 이미 **WAC 기반 실현 PnL**(`GET /v1/portfolios/{id}/pnl/realized`, REQ-040/041: `(매도가−running_wac)·qty−fee−tax`)을 제공한다. M3 중장기 인스턴스의 운영 리포트는 이 WAC API를 소비해 **멀티데이 정확 실현손익**을 보여야 한다.
|
||||
- 본 Discovery는 그 연동을 trex-core 변경 단위로 정식화한다(portfolio-hub는 기존 API 그대로 — 무변경).
|
||||
|
||||
# 2. 요구사항 판정 결과
|
||||
- 판정: 신규
|
||||
- 근거
|
||||
- dcy-029(REQ-088)는 **당일 net** 실현 PnL을 정의했다(`operator_report.py` 주석: "일중 진입·청산 전략에서는 net ≈ 실현손익"). 멀티데이 WAC 실현손익은 다른 계산 정의이며, **외부(portfolio-hub) WAC API 소비**라는 신규 연동이다.
|
||||
- trex-core에 portfolio-hub `/pnl/realized` 클라이언트 메서드/포트가 없다(신규).
|
||||
|
||||
# 3. 문제점의 요약
|
||||
- 현재 상태
|
||||
- `operator_report.py`(REQ-088): `realized_pnl(trades)`가 `ledger_outbox` 당일 거래로 net(매도대금−매수대금−수수료−세금)을 계산. 자산별 분해 포함. `trex-core report` CLI로 노출.
|
||||
- 이 정의는 **당일 매수→당일 매도(일중)** 에서만 실현손익과 일치한다. **전일 이전 매수분을 오늘 매도**하면, 당일 net은 "오늘 매도대금 − (오늘 없는 매수)"가 되어 cost basis가 빠진 채 실현손익이 과대/왜곡된다(중장기 보유의 본질).
|
||||
- portfolio-hub `/pnl/realized`(REQ-040)는 매수 누적 WAC를 cost basis로 써 매도별 정확 실현손익을 주지만, trex-core 리포트가 이를 소비하지 않는다.
|
||||
- 기대 상태
|
||||
- 중장기 인스턴스 운영 리포트의 실현 PnL이 **portfolio-hub WAC API(/pnl/realized) 기준의 멀티데이 정확 실현손익**으로 표시된다(매수 cost basis 반영).
|
||||
- portfolio-hub 이력 불완전 시(`data_completeness_warning`)가 리포트에 표면화된다.
|
||||
- portfolio-hub 미가용 시 리포트가 안전하게 degrade(에러 표시 또는 당일 net 폴백)한다.
|
||||
- 이해관계자
|
||||
- 사장님 — 리포트 정의(멀티데이 기준)·범위 결정
|
||||
- 팀장(Claude) — Discovery/게이트
|
||||
- trex-core-dev — delivery
|
||||
- 운영자 — 중장기 인스턴스 손익 리포트 소비자
|
||||
- 제약사항
|
||||
- portfolio-hub `/pnl/realized`는 **매도 기준 date-filter, 전 매수 WAC 참여**(REQ-041): 즉 기간 내 *매도*의 실현손익을 주고, 그 cost basis는 기간 밖 매수도 포함. (멀티데이 정의에 부합.)
|
||||
- **매수만 한 날**은 매도가 없어 realized=0 — 사장님 정의("매수만 한 경우 수수료 비용")를 충족하려면 리포트가 **수수료(비용)를 별도 표시**해야 함(realized와 분리).
|
||||
- trex-core wire 계약(slots RPC) 무관(리포트는 read-only 운영 표면). portfolio-hub HTTP 호출 추가(read).
|
||||
|
||||
## 주요 사용자 시나리오
|
||||
- 운영자: 중장기 인스턴스의 `trex-core report`(또는 동등)로 기간 실현손익을 본다 → 전일 매수분을 오늘 매도한 손익이 WAC 기준으로 정확히 표시(당일 net 왜곡 아님).
|
||||
- 운영자: 매수만 한 날 → 실현손익 0 + 수수료 비용 표시. 매도한 날 → WAC 실현손익. 둘 다 → 매수(WAC) 반영 후 매도 실현손익.
|
||||
|
||||
# 4. 이번에 정의할 변경
|
||||
- 변경 1 — portfolio-hub `/pnl/realized` 소비 포트/어댑터 신규: `PortfolioHubReadPort`(또는 신규 포트)에 realized-pnl read 메서드 + HTTP 어댑터(`GET /v1/portfolios/{id}/pnl/realized`, from/to/symbol).
|
||||
- 변경 2 — 운영 리포트의 실현 PnL을 WAC 기반으로 **전 인스턴스 통일**(OQ-1 결정): `operator_report.py`가 당일 net 대신 portfolio-hub WAC 실현손익을 사용(단·중·장기 공통 — WAC는 일중에도 정확). data_completeness_warning 표면화. 매수만 한 날의 수수료 비용 별도 표시.
|
||||
- 변경 3 — degrade: portfolio-hub 미가용 시 **실현손익 섹션에 에러 명시**(OQ-5 결정 — 당일 net 폴백 안 함). 나머지 리포트 섹션(보유/체결/대기주문)은 정상 출력.
|
||||
|
||||
## 영향 범위
|
||||
- 코드 영향: `trex_core/adapters/portfolio/*`(realized-pnl read 어댑터 신규), `trex_core/application/portfolio.py`(포트), `trex_core/application/operator_report.py`(실현 PnL 소스 분기), `trex_core/runtime/cli.py`(report 명령 — 기간/모드 옵션 필요시).
|
||||
- 문서 영향: `docs/discovery/index.md`, srs/batches. `docs/operations.md`(리포트 해석 갱신).
|
||||
- 운영 영향: 리포트 실현손익 정의가 중장기 모드에서 WAC로 바뀜 — 런북에 명시. portfolio-hub 호출 의존 추가.
|
||||
|
||||
# 5. 요구사항 목록
|
||||
## 기능 요구사항
|
||||
- FR-1: trex-core가 portfolio-hub `GET /v1/portfolios/{id}/pnl/realized`(from/to/symbol)를 호출하는 read 포트+어댑터를 갖는다.
|
||||
- FR-2: 운영 리포트의 실현 PnL을 **전 인스턴스 공통으로** portfolio-hub WAC 실현손익 기준으로 산출·표시한다(당일 net 대체, 멀티데이 cost basis 반영). 자산별 분해 유지.
|
||||
- FR-3: 매수만 한 기간(매도 0)은 실현손익 0 + **수수료 비용을 별도 항목으로 표시**(사장님 정의).
|
||||
- FR-4: portfolio-hub `data_completeness_warning`(이력 불완전)을 리포트에 표면화한다.
|
||||
- FR-5: portfolio-hub 미가용 시 **실현손익 섹션에 에러를 명시**하고(폴백 없음), 나머지 리포트 섹션은 정상 출력한다.
|
||||
|
||||
## 비기능 요구사항
|
||||
- NFR-1: trex-core wire 계약(slots RPC) 불변 — 리포트는 read-only 운영 표면.
|
||||
- NFR-2: 전 인스턴스 통일이므로, **일중 매수+매도(같은 날) 케이스에서 WAC 실현손익이 기존 당일 net과 일치**함을 회귀 테스트로 보장한다(단기 라이브 의미 보존 — WAC(=당일 매수가)·매도가 동일 정의).
|
||||
- NFR-3: portfolio-hub 호출 실패가 데몬 본업(슬롯/집행)에 영향 주지 않는다(리포트 격리).
|
||||
|
||||
## 범위 경계
|
||||
- In Scope
|
||||
- portfolio-hub /pnl/realized 소비(포트+어댑터) + 중장기 운영 리포트 WAC 실현손익 + 매수일 수수료 표시 + completeness 경고 + degrade.
|
||||
- Out of Scope
|
||||
- portfolio-hub 측 변경(이미 REQ-040 제공 — 무변경).
|
||||
- 미실현 손익(현재가 결합), 세무 리포트.
|
||||
- 슬롯↔계좌 동기화(dcy-034 별건).
|
||||
|
||||
# 6. 리스크/가정 목록
|
||||
## 리스크
|
||||
- R-1 (Medium): WAC 실현손익 소스 전환이 단기 인스턴스 리포트(당일 net)에 회귀를 줄 수 있다.
|
||||
- 완화: 모드/인스턴스로 분리(단기=net 유지 or WAC 통일은 OQ-1), 회귀 테스트.
|
||||
- R-2 (Low): portfolio-hub 호출 추가로 리포트가 외부 의존·지연. 미가용 시 리포트 실패.
|
||||
- 완화: degrade(폴백/에러 명시, OQ-5) + 본업 격리(NFR-3).
|
||||
|
||||
## 가정
|
||||
- A-1: portfolio-hub `/pnl/realized`(REQ-040/041)는 멀티데이 WAC 실현손익을 정확히 제공한다(매도 date-filter + 전 매수 WAC).
|
||||
- A-2: 중장기 인스턴스는 portfolio_id별로 실현손익을 조회한다(슬롯↔portfolio_id 1:1).
|
||||
- A-3: trex-core는 portfolio-hub를 세션/토큰으로 호출 가능하다(기존 whoami/get_portfolios 경로 재사용).
|
||||
|
||||
## 오픈 질문
|
||||
- OQ-1: WAC 실현손익을 전 인스턴스 통일인지, 중장기 모드만인지.
|
||||
- 상태: **Answered (2026-06-26, 사장님)** — **전 인스턴스 WAC 통일**(당일 net 폐기). WAC는 일중에도 정확하므로 단기 라이브도 WAC로 통일하되, NFR-2 회귀(일중 케이스 net 일치)로 의미 보존.
|
||||
- OQ-2: 리포트 기간 정의 — 당일/지정 기간(from~to). /pnl/realized는 from_dt/to_dt(매도 기준). 멀티데이 리포트의 기본 기간·옵션.
|
||||
- 상태: Open / 처리: design, 팀장 / 종료: 기간 모델 확정 시 Answered
|
||||
- OQ-3: 매수만 한 날 "수수료 비용" 표시 방식 — 실현손익과 별도 라인(비용)으로. 수수료 출처(portfolio-hub 거래내역 REQ-039 또는 trex-core ledger).
|
||||
- 상태: Open / 처리: design, 팀장 / 종료: 표시·출처 확정 시 Answered
|
||||
- OQ-4: trex-core가 realized PnL을 어떻게 조회 — portfolio_id별 N콜 vs daemon 집계. (slots↔portfolio 1:1이라 N콜이 자연스러우나 종목 多면 비용.)
|
||||
- 상태: Open / 처리: design, 팀장 / 종료: 조회 단위 확정 시 Answered
|
||||
- OQ-5: portfolio-hub 미가용 시 degrade.
|
||||
- 상태: **Answered (2026-06-26, 사장님)** — **(b) 실현손익 섹션 에러 명시**(당일 net 폴백 없음). 나머지 섹션(보유/체결/대기주문) 정상 출력.
|
||||
|
||||
### 오픈 질문 처리 기준
|
||||
- `Open`/`Answered`/`Deferred`/`Dropped` 표준 처리.
|
||||
|
||||
# 7. 초기 성공 기준
|
||||
- S-1: 전일 이전 매수분을 당일 매도한 시나리오에서 리포트 실현손익이 **WAC 기준 정확값**(당일 net 왜곡 아님)으로 표시된다.
|
||||
- S-2: 매수만 한 기간 → 실현손익 0 + 수수료 비용 표시.
|
||||
- S-3: portfolio-hub `data_completeness_warning`이 리포트에 표면화된다.
|
||||
- S-4: portfolio-hub 미가용 시 리포트가 degrade(정의된 방식)하고 데몬 본업 무영향.
|
||||
- S-5: 일중 매수+매도(같은 날) 케이스에서 WAC 실현손익 = 기존 당일 net (단기 의미 보존, NFR-2).
|
||||
|
||||
## 측정 방식 및 데이터 출처
|
||||
- S-1/S-2: 멀티데이 픽스처(전일 매수+당일 매도, 매수만) 통합 테스트(portfolio-hub 모킹) / 신규 테스트.
|
||||
- S-3/S-4: 경고 주입·미가용 모킹 테스트.
|
||||
- S-5: 기존 operator_report 테스트 회귀.
|
||||
|
||||
# 8. REQ로 넘기기 전 확인 체크
|
||||
- [x] 적용 범위 확정 — OQ-1 = 전 인스턴스 WAC 통일
|
||||
- [x] degrade 정책 — OQ-5 = 실현손익 섹션 에러 명시
|
||||
- [ ] 기간/수수료/조회단위 design 인계 — OQ-2/3/4 (draft-req/design 단계)
|
||||
- [x] 성공지표 측정 이견 없음
|
||||
- [x] Freeze 담당자(CONFIRMED_BY) 지정 — 팀장
|
||||
|
||||
# 9. 파일 처리 결과
|
||||
- 처리 결과: 생성
|
||||
- 생성 경로: docs/discovery/dcy-035_20260626_multiday-realized-pnl-report-wac.md
|
||||
- 참조 문서:
|
||||
- docs/discovery/dcy-029(운영 리포트 REQ-088), dcy-032(cost basis 오염)
|
||||
- portfolio-hub dcy-007/REQ-040/041(WAC 실현 PnL), app/api/v1_portfolios.py:712, app/domain/pnl.py
|
||||
- trex_core/application/operator_report.py(현행 당일 net), runtime/cli.py(report)
|
||||
|
||||
# 10. 사용자 결정 필요 항목 요약
|
||||
## DECIDE
|
||||
- (OQ-1) WAC 실현손익 적용 범위: 전 인스턴스 통일 vs 중장기 모드만.
|
||||
- (OQ-5) portfolio-hub 미가용 시 degrade 방식.
|
||||
## CONFIRM
|
||||
- 본 건을 M3 중장기 운영 리포트(멀티데이 WAC 실현손익) 단위로 채택 — portfolio-hub 무변경, trex-core 연동.
|
||||
## DATA
|
||||
- (OQ-3 보조) 매수일 수수료 출처(portfolio-hub 거래내역 REQ-039 vs trex-core ledger) — 팀장 design서 확인.
|
||||
|
||||
# 11. Discovery Freeze
|
||||
## 섹션 참조
|
||||
- 범위: [# 5 > 범위 경계](#5-요구사항-목록) / 리스크·OQ: [# 6](#6-리스크가정-목록) / 성공: [# 7](#7-초기-성공-기준) / 인계 전 확인: [# 8](#8-req로-넘기기-전-확인-체크) / 결정: [# 10](#10-사용자-결정-필요-항목-요약)
|
||||
## Freeze 플래그
|
||||
- Handoff Decision: 진행 (인계) — OQ-1/OQ-5 사장님 결정 완료, OQ-2/3/4는 draft-req/design 단계 처리
|
||||
- Handoff Rationale: portfolio-hub WAC API는 이미 존재(무변경), trex-core 연동만. 적용범위=전 인스턴스 WAC 통일, degrade=섹션 에러 명시 확정. 기간/수수료/조회단위는 REQ·design에서 구체화.
|
||||
- Ready for REQ Drafting: true
|
||||
- Confirmed By: 팀장 (Claude)
|
||||
- Confirmed At (KST): 2026-06-26
|
||||
|
||||
# 12. 작성 가이드
|
||||
- trex-core dcy 템플릿 기반. Open Questions는 가정 대체 금지. confirm-discovery 시 OQ 처리 + Freeze 갱신.
|
||||
Reference in New Issue
Block a user