[BE-19] 일반 주문 경로에 호가 단위 정렬 적용
작업 내용 (설계 의도)
변경 사항
BE-08이 만든 order/domain/KoreanPriceTick을 일반 주문 경로에도 적용한다. 현재 PlaceOrderSpec은 price: BigDecimal을 그대로 보유하고, OrderDomainService#placeOrder·#correctOrder 어디에도 호가 정렬이 없다.
토스 스펙은 호가 단위 위반 시 400 invalid-request와 함께 data.tickSize·data.nearestPrices를 반환한다. 즉 지정가 주문이 호가 배수가 아니면 거부된다. 자동매매와 무관하게 기존 수동 주문 경로에 이미 존재하는 결함이다.
KoreanPriceTick은 자동매매 전용이 아니라 order 도메인 공용 자산이므로 재사용한다 — 두 번째 구현을 만들지 않는다.
정렬 방향은 주문 방향에 따라 다르다. 매수 지정가는 올리면 체결 우선·불리, 매도 지정가는 내리면 체결 우선·불리다. 어느 쪽을 택하든 근거를 남기고 테스트로 고정한다. 사용자가 입력한 가격을 시스템이 조용히 바꾸는 것이므로, 조정 사실을 응답에 드러낼지도 함께 판단한다.
롤백: 정렬 호출 제거로 즉시 원복(신규 파일 없음).
의존
- BE-27 (
KoreanPriceTick산술 수정 — 이 티켓이 고쳐진 사다리와 헬퍼를 소비한다) - BE-28 (
PlaceOrderSpec소유 — 같은 파일이라 순차로 간다)
다이어그램
처리 흐름
sequenceDiagram participant UC as PlaceOrderUseCase participant Svc as OrderDomainService participant Tick as KoreanPriceTick participant Gw as OrderGateway UC->>Svc: placeOrder(spec) Svc->>Tick: 지정가 정렬 Tick-->>Svc: 호가 배수 가격 Svc->>Gw: placeOrder(정렬된 spec)
클래스 의존
flowchart LR Spec[PlaceOrderSpec] --> Tick[KoreanPriceTick] Svc[OrderDomainService] --> Spec Svc --> Gw[OrderGateway]
테스트 케이스
- 12,345원 지정가 매수 주문이 10원 호가 배수로 정렬돼 전송된다.
- 265,325원 지정가 주문이 500원 호가 배수로 정렬된다(가격대 경계 위).
- 시장가 주문은 정렬 대상이 아니다(
OrderPriceType분기). - 정정 주문(
correctOrder)의 가격도 동일하게 정렬된다. - 이미 호가 배수인 가격은 변경되지 않는다(멱등).
- 가격대 경계값(2,000/5,000/20,000/50,000/200,000/500,000) 바로 위·아래가 각 밴드 단위로 정렬된다.