Files
goldenChart/backend/src/main/java/com/goldenchart/service/TradeSignalService.java
T
2026-05-23 15:11:48 +09:00

89 lines
3.8 KiB
Java

package com.goldenchart.service;
import com.goldenchart.dto.TradeSignalDto;
import com.goldenchart.entity.GcTradeSignal;
import com.goldenchart.repository.GcTradeSignalRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 매매 시그널 이력 서비스.
* 실시간 전략 체크(LiveStrategyEvaluator / LiveStrategyScheduler)에서
* BUY/SELL 시그널이 발생하면 이 서비스를 통해 DB에 저장한다.
*/
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class TradeSignalService {
private final GcTradeSignalRepository repo;
private final FcmPushService fcmPushService;
// ── 저장 ─────────────────────────────────────────────────────────────────
public TradeSignalDto save(String deviceId, Long userId, String market,
Long strategyId, String strategyName,
String signalType, double price,
long candleTime, String candleType,
String executionType) {
GcTradeSignal entity = GcTradeSignal.builder()
.deviceId(deviceId)
.userId(userId)
.market(market)
.strategyId(strategyId)
.strategyName(strategyName)
.signalType(signalType)
.price(price)
.candleTime(candleTime)
.candleType(candleType)
.executionType(executionType)
.build();
GcTradeSignal saved = repo.save(entity);
log.info("[TradeSignal] saved {} {} @ {} market={}", signalType, candleType, price, market);
if (deviceId != null) {
fcmPushService.sendTradeSignalIfEnabled(
deviceId, userId, market, signalType, price, strategyName, saved.getId());
}
return toDto(saved);
}
// ── 조회 ─────────────────────────────────────────────────────────────────
@Transactional(readOnly = true)
public List<TradeSignalDto> list(Long userId, String deviceId) {
List<GcTradeSignal> list = userId != null
? repo.findByUserIdOrderByCreatedAtDesc(userId)
: repo.findByDeviceIdOrderByCreatedAtDesc(deviceId != null ? deviceId : "");
return list.stream().map(this::toDto).toList();
}
@Transactional(readOnly = true)
public List<TradeSignalDto> listByMarket(Long userId, String deviceId, String market) {
return repo.findByDeviceIdAndMarketOrderByCreatedAtDesc(
deviceId != null ? deviceId : "", market)
.stream().map(this::toDto).toList();
}
// ── 변환 ─────────────────────────────────────────────────────────────────
private TradeSignalDto toDto(GcTradeSignal e) {
return TradeSignalDto.builder()
.id(e.getId())
.market(e.getMarket())
.strategyId(e.getStrategyId())
.strategyName(e.getStrategyName())
.signalType(e.getSignalType())
.price(e.getPrice())
.candleTime(e.getCandleTime())
.candleType(e.getCandleType())
.executionType(e.getExecutionType())
.createdAt(e.getCreatedAt() != null ? e.getCreatedAt().toString() : null)
.build();
}
}