Files
stocksearch/services/stock_service.go
2026-03-31 19:32:59 +09:00

104 lines
2.7 KiB
Go

package services
import (
"fmt"
"stocksearch/models"
"time"
)
// StockService 주식 비즈니스 로직 (캐시 + 키움 API 조합)
type StockService struct {
kiwoom *KiwoomClient
cache *CacheService
}
var stockSvc *StockService
// GetStockService 주식 서비스 싱글턴 반환
func GetStockService() *StockService {
if stockSvc == nil {
stockSvc = &StockService{
kiwoom: GetKiwoomClient(),
cache: GetCacheService(),
}
}
return stockSvc
}
// GetCurrentPrice 현재가 조회 (1초 캐시 적용)
func (s *StockService) GetCurrentPrice(stockCode string) (*models.StockPrice, error) {
cacheKey := "price:" + stockCode
if cached, ok := s.cache.Get(cacheKey); ok {
if price, ok := cached.(*models.StockPrice); ok {
return price, nil
}
}
price, err := s.kiwoom.GetCurrentPrice(stockCode)
if err != nil {
return nil, fmt.Errorf("현재가 조회 실패 [%s]: %w", stockCode, err)
}
s.cache.Set(cacheKey, price, 30*time.Second)
return price, nil
}
// GetDailyChart 일봉 데이터 조회 (5분 캐시 적용)
func (s *StockService) GetDailyChart(stockCode string) ([]models.CandleData, error) {
cacheKey := "chart:daily:" + stockCode
if cached, ok := s.cache.Get(cacheKey); ok {
if candles, ok := cached.([]models.CandleData); ok {
return candles, nil
}
}
candles, err := s.kiwoom.GetDailyChart(stockCode)
if err != nil {
return nil, fmt.Errorf("일봉 조회 실패 [%s]: %w", stockCode, err)
}
s.cache.Set(cacheKey, candles, 5*time.Minute)
return candles, nil
}
// GetMinuteChart 분봉 데이터 조회 (30초 캐시 적용)
func (s *StockService) GetMinuteChart(stockCode string, minutes int) ([]models.CandleData, error) {
cacheKey := fmt.Sprintf("chart:minute%d:%s", minutes, stockCode)
if cached, ok := s.cache.Get(cacheKey); ok {
if candles, ok := cached.([]models.CandleData); ok {
return candles, nil
}
}
candles, err := s.kiwoom.GetMinuteChart(stockCode, minutes)
if err != nil {
return nil, fmt.Errorf("분봉 조회 실패 [%s]: %w", stockCode, err)
}
s.cache.Set(cacheKey, candles, 30*time.Second)
return candles, nil
}
// GetTopFluctuation 상위 등락률 종목 조회 (1분 캐시 적용)
func (s *StockService) GetTopFluctuation(market string, ascending bool, count int) ([]models.StockPrice, error) {
dir := "up"
if ascending {
dir = "down"
}
cacheKey := fmt.Sprintf("fluctuation:%s:%s:%d", market, dir, count)
if cached, ok := s.cache.Get(cacheKey); ok {
if stocks, ok := cached.([]models.StockPrice); ok {
return stocks, nil
}
}
stocks, err := s.kiwoom.GetTopFluctuation(market, ascending, count)
if err != nil {
return nil, fmt.Errorf("등락률 조회 실패: %w", err)
}
s.cache.Set(cacheKey, stocks, 1*time.Minute)
return stocks, nil
}