diff --git a/.gradle/8.14.3/executionHistory/executionHistory.bin b/.gradle/8.14.3/executionHistory/executionHistory.bin index b2eaa40..16cfc0f 100644 Binary files a/.gradle/8.14.3/executionHistory/executionHistory.bin and b/.gradle/8.14.3/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.14.3/executionHistory/executionHistory.lock b/.gradle/8.14.3/executionHistory/executionHistory.lock index 0f814d2..b11dabb 100644 Binary files a/.gradle/8.14.3/executionHistory/executionHistory.lock and b/.gradle/8.14.3/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.14.3/fileHashes/fileHashes.bin b/.gradle/8.14.3/fileHashes/fileHashes.bin index 6869a59..e481f13 100644 Binary files a/.gradle/8.14.3/fileHashes/fileHashes.bin and b/.gradle/8.14.3/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.14.3/fileHashes/fileHashes.lock b/.gradle/8.14.3/fileHashes/fileHashes.lock index 4a9a7c4..0eab916 100644 Binary files a/.gradle/8.14.3/fileHashes/fileHashes.lock and b/.gradle/8.14.3/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.14.3/fileHashes/resourceHashesCache.bin b/.gradle/8.14.3/fileHashes/resourceHashesCache.bin index 80d6dc6..d69e870 100644 Binary files a/.gradle/8.14.3/fileHashes/resourceHashesCache.bin and b/.gradle/8.14.3/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 37630ba..58fb288 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe index 5c6f488..1ed36e7 100644 Binary files a/.gradle/file-system.probe and b/.gradle/file-system.probe differ diff --git a/build/reports/problems/problems-report.html b/build/reports/problems/problems-report.html index e7767ad..6a55a2a 100644 --- a/build/reports/problems/problems-report.html +++ b/build/reports/problems/problems-report.html @@ -650,7 +650,7 @@ diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin index 7f5b5af..103d36b 100644 Binary files a/build/tmp/compileJava/previous-compilation-data.bin and b/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/src/main/java/com/stockport/server/application/controller/stock/StockUpdateController.java b/src/main/java/com/stockport/server/application/controller/stock/StockUpdateController.java index 16e99c4..6cf8d6d 100644 --- a/src/main/java/com/stockport/server/application/controller/stock/StockUpdateController.java +++ b/src/main/java/com/stockport/server/application/controller/stock/StockUpdateController.java @@ -54,14 +54,4 @@ public ApiResponse updatePeriodicStockData( stockService.updatePeriodicStockData(startDate, endDate); return ApiResponse.onSuccess("주가 데이터 업데이트 성공"); } - - @GetMapping("/update/historical-data") - @Operation( - summary = "과거 주식 데이터 전체 업데이트", - description = "과거 주식 데이터를 처음부터 현재까지 모두 업데이트 합니다. (1일 이상 소요)" - ) - public ApiResponse updateHistoricalStockData() { - stockService.updateHistoricalStockData(); - return ApiResponse.onSuccess("과거 주가 데이터 전체 업데이트 성공"); - } } diff --git a/src/main/java/com/stockport/server/application/controller/stock/dto/StockPriceResponse.java b/src/main/java/com/stockport/server/application/controller/stock/dto/StockPriceResponse.java index 6339690..6c5f09a 100644 --- a/src/main/java/com/stockport/server/application/controller/stock/dto/StockPriceResponse.java +++ b/src/main/java/com/stockport/server/application/controller/stock/dto/StockPriceResponse.java @@ -12,11 +12,11 @@ @Builder public class StockPriceResponse { private LocalDate baseDate; - private Integer openPrice; - private Integer highPrice; - private Integer lowPrice; - private Integer closePrice; - private Integer changeAmount; + private BigDecimal openPrice; + private BigDecimal highPrice; + private BigDecimal lowPrice; + private BigDecimal closePrice; + private BigDecimal changeAmount; private BigDecimal changeRate; public static StockPriceResponse of(StockCurrentPrice stockCurrentPrice) { diff --git a/src/main/java/com/stockport/server/application/scheduler/indexData/IndexDataScheduler.java b/src/main/java/com/stockport/server/application/scheduler/indexData/IndexDataScheduler.java index 9ae6404..e13e2b1 100644 --- a/src/main/java/com/stockport/server/application/scheduler/indexData/IndexDataScheduler.java +++ b/src/main/java/com/stockport/server/application/scheduler/indexData/IndexDataScheduler.java @@ -13,15 +13,15 @@ public class IndexDataScheduler { private final IndexDataService indexDataService; - @Scheduled(cron = "0 0/5 9-18 * * MON-FRI", zone = "Asia/Seoul") // todo: 공휴일/휴장일 스케쥴러 처리 필요. - public void updateKospi() { - indexDataService.updateCurrentIndexData(MarketType.KOSPI); - log.info("[Scheduler] 코스피 데이터 업데이트 완료"); - } - - @Scheduled(cron = "0 0/5 9-18 * * MON-FRI", zone = "Asia/Seoul") // todo: 공휴일/휴장일 스케쥴러 처리 필요. - public void updateKosdaq() { - indexDataService.updateCurrentIndexData(MarketType.KOSPI); - log.info("[Scheduler] 코스닥 데이터 업데이트 완료"); - } +// @Scheduled(cron = "0 0/5 9-18 * * MON-FRI", zone = "Asia/Seoul") // todo: 공휴일/휴장일 스케쥴러 처리 필요. +// public void updateKospi() { +// indexDataService.updateCurrentIndexData(MarketType.KOSPI); +// log.info("[Scheduler] 코스피 데이터 업데이트 완료"); +// } +// +// @Scheduled(cron = "0 0/5 9-18 * * MON-FRI", zone = "Asia/Seoul") // todo: 공휴일/휴장일 스케쥴러 처리 필요. +// public void updateKosdaq() { +// indexDataService.updateCurrentIndexData(MarketType.KOSPI); +// log.info("[Scheduler] 코스닥 데이터 업데이트 완료"); +// } } diff --git a/src/main/java/com/stockport/server/application/scheduler/stock/StockScheduler.java b/src/main/java/com/stockport/server/application/scheduler/stock/StockScheduler.java index 25f53b8..51dae71 100644 --- a/src/main/java/com/stockport/server/application/scheduler/stock/StockScheduler.java +++ b/src/main/java/com/stockport/server/application/scheduler/stock/StockScheduler.java @@ -12,15 +12,15 @@ public class StockScheduler { private final StockService stockService; - @Scheduled(cron = "0 5 18 * * MON-FRI", zone = "Asia/Seoul") // todo: 공휴일/휴장일 스케쥴러 처리 필요. - public void saveDailyStockData() { - stockService.saveDailyStockData(); - log.info("[Scheduler] 일별 주가 데이터 업데이트 완료"); - } - - @Scheduled(cron = "0 0/5 9-18 * * MON-FRI", zone = "Asia/Seoul") // todo: 공휴일/휴장일 스케쥴러 처리 필요. - public void updateStockData() { - stockService.updateCurrentStockData(); - log.info("[Scheduler] 주가 데이터 업데이트 완료"); - } +// @Scheduled(cron = "0 5 18 * * MON-FRI", zone = "Asia/Seoul") // todo: 공휴일/휴장일 스케쥴러 처리 필요. +// public void saveDailyStockData() { +// stockService.saveDailyStockData(); +// log.info("[Scheduler] 일별 주가 데이터 업데이트 완료"); +// } +// +// @Scheduled(cron = "0 0/5 9-18 * * MON-FRI", zone = "Asia/Seoul") // todo: 공휴일/휴장일 스케쥴러 처리 필요. +// public void updateStockData() { +// stockService.updateCurrentStockData(); +// log.info("[Scheduler] 주가 데이터 업데이트 완료"); +// } } diff --git a/src/main/java/com/stockport/server/application/service/stock/PeriodicStockSaver.java b/src/main/java/com/stockport/server/application/service/stock/PeriodicStockSaver.java new file mode 100644 index 0000000..aa6270d --- /dev/null +++ b/src/main/java/com/stockport/server/application/service/stock/PeriodicStockSaver.java @@ -0,0 +1,55 @@ +package com.stockport.server.application.service.stock; + +import com.stockport.server.domain.stock.entity.Stock; +import com.stockport.server.domain.stock.entity.StockPrice; +import com.stockport.server.domain.stock.repository.StockPriceRepository; +import com.stockport.server.global.feign.adaptor.KisStockPriceAdaptor; +import com.stockport.server.global.feign.dto.KisStockPeriodPrice; +import com.stockport.server.global.utils.KisParsingUtils; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +@Service +@Slf4j +@RequiredArgsConstructor +public class PeriodicStockSaver { + + private final StockPriceRepository stockPriceRepository; + private final KisStockPriceAdaptor kisStockPriceAdaptor; + @PersistenceContext private final EntityManager entityManager; + + @Transactional + public void saveOnePeriod(Stock stock, LocalDate start, LocalDate end) { + + // 1) 해당 종목의 기존 날짜 목록을 한 번에 가져오기 + List existingDates = stockPriceRepository + .findAllBaseDatesByStockAndDateRange(stock, start, end); + + Set existingDateSet = new HashSet<>(existingDates); // O(1) 조회용 + + // 2) API 호출하여 새 데이터 변환 + List newList = kisStockPriceAdaptor.getStockPeriodPrice(stock.getStockCd(), start, end) + .getOutput2().stream() + .filter(dto -> !existingDateSet.contains(KisParsingUtils.parseDateSafe(dto.getBaseDate()))) // 필터링 + .map(KisStockPeriodPrice::toEntity) + .peek(entity -> entity.updateStock(stock)) + .toList(); + + // 3) 새 데이터만 saveAll 수행 + if (!newList.isEmpty()) { + stockPriceRepository.saveAll(newList); + } + + entityManager.flush(); + entityManager.clear(); + } +} \ No newline at end of file diff --git a/src/main/java/com/stockport/server/application/service/stock/StockService.java b/src/main/java/com/stockport/server/application/service/stock/StockService.java index 9e9bdd9..3fa9d40 100644 --- a/src/main/java/com/stockport/server/application/service/stock/StockService.java +++ b/src/main/java/com/stockport/server/application/service/stock/StockService.java @@ -20,7 +20,5 @@ public interface StockService { void updatePeriodicStockData(LocalDate startDate, LocalDate endDate); - void updateHistoricalStockData(); - void saveDailyStockData(); } diff --git a/src/main/java/com/stockport/server/application/service/stock/StockServiceImpl.java b/src/main/java/com/stockport/server/application/service/stock/StockServiceImpl.java index 3a5eeed..89ee050 100644 --- a/src/main/java/com/stockport/server/application/service/stock/StockServiceImpl.java +++ b/src/main/java/com/stockport/server/application/service/stock/StockServiceImpl.java @@ -7,6 +7,7 @@ import com.stockport.server.domain.stock.entity.Stock; import com.stockport.server.domain.stock.entity.StockCurrentPrice; import com.stockport.server.domain.stock.entity.StockPrice; +import com.stockport.server.domain.stock.repository.StockCurrentPriceRepository; import com.stockport.server.domain.stock.repository.StockPriceRepository; import com.stockport.server.domain.stock.repository.StockRepository; import com.stockport.server.global.apipayload.code.status.ErrorStatus; @@ -36,6 +37,8 @@ public class StockServiceImpl implements StockService { private final StockRepository stockRepository; private final StockPriceRepository stockPriceRepository; private final KisStockPriceAdaptor kisStockPriceAdaptor; + private final StockCurrentPriceRepository stockCurrentPriceRepository; + private final PeriodicStockSaver periodicSaver; @PersistenceContext private EntityManager entityManager; @@ -66,7 +69,7 @@ public StockInfoResponse getStockInfo(String stockCode, LocalDate startDate, Loc @Override public List searchStocks(String query) { - List stocks = stockRepository.findTop10ByStockNameContainingIgnoreCaseOrStockCdContainingIgnoreCaseOrIsinCdContainingIgnoreCaseOrderByStockNameAsc(query, query, query); + List stocks = stockRepository.findTop10ByStockNameContainingIgnoreCaseOrStockCdContainingIgnoreCaseOrIsinCdContainingIgnoreCaseOrderByMarketCapDesc(query, query, query); return stocks.stream() .map(StockQueryResponse::of) @@ -82,61 +85,32 @@ public void updateCurrentStockData() { List stockCdList = stockList.stream() .map(Stock::getStockCd) .toList(); - List stockCurrentPriceList = kisStockPriceAdaptor.getMultiStockCurrentPrice(stockCdList).getOutput().stream() + + List output = kisStockPriceAdaptor.getMultiStockCurrentPrice(stockCdList).getOutput(); + + List stockCurrentPriceList = output.stream() .map(currentPrice -> currentPrice.toEntity(LocalDate.now())) .toList(); for (int i = 0; i < Math.min(30, stockList.size()); i++) stockList.get(i).updateCurrentPriceInfo(stockCurrentPriceList.get(i)); + log.info("[stock] 현재 주가 데이터 업데이트 진행률 {}%", Math.min((stockIdx + 1) * 30, stocks.size()) * 100 / stocks.size()); } log.info("[stock] 현재 주가 데이터 업데이트 완료"); } @Override - @Transactional public void updatePeriodicStockData(LocalDate startDate, LocalDate endDate) { List stocks = stockRepository.findAll(); - for (Stock stock : stocks) { - List stockPriceList = kisStockPriceAdaptor.getStockPeriodPrice(stock.getStockCd(), startDate, endDate) - .getOutput2().stream() - .map(KisStockPeriodPrice::toEntity) - .toList(); - - for (StockPrice stockPrice : stockPriceList) { - if (stockPriceRepository.existsByStockAndBaseDate(stock, stockPrice.getBaseDate())) - continue; - stockPrice.updateStock(stock); - stockPriceRepository.save(stockPrice); - } - log.info("[stock] 기간 주가 데이터 업데이트 완료: {} 진행률 {}%", stock.getStockCd(), (stocks.indexOf(stock) + 1) * 100 / stocks.size()); - entityManager.flush(); - entityManager.clear(); - } - } - - @Override - @Transactional - public void updateHistoricalStockData() { - List stocks = stockRepository.findAll(); - LocalDate endDate = LocalDate.now(); - LocalDate startDate = endDate.minusYears(10); for (Stock stock : stocks) { for (LocalDate updateDate = startDate; updateDate.isBefore(endDate); updateDate = updateDate.plusDays(140)) { - List stockPriceList = kisStockPriceAdaptor.getStockPeriodPrice(stock.getStockCd(), updateDate, updateDate.plusDays(139)) - .getOutput2().stream() - .map(KisStockPeriodPrice::toEntity) - .toList(); - for (StockPrice stockPrice : stockPriceList) { - if (stockPriceRepository.existsByStockAndBaseDate(stock, stockPrice.getBaseDate())) - continue; - stockPrice.updateStock(stock); - stockPriceRepository.save(stockPrice); - } + periodicSaver.saveOnePeriod(stock, updateDate, updateDate.plusDays(139)); } - log.info("[stock] 과거 주가 데이터 업데이트 완료: {} 진행률 {}%", stock.getStockCd(), (stocks.indexOf(stock) + 1) * 100 / stocks.size()); - entityManager.flush(); - entityManager.clear(); + + log.info("[stock] 기간 주가 데이터 업데이트 완료: {} 진행률 {}%", + stock.getStockCd(), + (stocks.indexOf(stock) + 1) * 100 / stocks.size()); } } diff --git a/src/main/java/com/stockport/server/domain/stock/entity/Stock.java b/src/main/java/com/stockport/server/domain/stock/entity/Stock.java index 63f9956..53374a4 100644 --- a/src/main/java/com/stockport/server/domain/stock/entity/Stock.java +++ b/src/main/java/com/stockport/server/domain/stock/entity/Stock.java @@ -40,17 +40,18 @@ public class Stock extends BaseEntity { private List stockPrices; // 과거 주가 정보 public void updateCurrentPriceInfo(StockCurrentPrice newCurrentPriceInfo) { - if (this.currentPriceInfo != null) - this.currentPriceInfo.updateStock(null); - - this.currentPriceInfo = newCurrentPriceInfo; - newCurrentPriceInfo.updateStock(this); + if (this.currentPriceInfo == null) { + this.currentPriceInfo = newCurrentPriceInfo; + newCurrentPriceInfo.updateStock(this); + return; + } + this.currentPriceInfo.updateCurrentPrice(newCurrentPriceInfo); updateMarketCap(); } public void updateMarketCap() { - this.marketCap = currentPriceInfo.getCurrentPrice() * this.listedShares; + this.marketCap = currentPriceInfo.getCurrentPrice().toBigInteger().longValue() * this.listedShares; } @Builder diff --git a/src/main/java/com/stockport/server/domain/stock/entity/StockCurrentPrice.java b/src/main/java/com/stockport/server/domain/stock/entity/StockCurrentPrice.java index 55b501f..049399f 100644 --- a/src/main/java/com/stockport/server/domain/stock/entity/StockCurrentPrice.java +++ b/src/main/java/com/stockport/server/domain/stock/entity/StockCurrentPrice.java @@ -28,20 +28,20 @@ public class StockCurrentPrice extends BaseEntity { @Column(nullable = false) private LocalDate baseDate; // 기준일 - @Column(nullable = false) - private Integer openPrice; // 시가 + @Column(precision = 12, scale = 2) + private BigDecimal openPrice; // 시가 - @Column(nullable = false) - private Integer currentPrice; // 현재가 + @Column(precision = 12, scale = 2) + private BigDecimal currentPrice; // 현재가 - @Column(nullable = false) - private Integer highPrice; // 고가 + @Column(precision = 12, scale = 2) + private BigDecimal highPrice; // 고가 - @Column(nullable = false) - private Integer lowPrice; // 저가 + @Column(precision = 12, scale = 2) + private BigDecimal lowPrice; // 저가 - @Column(nullable = false) - private Integer changeAmount; // 등락폭 + @Column(precision = 12, scale = 2) + private BigDecimal changeAmount; // 등락폭 @Column(precision = 5, scale = 2) private BigDecimal changeRate; // 등락률 @@ -50,11 +50,21 @@ public void updateStock(Stock stock) { this.stock = stock; } + public void updateCurrentPrice(StockCurrentPrice newCurrentPrice) { + this.baseDate = newCurrentPrice.getBaseDate(); + this.openPrice = newCurrentPrice.getOpenPrice(); + this.currentPrice = newCurrentPrice.getCurrentPrice(); + this.highPrice = newCurrentPrice.getHighPrice(); + this.lowPrice = newCurrentPrice.getLowPrice(); + this.changeAmount = newCurrentPrice.getChangeAmount(); + this.changeRate = newCurrentPrice.getChangeRate(); + } + @Builder public StockCurrentPrice(Stock stock, LocalDate baseDate, - Integer openPrice, Integer currentPrice, - Integer highPrice, Integer lowPrice, - Integer changeAmount, BigDecimal changeRate) { + BigDecimal openPrice, BigDecimal currentPrice, + BigDecimal highPrice, BigDecimal lowPrice, + BigDecimal changeAmount, BigDecimal changeRate) { this.stock = stock; this.baseDate = baseDate; this.openPrice = openPrice; @@ -66,9 +76,9 @@ public StockCurrentPrice(Stock stock, LocalDate baseDate, } public static StockCurrentPrice create(LocalDate baseDate, - Integer openPrice, Integer currentPrice, - Integer highPrice, Integer lowPrice, - Integer changeAmount, BigDecimal changeRate) { + BigDecimal openPrice, BigDecimal currentPrice, + BigDecimal highPrice, BigDecimal lowPrice, + BigDecimal changeAmount, BigDecimal changeRate) { return StockCurrentPrice.builder() .baseDate(baseDate) .openPrice(openPrice) diff --git a/src/main/java/com/stockport/server/domain/stock/entity/StockPrice.java b/src/main/java/com/stockport/server/domain/stock/entity/StockPrice.java index fb298ac..5f5a708 100644 --- a/src/main/java/com/stockport/server/domain/stock/entity/StockPrice.java +++ b/src/main/java/com/stockport/server/domain/stock/entity/StockPrice.java @@ -31,23 +31,23 @@ public class StockPrice extends BaseEntity { @JoinColumn(name = "isin_cd", nullable = false) private Stock stock; - @Column(nullable = false) + @Column(precision = 12, scale = 2) private LocalDate baseDate; // 기준일 - @Column(nullable = false) - private Integer openPrice; // 시가 + @Column(precision = 12, scale = 2) + private BigDecimal openPrice; // 시가 - @Column(nullable = false) - private Integer closePrice; // 종가 + @Column(precision = 12, scale = 2) + private BigDecimal closePrice; // 종가 - @Column(nullable = false) - private Integer highPrice; // 고가 + @Column(precision = 12, scale = 2) + private BigDecimal highPrice; // 고가 - @Column(nullable = false) - private Integer lowPrice; // 저가 + @Column(precision = 12, scale = 2) + private BigDecimal lowPrice; // 저가 - @Column(nullable = false) - private Integer changeAmount; // 등락폭 + @Column(precision = 12, scale = 2) + private BigDecimal changeAmount; // 등락폭 @Column(precision = 7, scale = 2) private BigDecimal changeRate; // 등락률 @@ -59,8 +59,8 @@ public StockPrice updateStock(Stock stock) { @Builder public StockPrice(Stock stock, LocalDate baseDate, - Integer openPrice, Integer closePrice, Integer highPrice, - Integer lowPrice, Integer changeAmount, BigDecimal changeRate) { + BigDecimal openPrice, BigDecimal closePrice, BigDecimal highPrice, + BigDecimal lowPrice, BigDecimal changeAmount, BigDecimal changeRate) { this.stock = stock; this.baseDate = baseDate; this.openPrice = openPrice; @@ -72,8 +72,8 @@ public StockPrice(Stock stock, LocalDate baseDate, } public static StockPrice create(Stock stock, LocalDate baseDate, - Integer closePrice, Integer openPrice, Integer highPrice, - Integer lowPrice, Integer changeAmount, BigDecimal changeRate) { + BigDecimal closePrice, BigDecimal openPrice, BigDecimal highPrice, + BigDecimal lowPrice, BigDecimal changeAmount, BigDecimal changeRate) { return StockPrice.builder() .stock(stock) .baseDate(baseDate) diff --git a/src/main/java/com/stockport/server/domain/stock/repository/StockPriceRepository.java b/src/main/java/com/stockport/server/domain/stock/repository/StockPriceRepository.java index dad04cf..3ee0dee 100644 --- a/src/main/java/com/stockport/server/domain/stock/repository/StockPriceRepository.java +++ b/src/main/java/com/stockport/server/domain/stock/repository/StockPriceRepository.java @@ -4,6 +4,8 @@ import com.stockport.server.domain.stock.entity.Stock; import com.stockport.server.domain.stock.entity.StockPrice; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.time.LocalDate; import java.util.List; @@ -12,4 +14,16 @@ public interface StockPriceRepository extends JpaRepository { List findByStockAndBaseDateBetween(Stock stock, LocalDate startDate, LocalDate endDate); boolean existsByStockAndBaseDate(Stock stock, LocalDate baseDate); + + @Query(""" + select sp.baseDate + from StockPrice sp + where sp.stock = :stock + and sp.baseDate between :start and :end +""") + List findAllBaseDatesByStockAndDateRange( + @Param("stock") Stock stock, + @Param("start") LocalDate start, + @Param("end") LocalDate end + ); } diff --git a/src/main/java/com/stockport/server/domain/stock/repository/StockRepository.java b/src/main/java/com/stockport/server/domain/stock/repository/StockRepository.java index 692c1ea..f575c9c 100644 --- a/src/main/java/com/stockport/server/domain/stock/repository/StockRepository.java +++ b/src/main/java/com/stockport/server/domain/stock/repository/StockRepository.java @@ -11,6 +11,6 @@ public interface StockRepository extends JpaRepository { Page findAllByOrderByMarketCapDesc(Pageable pageable); Optional findByStockCd(String stockCd); - List findTop10ByStockNameContainingIgnoreCaseOrStockCdContainingIgnoreCaseOrIsinCdContainingIgnoreCaseOrderByStockNameAsc( + List findTop10ByStockNameContainingIgnoreCaseOrStockCdContainingIgnoreCaseOrIsinCdContainingIgnoreCaseOrderByMarketCapDesc( String name, String code, String isin );} diff --git a/src/main/java/com/stockport/server/global/feign/adaptor/KisStockPriceAdaptor.java b/src/main/java/com/stockport/server/global/feign/adaptor/KisStockPriceAdaptor.java index 989f8fe..200d218 100644 --- a/src/main/java/com/stockport/server/global/feign/adaptor/KisStockPriceAdaptor.java +++ b/src/main/java/com/stockport/server/global/feign/adaptor/KisStockPriceAdaptor.java @@ -14,6 +14,7 @@ import org.springframework.stereotype.Component; import java.time.LocalDate; +import java.time.format.DateTimeFormatter; import java.util.List; @Slf4j @@ -70,10 +71,10 @@ public KisPeriodResponseWrapper getSt "P", "J", stockCode, - "D", - "J", - startDate.format(java.time.format.DateTimeFormatter.BASIC_ISO_DATE), - endDate.format(java.time.format.DateTimeFormatter.BASIC_ISO_DATE) + startDate.format(DateTimeFormatter.BASIC_ISO_DATE), + endDate.format(DateTimeFormatter.BASIC_ISO_DATE), + "D", + "1" ) ); @@ -81,7 +82,7 @@ public KisPeriodResponseWrapper getSt throw new GeneralException(ErrorStatus.FEIGN_ERROR); } - log.info("[KIS] 기간별 주가 조회 성공: {} ({} ~ {})", stockCode, startDate, endDate); + log.info("[KIS] 기간별 주가 조회 성공: {} ({} ~ {}) {}개 조회", stockCode, startDate, endDate, response.getOutput2().size()); return response; } catch (Exception e) { diff --git a/src/main/java/com/stockport/server/global/feign/dto/KisIndexCurrentPrice.java b/src/main/java/com/stockport/server/global/feign/dto/KisIndexCurrentPrice.java index 5992777..197fd49 100644 --- a/src/main/java/com/stockport/server/global/feign/dto/KisIndexCurrentPrice.java +++ b/src/main/java/com/stockport/server/global/feign/dto/KisIndexCurrentPrice.java @@ -9,7 +9,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; -import java.math.BigDecimal; import java.time.LocalDate; @Getter @@ -40,12 +39,12 @@ public IndexData toEntity(MarketType marketType, LocalDate baseDate) { return IndexData.builder() .marketType(marketType) .baseDate(baseDate) - .closePrice(KisParsingUtils.parseDoubleSafe(currentPrice)) - .openPrice(KisParsingUtils.parseDoubleSafe(openPrice)) - .highPrice(KisParsingUtils.parseDoubleSafe(highPrice)) - .lowPrice(KisParsingUtils.parseDoubleSafe(lowPrice)) - .changeAmount(KisParsingUtils.parseDoubleSafe(changeAmount)) - .changeRate(KisParsingUtils.parseDoubleSafe(changeRate)) + .closePrice(KisParsingUtils.parseBigDecimalSafe(currentPrice)) + .openPrice(KisParsingUtils.parseBigDecimalSafe(openPrice)) + .highPrice(KisParsingUtils.parseBigDecimalSafe(highPrice)) + .lowPrice(KisParsingUtils.parseBigDecimalSafe(lowPrice)) + .changeAmount(KisParsingUtils.parseBigDecimalSafe(changeAmount)) + .changeRate(KisParsingUtils.parseBigDecimalSafe(changeRate)) .build(); } } \ No newline at end of file diff --git a/src/main/java/com/stockport/server/global/feign/dto/KisIndexPeriodPrice.java b/src/main/java/com/stockport/server/global/feign/dto/KisIndexPeriodPrice.java index 8a9a437..af785c4 100644 --- a/src/main/java/com/stockport/server/global/feign/dto/KisIndexPeriodPrice.java +++ b/src/main/java/com/stockport/server/global/feign/dto/KisIndexPeriodPrice.java @@ -38,7 +38,7 @@ public class KisIndexPeriodPrice { private String lowPrice; // 저가 private BigDecimal caculateChangeAmount(String closePrice, BigDecimal prevClosePrice) { - BigDecimal clpr = KisParsingUtils.parseDoubleSafe(closePrice); + BigDecimal clpr = KisParsingUtils.parseBigDecimalSafe(closePrice); return clpr.subtract(prevClosePrice); } @@ -55,10 +55,10 @@ public IndexData toEntity(BigDecimal prevClosePrice, MarketType marketType) { return IndexData.builder() .marketType(marketType) .baseDate(KisParsingUtils.parseDateSafe(this.baseDate)) - .closePrice(KisParsingUtils.parseDoubleSafe(this.closePrice)) - .openPrice(KisParsingUtils.parseDoubleSafe(this.openPrice)) - .highPrice(KisParsingUtils.parseDoubleSafe(this.highPrice)) - .lowPrice(KisParsingUtils.parseDoubleSafe(this.lowPrice)) + .closePrice(KisParsingUtils.parseBigDecimalSafe(this.closePrice)) + .openPrice(KisParsingUtils.parseBigDecimalSafe(this.openPrice)) + .highPrice(KisParsingUtils.parseBigDecimalSafe(this.highPrice)) + .lowPrice(KisParsingUtils.parseBigDecimalSafe(this.lowPrice)) .changeAmount(caculateChangeAmount(this.closePrice, prevClosePrice)) .changeRate(caculateChangeRate(this.closePrice, prevClosePrice)) .build(); diff --git a/src/main/java/com/stockport/server/global/feign/dto/KisMultieStockCurrentPrice.java b/src/main/java/com/stockport/server/global/feign/dto/KisMultieStockCurrentPrice.java index 4657cc1..8cc3ea1 100644 --- a/src/main/java/com/stockport/server/global/feign/dto/KisMultieStockCurrentPrice.java +++ b/src/main/java/com/stockport/server/global/feign/dto/KisMultieStockCurrentPrice.java @@ -1,8 +1,6 @@ package com.stockport.server.global.feign.dto; import com.fasterxml.jackson.annotation.JsonProperty; -import com.stockport.server.domain.indexData.constant.MarketType; -import com.stockport.server.domain.indexData.entity.IndexData; import com.stockport.server.domain.stock.entity.StockCurrentPrice; import com.stockport.server.global.utils.KisParsingUtils; import lombok.Getter; @@ -32,12 +30,12 @@ public class KisMultieStockCurrentPrice { public StockCurrentPrice toEntity(LocalDate baseDate) { return StockCurrentPrice.builder() .baseDate(baseDate) - .currentPrice(KisParsingUtils.parseIntSafe(currentPrice)) - .openPrice(KisParsingUtils.parseIntSafe(openPrice)) - .highPrice(KisParsingUtils.parseIntSafe(highPrice)) - .lowPrice(KisParsingUtils.parseIntSafe(lowPrice)) - .changeAmount(KisParsingUtils.parseIntSafe(changeAmount)) - .changeRate(KisParsingUtils.parseDoubleSafe(changeRate)) + .currentPrice(KisParsingUtils.parseBigDecimalSafe(currentPrice)) + .openPrice(KisParsingUtils.parseBigDecimalSafe(openPrice)) + .highPrice(KisParsingUtils.parseBigDecimalSafe(highPrice)) + .lowPrice(KisParsingUtils.parseBigDecimalSafe(lowPrice)) + .changeAmount(KisParsingUtils.parseBigDecimalSafe(changeAmount)) + .changeRate(KisParsingUtils.parseBigDecimalSafe(changeRate)) .build(); } } diff --git a/src/main/java/com/stockport/server/global/feign/dto/KisStockCurrentPrice.java b/src/main/java/com/stockport/server/global/feign/dto/KisStockCurrentPrice.java index 13c08b4..c9e5a47 100644 --- a/src/main/java/com/stockport/server/global/feign/dto/KisStockCurrentPrice.java +++ b/src/main/java/com/stockport/server/global/feign/dto/KisStockCurrentPrice.java @@ -1,21 +1,13 @@ package com.stockport.server.global.feign.dto; import com.fasterxml.jackson.annotation.JsonProperty; -import com.stockport.server.domain.stock.entity.Stock; import com.stockport.server.domain.stock.entity.StockCurrentPrice; -import com.stockport.server.domain.stock.entity.StockPrice; -import com.stockport.server.global.apipayload.code.status.ErrorStatus; -import com.stockport.server.global.exception.GeneralException; import com.stockport.server.global.utils.KisParsingUtils; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import java.math.BigDecimal; -import java.time.LocalDate; -import java.time.format.DateTimeFormatter; - @Getter @Builder @AllArgsConstructor @@ -41,12 +33,12 @@ public class KisStockCurrentPrice { public StockCurrentPrice toEntity() { return StockCurrentPrice.builder() - .openPrice(KisParsingUtils.parseIntSafe(this.openPrice)) - .currentPrice(KisParsingUtils.parseIntSafe(this.currentPrice)) - .highPrice(KisParsingUtils.parseIntSafe(this.highPrice)) - .lowPrice(KisParsingUtils.parseIntSafe(this.lowPrice)) - .changeAmount(KisParsingUtils.parseIntSafe(this.changeAmount)) - .changeRate(KisParsingUtils.parseDoubleSafe(this.changeRate)) + .openPrice(KisParsingUtils.parseBigDecimalSafe(this.openPrice)) + .currentPrice(KisParsingUtils.parseBigDecimalSafe(this.currentPrice)) + .highPrice(KisParsingUtils.parseBigDecimalSafe(this.highPrice)) + .lowPrice(KisParsingUtils.parseBigDecimalSafe(this.lowPrice)) + .changeAmount(KisParsingUtils.parseBigDecimalSafe(this.changeAmount)) + .changeRate(KisParsingUtils.parseBigDecimalSafe(this.changeRate)) .build(); } diff --git a/src/main/java/com/stockport/server/global/feign/dto/KisStockPeriodPrice.java b/src/main/java/com/stockport/server/global/feign/dto/KisStockPeriodPrice.java index c24633d..6ab21a2 100644 --- a/src/main/java/com/stockport/server/global/feign/dto/KisStockPeriodPrice.java +++ b/src/main/java/com/stockport/server/global/feign/dto/KisStockPeriodPrice.java @@ -39,18 +39,18 @@ public class KisStockPeriodPrice { @JsonProperty("prdy_vrss") private String changeAmount; // 등락폭 - private Integer caculateChangeAmount(String sign, String amount) { - Integer amt = KisParsingUtils.parseIntSafe(amount); + private BigDecimal caculateChangeAmount(String sign, String amount) { + BigDecimal amt = KisParsingUtils.parseBigDecimalSafe(amount); if (sign.equals("-")) { - return -amt; + return amt.negate(); } return amt; } private BigDecimal caculateChangeRate(String closePrice, String sign, String amount) { try { - BigDecimal clpr = BigDecimal.valueOf(KisParsingUtils.parseIntSafe(closePrice)); - BigDecimal chgAmt = BigDecimal.valueOf(caculateChangeAmount(sign, amount)); + BigDecimal clpr = KisParsingUtils.parseBigDecimalSafe(closePrice); + BigDecimal chgAmt = caculateChangeAmount(sign, amount); BigDecimal prevClpr = clpr.subtract(chgAmt); return chgAmt.multiply(BigDecimal.valueOf(100)).divide(prevClpr, 2, RoundingMode.HALF_UP); @@ -62,10 +62,10 @@ private BigDecimal caculateChangeRate(String closePrice, String sign, String amo public StockPrice toEntity() { return StockPrice.builder() .baseDate(KisParsingUtils.parseDateSafe(this.baseDate)) - .openPrice(KisParsingUtils.parseIntSafe(this.openPrice)) - .closePrice(KisParsingUtils.parseIntSafe(this.closePrice)) - .highPrice(KisParsingUtils.parseIntSafe(this.highPrice)) - .lowPrice(KisParsingUtils.parseIntSafe(this.lowPrice)) + .openPrice(KisParsingUtils.parseBigDecimalSafe(this.openPrice)) + .closePrice(KisParsingUtils.parseBigDecimalSafe(this.closePrice)) + .highPrice(KisParsingUtils.parseBigDecimalSafe(this.highPrice)) + .lowPrice(KisParsingUtils.parseBigDecimalSafe(this.lowPrice)) .changeAmount(caculateChangeAmount(this.changeSign, this.changeAmount)) .changeRate(caculateChangeRate(this.closePrice, this.changeSign, this.changeAmount)) .build(); diff --git a/src/main/java/com/stockport/server/global/utils/KisParsingUtils.java b/src/main/java/com/stockport/server/global/utils/KisParsingUtils.java index ac6e2a7..228bcb3 100644 --- a/src/main/java/com/stockport/server/global/utils/KisParsingUtils.java +++ b/src/main/java/com/stockport/server/global/utils/KisParsingUtils.java @@ -11,15 +11,10 @@ public final class KisParsingUtils { private KisParsingUtils() {} // 인스턴스화 방지 - public static Integer parseIntSafe(String val) { - try { - return Integer.parseInt(val); - } catch (Exception e) { - throw new GeneralException(ErrorStatus.PARSE_ERROR); - } - } - public static BigDecimal parseBigDecimalSafe(String val) { + if (val == null || val.isEmpty()) + return BigDecimal.ZERO; + try { return new BigDecimal(val); } catch (Exception e) { @@ -34,12 +29,4 @@ public static LocalDate parseDateSafe(String val) { throw new GeneralException(ErrorStatus.PARSE_ERROR); } } - - public static BigDecimal parseDoubleSafe(String val) { - try { - return new BigDecimal(val); - } catch (Exception e) { - throw new GeneralException(ErrorStatus.PARSE_ERROR); - } - } } \ No newline at end of file