Skip to content

Commit

Permalink
Merge pull request #59 from CSID-DGU/feature/#53/chart
Browse files Browse the repository at this point in the history
[feat] : 차트 선택 지표 목록 조회 API 구현 (GET)
  • Loading branch information
bbbang105 authored Jun 9, 2024
2 parents cf79b1f + ecbb1cd commit d15bba9
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ public enum SuccessStatus implements BaseCode {
// Upbit-Key
SUCCESS_ADD_UPBIT_KEYS(HttpStatus.CREATED, "201", "업비트 키 등록에 성공했습니다"),
// Chart
SUCCESS_GET_OHLCV_CHART(HttpStatus.OK, "200", "OHLCV 차트 조회에 성공했습니다.");
SUCCESS_GET_OHLCV_CHART(HttpStatus.OK, "200", "OHLCV 차트 조회에 성공했습니다."),
SUCCESS_GET_ALL_CHART_OPTIONS(HttpStatus.OK, "200", "차트 선택 지표 목록 조회에 성공했습니다.");

private final HttpStatus httpStatus;
private final String code;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,12 @@ public ResponseEntity<ApiResponse<List<ChartDto.OHLCVResponse>>> getOHLCVCharts(
List<ChartDto.OHLCVResponse> ohlcvResponses = chartService.getOHLCVCharts(koreanName, candleName);
return ApiResponse.onSuccess(SuccessStatus.SUCCESS_GET_OHLCV_CHART, ohlcvResponses);
}

// 차트 선택 지표 목록을 조회하는 API
@GetMapping("/options")
public ResponseEntity<ApiResponse<List<ChartDto.ChartOptionResponse>>> getAllChartOptions() {

List<ChartDto.ChartOptionResponse> chartOptionResponses = chartService.getAllChartOptions();
return ApiResponse.onSuccess(SuccessStatus.SUCCESS_GET_ALL_CHART_OPTIONS, chartOptionResponses);
}
}
27 changes: 26 additions & 1 deletion backend/src/main/java/org/dgu/backend/dto/ChartDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import org.dgu.backend.domain.Candle;
import org.dgu.backend.domain.CandleInfo;
import org.dgu.backend.domain.Market;
import org.dgu.backend.util.BigDecimalSerializer;

import java.math.BigDecimal;
Expand All @@ -32,7 +34,7 @@ public static class OHLCVResponse {
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal volume;

public static ChartDto.OHLCVResponse of(CandleInfo candleInfo) {
public static OHLCVResponse of(CandleInfo candleInfo) {
return OHLCVResponse.builder()
.date(String.valueOf(candleInfo.getDateTime()))
.openingPrice(BigDecimal.valueOf(candleInfo.getOpeningPrice()))
Expand All @@ -43,4 +45,27 @@ public static ChartDto.OHLCVResponse of(CandleInfo candleInfo) {
.build();
}
}

@Builder
@Getter
@AllArgsConstructor
@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class)
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class ChartOptionResponse {
private String englishName;
private String koreanName;
private String marketName;
private String candleName;
private String candleKoreanName;

public static ChartOptionResponse of(Market market, Candle candle) {
return ChartOptionResponse.builder()
.englishName(market.getEnglishName())
.koreanName(market.getKoreanName())
.marketName(market.getMarketName())
.candleName(candle.getCandleName())
.candleKoreanName(candle.getKoreanName())
.build();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.dgu.backend.exception;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.dgu.backend.common.code.BaseErrorCode;
import org.dgu.backend.common.dto.ErrorReasonDto;
import org.springframework.http.HttpStatus;

@Getter
@RequiredArgsConstructor
public enum CandleErrorResult implements BaseErrorCode {
NOT_FOUND_CANDLE(HttpStatus.NOT_FOUND, "404", "존재하지 않는 캔들입니다."),
NOT_FOUND_CANDLES(HttpStatus.NOT_FOUND, "404", "캔들 목록이 존재하지 않습니다.");

private final HttpStatus httpStatus;
private final String code;
private final String message;

@Override
public ErrorReasonDto getReason() {
return ErrorReasonDto.builder()
.isSuccess(false)
.code(code)
.message(message)
.build();
}

@Override
public ErrorReasonDto getReasonHttpStatus() {
return ErrorReasonDto.builder()
.isSuccess(false)
.httpStatus(httpStatus)
.code(code)
.message(message)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.dgu.backend.exception;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public class CandleException extends RuntimeException {
private final CandleErrorResult candleErrorResult;

@Override
public String getMessage() {
return candleErrorResult.getMessage();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import lombok.extern.slf4j.Slf4j;
import org.dgu.backend.common.ApiResponse;
import org.dgu.backend.common.code.BaseErrorCode;
import org.dgu.backend.domain.Market;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MissingRequestHeaderException;
Expand Down Expand Up @@ -68,4 +69,16 @@ public ResponseEntity<ApiResponse<BaseErrorCode>> handleChartException(ChartExce
ChartErrorResult errorResult = e.getChartErrorResult();
return ApiResponse.onFailure(errorResult);
}
// Market
@ExceptionHandler(MarketException.class)
public ResponseEntity<ApiResponse<BaseErrorCode>> handleMarketException(MarketException e) {
MarketErrorResult errorResult = e.getMarketErrorResult();
return ApiResponse.onFailure(errorResult);
}
// Candle
@ExceptionHandler(CandleException.class)
public ResponseEntity<ApiResponse<BaseErrorCode>> handleCandleException(CandleException e) {
CandleErrorResult errorResult = e.getCandleErrorResult();
return ApiResponse.onFailure(errorResult);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.dgu.backend.exception;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.dgu.backend.common.code.BaseErrorCode;
import org.dgu.backend.common.dto.ErrorReasonDto;
import org.springframework.http.HttpStatus;

@Getter
@RequiredArgsConstructor
public enum MarketErrorResult implements BaseErrorCode {
NOT_FOUND_MARKET(HttpStatus.NOT_FOUND, "404", "존재하지 않는 가상화폐입니다."),
NOT_FOUND_MARKETS(HttpStatus.NOT_FOUND, "404", "가상화폐 목록이 존재하지 않습니다.");

private final HttpStatus httpStatus;
private final String code;
private final String message;

@Override
public ErrorReasonDto getReason() {
return ErrorReasonDto.builder()
.isSuccess(false)
.code(code)
.message(message)
.build();
}

@Override
public ErrorReasonDto getReasonHttpStatus() {
return ErrorReasonDto.builder()
.isSuccess(false)
.httpStatus(httpStatus)
.code(code)
.message(message)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.dgu.backend.exception;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public class MarketException extends RuntimeException {
private final MarketErrorResult marketErrorResult;

@Override
public String getMessage() {
return marketErrorResult.getMessage();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@

public interface ChartService {
List<ChartDto.OHLCVResponse> getOHLCVCharts(String koreanName, String candleType);
List<ChartDto.ChartOptionResponse> getAllChartOptions();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import org.dgu.backend.domain.CandleInfo;
import org.dgu.backend.domain.Market;
import org.dgu.backend.dto.ChartDto;
import org.dgu.backend.exception.ChartErrorResult;
import org.dgu.backend.exception.ChartException;
import org.dgu.backend.exception.*;
import org.dgu.backend.repository.CandleInfoRepository;
import org.dgu.backend.repository.CandleRepository;
import org.dgu.backend.repository.MarketRepository;
Expand All @@ -16,6 +15,7 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
Expand All @@ -35,6 +35,24 @@ public List<ChartDto.OHLCVResponse> getOHLCVCharts(String koreanName, String can
return fetchUpdatedCandleInfo(koreanName, candleName);
}

// 차트 선택 지표 목록을 반환하는 메서드
@Override
public List<ChartDto.ChartOptionResponse> getAllChartOptions() {
List<Market> markets = marketRepository.findAll();
if (markets.isEmpty()) {
throw new MarketException(MarketErrorResult.NOT_FOUND_MARKETS);
}
List<Candle> candles = candleRepository.findAll();
if (candles.isEmpty()) {
throw new CandleException(CandleErrorResult.NOT_FOUND_CANDLES);
}

return markets.stream()
.flatMap(market -> candles.stream()
.map(candle -> ChartDto.ChartOptionResponse.of(market, candle)))
.collect(Collectors.toList());
}

// 캔들 정보 최신화 메서드
@Transactional
protected void updateCandleInfo(String koreanName, String candleName) {
Expand All @@ -45,7 +63,13 @@ protected void updateCandleInfo(String koreanName, String candleName) {
@Transactional
protected List<ChartDto.OHLCVResponse> fetchUpdatedCandleInfo(String koreanName, String candleName) {
Market market = marketRepository.findByKoreanName(koreanName);
if (Objects.isNull(market)) {
throw new MarketException(MarketErrorResult.NOT_FOUND_MARKET);
}
Candle candle = candleRepository.findByCandleName(candleName);
if (Objects.isNull(candle)) {
throw new CandleException(CandleErrorResult.NOT_FOUND_CANDLE);
}
LocalDateTime startDate = candleUtil.getStartDateByCandleName(candleName);

List<CandleInfo> candleInfos = candleInfoRepository.findByMarketAndCandleAndDateTimeAfter(market, candle, startDate);
Expand Down

0 comments on commit d15bba9

Please sign in to comment.