Skip to content

Commit e17e715

Browse files
authored
Merge pull request #130 from CleanEngine/feat/trade-core
Feat/trade core
2 parents a1dc0f6 + e2320d8 commit e17e715

File tree

5 files changed

+18
-12
lines changed

5 files changed

+18
-12
lines changed

src/main/java/com/cleanengine/coin/CoinApplication.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
import jakarta.annotation.PostConstruct;
44
import org.springframework.boot.SpringApplication;
55
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
import org.springframework.scheduling.annotation.EnableAsync;
67
import org.springframework.scheduling.annotation.EnableScheduling;
78

89
import java.util.TimeZone;
910

1011

1112
@EnableScheduling
13+
@EnableAsync
1214
@SpringBootApplication
1315
public class CoinApplication {
1416

src/main/java/com/cleanengine/coin/trade/application/TradeExecutor.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import com.cleanengine.coin.common.error.BusinessException;
44
import com.cleanengine.coin.common.response.ErrorStatus;
5-
import com.cleanengine.coin.order.application.OrderService;
65
import com.cleanengine.coin.order.domain.BuyOrder;
76
import com.cleanengine.coin.order.domain.Order;
87
import com.cleanengine.coin.order.domain.OrderStatus;
@@ -89,12 +88,12 @@ public void executeTrade(WaitingOrders waitingOrders, TradePair<Order, Order> tr
8988
tradeExecutedEventPublisher.publish(tradeExecutedEvent);
9089
}
9190

92-
public void increaseAccountCash(Order order, Double amount) {
91+
private Account increaseAccountCash(Order order, Double amount) {
9392
Account account = accountService.findAccountByUserId(order.getUserId()).orElseThrow();
94-
accountService.save(account.increaseCash(amount));
93+
return accountService.save(account.increaseCash(amount));
9594
}
9695

97-
public void updateWalletAfterTrade(Order order, String ticker, double tradedSize, double totalTradedPrice) {
96+
private Wallet updateWalletAfterTrade(Order order, String ticker, double tradedSize, double totalTradedPrice) {
9897
if (order instanceof BuyOrder) {
9998
Wallet buyerWallet = walletService.findWalletByUserIdAndTicker(order.getUserId(), ticker);
10099
double updatedBuySize = buyerWallet.getSize() + tradedSize;
@@ -103,17 +102,17 @@ public void updateWalletAfterTrade(Order order, String ticker, double tradedSize
103102
buyerWallet.setSize(updatedBuySize);
104103
buyerWallet.setBuyPrice(updatedBuyPrice);
105104
// TODO : ROI 계산
106-
walletService.save(buyerWallet);
105+
return walletService.save(buyerWallet);
107106
} else if (order instanceof SellOrder) {
108107
// 매도 시에는 평단가 변동 없음
109108
Wallet sellerWallet = walletService.findWalletByUserIdAndTicker(order.getUserId(), ticker);
110-
walletService.save(sellerWallet);
109+
return walletService.save(sellerWallet);
111110
} else {
112111
throw new BusinessException("Unsupported order type: " + order.getClass().getName(), ErrorStatus.INTERNAL_SERVER_ERROR);
113112
}
114113
}
115114

116-
public Trade insertNewTrade(String ticker, BuyOrder buyOrder, SellOrder sellOrder, double tradeSize, Double tradePrice) {
115+
private Trade insertNewTrade(String ticker, BuyOrder buyOrder, SellOrder sellOrder, double tradeSize, Double tradePrice) {
117116
Trade newTrade = Trade.of(ticker, LocalDateTime.now(), buyOrder.getUserId(), sellOrder.getUserId(), tradePrice, tradeSize);
118117

119118
return tradeService.save(newTrade);
@@ -184,7 +183,7 @@ private void removeCompletedSellOrder(WaitingOrders waitingOrders, SellOrder ord
184183
}
185184
}
186185

187-
public void updateCompletedOrderStatus(Order order) {
186+
private void updateCompletedOrderStatus(Order order) {
188187
order.setState(OrderStatus.DONE);
189188
}
190189

src/main/java/com/cleanengine/coin/trade/application/TradeFlowService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@
55
import lombok.RequiredArgsConstructor;
66
import lombok.extern.slf4j.Slf4j;
77
import org.springframework.stereotype.Component;
8+
import org.springframework.transaction.annotation.Propagation;
89
import org.springframework.transaction.annotation.Transactional;
910

1011
import java.util.Optional;
1112

1213
@Slf4j
1314
@RequiredArgsConstructor
14-
@Transactional
1515
@Component
1616
public class TradeFlowService {
1717

1818
private final TradeMatcher tradeMatcher;
1919
private final TradeExecutor tradeExecutor;
2020

21+
@Transactional(propagation = Propagation.REQUIRES_NEW)
2122
public void execMatchAndTrade(String ticker) {
2223
WaitingOrders waitingOrders = tradeMatcher.getWaitingOrders(ticker);
2324
// TODO : peek() 해온 Order 객체들을 lock -> 체결 도중 취소 방지

src/main/java/com/cleanengine/coin/trade/application/TradeQueueManager.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.cleanengine.coin.trade.application;
22

33
import com.cleanengine.coin.order.application.event.OrderCreated;
4+
import com.cleanengine.coin.order.application.event.OrderInsertedToQueue;
45
import lombok.extern.slf4j.Slf4j;
6+
import org.springframework.context.event.EventListener;
7+
import org.springframework.scheduling.annotation.Async;
58
import org.springframework.stereotype.Component;
69
import org.springframework.transaction.event.TransactionalEventListener;
710

@@ -15,8 +18,8 @@ public TradeQueueManager(TradeFlowService tradeFlowService) {
1518
this.tradeFlowService = tradeFlowService;
1619
}
1720

18-
@TransactionalEventListener
19-
public void handleOrderInserted(OrderCreated event) {
21+
@EventListener
22+
public void handleOrderInserted(OrderInsertedToQueue event) {
2023
try {
2124
tradeFlowService.execMatchAndTrade(event.order().getTicker());
2225
} catch (Exception e) {

src/test/java/com/cleanengine/coin/trade/application/TradeExecuteLoadTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
import com.cleanengine.coin.common.domain.port.PriorityQueueStore;
44
import com.cleanengine.coin.order.application.OrderService;
55
import com.cleanengine.coin.order.application.dto.OrderCommand;
6-
import com.cleanengine.coin.order.application.dto.OrderInfo;
76
import com.cleanengine.coin.order.domain.BuyOrder;
87
import com.cleanengine.coin.order.domain.OrderType;
98
import com.cleanengine.coin.order.domain.SellOrder;
109
import com.cleanengine.coin.order.domain.spi.WaitingOrders;
1110
import com.cleanengine.coin.order.domain.spi.WaitingOrdersManager;
1211
import com.cleanengine.coin.trade.repository.TradeRepository;
1312
import org.junit.jupiter.api.BeforeEach;
13+
import org.junit.jupiter.api.Disabled;
1414
import org.junit.jupiter.api.DisplayName;
1515
import org.junit.jupiter.api.Test;
1616
import org.springframework.beans.factory.annotation.Autowired;
@@ -20,6 +20,7 @@
2020
import java.time.LocalDateTime;
2121

2222
@SpringBootTest
23+
@Disabled
2324
class TradeExecuteLoadTest {
2425

2526
@Autowired

0 commit comments

Comments
 (0)