Skip to content

Feat/8/trade 매칭엔진 및 Trade 체결 구현#9

Merged
ohhalim merged 4 commits into
developfrom
feat/8/trade
May 13, 2026
Merged

Feat/8/trade 매칭엔진 및 Trade 체결 구현#9
ohhalim merged 4 commits into
developfrom
feat/8/trade

Conversation

@ohhalim
Copy link
Copy Markdown
Owner

@ohhalim ohhalim commented May 13, 2026

Summary

  • 가격-시간 우선순위 인메모리 매칭엔진 구현
  • 체결 시 Trade 저장 및 Wallet 정산 연결
  • 전량/부분 체결, self-trade 방지 지원

Changes

Domain

  • Trade 엔티티 추가 (maker/taker, buy/sell 구분, price/quantity/quoteAmount)
  • TradeRepository: 마켓별 체결 내역 조회
  • Order: fill() 메서드 추가 (FILLED/PARTIALLY_FILLED 상태 전환)

Matching Engine

  • OrderBookEntry: 오더북 항목 record
  • MatchResult: 체결 결과 record
  • MemoryOrderBook: BUY 높은 가격 우선 / SELL 낮은 가격 우선 PriorityQueue, self-trade 방지
  • MatchingEngine: 마켓별 오더북 관리 (ConcurrentHashMap), 부분 체결 지원

Settlement

  • settle(): 체결 시 maker/taker Order 수량 업데이트, Trade 저장, Wallet 정산
  • BUY 체결: KRW locked 소진 + BTC 지급
  • SELL 체결: BTC locked 소진 + KRW 지급
  • CreateOrderResponse: trades[] 에 liquidity(MAKER/TAKER) 포함

Test plan

  • BUY/SELL 전량 체결 후 wallet 정산 검증 (KRW locked 소진, BTC 지급)
  • BUY/SELL 부분 체결: SELL FILLED, BUY PARTIALLY_FILLED
  • self-trade 방지: 동일 유저 BUY/SELL 매칭 불가
  • @beforeeach MatchingEngine 초기화로 테스트 간 오더북 상태 격리
  • 기존 주문 생성/취소/조회 16개 테스트 전부 통과

관련 이슈

closes #8

Summary by CodeRabbit

  • New Features
    • Orders are now matched against the market order book with automatic settlement.
    • Partially filled and fully filled orders are tracked with updated status.
    • Completed trades are recorded and persisted in the system.
    • Self-trading protection prevents users from matching orders with themselves.
    • Wallet balances are automatically updated upon trade settlement.

Review Change Stack

ohhalim added 4 commits May 13, 2026 18:22
- 체결 정보 저장을 위한 Trade 엔티티 추가 (maker/taker, buy/sell 구분)
- TradeRepository: 마켓별 체결 내역 조회 추가
- OrderBookEntry: 오더북 항목 record (orderId, userId, price, remainingQuantity, sequence)
- MatchResult: 체결 결과 record (maker/taker/buy/sell 정보, price, quantity, quoteAmount)
- MemoryOrderBook: BUY는 높은 가격 우선, SELL은 낮은 가격 우선 PriorityQueue
- MatchingEngine: 마켓별 오더북 관리, self-trade 방지, 부분 체결 지원
- Order: fill() 메서드 추가 (수량 업데이트, FILLED/PARTIALLY_FILLED 상태 전환)
- CreateOrderResponse: List<Trade> 받아 TradeResult로 변환, liquidity(MAKER/TAKER) 포함
- OrderService: createOrder에 매칭 및 정산 연결, cancelOrder에 오더북 제거 추가
- settle(): 체결 시 Order 수량 업데이트, Trade 저장, Wallet 정산 (BUY→BTC 지급, SELL→KRW 지급)
- @beforeeach로 MatchingEngine 오더북 초기화 (테스트 간 상태 격리)
- BUY/SELL 전량 체결: 체결 후 wallet 정산 검증
- BUY/SELL 부분 체결: seller FILLED, buyer PARTIALLY_FILLED 검증
- self-trade 방지: 동일 유저 BUY/SELL 매칭 불가 검증
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 13, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR implements a complete order matching engine with in-memory order books using priority queues, integrates matching into order creation, and persists trade records with wallet settlement. The implementation flows from creating domain contracts (MatchResult, Trade), through the priority-queue-based matching algorithm, orchestration via MatchingEngine, integration into OrderService with settlement logic, and API response mapping with integration test coverage.

Changes

Matching Engine and Trade Settlement

Layer / File(s) Summary
Matching data contracts
src/main/java/com/coinflow/order/matching/MatchResult.java, src/main/java/com/coinflow/order/matching/OrderBookEntry.java, src/main/java/com/coinflow/trade/domain/Trade.java, src/main/java/com/coinflow/trade/repository/TradeRepository.java
MatchResult record carries maker/taker and buy/sell order/user IDs plus matched price/quantity/quoteAmount; OrderBookEntry record models in-memory order state with price, remaining quantity, and sequence; Trade JPA entity and TradeRepository persist completed trades with market and order identifiers.
In-memory order book matching
src/main/java/com/coinflow/order/matching/MemoryOrderBook.java
Two side-specific PriorityQueues (BUY by highest price-then-sequence, SELL by lowest price-then-sequence) implement price-crossing matching that prevents self-trades, computes matched quantities and scaled quote amounts, and re-queues partially filled makers.
Matching engine orchestration
src/main/java/com/coinflow/order/matching/MatchingEngine.java
Spring component managing per-market MemoryOrderBook instances in a ConcurrentHashMap, delegating taker order matching, conditionally adding residual orders, and supporting order cancellation and state reset.
Order state updates and service integration
src/main/java/com/coinflow/order/domain/Order.java, src/main/java/com/coinflow/order/service/OrderService.java
Order.fill() increments executed quantities/amounts and sets status to FILLED or PARTIALLY_FILLED; OrderService.createOrder() calls matchingEngine.match(), settles results into Trade records, and returns response with trades; cancelOrder() delegates to matching engine; settle() updates fill state, unlocks locked balances, deposits counter-assets, and persists trades.
API response mapping and test coverage
src/main/java/com/coinflow/order/dto/CreateOrderResponse.java, src/test/java/com/coinflow/order/OrderApiTest.java
CreateOrderResponse.of() streams Trade objects into mapped TradeResult DTOs with stringified amounts and liquidity type; OrderApiTest injects MatchingEngine, clears state before each test, and validates full match execution with wallet state verification, partial matches, and self-trade prevention.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • ohhalim/CoinFlow#7: Extends the existing Order domain by adding fill() method and status progression that builds directly on the Order entity foundation from that PR.

Poem

🐰 A matching engine hops to life,
Two queues in sync, no self-trade strife—
Prices cross, trades bloom and settle,
Wallets balance with full mettle! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat/8/trade 매칭엔진 및 Trade 체결 구현' directly describes the main feature: matching engine and trade settlement implementation, which aligns with the core changes in the PR.
Linked Issues check ✅ Passed The PR implements all primary coding objectives from issue #8: Trade entity/repository, MemoryOrderBook with price-time priority, MatchingEngine with partial fill support, Order.fill() method, wallet settlement logic, and comprehensive integration tests validating matching and settlement.
Out of Scope Changes check ✅ Passed All code changes are directly related to implementing the matching engine and trade settlement objectives. No extraneous changes outside the scope of issue #8 were identified.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/8/trade

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ohhalim
Copy link
Copy Markdown
Owner Author

ohhalim commented May 13, 2026

LGTM??

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat]: Matching Engine / Trade 구현

1 participant