feat: add shared account capital allocation policy
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
# req-127: 공통 계좌 자본배분 순수 정책
|
||||
|
||||
- Status: Approved
|
||||
- Type: Interface
|
||||
- Priority: High
|
||||
- Owner: trex-core-dev
|
||||
|
||||
## Intent
|
||||
|
||||
- 메가 스윙과 탑50 스윙이 같은 계좌 현금 배분 규칙을 사용하도록, 외부 입출력과 분리된 결정적 정책을 Core 도메인에 제공한다.
|
||||
- 고가 종목을 무조건 균등액으로 자르지 않고 제한된 한 주 가격 여유를 허용하되, 실제로 동시에 열릴 수 있는 최악 슬롯 조합도 가용 현금을 넘지 않게 한다.
|
||||
- KIS 어댑터는 현금·호가 조회와 결과 매핑만 맡고, Portfolio Hub 원장과 기존 주문수량 계약은 변경하지 않는다.
|
||||
|
||||
## Requirement
|
||||
|
||||
1. Core는 `available_cash`, 양의 `slot_count`, 고유한 `portfolio_id`·`symbol`과 양의 `protected_share_cost`를 가진 후보 목록, 0 이상의 `flex_share_count`를 입력받는 순수 자본배분 정책을 제공해야 한다.
|
||||
2. 보호된 한 주 가격은 양의 `price`와 0 이상의 `slippage_pct`를 받아 `price × (1 + slippage_pct/100)`을 원 단위 올림해 계산해야 한다.
|
||||
3. 초기 후보 적격 상한은 `available_cash // slot_count + cheapest_protected_share_cost × flex_share_count`여야 하며, 이를 넘는 후보는 `protected_share_above_flex_limit`으로 제외해야 한다.
|
||||
4. 1차 적격 후보 중 가장 비싼 `min(slot_count, eligible_count)`개 한 주 가격 합이 가용 현금을 넘으면, 후보 가격과 입력 순서를 안정적인 동률 기준으로 가장 비싼 후보부터 제외하고 `worst_case_cash_overcommit`을 반환해야 한다.
|
||||
5. 남은 후보에는 각 후보의 보호 한 주 가격 이상이면서, 가장 큰 `min(slot_count, eligible_count)`개 배정액 합이 가용 현금 이하인 최대 공통 배정액을 적용해야 한다.
|
||||
6. 현금이 0이면 모든 후보의 배정액을 0으로 하고 `no_available_cash`를 반환해야 한다. 음수 현금, 0 이하 슬롯 수, 빈 후보, 음수 유동 여유, 중복 식별자, 0 이하 한 주 가격은 명시적으로 거부해야 한다.
|
||||
7. 결과는 입력 후보 순서를 보존한 후보별 `portfolio_id`, `symbol`, 배정액, 사유와 계좌 수준 `available_cash`, `slot_count`를 제공해야 하며, 단순 `portfolio_id → 배정액` 호환 표면도 제공해야 한다.
|
||||
8. 정책 모듈은 네트워크, 파일, 환경변수, 데이터베이스, 브로커 및 전략 모듈에 의존하지 않아야 한다. 현금·호가 조회, 후보·슬롯 선택, 설정 저장, 실제 주문수량 산출과 주문 제출은 호출 계층 책임으로 유지해야 한다.
|
||||
9. 기존 `BuyIntent`의 정수 수량·가격 계약, Core 주문 실행, 슬롯 상태머신, Portfolio Hub 원장 계약을 변경하지 않아야 한다.
|
||||
10. `docs/project-structure.md`와 배치 검증 문서는 공통 정책의 책임, 호출 계층 책임, 비운영 범위, 회귀 증거를 구현과 일치하게 기록해야 한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
1. Given 메가 스윙 후보가 삼성전자 보호가격 220,000원과 SK하이닉스 보호가격 1,400,000원이고 현금 2,000,000원·2슬롯인 경우, When 정책을 실행하면, Then 삼성전자 2,000,000원·SK하이닉스 0원을 반환하고 SK하이닉스 제외 사유가 `protected_share_above_flex_limit`이다.
|
||||
2. Given 같은 후보에서 현금 3,000,000원이고 SK하이닉스 보호가격이 1,510,000원인 경우, When 한 주 유동 여유를 적용하면, Then 삼성전자 1,490,000원·SK하이닉스 1,510,000원을 반환한다.
|
||||
3. Given 현금 2,000,000원·3슬롯과 보호가격 100,000/200,000/500,000/700,000/1,050,000원인 탑50 후보 5개, When 정책을 실행하면, Then 마지막 후보를 제외하고 650,000/650,000/650,000/700,000/0원을 반환한다.
|
||||
4. Given 현금 0원, When 정책을 실행하면, Then 모든 배정액은 0이고 사유는 `no_available_cash`이다.
|
||||
5. Given 잘못된 가격·현금·슬롯·후보·중복 식별자 입력, When 정책을 실행하면, Then 조용한 보정 없이 `ValueError`로 거부한다.
|
||||
6. Given 고정 시드 무작위 입력 10,000개, When 모든 결과의 가장 큰 양수 배정액을 슬롯 수만큼 합하면, Then 모든 경우 가용 현금 이하이고 양수 배정액은 해당 후보의 한 주 가격 이상이다.
|
||||
7. Given 기존 로컬 어댑터 공식과 고정 시드 무작위 입력 50,000개, When 양쪽 결과를 비교하면, Then `portfolio_id → 배정액` 결과가 모든 경우 완전히 일치한다.
|
||||
8. Given Core 전체 테스트와 로컬 어댑터 전체 테스트, When Core 정책 연결 상태로 실행하면, Then 기존 회귀와 신규 정책 테스트가 모두 통과한다.
|
||||
9. Given 탑50 3슬롯 한 달 가상거래 입력, When 기존 공식과 Core 정책 연결 결과를 비교하면, Then 요약 지표와 거래원장·배분결정 원장이 동일하다.
|
||||
10. Given 이 브랜치가 검토 중인 경우, When 운영 상태를 확인하면, Then 실전 런타임·주문 게이트·계좌 설정·Portfolio Hub 데이터에는 변경이 없다.
|
||||
|
||||
## Impacted Area
|
||||
|
||||
- Docs:
|
||||
- `docs/discovery/dcy-042_20260729_shared-account-capital-allocation-policy.md`
|
||||
- `docs/project-structure.md`
|
||||
- 신규 배치의 계획·설계·구현·검증 문서
|
||||
- Modules:
|
||||
- `trex_core/domain/capital_allocation.py`
|
||||
- 로컬 KIS 어댑터의 자본배분 호환 연결부
|
||||
- Tests:
|
||||
- `tests/domain/test_capital_allocation.py`
|
||||
- 로컬 어댑터 회귀
|
||||
- 메가 대표 경계값과 탑50 월간 가상거래 비교
|
||||
|
||||
## Notes
|
||||
|
||||
- Source Discovery: `docs/discovery/dcy-042_20260729_shared-account-capital-allocation-policy.md`.
|
||||
- 기존 `dcy-021`과 `REQ-061`의 주문수량 책임은 유지한다. Core는 이 반복에서 계좌 배분의 순수 계산만 소유하며, 실제 주문 의도의 수량을 자동 수정하지 않는다.
|
||||
- Portfolio Hub는 현금·보유·손익 원장의 정본으로 유지한다. 이 요구사항은 Hub API·스키마·데이터를 변경하지 않는다.
|
||||
- `REQ-124`~`REQ-126`과 `dcy-039`~`dcy-041`, `BAT-059`~`BAT-061`은 병렬 Core 브랜치 작업에 예약되어 있어 충돌 방지를 위해 다음 미사용 번호를 선택했다.
|
||||
- 구현·가상 검증·Draft PR은 허용되지만 실전 배포와 주문 활성화는 별도 승인 대상이다.
|
||||
|
||||
## Change Log
|
||||
|
||||
### CHG-20260729-01
|
||||
|
||||
- Date: 2026-07-29
|
||||
- Author: delivery-runner
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- 확정된 `dcy-042`의 공통 계좌 자본배분을 단일 Core 도메인 인터페이스 요구사항으로 작성했다.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 공통 계산의 중복을 제거하면서 브로커·원장·전략 책임 경계를 유지한다.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- 메가 대표 2건, 탑50 대표 1건, 입력 거부, 10,000건 불변식, 50,000건 기존 공식 완전 일치, 전체 회귀, 월간 원장 비교, 비운영 확인.
|
||||
- Updated:
|
||||
- 없음.
|
||||
- Removed:
|
||||
- 없음.
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs:
|
||||
- Discovery, 프로젝트 구조, 신규 배치 문서.
|
||||
- Modules:
|
||||
- Core 순수 도메인 정책과 로컬 어댑터 연결부.
|
||||
- Tests:
|
||||
- Core 단위·속성 회귀, 어댑터 전체 회귀, 탑50 월간 가상 비교.
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches:
|
||||
- none.
|
||||
- Releases:
|
||||
- none.
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: 요구사항 승인 후 단일 배치에서 구현·문서·교차 검증을 완료한다.
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- Core 단위·전체 회귀, 기존 공식 50,000건 완전 일치, 로컬 어댑터 전체 회귀, 메가 경계값, 탑50 월간 가상 원장 비교와 공용 7단계 가상 인증을 수행한다.
|
||||
|
||||
### CHG-20260729-02
|
||||
|
||||
- Date: 2026-07-29
|
||||
- Author: trex-dev-lead
|
||||
|
||||
#### Change Summary
|
||||
|
||||
- 사용자 승인 범위, 필수 문서 필드, 측정 가능한 수락 기준과 비운영 경계를 재검토해 `REQ-127`을 Approved로 전환했다.
|
||||
|
||||
#### Intent
|
||||
|
||||
- 단일 배치의 구현·검증 기준으로 사용할 수 있도록 요구사항을 동결한다.
|
||||
|
||||
#### Acceptance Criteria Delta
|
||||
|
||||
- Added:
|
||||
- 없음.
|
||||
- Updated:
|
||||
- 없음.
|
||||
- Removed:
|
||||
- 없음.
|
||||
|
||||
#### Impacted Area Delta
|
||||
|
||||
- Docs:
|
||||
- SRS 상태와 인덱스 상태 동기화.
|
||||
- Modules:
|
||||
- 없음.
|
||||
- Tests:
|
||||
- 없음.
|
||||
|
||||
#### Delivery Trace Delta
|
||||
|
||||
- Batches:
|
||||
- 다음 단계에서 BAT-062 생성.
|
||||
- Releases:
|
||||
- none.
|
||||
|
||||
#### Revalidation Impact
|
||||
|
||||
- Reverification Needed: yes
|
||||
- Existing Implementation Invalidated: no
|
||||
- Status Recommendation: keep-current
|
||||
- Follow-up Action: BAT-062에서 구현·검증 증거를 수락 기준별로 연결한다.
|
||||
|
||||
#### Validation Plan
|
||||
|
||||
- REQ-127 수락 기준 1~10을 배치 검증 문서와 자동화된 테스트·가상거래 증거로 대조한다.
|
||||
+4
-4
@@ -74,7 +74,7 @@
|
||||
|
||||
## Next Requirement ID
|
||||
|
||||
- Current: `REQ-124`
|
||||
- Current: `REQ-128`
|
||||
- Rule: `Requirement Register`에 있는 가장 큰 REQ 번호보다 정확히 1 커야 한다.
|
||||
|
||||
## Requirement Register
|
||||
@@ -205,18 +205,18 @@
|
||||
| REQ-122 | operator broker truth hotfix baseline 문서 정합 | Documentation | Implemented | High | trex-core-dev | [req-122](./Documentation/req-122_operator-broker-truth-hotfix-baseline-alignment.md) |
|
||||
| REQ-123 | cost-basis canonical parse 및 WAC unavailable 안전 sync seed | Integration | Approved | High | trex-core-dev | [req-123](./Integration/req-123_cost-basis-canonical-parse-and-safe-sync-seeding.md) |
|
||||
| REQ-124 | intent venue persistence and execution | Integration | Implemented | High | trex-core-dev | [req-124](./Integration/req-124_intent-venue-persistence-and-execution.md) |
|
||||
| REQ-127 | 공통 계좌 자본배분 순수 정책 | Interface | Approved | High | trex-core-dev | [req-127](./Interface/req-127_shared-account-capital-allocation-policy.md) |
|
||||
|
||||
## Recent Change Log Summary
|
||||
|
||||
- 2026-07-29 :: REQ-127 **승인(Approved, confirm-req)**: 사용자 승인 범위, 순수 Core 정책·어댑터 입출력·기존 주문/원장 불변 경계, 10개 측정 가능한 수락 기준과 비운영 조건을 확인해 단일 배치 인계를 승인.
|
||||
- 2026-07-29 :: REQ-127 **신규 생성(Proposed, draft-req, dcy-042)**: 메가·탑50 공통 계좌 자본배분 순수 정책, 고가 후보 유동 제외, 최악 활성 슬롯 현금 불변식, Core·어댑터 책임 경계와 완전 일치·가상 원장 검증을 요구사항으로 고정. 실전 배포·주문 게이트·원장 변경 제외.
|
||||
- 2026-07-27 :: REQ-124 Implemented: strategy intent venue를 pending slot과 broker submit/cancel까지 additive 전달. 전체 회귀 837 passed, 47 skipped. 배포·실주문 제외.
|
||||
|
||||
- 2026-07-16 :: REQ-123 **confirm-req 승인(Approved, lead confirm)**: dcy-038 OQ-1~3 완료 기준으로 제약(scope 제외 항목: API/schema 변경/credential/config 변경/live sync/배포), OQ-2/OQ-3 결정 반영, fail-closed WAC unavail no-write 정책, canonical parsing 우선순위/legacy fallback 규칙 및 dry-run diagnostics가 일치함을 확인해 `REQ-123`을 Approved 전환.
|
||||
- 2026-07-16 :: REQ-123 **신규 생성(Proposed, draft-req, dcy-038)**: portfolio-hub canonical `cost_basis_per_unit` consumer parse, legacy alias precedence, WAC unavailable fail-closed sync/no-write, dry-run diagnostics, response-contract/regression tests, observability 및 rollback/release gate. portfolio-hub API/schema/auth·token/config·DB migration/direct edit·live sync·배포 제외.
|
||||
- 2026-07-15 :: REQ-119~122 **`Approved` → `Implemented`** (`confirm-req-implemented`, dcy-037/BAT-057): PR #42 merged to `main` (94e1489). Independent QC PASS-WITH-NOTES (acceptance blocker 0); 806 passed/47 skipped/1 deselected. `sync --live`, deployment, and production remediation remain separate release-approval work.
|
||||
- 2026-07-14 :: REQ-119~122 **승인(Approved, confirm-req, dcy-037)**: lead 검토로 각 REQ의 owner·priority·scope·검증 가능 AC와 Notes의 non-blocking 설계 제약을 확인했다. #39/#40/#41은 다음 `suggest-batch-reqs`에서 단일 emergency batch 후보이며, `sync --live`는 여전히 별도 release approval gate다.
|
||||
- 2026-07-14 :: REQ-119~122 **신규 생성(Proposed, draft-req, dcy-037)**: #39 fetched credential daemon/operator broker truth parity, #40 token/auth fail-loud empty-balance 분리, #41 managed non-holding divergence classification, runtime/interface/operations baseline 정합. #39/#40/#41 단일 emergency batch 및 `sync --live` 별도 release approval gate를 유지한다.
|
||||
- 2026-07-06 :: REQ-117/118 **신규 생성(Implemented, draft-req, trex-tvr-v1 dcy-002 FR-6)**: KIS 브로커 venue 파라미터화 — REQ-117 OrderRequest.venue additive 필드(기본 KRX, 포트 DTO 계층), REQ-118 KIS 어댑터 EXCG_ID_DVSN_CD 전송 + cancel venue 의미론 + poll_fill NXT 체결 보장 + get_current_price market 파라미터화. 실측 근거: 2026-07-06 실전 NXT 주문/취소 rt_cd=0. 고위험(라이브 주문 경로) — worktree+PR+QC(opus) 필수. confirm-req 대기.
|
||||
- 2026-07-04 :: REQ-116 **신규 생성(Implemented, draft-req, trex-tvr-v1 dcy-001/dcy-002 v3 FR-8)**: `trex.slots.req` additive 확장 — 행 `strategy_name`·`strategy_params`·`markets` 필드 노출(hub 정본, safe-default) + 요청 `strategy` 필터(exact-match, status 필터 AND 조합, available_slots 불변). REQ-074 AC-5 additive 재도입(dcy-025 OQ-4 후속). 라이브 wire 계약 고위험 — worktree+PR+QC 정식 플로, 배포 선행조건=portfolio-hub REQ① 먼저.
|
||||
- 2026-06-28 :: REQ-112/114 **`Approved` → `Implemented`**, REQ-113/115 **`Approved` 유지(confirm-req-implemented, dcy-036/BAT-053)**: BAT-053 PR #34 머지(01655ab). QC PASS-WITH-NOTES(opus, blocker 0). 745 passed/0 회귀. REQ-112(fetch 포트+어댑터+stub AC-1~8 완료), REQ-114(fail-closed 게이트 AC-1~9, BuyIntent 차단/SellIntent 통과 비대칭·CRITICAL 알람·opt-in off 비활성 완료). REQ-113/115 스캐폴드 완료 — KISBroker 런타임 재조립(REQ-113 AC-2, REQ-115 AC-1) M3 후속 batch 연기.
|
||||
- 2026-06-28 :: REQ-112~115 **`Proposed` → `Approved`(confirm-req 팀장 승인)**: dcy-036 FR/NFR 추적·AC testable·blocker 0. 진입 fail-closed/청산·DISPATCHED 통과 비대칭(REQ-114 AC-4/5), 그날 고정 캐시·ledger 무손실(REQ-115), TradingContext 원자 read(REQ-112), opt-in 회귀차단(REQ-113 AC-1). OQ-4(trex-notifier) Deferred. 선행 의존 portfolio-hub dcy-010(머지완료). 다음=suggest-batch-reqs.
|
||||
- 2026-06-26 :: REQ-109~111 **Approved → Implemented** (confirm-req-implemented, dcy-035): BAT-052 머지(PR #33, 81d06d9) 완료. QC PASS. 717 passed/47 skipped/0 fail. REQ-109(portfolio-hub /pnl/realized 포트+어댑터+stub AC-1~6), REQ-110(WAC 운영리포트 통합 AC-1~7, CHG-20260626-02 buy_fee편입 반영), REQ-111(degrade AC-1~5) 전 AC 검증 완료. M3 배포 대기.
|
||||
|
||||
Reference in New Issue
Block a user