65 lines
2.3 KiB
Java
65 lines
2.3 KiB
Java
package com.goldenchart.controller;
|
|
|
|
import com.goldenchart.dto.CandleBarDto;
|
|
import com.goldenchart.service.HistoricalDataService;
|
|
import com.goldenchart.websocket.DynamicSubscriptionManager;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import java.util.List;
|
|
|
|
/**
|
|
* 캔들 데이터 REST API 컨트롤러.
|
|
*
|
|
* context-path: /api
|
|
* endpoint: GET /api/candles/history
|
|
*
|
|
* 명세서 5.1 포맷:
|
|
* Query Params: market=KRW-BTC, type=1m, to=2026-05-20T10:17:00Z, count=200
|
|
* Response: CandleBarDto[] (time, open, high, low, close, volume, rsi)
|
|
*/
|
|
@RestController
|
|
@RequestMapping("/candles")
|
|
@RequiredArgsConstructor
|
|
@Slf4j
|
|
public class CandleController {
|
|
|
|
private final HistoricalDataService historicalDataService;
|
|
private final DynamicSubscriptionManager subscriptionManager;
|
|
|
|
/**
|
|
* 과거 캔들 데이터 조회.
|
|
*
|
|
* @param market 업비트 마켓 코드 (e.g. "KRW-BTC")
|
|
* @param type 캔들 타입 (e.g. "1m", "5m", "1h", "1d")
|
|
* @param to 기준 시간 이전(exclusive) ISO-8601 (e.g. "2026-05-20T10:00:00" 또는 "...Z")
|
|
* @param count 요청 캔들 수 (기본값 200, 최대 200)
|
|
* @return 시간 오름차순 CandleBarDto 배열
|
|
*/
|
|
@GetMapping("/history")
|
|
public ResponseEntity<List<CandleBarDto>> getHistory(
|
|
@RequestParam String market,
|
|
@RequestParam(defaultValue = "1d") String type,
|
|
@RequestParam(required = false) String to,
|
|
@RequestParam(defaultValue = "200") int count) {
|
|
|
|
log.info("[CandleController] history 요청: market={}, type={}, to={}, count={}", market, type, to, count);
|
|
List<CandleBarDto> bars = historicalDataService.getHistory(market, type, to, count);
|
|
return ResponseEntity.ok(bars);
|
|
}
|
|
|
|
/**
|
|
* 차트 실시간용 — 업비트 WS·Ta4j warm-up 고정 (STOMP 구독과 병행).
|
|
*/
|
|
@PostMapping("/watch")
|
|
public ResponseEntity<Void> watch(
|
|
@RequestParam String market,
|
|
@RequestParam(defaultValue = "1m") String type) {
|
|
subscriptionManager.ensureMarketPinned(market, type);
|
|
subscriptionManager.ensureMarketPinned(market, "1m");
|
|
return ResponseEntity.ok().build();
|
|
}
|
|
}
|