diff --git a/docs/batches/bat-031_20260610_position-sizing/design.md b/docs/batches/bat-031_20260610_position-sizing/design.md new file mode 100644 index 0000000..608b785 --- /dev/null +++ b/docs/batches/bat-031_20260610_position-sizing/design.md @@ -0,0 +1,47 @@ +# BAT-031 Design + +- Status: confirmed (D1~D4, 2026-06-10) +- Batch: BAT-031 + +## 설계 원칙 +- 수량 정본 = **브로커 잔고**(REQ-062). 슬롯 `qty` 는 (a) pending 동안 = **주문 수량**, (b) 체결/롤백 후 = **브로커 잔고(보유)** 로 재동기화한다. core 는 "의도 수량"을 별도 저장하지 않는다(dcy-021 OQ-1). +- avg_price 는 증액 시 가중평균, 매도(부분/전량) 시 cost basis 유지(dcy-021 OQ-3). +- 모든 전이는 dcy-020 자산 중심 모델에 additive(무회귀, NFR-2). + +## D1 — 증액: 주문 수량 vs 보유 수량 (브로커 정본 재동기화) +- `HOLDING→PENDING_BUY`(증액): `slot.qty := intent.qty`(추가 주문 수량), `avg_price` **보존**(가중평균용), `limit_price := price`. (generic 전이 규칙이 caller None 일 때 avg 보존 → 별도 service 분기 불요) +- dispatch 매수: `qty = slot.qty`(주문 수량) 그대로. +- `PENDING_BUY→HOLDING`(체결): 보유 = **브로커 잔고 total**, avg_price = 가중평균. + - `old_qty = max(0, broker_total − filled)`, `old_avg = slot.avg_price or 0`, `new_avg = (old_qty×old_avg + filled×fill_price)/broker_total`(broker_total 0 이면 fill_price). + - 초기 매수도 동일 공식(avg None→0, old_qty=0 → new_avg=fill_price) — 통일. + +## D2 — 초기 매수 vs 증액 판별 +- `INACTIVE→PENDING_BUY`(초기): slot 이 inactive 라 avg_price=None. +- `HOLDING→PENDING_BUY`(증액): avg_price 보존(>0). +- 체결/롤백 핸들러는 **브로커 잔고**로 판별(잔고>0 → 증액/보유 잔존, 0 → 초기/미보유). avg_price 보존은 가중평균 계산에만 사용. + +## D3 — 증액/매도 롤백 +- 매수 거부 `_rollback`: 브로커 잔고>0 → `PENDING_BUY→HOLDING`(qty=브로커 잔고, 증액 실패해도 기존 보유 유지) / 잔고 0 → `PENDING_BUY→INACTIVE`(초기 매수 실패). +- 매도 거부: `PENDING_SELL→HOLDING`(qty=브로커 잔고) (기존). + +## D4 — 부분 매도 + 전량 매도 구분 + 부분 체결 +- pending_sell 의 `slot.qty` 의미: **부분 매도** intent(SellIntent.qty 지정) → `slot.qty = 주문 수량`; **전량 매도**(svc.sell/safety-sell/kill-switch, qty 미지정) → `slot.qty = None`("전량" sentinel). → `_apply_transition_fields` 의 PENDING_SELL 진입 규칙: `new_qty = caller qty`(None 보존, mirror 안 씀). +- dispatch 매도: `qty = 브로커잔고 if slot.qty is None else min(int(slot.qty), 브로커잔고)`. 0 이면 skip+WARN(divergence, REQ-062). → 전량은 항상 브로커 정본(stale mirror 무관), 부분은 min(주문, 잔고)·잔고 이상이면 전량. +- `PENDING_SELL→체결`: 체결 후 **브로커 잔고**로 분기 — 잔고>0 → `HOLDING`(qty=잔고, avg=cost basis 유지) / 0 → `INACTIVE`. (기존 항상 INACTIVE 에서 변경 — 부분 매도 잔량 holding 지원) +- 부분 체결: 실제 체결분만 ledger(기존 `_record_ledger` = `fs.filled_qty`), 미체결 잔량 미추적. dcy-013 `_on_partial_cancel` 도 브로커 정본 resync 로 정합. + +## D-impl — 브로커 잔고 조회 +- `_poll` tick 시작 시 `broker.get_balance()` 1회 fetch → symbol→hldg_qty 맵을 fill/rollback 핸들러에 전달(체결당 중복 호출 회피). dispatch 의 매도 잔고 맵과 동일 패턴(BAT-030 M2). + +## intent (REQ-061) +- 매수 admission: 대상 슬롯이 `INACTIVE` → 초기 매수(M 캡 적용); `HOLDING` → **증액**(M 캡 미적용 — active 수 불변); `pending_*` → `already_active`. (증액은 별도 intent 타입 없이 holding 슬롯 buy 로 검출) +- 매도 admission: `SellIntent.qty`(선택) 추가 — 지정 시 부분 매도(slot.qty=order), 미지정 시 전량(slot.qty=None). + +## 상태머신 (REQ-057) +- `_BASE_TRANSITIONS` 에 `(HOLDING, PENDING_BUY)` 추가 → 13 transitions. + +## 롤백/회귀 +- 전부 additive. 기존 초기 매수/전량 매도/safety-sell/kill-switch/reconcile 경로 무회귀(전량 매도 slot.qty=None·dispatch 브로커 정본은 기존 동작과 동일 결과). + +## 체크포인트 결정 +- D1~D4 확정(브로커 정본 재동기화로 "주문 수량 vs 보유 수량" 충돌 해소, 별도 필드 없음). 구현 진행. diff --git a/docs/batches/bat-031_20260610_position-sizing/implementation.md b/docs/batches/bat-031_20260610_position-sizing/implementation.md new file mode 100644 index 0000000..a0ab835 --- /dev/null +++ b/docs/batches/bat-031_20260610_position-sizing/implementation.md @@ -0,0 +1,39 @@ +# BAT-031 Implementation + +- Status: done +- Batch: BAT-031 +- 일자: 2026-06-10 + +## 구현 요약 +design.md D1~D4 그대로 구현. 수량 정본=브로커 잔고 재동기화로 "주문 수량 vs 보유 수량" 충돌을 별도 필드 없이 해소. + +- **M1 (REQ-057)**: `state.py` `_BASE_TRANSITIONS` 에 `(HOLDING, PENDING_BUY)` 추가 → 13 전이(증액). +- **M2 (REQ-066/062)**: `service.py` `_apply_transition_fields` — PENDING_SELL 진입 시 `qty = caller as-is`(None=전량 sentinel, 값=부분 주문 qty). 증액 pending(HOLDING→PENDING_BUY)은 generic 분기가 avg_price 보존(caller None)·qty=주문으로 처리(별도 분기 불요). +- **M3 (REQ-061)**: `intents.py` — `_admit_buy` 가 HOLDING 슬롯 매수를 **증액**으로 검출(M 캡 미적용, `position_increase` reason), PENDING_* 만 `already_active`. `SellIntent.qty`(부분) 추가, `_admit_sell` 가 qty 를 transit 에 전달. `messaging_handlers` sell 파서에 `qty` 추출. +- **M4 (REQ-062/066)**: `execution.py` — `_balance_map()` 헬퍼. dispatch 매도 `qty = 브로커잔고 if slot.qty is None else min(int(slot.qty), 브로커잔고)`(0이면 skip+WARN). `_on_filled`: 매수 체결 → 보유=브로커 잔고·avg 가중평균; 매도 체결 → 브로커 잔고>0 `pending_sell→holding`(cost basis) / 0 `→inactive`. `_on_partial_cancel` 도 브로커 정본 resync. `_rollback`: 매수 거부 시 브로커>0 `→holding`(증액 실패, 기존 보유 유지) / 0 `→inactive`. +- **M5 (REQ-067)**: data-model/runtime-flows/interface-contract/project-structure 4문서 사이징 정합. + +## 변경 내역 (Changed Files) +- trex_core/domain/slot/state.py — holding→pending_buy 전이 +- trex_core/domain/slot/service.py — PENDING_SELL qty sentinel +- trex_core/application/intents.py — 증액 admission, SellIntent.qty, partial sell +- trex_core/application/execution.py — _balance_map, 부분/전량 매도 dispatch, 매수 체결 가중평균, 브로커 정본 resync, 증액 롤백 +- trex_core/application/messaging_handlers.py — sell qty 파싱 +- docs: data-model/runtime-flows/interface-contract/project-structure (REQ-067) +- tests: test_state(13 전이), test_service(TestPositionSizing 3), test_execution(전량/부분 매도·증액·capacity 5신규), test_execution_cancel(브로커 정본 잔량) + +## 테스트 +- 단위 전체: **378 passed** (45 skipped), ruff clean +- 통합(PG+RabbitMQ): **422 passed, 1 skipped**(KIS sandbox, 환경 무관) + +## 검증 실행 (run-the-app, 사이징 e2e) +라이브 trex_core(reset 후) + 실 RabbitMQ + paper + instance=test, M=5: +1. 초기 매수 qty=10 @1000 → holding 10 @1000 +2. **증액 +5 @1200**(holding 슬롯 매수, admitted) → holding **15 @1066.6667**(가중평균) +3. **부분 매도 qty=6** → holding **9 @1066.6667**(cost basis 유지) +4. **전량 매도**(qty 미지정) → **inactive**(qty None) +- 데몬 로그 ERROR/Traceback 0. messaging sell qty 갭은 e2e 에서 발견·수정(부분 매도가 전량으로 가던 버그) 후 재검증 green. + +## Remaining Risks / Blockers +- 전략 모듈(trex-orb) 사이징 intent 발행 전환 필요 — 기존 buy/sell 와 병존(additive)이라 무중단. +- 미체결 pending 고착 처분은 본 배치 범위 밖(issue #21 별도 Discovery). diff --git a/docs/batches/bat-031_20260610_position-sizing/index.md b/docs/batches/bat-031_20260610_position-sizing/index.md new file mode 100644 index 0000000..22b4c09 --- /dev/null +++ b/docs/batches/bat-031_20260610_position-sizing/index.md @@ -0,0 +1,23 @@ +# BAT-031: 보유 자산 포지션 사이징 (dcy-021) + +- Status: release-candidate +- Profile: standard +- Source Discovery: dcy-021 +- Included REQ: REQ-066 (사이징 도메인·end-to-end), REQ-067 (baseline 정합), REQ-057 (CHG-03 상태머신 holding→pending_buy), REQ-061 (CHG-04 사이징 intent), REQ-062 (CHG-03 부분 매도 집행) + +## Summary +- dcy-021: 자산 영구 슬롯(dcy-020)의 수량 가변 전제 위에 **보유 포지션 수량 조정**(증액·부분 감액)을 구현한다. 명령형 계약(전략이 cash+quantity 로 qty+price 계산·전송), core 는 실행 substrate(target 미저장·미추적), 수량 정본 = 브로커 잔고. + +## Scope +- In: 증액(holding→pending_buy→holding, avg_price 가중평균), 부분 감액(부분 매도 min(intent,잔고), 잔량 holding/전량 inactive, cost basis), 부분 체결 실제만 반영·미추적, 사이징 intent + 멱등, baseline 4문서. +- Out: 능동 capacity 배분, 자동 리밸런싱 스케줄러, 미체결 pending 고착 처분(issue #21). + +## Documents +- Planning: [planning.md](./planning.md) +- Design: [design.md](./design.md) +- Implementation: [implementation.md](./implementation.md) +- Verification: [verification.md](./verification.md) + +## Notes +- 집행 핫패스(라이브 주문) 변경 — additive·paper 검증. design.md 의 D1~D4 확정 후 구현. +- 본 배치 완료 후 REQ-057/061/062/066/067 confirm-req-implemented. diff --git a/docs/batches/bat-031_20260610_position-sizing/planning.md b/docs/batches/bat-031_20260610_position-sizing/planning.md new file mode 100644 index 0000000..0d31e5d --- /dev/null +++ b/docs/batches/bat-031_20260610_position-sizing/planning.md @@ -0,0 +1,42 @@ +# BAT-031 Planning + +- Status: confirmed +- Batch: BAT-031 +- Profile: standard + +## Included REQ +- REQ-066 (Interface, Approved): 사이징 도메인 수량/avg_price 재계산 + end-to-end. +- REQ-067 (Documentation, Approved): baseline 4문서 정합. +- REQ-057 (CHG-20260610-03, Approved): 상태머신 `holding→pending_buy` 전이. +- REQ-061 (CHG-20260610-04, Approved): 사이징 intent(증액/부분 매도, 명령형 qty+price). +- REQ-062 (CHG-20260610-03, Approved): 부분 매도 집행 `min(intent,잔고)`·부분 체결 실제만. + +## Delivery Plan (마일스톤) +1. **M1 (REQ-057)**: `state.py` 전이 집합에 `HOLDING→PENDING_BUY` 추가(증액). test_state 갱신(13 transitions). +2. **M2 (REQ-066)**: `service.py` 전이 필드 규칙 — 증액 pending(avg_price 보존), 매수 체결 avg_price 가중평균 + 수량 = 브로커 정본 resync. +3. **M3 (REQ-061)**: `intents.py` 사이징 admission — 증액 매수(holding 슬롯 buy, `already_active` 예외)·부분 매도(SellIntent qty). messaging_handlers payload(qty/price). +4. **M4 (REQ-062)**: `execution.py` — 부분 매도 dispatch qty = `min(intent, 브로커 잔고)`, 매수/매도 체결 시 broker 정본 resync·avg 가중평균, 증액 롤백은 holding 복귀. +5. **M5 (REQ-067)**: baseline 4문서 정합 + run-the-app e2e. + +## Dependencies +- Internal: dcy-020(자산 영구 슬롯·REQ-062 브로커 정본·집행 루프) 전 단계 green. +- External: 전략 모듈(trex-orb)이 사이징 intent 발행 — 기존 buy/sell 와 병존(additive)이라 무중단. + +## Design Gate +- Design Required Before Implementation: yes +- Reason: M3/M4 는 **라이브 주문 집행 동작 변경**(증액 매수·부분 매도 dispatch). 증액 시 "주문 수량 vs 보유 수량" 충돌·avg_price 가중평균·증액 롤백·부분 체결 처리는 잘못 구현 시 과매수/과매도/평단 오류 → design.md 에서 확정. + +## Milestones +1. M1 상태머신 + test +2. M2 service avg/qty +3. M3 intent +4. M4 execution +5. M5 baseline + e2e + +## Risks +- R-exec (High): 증액/부분 매도 집행 회귀(과매수·과매도·avg drift). 대응: 브로커 정본 resync(REQ-062), 멱등, 단위+paper e2e. +- R-statemachine (Medium): 전이 추가 회귀. 대응: additive + test_state 회귀 가드. +- R-strategy (Medium): trex-orb 계약 전환. 대응: 기존 intent 병존. + +## Notes +- green 기준: 단위 전체 회귀(증액/부분 매도/부분 체결/avg 가중평균) + paper run-the-app e2e + ruff. diff --git a/docs/batches/bat-031_20260610_position-sizing/verification.md b/docs/batches/bat-031_20260610_position-sizing/verification.md new file mode 100644 index 0000000..c9e68cf --- /dev/null +++ b/docs/batches/bat-031_20260610_position-sizing/verification.md @@ -0,0 +1,51 @@ +# BAT-031 Verification + +- Status: approved (confirm-batch-verification, 2026-06-10) +- Batch: BAT-031 +- 검증 환경: Python 3.12 / PostgreSQL trex_core_test / 실 RabbitMQ / paper broker + +## Acceptance Mapping + +### REQ-066 (포지션 사이징 end-to-end) +| AC | 판정 | Evidence | +|---|---|---| +| AC-1 증액 가중평균 | pass | `test_increase_accumulates_qty_and_weights_avg_price`(10@1000 +5@1200 → 15@1066.67) + e2e 2단계 | +| AC-2 부분 매도 잔량 holding·cost basis | pass | `test_partial_sell_qty_is_min_intent_broker`(잔량 6, avg 1000) + e2e 3단계(9 @1066.67) | +| AC-3 전량 매도 → inactive | pass | `test_full_sell_qty_is_broker_balance`·`test_partial_sell_caps_at_broker_balance` + e2e 4단계 | +| AC-4 부분 체결 실제만 반영·미추적 | pass | `test_execution_cancel`(부분 체결→브로커 정본 잔량) + _on_filled/_on_partial_cancel 브로커 resync | +| AC-5 무회귀 | pass | 단위 378 / 통합 422 passed | + +### REQ-057 (CHG-03 상태머신 holding→pending_buy) +| AC | 판정 | Evidence | +|---|---|---| +| AC-1 전이 집합(13) | pass | `test_state.py`(holding→pending_buy allowed, size 13) | +| AC-5 증액 전이·복귀 | pass | `test_holding_to_pending_buy_increase_preserves_avg` + e2e | + +### REQ-061 (CHG-04 사이징 intent) +| AC | 판정 | Evidence | +|---|---|---| +| AC-6 증액 매수(holding) | pass | `test_increase_*` + e2e 2단계(admitted) | +| AC-7 부분 매도 qty·명령형·core 미저장 | pass | `test_partial_sell_*` + messaging sell qty 파싱 + e2e 3단계 | + +### REQ-062 (CHG-03 부분 매도 집행) +| AC | 판정 | Evidence | +|---|---|---| +| AC-1 매도 = min(intent, 브로커)·이상이면 전량 | pass | `test_partial_sell_qty_is_min_intent_broker`·`test_partial_sell_caps_at_broker_balance` | +| AC-5 부분 체결 실제만·미추적 | pass | `test_execution_cancel` + _balance_map resync | + +### REQ-067 (baseline 정합) +| AC | 판정 | Evidence | +|---|---|---| +| AC-1~3 data-model/runtime-flows/interface-contract/project-structure 정합 | pass | commit (사이징 흐름·13 전이·intent qty·가중평균 반영) | + +## Evidence +1. 단위: `pytest tests` → **378 passed**, ruff clean. +2. 통합(PG `trex_core_test` + 실 RabbitMQ): **422 passed, 1 skipped**(KIS sandbox 환경 이슈, 무관). +3. **run-the-app e2e**(라이브 trex_core + 실 MQ + paper, M=5): 초기 매수 10@1000 → 증액 +5@1200 → holding 15@1066.67(가중평균) → 부분 매도 6 → holding 9@1066.67(cost basis) → 전량 매도 → inactive. 데몬 ERROR 0. +4. baseline 동기화: 4문서 + (run-the-app e2e 가 증액·부분/전량 매도 흐름 실증). + +## Blocking Issues +- 없음. 전략 모듈(trex-orb) 사이징 전환은 병존(additive)이라 무중단; 미체결 pending 처분은 issue #21(별도) 범위. + +## Result +- 포함 REQ AC 전부 evidence 연결. **Ready for Release: true** (코드·단위·통합·e2e·baseline). 실 운영 전환은 전략 모듈 사이징 발행 시 활성(계약 병존). diff --git a/docs/batches/index.md b/docs/batches/index.md index fb99a51..c8cac73 100644 --- a/docs/batches/index.md +++ b/docs/batches/index.md @@ -38,3 +38,4 @@ | BAT-028 | standard | release-candidate | REQ-058, REQ-059, REQ-060 | dcy-020 (BAT-β) | [bat-028](./bat-028_20260610_universe-reconcile-and-active-admission/) | | BAT-029 | standard | release-candidate | REQ-061, REQ-062, REQ-063 | dcy-020 (BAT-γ) | [bat-029](./bat-029_20260610_asset-keyed-intent-and-divergence/) | | BAT-030 | standard | release-candidate | REQ-064, REQ-062, REQ-056·057·065(잔여) | dcy-020 (BAT-δ) | [bat-030](./bat-030_20260610_asset-centric-cutover/) | +| BAT-031 | standard | release-candidate | REQ-066, REQ-067, REQ-057·061·062(CHG) | dcy-021 | [bat-031](./bat-031_20260610_position-sizing/) | diff --git a/docs/discovery/dcy-021_20260610_position-sizing-target-intent.md b/docs/discovery/dcy-021_20260610_position-sizing-target-intent.md index 9d012f6..302e4c3 100644 --- a/docs/discovery/dcy-021_20260610_position-sizing-target-intent.md +++ b/docs/discovery/dcy-021_20260610_position-sizing-target-intent.md @@ -5,10 +5,10 @@ - 문서 ID: dcy-021_20260610_position-sizing-target-intent - 이슈명: 포지션 사이징 — 활성 자산 슬롯 보유 수량 변경(HOLDING→HOLDING)·부분 매도·선언형 target intent (issue #1, dcy-020 OQ-4 후속) - 작성 시각(KST): 2026-06-10 17:06 KST -- 마지막 갱신 시각(KST): 2026-06-10 17:39 KST (confirm-discovery 승인 — 전 OQ Answered, 상태 confirmed) +- 마지막 갱신 시각(KST): 2026-06-10 17:46 KST (draft-req: REQ-066·067 생성 + change-req REQ-057/061/062 예정) - 대체됨: 없음 - 후속 Discovery 참조: 없음 -- 생성된 REQ 참조: 없음 +- 생성된 REQ 참조: REQ-066, REQ-067 (+ change-req REQ-057/061/062) # 1. 계획 상태 요약 현재 Discovery가 어떤 배경에서 작성되고 있는지, 연계 문서가 있는지, 지금 시점의 해석이 무엇인지 짧게 요약한다. diff --git a/docs/srs/Documentation/req-067_position-sizing-baseline-alignment.md b/docs/srs/Documentation/req-067_position-sizing-baseline-alignment.md new file mode 100644 index 0000000..22f8d56 --- /dev/null +++ b/docs/srs/Documentation/req-067_position-sizing-baseline-alignment.md @@ -0,0 +1,88 @@ +# req-067: 포지션 사이징 baseline 문서 정합 + +- Status: Implemented +- Type: Documentation +- Priority: Medium +- Owner: project maintainers + +## Intent +- dcy-021: 보유 포지션 사이징(증액·부분 감액·명령형 사이징 intent) 구현이 끝나면 cross-cutting baseline 문서를 실제 동작과 일치시켜, 이후 Discovery/REQ/Batch 가 정확한 기준을 참조하게 한다. (issue #1, dcy-020 OQ-4 후속) + +## Requirement +- `docs/data-model.md`: 보유 슬롯 수량 가변(증액 누적·부분 감액 잔량)·avg_price 가중평균 재계산·cost basis 유지 규칙을 반영한다. +- `docs/runtime-flows.md`: 사이징 intent 수신 → 집행(증액 매수/부분 매도, 집행 수량 = min(intent, 브로커 잔고)) → 부분 체결 실제 반영·미추적 → 슬롯 holding 유지/inactive 종료 흐름과 확장된 상태 전이(HOLDING→PENDING_BUY 등)를 반영한다. +- `docs/interface-contract.md`: 사이징 intent payload(명령형 qty+price; 증액 buy-on-holding·부분 매도 qty)·이벤트·집행 수량 규칙을 반영한다. +- `docs/project-structure.md`: 사이징으로 영향받은 모듈(slot service·state·intents·execution) 책임 서술을 갱신한다. + +## Acceptance Criteria +1. Given 사이징 구현 완료, When `docs/data-model.md` 확인, Then 수량 가변·avg_price 가중평균·cost basis 유지가 코드와 일치한다. +2. Given 사이징 구현 완료, When `docs/runtime-flows.md`·`docs/interface-contract.md` 확인, Then 사이징 intent·집행(min(intent,잔고))·부분 체결 미추적·상태 전이 확장이 실제와 일치한다. +3. Given baseline 갱신, When `docs/project-structure.md` 확인, Then 영향 모듈 서술이 구현과 일치한다. + +## Impacted Area +- Docs: docs/data-model.md, docs/runtime-flows.md, docs/interface-contract.md, docs/project-structure.md +- Modules: 없음(문서) +- Tests: 없음(문서 리뷰) + +## Notes +- 본 REQ 는 REQ-066 및 change-req(REQ-057/061/062) 구현 완료 후 마지막에 정합한다(dcy-020 REQ-065 와 동일 패턴). +- 출처: dcy-021 FR-4. + +## Change Log + +### CHG-20260610-01 +- Date: 2026-06-10 +- Author: Justin Ko + +#### Change Summary +- dcy-021(포지션 사이징)로부터 최초 생성(Proposed). 사이징 baseline 4문서 정합. + +#### Intent +- 구현 후 cross-cutting baseline 을 실제 동작과 일치. + +#### Acceptance Criteria Delta +- Added: data-model/runtime-flows·interface-contract/project-structure 정합 3개 기준 +- Updated: 없음 / Removed: 없음 + +#### Impacted Area Delta +- Docs: data-model/runtime-flows/interface-contract/project-structure / Modules: 없음 / Tests: 없음(문서 리뷰) + +#### Delivery Trace Delta +- Batches: dcy-021 신규 배치(예정) / Releases: none + +#### Revalidation Impact +- Reverification Needed: no(문서) / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: confirm-req → dcy-021 배치 마지막 정합. + +#### Validation Plan +- 사이징 구현 완료 후 baseline 4문서 diff 리뷰. + +### CHG-20260610-02 +- Date: 2026-06-10 +- Author: Justin Ko + +#### Change Summary +- Status Proposed → Approved (confirm-req). 필수 필드·구체 AC 충족, source dcy-021 와 모순 없음. + +#### Intent +- delivery input 으로 승격. + +#### Acceptance Criteria Delta +- Added: 없음 / Updated: 없음 / Removed: 없음 + +#### Impacted Area Delta +- Docs: docs/srs/index.md(Register Approved) / Modules: 없음 / Tests: 없음 + +#### Delivery Trace Delta +- Batches: none / Releases: none + +#### Revalidation Impact +- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: dcy-021 배치 마지막 정합. + +#### Validation Plan +- 승인 후 dcy-021 배치 verification 에서 baseline 정합 확인. + +### CHG-20260610-IMPL +- Date: 2026-06-10 +- Author: Justin Ko +- Type: status +- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-031(release-candidate) verification — 단위 378 / 통합 422 passed + run-the-app 사이징 e2e(증액 가중평균·부분 매도 잔량·전량 매도) green. Blocking Issues 없음. diff --git a/docs/srs/Integration/req-062_quantity-hub-authority-and-divergence.md b/docs/srs/Integration/req-062_quantity-hub-authority-and-divergence.md index c1a8856..5a8880b 100644 --- a/docs/srs/Integration/req-062_quantity-hub-authority-and-divergence.md +++ b/docs/srs/Integration/req-062_quantity-hub-authority-and-divergence.md @@ -12,10 +12,11 @@ - 보유 **수량(asset_quantity)의 정본은 portfolio-hub** 이며, 슬롯은 수량을 정본 소유하지 않고 로컬 best-effort 미러(option D write-back/추정)로 둔다. 실제 청산 시 매도 수량은 **브로커 잔고(`get_balance().hldg_qty`)를 정본**으로 조회한다. 불일치 감지는 `reconcile_positions`(REQ-031)를 확장해 **브로커 잔고 + hub 수량 + 코어 슬롯 holding** 3자를 비교하며, 브로커를 ground truth 로 한다. 해소: A(코어 holding/브로커 0) → 슬롯 `error` + 운영자 resolve; B(코어 flat/브로커 보유, 최위험) → WARN/alert + 격리 + 운영자 결정(자동 청산·자동 편입 금지); C(수량만 불일치) → 미러 갱신 + warning, 상태 변경 없음; D(hub 만 지연) → 기존 write-back. **조용한 자동 교정 금지·표면화**, 실주문은 운영자 게이트(issue #15). 감지 reconcile 은 일일 refresh 와 분리해 더 자주 수행 가능(브로커 잔고+슬롯 상태만 필요). ## Acceptance Criteria -1. Given 매도 청산, When 매도 수량 결정, Then 로컬 미러가 stale 해도 브로커 잔고 기준으로 정확히 청산된다. +1. Given 매도 청산, When 매도 수량 결정, Then 로컬 미러가 stale 해도 브로커 잔고 기준으로 정확히 청산된다. **부분 매도(dcy-021)**: 집행 수량 = `min(intent qty, 브로커 hldg_qty)`; intent 가 잔고 이상이면 전량 매도(→inactive). 2. Given 코어 holding 인데 브로커 0, When reconcile, Then 슬롯이 `error` 로 격리되고 safety-sell 대상에서 빠지며 운영자 resolve 가 요구된다. 3. Given 코어 flat 인데 브로커 보유, When reconcile, Then WARN/alert + 격리되고 자동 청산·자동 편입 없이 운영자 결정으로 넘어간다. 4. Given 둘 다 보유, 수량만 불일치, When reconcile, Then 미러만 갱신되고 상태 전이는 없으며 hub 지속 불일치는 warning 으로 노출된다. +5. Given 사이징 주문(증액/부분 매도)이 일부만 체결(dcy-021), When 집행, Then 실제 체결분만 ledger 기록·슬롯 반영하고 미체결 잔량은 core 가 추적/재시도하지 않는다(재수렴은 전략). ## Impacted Area - Docs: docs/runtime-flows.md(불일치 해소·write-back) @@ -91,3 +92,42 @@ - Author: Justin Ko - Type: status - Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-029(M2a 불일치 reconcile)+BAT-030(M2b 매도 수량 브로커 정본) — 모든 AC 가 release-candidate 배치 verification 의 evidence 와 연결됨(단위 367/PG 29/MQ 21 passed + run-the-app 자산 중심 e2e). Blocking Issues 없음. + +### CHG-20260610-03 +- Date: 2026-06-10 +- Author: Justin Ko + +#### Change Summary +- dcy-021(포지션 사이징) 반영: 부분 매도 집행 수량 = **`min(intent qty, 브로커 hldg_qty)`**(과매도 방지, 잔고 이상이면 전량→inactive). 사이징 주문 부분 체결 시 **실제 체결분만** ledger/슬롯 반영, 미체결 잔량 미추적(전략 재수렴). 기존 "매도 수량=브로커 정본"의 부분 매도 확장. + +#### Intent +- 보유 수량 부분 감액을 브로커 정본 하에 과매도 없이 집행하고, 부분 체결은 실제 거래만 원장에 남긴다(dcy-021 OQ-3, dcy-013 부분 체결 처리 정합). + +#### Acceptance Criteria Delta +- Added: AC-5(사이징 부분 체결 → 실제 체결만 반영·미추적) +- Updated: AC-1 에 부분 매도 집행 수량 = min(intent, 브로커 잔고)·이상이면 전량 +- Removed: 없음 + +#### Impacted Area Delta +- Docs: docs/runtime-flows.md, docs/interface-contract.md (REQ-067 정합) +- Modules: trex_core/application/execution.py(부분 매도 dispatch qty), reconciliation.py(불변) +- Tests: tests/application/test_execution*.py(부분 매도 min·부분 체결) + +#### Delivery Trace Delta +- Batches: dcy-021 신규 배치(예정) +- Releases: none + +#### Revalidation Impact +- Reverification Needed: yes (부분 매도 집행 수량 정책 신규) +- Existing Implementation Invalidated: no (전량 매도=브로커 정본 기존 동작 보존, 부분은 확장) +- Status Recommendation: revert-to-approved (부분 매도 집행 미구현 — dcy-021 배치에서 구현·검증) +- Follow-up Action: dcy-021 배치 구현 후 Implemented 복귀. + +#### Validation Plan +- 부분 매도 min(intent,잔고)·잔고 이상 전량·부분 체결 실제만 ledger 단위 + 회귀. + +### CHG-20260610-IMPL +- Date: 2026-06-10 +- Author: Justin Ko +- Type: status +- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-031(release-candidate) verification — 단위 378 / 통합 422 passed + run-the-app 사이징 e2e(증액 가중평균·부분 매도 잔량·전량 매도) green. Blocking Issues 없음. diff --git a/docs/srs/Interface/req-057_asset-slot-state-machine.md b/docs/srs/Interface/req-057_asset-slot-state-machine.md index 3b1f0b5..9b1861e 100644 --- a/docs/srs/Interface/req-057_asset-slot-state-machine.md +++ b/docs/srs/Interface/req-057_asset-slot-state-machine.md @@ -12,10 +12,11 @@ - 상태 집합을 `inactive → pending_buy → holding → pending_sell → inactive` (+ 모든 비-error → `error`, `error → {inactive, holding}` 운영자 resolve)로 재정의한다. 기존 `idle`·`closed` 는 영구 슬롯에서 단일 `inactive` 로 합치고 `closed→idle` 복구 전이를 제거한다. `holding`(포지션 열림)은 코어 슬롯의 로컬 정본으로 체결 시 동기 set, 매도 체결 시 동기 clear 한다(portfolio-hub `asset_quantity` 로 판단하지 않음). advisory lock 을 **인스턴스 스코프**(`pg_advisory_xact_lock(SLOT_LOCK_ID, hash(instance_key))`)로 두어 인스턴스 간 교차 직렬화를 제거한다. ## Acceptance Criteria -1. Given 상태머신, When 허용 전이 집합을 확인, Then `{inactive→pending_buy, pending_buy→holding, pending_buy→inactive, holding→pending_sell, pending_sell→inactive, pending_sell→holding, *→error, error→inactive, error→holding}` 와 정확히 일치한다. +1. Given 상태머신, When 허용 전이 집합을 확인, Then `{inactive→pending_buy, pending_buy→holding, pending_buy→inactive, holding→pending_buy, holding→pending_sell, pending_sell→inactive, pending_sell→holding, *→error, error→inactive, error→holding}` 와 정확히 일치한다(dcy-021 CHG-20260610-03: `holding→pending_buy` 증액 전이 추가). 2. Given 영구 슬롯, When 매도 체결로 종료, Then 슬롯은 `inactive` 로 돌아가고(별도 `closed`·`closed→idle` 없음) holding 로컬 플래그가 clear 된다. 3. Given 서로 다른 instance_key 의 두 슬롯, When 동시에 전이, Then 인스턴스별 락으로 서로를 차단하지 않는다(교차 경합 없음). 4. Given 같은 슬롯에 대한 동시 전이, When 병렬 처리, Then 인스턴스 스코프 락으로 직렬화되어 단일 writer 불변식이 유지된다. +5. Given 보유(holding) 슬롯 증액, When `holding→pending_buy` 전이, Then 허용되고 체결 시 `pending_buy→holding` 으로 복귀한다(dcy-021 REQ-066). 부분 매도 잔량은 기존 `pending_sell→holding` 전이로 holding 을 유지한다. ## Impacted Area - Docs: docs/runtime-flows.md(전이 흐름), docs/data-model.md(상태) @@ -93,3 +94,42 @@ - Author: Justin Ko - Type: status - Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-027(토대)+BAT-030(literal inactive·별칭 제거) — 모든 AC 가 release-candidate 배치 verification 의 evidence 와 연결됨(단위 367/PG 29/MQ 21 passed + run-the-app 자산 중심 e2e). Blocking Issues 없음. + +### CHG-20260610-03 +- Date: 2026-06-10 +- Author: Justin Ko + +#### Change Summary +- dcy-021(포지션 사이징, issue #1) 반영: 상태 전이 집합에 **`holding→pending_buy`(보유 슬롯 증액)** 를 추가하고, `pending_sell→holding`(기존)을 부분 매도 잔량 holding 유지 경로로 명시. 전량 매도만 `pending_sell→inactive`. + +#### Intent +- 보유 자산 슬롯이 holding 을 유지한 채 수량 증액(추가 매수)·부분 감액을 표현하도록 상태머신을 additive 확장(dcy-020 이 고정한 "종료=전량 청산" 경계 해제). + +#### Acceptance Criteria Delta +- Added: AC-5(holding→pending_buy 증액 전이 허용·체결 시 holding 복귀, 부분 매도 잔량 pending_sell→holding) +- Updated: AC-1 허용 전이 집합에 holding→pending_buy 포함 +- Removed: 없음 + +#### Impacted Area Delta +- Docs: docs/runtime-flows.md, docs/data-model.md (REQ-067 정합) +- Modules: trex_core/domain/slot/state.py(전이 추가), service.py(증액 qty/avg_price = REQ-066) +- Tests: tests/domain/slot/test_state.py(전이 집합·size), test_service.py + +#### Delivery Trace Delta +- Batches: dcy-021 신규 배치(예정) +- Releases: none + +#### Revalidation Impact +- Reverification Needed: yes (전이 집합 변경 — test_state 갱신·증액 경로 검증) +- Existing Implementation Invalidated: no (기존 전이 보존, additive) — 단 AC-1 "정확히 일치"가 신규 전이를 포함하도록 확장되어 재검증 필요 +- Status Recommendation: revert-to-approved (신규 전이 미구현 — dcy-021 배치에서 구현·검증 후 confirm-req-implemented) +- Follow-up Action: dcy-021 배치 구현 + test_state 전이 집합 갱신 후 Implemented 복귀. + +#### Validation Plan +- ALLOWED_TRANSITIONS 에 holding→pending_buy 포함·size 갱신 단위 테스트 + 증액 end-to-end(REQ-066). + +### CHG-20260610-IMPL +- Date: 2026-06-10 +- Author: Justin Ko +- Type: status +- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-031(release-candidate) verification — 단위 378 / 통합 422 passed + run-the-app 사이징 e2e(증액 가중평균·부분 매도 잔량·전량 매도) green. Blocking Issues 없음. diff --git a/docs/srs/Interface/req-061_asset-keyed-intent-contract.md b/docs/srs/Interface/req-061_asset-keyed-intent-contract.md index 35fd84e..3866f2f 100644 --- a/docs/srs/Interface/req-061_asset-keyed-intent-contract.md +++ b/docs/srs/Interface/req-061_asset-keyed-intent-contract.md @@ -17,6 +17,8 @@ 3. Given 보유(holding) 아닌 슬롯, When 매도, Then `not_holding`(또는 not-holding 사유)로 거부된다. 4. Given 레거시 매수(`portfolio_id`), When 제출, Then `find_slot_by_portfolio` 로 슬롯에 매핑되어 동일하게 처리된다(dual-accept, 무중단). 5. Given 같은 `intent_id` 재전송, When 처리, Then 슬롯 중복 전이 없이 최초 결정과 동일 응답(멱등). +6. Given 보유(holding) 슬롯, When **증액 매수 intent**(qty+price)를 제출, Then `holding→pending_buy` 로 추가 매수가 집행된다(dcy-021, 이미 active 라도 증액은 허용 — `already_active` 예외). +7. Given 보유 슬롯, When **부분 매도 intent**(qty+price)를 제출, Then 명시 수량으로 `holding→pending_sell` 집행된다(집행 수량 정책 REQ-062). 사이징 intent 는 명령형(전략이 qty+price 계산·전송), core 는 target/의도 수량을 저장·추적하지 않는다. ## Impacted Area - Docs: docs/runtime-flows.md(intent 흐름), docs/interface-contract.md(메시지 계약) @@ -126,3 +128,42 @@ - Author: Justin Ko - Type: status - Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-029(+BAT-030 trading_date 제거·e2e slot_id 매수) — 모든 AC 가 release-candidate 배치 verification 의 evidence 와 연결됨(단위 367/PG 29/MQ 21 passed + run-the-app 자산 중심 e2e). Blocking Issues 없음. + +### CHG-20260610-04 +- Date: 2026-06-10 +- Author: Justin Ko + +#### Change Summary +- dcy-021(포지션 사이징) 반영: intent 계약에 **사이징 intent**(보유 슬롯 증액 매수 / 부분 매도)를 추가. 명령형 — 전략이 스냅샷 cash+quantity 로 **정수 주식 수(qty)+가격(price)** 을 계산해 보내고, core 는 실행만 한다(target/의도 수량 미저장·미추적). 증액은 이미 active 슬롯에도 허용(전량 매수 활성화의 `already_active` 와 구분). + +#### Intent +- 보유 자산의 수량 조정을 기존 명령형 buy/sell 계약의 최소 additive 확장으로 표현(dcy-021 OQ-1/OQ-2 확정). + +#### Acceptance Criteria Delta +- Added: AC-6(증액 매수 intent → holding→pending_buy), AC-7(부분 매도 intent qty → holding→pending_sell, 명령형·core 미저장) +- Updated: 없음(기존 활성/청산 계약 보존) +- Removed: 없음 + +#### Impacted Area Delta +- Docs: docs/interface-contract.md(사이징 intent payload), docs/runtime-flows.md +- Modules: trex_core/application/intents.py(증액/부분 매도 admission), messaging_handlers.py(payload) +- Tests: tests/application/test_*intent*.py, 사이징 admission 신규 + +#### Delivery Trace Delta +- Batches: dcy-021 신규 배치(예정) +- Releases: none + +#### Revalidation Impact +- Reverification Needed: yes (신규 사이징 계약 경로) +- Existing Implementation Invalidated: no (기존 slot_id 매수·전량 매도 계약 보존, additive) +- Status Recommendation: revert-to-approved (사이징 계약 미구현 — dcy-021 배치에서 구현·검증) +- Follow-up Action: dcy-021 배치 구현 후 Implemented 복귀. + +#### Validation Plan +- 증액 매수·부분 매도 intent admission 단위 + end-to-end(REQ-066). 명령형·멱등·core 미저장 검증. + +### CHG-20260610-IMPL +- Date: 2026-06-10 +- Author: Justin Ko +- Type: status +- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-031(release-candidate) verification — 단위 378 / 통합 422 passed + run-the-app 사이징 e2e(증액 가중평균·부분 매도 잔량·전량 매도) green. Blocking Issues 없음. diff --git a/docs/srs/Interface/req-066_position-sizing-resize.md b/docs/srs/Interface/req-066_position-sizing-resize.md new file mode 100644 index 0000000..f8a15bc --- /dev/null +++ b/docs/srs/Interface/req-066_position-sizing-resize.md @@ -0,0 +1,95 @@ +# req-066: 보유 자산 포지션 사이징 — 증액·부분 감액 (수량/avg_price 재계산) + +- Status: Implemented +- Type: Interface +- Priority: High +- Owner: project maintainers + +## Intent +- dcy-021: 자산 중심 영구 슬롯(dcy-020)의 "수량 가변 전제" 위에, 보유(holding) 자산 슬롯의 **수량을 holding 을 유지한 채 조정**(증액·부분 감액)하는 end-to-end 동작과 수량/avg_price 재계산 규칙을 정의한다. 전량 청산만 종료(inactive)한다. (issue #1, dcy-020 OQ-4 후속) + +## Requirement +- 보유 슬롯 **증액**: 같은 슬롯이 `HOLDING→PENDING_BUY→HOLDING` 로 순환하며 **실제 체결분만큼** 보유 수량이 누적되고, `avg_price = (기존수량×기존평단 + 체결수량×체결가) / 총수량` 가중평균으로 재계산된다(REQ-057 전이·REQ-061 intent 계약 사용). +- 보유 슬롯 **부분 감액**: 같은 슬롯이 `HOLDING→PENDING_SELL` 로 전이하고, 체결 후 브로커 정본 수량을 반영해 잔량>0 이면 `HOLDING`(**cost basis=avg_price 유지**), 잔량 0(전량)이면 `INACTIVE` 로 종료한다(집행 수량 정책은 REQ-062). +- **부분 체결**: 증액·감액 모두 **실제 체결분만** 슬롯 수량/원장에 반영하고, 미체결 잔량은 core 가 추적·재시도하지 않는다(재수렴은 전략이 스냅샷 기준으로 재발행). 실현손익은 core 가 계산하지 않고 ledger/portfolio-hub 가 소유한다. +- 활성 자산 수(M 캡 대상, REQ-059)는 증액으로 증가하지 않는다(이미 active 인 자산의 수량 변경). +- 기존 활성/전량 청산/admission 경로는 무회귀(additive 확장). + +## Acceptance Criteria +1. Given 100주 holding(avg 1000) 슬롯, When 50주(@1200) 증액 매수가 전량 체결, Then 슬롯은 holding 유지·수량 150·avg_price = (100×1000+50×1200)/150 = 1066.67(반올림 규칙 적용)로 재계산된다. +2. Given 100주 holding 슬롯, When 60주 부분 매도가 전량 체결, Then 슬롯은 holding 유지·수량 40·avg_price(cost basis) 불변이다. +3. Given 100주 holding 슬롯, When 전량(또는 잔고 이상) 매도가 체결, Then 슬롯은 INACTIVE 로 종료되고 점유 필드가 초기화된다. +4. Given 증액/부분 매도 주문이 일부만 체결(예: 50 중 30), When 집행, Then 실제 체결분(30)만 슬롯 수량·ledger 에 반영되고 미체결 잔량은 추적되지 않는다. +5. Given dcy-020 기존 경로(신규 활성·전량 청산·admission·M 캡), When 사이징 도입 후 회귀, Then 무회귀(green)다. + +## Impacted Area +- Docs: docs/data-model.md(수량 가변·avg_price 재계산), docs/runtime-flows.md(사이징 흐름) — REQ-067 에서 정합 +- Modules: trex_core/domain/slot/service.py(qty 누적·avg_price 가중평균·cost basis 유지), trex_core/domain/slot/state.py(REQ-057 change-req), trex_core/application/execution.py(부분 체결 반영), trex_core/application/intents.py(REQ-061 change-req) +- Tests: 증액 avg_price 가중평균, 부분 매도 잔량/전량 분기, 부분 체결 실제만 반영, 회귀 가드 + +## Notes +- 계약 형태(명령형 qty+price)는 dcy-021 OQ-1, 단위(정수 주식 수+가격)는 OQ-2, avg_price/cost basis/실현손익은 OQ-3, 트리거(intent 당 1회)는 OQ-4 확정. +- 본 REQ 는 사이징의 **도메인 수량/avg_price 의미·end-to-end 동작**을 소유한다. 상태 전이(REQ-057)·intent 계약(REQ-061)·집행 매도 수량(REQ-062)의 계약 변경은 각 change-req 로 기록한다. +- 반올림 규칙: avg_price 는 기존 슬롯 `avg_price`(float/NUMERIC) 정밀도를 따른다(별도 통화 반올림 정책 없음). 주식 수는 정수. +- 출처: dcy-021 FR-1/FR-2 + NFR-1/NFR-2. + +## Change Log + +### CHG-20260610-01 +- Date: 2026-06-10 +- Author: Justin Ko + +#### Change Summary +- dcy-021(포지션 사이징, issue #1)로부터 최초 생성(Proposed). 보유 슬롯 증액·부분 감액 end-to-end + 수량/avg_price 재계산. + +#### Intent +- 자산 영구 슬롯의 수량 가변 전제 위에 보유 포지션 리사이즈를 정규화. + +#### Acceptance Criteria Delta +- Added: 증액 가중평균/부분 감액 잔량·전량/부분 체결 실제만/무회귀 5개 기준 +- Updated: 없음 / Removed: 없음 + +#### Impacted Area Delta +- Docs: data-model/runtime-flows(REQ-067) +- Modules: domain/slot service·state(REQ-057), application/execution·intents(REQ-061/062) +- Tests: 증액·부분 매도·부분 체결·회귀 + +#### Delivery Trace Delta +- Batches: dcy-021 신규 배치(예정) / Releases: none + +#### Revalidation Impact +- Reverification Needed: yes / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: confirm-req → dcy-021 배치. + +#### Validation Plan +- 단위(avg_price 가중평균·잔량 분기·부분 체결) + run-the-app end-to-end. + +### CHG-20260610-02 +- Date: 2026-06-10 +- Author: Justin Ko + +#### Change Summary +- Status Proposed → Approved (confirm-req). 필수 필드·구체 AC 충족, source dcy-021(confirmed, handoff 승인, OQ-1~4 Answered)과 모순 없음. + +#### Intent +- delivery input 으로 승격. + +#### Acceptance Criteria Delta +- Added: 없음 / Updated: 없음 / Removed: 없음 + +#### Impacted Area Delta +- Docs: docs/srs/index.md(Register Approved) / Modules: 없음 / Tests: 없음 + +#### Delivery Trace Delta +- Batches: none / Releases: none + +#### Revalidation Impact +- Reverification Needed: no / Existing Implementation Invalidated: no / Status Recommendation: keep-current / Follow-up Action: suggest-batch-reqs → draft-batch. + +#### Validation Plan +- 승인 후 dcy-021 배치 planning 에서 본 REQ AC 를 검증 기준으로 사용. + +### CHG-20260610-IMPL +- Date: 2026-06-10 +- Author: Justin Ko +- Type: status +- Summary: Approved → Implemented (confirm-req-implemented). 근거: BAT-031(release-candidate) verification — 단위 378 / 통합 422 passed + run-the-app 사이징 e2e(증액 가중평균·부분 매도 잔량·전량 매도) green. Blocking Issues 없음. diff --git a/docs/srs/index.md b/docs/srs/index.md index e9451ec..594a018 100644 --- a/docs/srs/index.md +++ b/docs/srs/index.md @@ -74,7 +74,7 @@ ## Next Requirement ID -- Current: `REQ-066` +- Current: `REQ-068` - Rule: `Requirement Register`에 있는 가장 큰 REQ 번호보다 정확히 1 커야 한다. ## Requirement Register @@ -146,13 +146,13 @@ | REQ-063 | 운영자 표면 단일화 — slots = 자산 포지션 단일 뷰 | Interface | Implemented | Medium | project maintainers | [req-063](./Interface/req-063_unified-operator-slot-view.md) | | REQ-064 | 풀 모델 → 자산 중심 DB 재초기화 (구 cutover) | Migration | Implemented | High | project maintainers | [req-064](./Migration/req-064_pool-to-permanent-slot-cutover.md) | | REQ-065 | 자산 중심 모델 baseline 문서 정합 + 풀 모델 폐기 명시 | Documentation | Implemented | Medium | project maintainers | [req-065](./Documentation/req-065_asset-centric-baseline-alignment.md) | +| REQ-066 | 보유 자산 포지션 사이징 — 증액·부분 감액 (수량/avg_price 재계산) | Interface | Implemented | High | project maintainers | [req-066](./Interface/req-066_position-sizing-resize.md) | +| REQ-067 | 포지션 사이징 baseline 문서 정합 | Documentation | Implemented | Medium | project maintainers | [req-067](./Documentation/req-067_position-sizing-baseline-alignment.md) | ## Recent Change Log Summary +- 2026-06-10 :: REQ-057/061/062/066/067 → Implemented (confirm-req-implemented, BAT-031 dcy-021 포지션 사이징): 보유 슬롯 증액(holding→pending_buy, avg_price 가중평균)·부분 매도(min(주문,잔고), 잔량 holding/전량 inactive, cost basis)·부분 체결 실제만 반영. 수량 정본=브로커 잔고 재동기화. 단위 378/통합 422 passed + 사이징 e2e green. BAT-031 release-candidate. +- 2026-06-10 :: REQ-057/061/062 change-req (dcy-021 포지션 사이징, CHG: 057-03/061-04/062-03): Implemented→**Approved** 되돌림(신규 동작 미구현, dcy-021 배치에서 재구현·confirm-req-implemented 로 복귀). REQ-057 상태머신에 `holding→pending_buy`(증액) 전이 추가·부분 매도 잔량 pending_sell→holding 명시, REQ-061 사이징 intent(증액 매수/부분 매도, 명령형 qty+price·core 미저장) 추가, REQ-062 부분 매도 집행 수량=min(intent,브로커잔고)·부분 체결 실제만 ledger·미추적. REQ-066/067(신규)이 end-to-end·baseline 소유. +- 2026-06-10 :: REQ-066~067 신규 생성(Proposed) (draft-req, dcy-021 포지션 사이징/issue #1, dcy-020 OQ-4 후속): 보유 자산 슬롯의 holding 유지 수량 조정. REQ-066(Interface — 증액 HOLDING→PENDING_BUY→HOLDING qty 누적·avg_price 가중평균 / 부분 감액 잔량 holding·전량 inactive·cost basis 유지 / 부분 체결 실제만 반영·미추적), REQ-067(Documentation — baseline 4문서 정합). 명령형 계약(전략이 cash+quantity 로 qty+price 계산·전송, core 미저장)·정수 주식 수+가격(OQ-1/2), avg_price 가중평균·실현손익 hub(OQ-3), intent 당 1회(OQ-4). 기존 Implemented 계약 REQ-057(상태머신)·REQ-061(intent)·REQ-062(수량)은 change-req 로 확장 동반. 전부 **Proposed**(confirm-req 대기). (draft-req) - 2026-06-10 :: REQ-056~065 신규 생성(Proposed) (draft-req, dcy-020 자산 중심 슬롯 모델 재설계): 익명 슬롯 풀 → portfolio-hub universe 자산과 1:1 **영구 슬롯** + 동시 활성(M) 제어로 substrate 전환. REQ-056(영구 슬롯 스키마·UNIQUE(instance_key,portfolio_id)·trading_date/entry_count 제거), REQ-057(상태머신 inactive↔pending_buy↔holding↔pending_sell·holding 로컬·인스턴스 스코프 lock), REQ-058(universe reconcile 생성/soft-retire/tombstone·degrade 보류·일일 preallocation 폐기), REQ-059(FCFS·M캡·무치환·over-cap), REQ-060(max_active_slots per-instance TOML), REQ-061(intent 자산 키 통일·sell-by-slot_id 폐기), REQ-062(수량 hub 정본+미러·청산 브로커·불일치 해소), REQ-063(slots 단일 뷰), REQ-064(풀→영구 cutover), REQ-065(baseline 정합·폐기 명시). 기존 REQ-002/003/005/006/007/048 등은 폐기/재정의 change-req 동반 예정. 단계적 배치(스키마·상태머신 → reconcile·admission → intent·수량·CLI → cutover) delivery. 전부 **Proposed**(confirm-req 대기). (draft-req) - 2026-06-09 :: REQ-048/010 change-req→Implemented (CHG-20260609-01/02, trex-orb-v1 설정 관리 정합, BAT-026): config 디렉터리 기반 설정 관리 도입 — `--config` 를 이름으로 해석 + `--config-path