Skip to content

Commit

Permalink
#53 [feat] : 차트 관련 요청 시, 최신화 후 반환하는 기능 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
bbbang105 committed Jun 9, 2024
1 parent ac89d4f commit 3196ffa
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.dgu.backend.exception.PortfolioErrorResult;
import org.dgu.backend.exception.PortfolioException;
import org.dgu.backend.repository.*;
import org.dgu.backend.util.CandleUtil;
import org.dgu.backend.util.DateUtil;
import org.dgu.backend.util.JwtUtil;
import org.springframework.stereotype.Service;
Expand All @@ -15,14 +16,16 @@
import java.util.*;

@Service
@Transactional
@RequiredArgsConstructor
public class BackTestingServiceImpl implements BackTestingService {
private final JwtUtil jwtUtil;
private final DateUtil dateUtil;
private final CandleUtil candleUtil;
private final BackTestingCalculator backTestingCalculator;
private final CandleInfoUpdater candleInfoUpdater;
private final CandleInfoRepository candleInfoRepository;
private final CandleRepository candleRepository;
private final MarketRepository marketRepository;
private final PortfolioRepository portfolioRepository;
private final PortfolioOptionRepository portfolioOptionRepository;
private final TradingResultRepository tradingResultRepository;
Expand All @@ -32,12 +35,27 @@ public class BackTestingServiceImpl implements BackTestingService {
// 백테스팅 결과를 생성하는 메서드
@Override
public BackTestingDto.BackTestingResponse createBackTestingResult(String authorizationHeader, BackTestingDto.StepInfo stepInfo) {
updateCandleInfo("비트코인", stepInfo.getCandleName());

return fetchBackTestingResult(authorizationHeader, stepInfo);
}

// 캔들 정보 최신화 메서드
@Transactional
protected void updateCandleInfo(String koreanName, String candleName) {
candleInfoUpdater.ensureCandleInfoUpToDate(koreanName, candleName);
}

// 최신화된 캔들 정보를 사용해 백테스팅 결과를 생성하는 메서드
@Transactional
protected BackTestingDto.BackTestingResponse fetchBackTestingResult(String authorizationHeader, BackTestingDto.StepInfo stepInfo) {
Market market = marketRepository.findByKoreanName("비트코인");
Candle candle = candleRepository.findByCandleName(stepInfo.getCandleName());
LocalDateTime startDate = dateUtil.convertToLocalDateTime(stepInfo.getStartDate());
LocalDateTime endDate = dateUtil.convertToLocalDateTime(stepInfo.getEndDate());

List<CandleInfo> candles = candleInfoRepository.findFilteredCandleInfo(candle, startDate, endDate);
candles = backTestingCalculator.removeDuplicatedCandles(candles); // 중복 데이터 제거
List<CandleInfo> candles = candleInfoRepository.findFilteredCandleInfo(market, candle, startDate, endDate);
candles = candleUtil.removeDuplicatedCandles(candles);

// 골든 크로스 지점 찾기
List<LocalDateTime> goldenCrossPoints = backTestingCalculator.findGoldenCrossPoints(candles, stepInfo);
Expand All @@ -58,6 +76,7 @@ public BackTestingDto.BackTestingResponse createBackTestingResult(String authori

// 백테스팅 결과를 저장하는 메서드
@Override
@Transactional
public void saveBackTestingResult(String authorizationHeader, BackTestingDto.SavingRequest savingRequest) {
User user = jwtUtil.getUserFromHeader(authorizationHeader);

Expand All @@ -76,6 +95,7 @@ public void saveBackTestingResult(String authorizationHeader, BackTestingDto.Sav

// 백테스팅 최근 결과를 반환하는 메서드
@Override
@Transactional
public BackTestingDto.BackTestingResponse getRecentBackTestingResult(String authorizationHeader) {
User user = jwtUtil.getUserFromHeader(authorizationHeader);

Expand All @@ -90,7 +110,8 @@ public BackTestingDto.BackTestingResponse getRecentBackTestingResult(String auth
}

// 백테스팅 결과를 임시 저장하는 메서드
private void saveTempBackTestingResult(String authorizationHeader, BackTestingDto.StepInfo stepInfo, BackTestingDto.BackTestingResponse backTestingResponse) {
@Transactional
protected void saveTempBackTestingResult(String authorizationHeader, BackTestingDto.StepInfo stepInfo, BackTestingDto.BackTestingResponse backTestingResponse) {
User user = jwtUtil.getUserFromHeader(authorizationHeader);

// 기존에 있던 거래 로그 삭제
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.dgu.backend.service;

import lombok.RequiredArgsConstructor;
import org.dgu.backend.domain.Candle;
import org.dgu.backend.domain.CandleInfo;
import org.dgu.backend.domain.Market;
import org.dgu.backend.repository.CandleInfoRepository;
import org.dgu.backend.repository.CandleRepository;
import org.dgu.backend.repository.MarketRepository;
import org.dgu.backend.util.CandleDataCollector;
import org.dgu.backend.util.CandleUtil;
import org.dgu.backend.util.DateUtil;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Objects;

@Component
@RequiredArgsConstructor
public class CandleInfoUpdater {
private final MarketRepository marketRepository;
private final CandleRepository candleRepository;
private final CandleInfoRepository candleInfoRepository;
private final CandleDataCollector candleDataCollector;
private final CandleUtil candleUtil;
private final DateUtil dateUtil;

// 현재 시각을 기준으로 캔들 정보를 최신화하는 메서드
public void ensureCandleInfoUpToDate(String koreanName, String candleName) {
Market market = marketRepository.findByKoreanName(koreanName);
Candle candle = candleRepository.findByCandleName(candleName);

// 가장 최근 캔들 차트
CandleInfo latestCandleInfo = candleInfoRepository.findTopByMarketAndCandleOrderByTimestampDesc(market, candle);
int candleInterval = candleUtil.calculateCandleInterval(candleName);
LocalDateTime startDate;
if (Objects.isNull(latestCandleInfo)) {
startDate = dateUtil.convertToLocalDateTime("2019-01-01T00:00:00");
} else {
startDate = latestCandleInfo.getDateTime();
if (startDate.plusMinutes(candleInterval).isAfter(LocalDateTime.now())) {
return;
}
}

candleDataCollector.collectCandleData(koreanName, candleName, startDate, LocalDateTime.now());
}
}
41 changes: 21 additions & 20 deletions backend/src/main/java/org/dgu/backend/service/ChartServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,50 +11,51 @@
import org.dgu.backend.repository.CandleInfoRepository;
import org.dgu.backend.repository.CandleRepository;
import org.dgu.backend.repository.MarketRepository;
import org.dgu.backend.util.CandleUtil;
import org.springframework.stereotype.Service;

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

@Service
@Transactional
@RequiredArgsConstructor
public class ChartServiceImpl implements ChartService {
private final MarketRepository marketRepository;
private final CandleRepository candleRepository;
private final CandleInfoRepository candleInfoRepository;

private static final List<String> SEVEN_DAY_CANDLES = Arrays.asList("minutes1", "minutes3", "minutes5", "minutes10", "minutes15", "minutes30");
private static final List<String> SIX_MONTH_CANDLES = Arrays.asList("minutes60", "minutes240");
private final CandleInfoUpdater candleInfoUpdater;
private final CandleUtil candleUtil;

// OHLCV 차트를 반환하는 메서드
@Override
public List<ChartDto.OHLCVResponse> getOHLCVCharts(String koreanName, String candleName) {
updateCandleInfo(koreanName, candleName);

return fetchUpdatedCandleInfo(koreanName, candleName);
}

// 캔들 정보 최신화 메서드
@Transactional
protected void updateCandleInfo(String koreanName, String candleName) {
candleInfoUpdater.ensureCandleInfoUpToDate(koreanName, candleName);
}

// 최신화된 캔들 정보를 반환하는 메서드
@Transactional
protected List<ChartDto.OHLCVResponse> fetchUpdatedCandleInfo(String koreanName, String candleName) {
Market market = marketRepository.findByKoreanName(koreanName);
Candle candle = candleRepository.findByCandleName(candleName);

LocalDateTime startDate = getStartDateByCandleName(candleName);
LocalDateTime startDate = candleUtil.getStartDateByCandleName(candleName);

List<CandleInfo> candleInfos = candleInfoRepository.findByMarketAndCandleAndDateTimeAfter(market, candle, startDate);
if (candleInfos.isEmpty()) {
throw new ChartException(ChartErrorResult.NOT_FOUND_CHARTS);
}
candleInfos = candleUtil.removeDuplicatedCandles(candleInfos);

return candleInfos.stream()
.map(ChartDto.OHLCVResponse::of)
.collect(Collectors.toList());
}

// 캔들 종류에 따라 시작 기간을 계산해 반환하는 메서드
private LocalDateTime getStartDateByCandleName(String candleName) {
LocalDateTime now = LocalDateTime.now();
if (SEVEN_DAY_CANDLES.contains(candleName)) {
return now.minusDays(7);
} else if (SIX_MONTH_CANDLES.contains(candleName)) {
return now.minusMonths(6);
} else {
return LocalDateTime.of(2019, 1, 1, 0, 0);
}
}
}
}

0 comments on commit 3196ffa

Please sign in to comment.