Skip to content

Commit 9d18841

Browse files
authored
Merge pull request #87 from SynergyX-AI-Pattern/feat/#86_resample_15m_to_1h_candles
[FEAT] 15분봉을 1시간봉으로 리샘플링하는 로직 추가 #86
2 parents a3abfab + fe0ee3f commit 9d18841

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

src/main/java/com/synergyx/trading/service/stockService/candle/StockCandleQueryServiceImpl.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,19 @@
55
import com.synergyx.trading.converter.StockCandleConverter;
66
import com.synergyx.trading.dto.stockDetail.StockCandleResponseDTO;
77
import com.synergyx.trading.enums.CandleInterval;
8+
import com.synergyx.trading.model.StockOhlcv;
89
import com.synergyx.trading.repository.StockOhlcv1dRepository;
9-
import com.synergyx.trading.repository.StockOhlcv1hRepository;
10+
import com.synergyx.trading.repository.StockOhlcvRepository;
1011
import com.synergyx.trading.service.stockService.candle.strategy.CandleCompressionStrategy;
1112
import lombok.RequiredArgsConstructor;
1213
import lombok.extern.slf4j.Slf4j;
14+
import java.util.TreeMap;
1315

1416
import java.time.LocalDate;
1517
import java.time.LocalDateTime;
1618
import java.util.List;
19+
import java.util.Map;
20+
import java.util.stream.Collectors;
1721

1822
import org.springframework.stereotype.Service;
1923
import org.springframework.transaction.annotation.Transactional;
@@ -49,8 +53,8 @@ public List<StockCandleResponseDTO> getCandles(Long stockId, String intervalStr)
4953
.compress(stockId);
5054
}
5155

56+
private final StockOhlcvRepository stockOhlcvRepository;
5257
private final StockOhlcv1dRepository stockOhlcv1dRepository;
53-
private final StockOhlcv1hRepository stockOhlcv1hRepository;
5458
private final StockCandleConverter stockCandleConverter;
5559

5660
/**
@@ -100,13 +104,36 @@ public List<StockCandleResponseDTO> getBacktestHourlyCandles(Long stockId, Local
100104
throw new GeneralException(ErrorStatus._BAD_REQUEST);
101105
}
102106

103-
var candles = stockOhlcv1hRepository
107+
// 15분봉 데이터 조회
108+
var candles15m = stockOhlcvRepository
104109
.findByStockIdAndTimestampBetweenOrderByTimestampAsc(stockId, startDate, endDate);
105110

106-
if (candles == null || candles.isEmpty()) {
111+
if (candles15m == null || candles15m.isEmpty()) {
107112
throw new GeneralException(ErrorStatus.CANDLE_DATA_NOT_FOUND);
108113
}
109114

110-
return stockCandleConverter.toDtoList(candles);
115+
116+
// 15분봉 -> 1시간봉 리샘플링
117+
Map<LocalDateTime, List<StockOhlcv>> grouped = candles15m.stream()
118+
.collect(Collectors.groupingBy(
119+
c -> c.getTimestamp().truncatedTo(java.time.temporal.ChronoUnit.HOURS),
120+
TreeMap::new,
121+
Collectors.toList()
122+
));
123+
124+
return grouped.entrySet().stream()
125+
.map(entry -> {
126+
List<StockOhlcv> group = entry.getValue();
127+
group.sort(java.util.Comparator.comparing(StockOhlcv::getTimestamp));
128+
return StockCandleResponseDTO.builder()
129+
.time(entry.getKey())
130+
.open(group.get(0).getOpen())
131+
.high(group.stream().mapToDouble(StockOhlcv::getHigh).max().orElse(0))
132+
.low(group.stream().mapToDouble(StockOhlcv::getLow).min().orElse(0))
133+
.close(group.get(group.size() - 1).getClose())
134+
.volume(group.stream().mapToLong(StockOhlcv::getVolume).sum())
135+
.build();
136+
})
137+
.toList();
111138
}
112139
}

0 commit comments

Comments
 (0)