Skip to content

Commit

Permalink
#42 [refactor] : 현재가 기준으로 계산하도록 리팩토링
Browse files Browse the repository at this point in the history
  • Loading branch information
bbbang105 committed Jun 14, 2024
1 parent 55386da commit 1e13211
Showing 1 changed file with 79 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.dgu.backend.repository.UpbitKeyRepository;
import org.dgu.backend.repository.UserCoinRepository;
import org.dgu.backend.util.JwtUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
Expand All @@ -30,6 +31,10 @@
@RequiredArgsConstructor
@Slf4j
public class DashBoardServiceImpl implements DashBoardService {
@Value("${upbit.url.account}")
private String UPBIT_URL_ACCOUNT;
@Value("${upbit.url.ticker}")
private String UPBIT_URL_TICKER;
private final RestTemplate restTemplate;
private final JwtUtil jwtUtil;
private final UpbitKeyRepository upbitKeyRepository;
Expand All @@ -39,18 +44,9 @@ public class DashBoardServiceImpl implements DashBoardService {
@Override
public DashBoardDto.UserAccountResponse getUserAccount(String authorizationHeader) {
User user = jwtUtil.getUserFromHeader(authorizationHeader);
UpbitKey upbitKey = upbitKeyRepository.findByUser(user);
if (Objects.isNull(upbitKey)) {
throw new UpbitException(UpbitErrorResult.NOT_FOUND_UPBIT_KEY);
}
UpbitDto.Account[] accounts = getUpbitAccounts(user);

String token = jwtUtil.generateUpbitToken(upbitKey);
String url = "https://api.upbit.com/v1/accounts";
UpbitDto.Account[] responseBody = getUserAccountsAtUpbit(url, token);
if (Objects.isNull(responseBody)) {
throw new UpbitException(UpbitErrorResult.FAIL_ACCESS_USER_ACCOUNT);
}
BigDecimal accountSum = getAccountSum(responseBody);
BigDecimal accountSum = getAccountSum(accounts);

return DashBoardDto.UserAccountResponse.builder()
.account(accountSum.setScale(3, RoundingMode.HALF_UP))
Expand All @@ -61,86 +57,109 @@ public DashBoardDto.UserAccountResponse getUserAccount(String authorizationHeade
@Override
public List<DashBoardDto.UserCoinResponse> getUserCoins(String authorizationHeader) {
User user = jwtUtil.getUserFromHeader(authorizationHeader);
UpbitKey upbitKey = upbitKeyRepository.findByUser(user);
if (Objects.isNull(upbitKey)) {
throw new UpbitException(UpbitErrorResult.NOT_FOUND_UPBIT_KEY);
}
UpbitDto.Account[] accounts = getUpbitAccounts(user);

String token = jwtUtil.generateUpbitToken(upbitKey);
String url = "https://api.upbit.com/v1/accounts";
UpbitDto.Account[] responseBody = getUserAccountsAtUpbit(url, token);
if (Objects.isNull(responseBody)) {
throw new UpbitException(UpbitErrorResult.FAIL_ACCESS_USER_ACCOUNT);
}
return processUserCoins(accounts, user);
}

// 유저 보유 코인을 처리하는 메서드
private List<DashBoardDto.UserCoinResponse> processUserCoins(UpbitDto.Account[] accounts, User user) {
List<DashBoardDto.UserCoinResponse> userCoinResponses = new ArrayList<>();
for (UpbitDto.Account account : responseBody) {
for (UpbitDto.Account account : accounts) {
String coinName = account.getCurrency();
if (coinName.equals("KRW")) {
continue;
}

UserCoin userCoin = userCoinRepository.findByCoinName(account.getCurrency());
boolean isIncrease = false;
if (!Objects.isNull(userCoin)) {
isIncrease = isBalanceIncreased(account, userCoin);
userCoinRepository.delete(userCoin);
// 현금은 제외
if (!coinName.equals("KRW")) {
userCoinResponses.add(processSingleCoin(account, user, coinName));
}
}
return userCoinResponses;
}

DashBoardDto.UserCoinResponse userCoinResponse = DashBoardDto.UserCoinResponse.builder()
.coinName(coinName)
.balance(account.getBalance())
.price(account.getAvgBuyPrice())
.isIncrease(isIncrease)
.build();
userCoinResponses.add(userCoinResponse);

userCoinRepository.save(userCoinResponse.to(user));
// 단일 코인 정보를 처리하는 메서드
private DashBoardDto.UserCoinResponse processSingleCoin(UpbitDto.Account account, User user, String coinName) {
coinName = "KRW-" + coinName;
UserCoin userCoin = userCoinRepository.findByCoinName(coinName);
UpbitDto.Ticker[] ticker = getTickerPriceAtUpbit(UPBIT_URL_TICKER + coinName);
BigDecimal curPrice = BigDecimal.valueOf(ticker[0].getPrice());
BigDecimal curCoinCount = account.getCoinCount();
boolean isIncrease = false;
BigDecimal rate = BigDecimal.ZERO;
if (!Objects.isNull(userCoin)) {
rate = getCoinPriceIncreaseRate(userCoin, curPrice, curCoinCount);
isIncrease = rate.compareTo(BigDecimal.ZERO) > 0;
userCoinRepository.delete(userCoin);
}

return userCoinResponses;
DashBoardDto.UserCoinResponse userCoinResponse = DashBoardDto.UserCoinResponse.builder()
.coinName(coinName)
.coinCount(curCoinCount)
.price(curPrice)
.balance(curPrice.multiply(curCoinCount).setScale(4, RoundingMode.HALF_UP))
.isIncrease(isIncrease)
.rate(rate)
.build();

userCoinRepository.save(userCoinResponse.to(user));
return userCoinResponse;
}

// 대표 코인 5개 정보를 반환하는 메서드
@Override
public List<DashBoardDto.RepresentativeCoinResponse> getRepresentativeCoins() {
String url = "https://api.upbit.com/v1/ticker?markets=";
List<DashBoardDto.RepresentativeCoinResponse> representativeCoinResponses = new ArrayList<>();
for (Coin coin : Coin.values()) {
UpbitDto.Ticker[] responseBody = getTickerPriceAtUpbit(url + coin.getMarketName());
if (Objects.isNull(responseBody[0])) {
throw new UpbitException(UpbitErrorResult.FAIL_ACCESS_COIN_INFO);
}
representativeCoinResponses.add(DashBoardDto.RepresentativeCoinResponse.of(responseBody[0], coin.getKoreanName()));
UpbitDto.Ticker[] ticker = getTickerPriceAtUpbit(UPBIT_URL_TICKER + coin.getMarketName());
representativeCoinResponses.add(DashBoardDto.RepresentativeCoinResponse.of(ticker[0], coin.getKoreanName()));
}

return representativeCoinResponses;
}

// 현재 업비트 잔고를 계산하는 메서드
private BigDecimal getAccountSum(UpbitDto.Account[] responseBody) {
private BigDecimal getAccountSum(UpbitDto.Account[] accounts) {
BigDecimal accountSum = BigDecimal.ZERO;
for (UpbitDto.Account account : responseBody) {
for (UpbitDto.Account account : accounts) {
if (account.getCurrency().equals("KRW")) {
accountSum = accountSum.add(account.getBalance());
accountSum = accountSum.add(account.getCoinCount());
} else {
BigDecimal balance = account.getBalance();
BigDecimal avgBuyPrice = account.getAvgBuyPrice();
accountSum = accountSum.add(balance.multiply(avgBuyPrice));
// 현재가를 가져옴
String coinName = "KRW-" + account.getCurrency();
UpbitDto.Ticker[] ticker = getTickerPriceAtUpbit(UPBIT_URL_TICKER + coinName);
BigDecimal curPrice = BigDecimal.valueOf(ticker[0].getPrice());
BigDecimal userCoinCount = account.getCoinCount();
accountSum = accountSum.add(curPrice.multiply(userCoinCount));
}
}
return accountSum;
}

// 코인 가격 상승 여부를 판단하는 메서드
private boolean isBalanceIncreased(UpbitDto.Account account, UserCoin userCoin) {
// 기존 대비 코인 가격 상승률을 계산하는 메서드
private BigDecimal getCoinPriceIncreaseRate(UserCoin userCoin, BigDecimal curPrice, BigDecimal curCoinCount) {
BigDecimal pastValue = userCoin.getPrice().multiply(userCoin.getCoinCount());
BigDecimal currentValue = curPrice.multiply(curCoinCount);

return account.getBalance().compareTo(userCoin.getBalance()) > 0;
return currentValue.subtract(pastValue)
.divide(pastValue, 6, RoundingMode.HALF_UP)
.multiply(new BigDecimal("100"));
}

// 유저 업비트 계좌 정보를 조회하는 메서드
private UpbitDto.Account[] getUpbitAccounts(User user) {
UpbitKey upbitKey = upbitKeyRepository.findByUser(user);
if (Objects.isNull(upbitKey)) {
throw new UpbitException(UpbitErrorResult.NOT_FOUND_UPBIT_KEY);
}

String token = jwtUtil.generateUpbitToken(upbitKey);
UpbitDto.Account[] responseBody = getUserAccountsAtUpbit(UPBIT_URL_ACCOUNT, token);
if (Objects.isNull(responseBody)) {
throw new UpbitException(UpbitErrorResult.FAIL_ACCESS_USER_ACCOUNT);
}
return responseBody;
}

// 전체 계좌 조회 업비트 API와 통신하는 메서드
private UpbitDto.Account[] getUserAccountsAtUpbit(String url, String token) {

String authenticationToken = "Bearer " + token;
HttpHeaders headers = new HttpHeaders();
headers.set("accept", MediaType.APPLICATION_JSON_VALUE);
Expand Down Expand Up @@ -175,6 +194,9 @@ private UpbitDto.Ticker[] getTickerPriceAtUpbit(String url) {
new HttpEntity<>(headers),
UpbitDto.Ticker[].class
);
if (Objects.isNull(responseEntity.getBody()[0])) {
throw new UpbitException(UpbitErrorResult.FAIL_ACCESS_COIN_INFO);
}
return responseEntity.getBody();
} catch (HttpClientErrorException e) {
if (e.getStatusCode() == HttpStatus.UNAUTHORIZED && e.getResponseBodyAsString().contains("no_authorization_ip")) {
Expand Down

0 comments on commit 1e13211

Please sign in to comment.