package util import network.KisTradeService import java.time.LocalTime import java.time.ZoneId object MarketUtil { private var isHolidayCached: Boolean? = null // 하루 한 번만 체크하기 위한 캐시 var holiDays = hashMapOf() suspend fun canTradeToday(): Boolean { val seoulZone = java.time.ZoneId.of("Asia/Seoul") val now = java.time.ZonedDateTime.now(seoulZone) val todayStr = now.format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMdd")) // 1. 주말 체크 val dayOfWeek = now.dayOfWeek.value if (dayOfWeek >= 6) return false // 1. 주말 체크 (토, 일) try { if (holiDays.contains(todayStr)) { println("📂 [DB Cache] 오늘($todayStr)의 휴장 여부를 DB에서 로드했습니다: ${if(holiDays.get(todayStr) == true) "휴장" else "영업일"}") return holiDays.get(todayStr) == false } } catch (e: Exception) {e.printStackTrace()} // 3. DB에 없으면 API 호출 return try { val result = KisTradeService.fetchIsHoliday(todayStr) val isHoliday = result.getOrDefault(true) // 결과를 DB에 저장하여 다음 실행 시 재사용 holiDays.put(todayStr, isHoliday) println("🌐 [API Call] 오늘($todayStr)의 휴장 여부를 새로 조회하여 DB에 저장했습니다.") isHoliday } catch (e: Exception) { e.printStackTrace() false } } fun isKoreanMarketOpen(): Boolean { // 한국 시간대 기준 현재 시간 가져오기 val now = LocalTime.now(ZoneId.of("Asia/Seoul")) val start = LocalTime.of(9, 0) val end = LocalTime.of(15, 30) // 주말 제외 로직은 필요시 추가 (일단 시간대 우선) return now.isAfter(start) && now.isBefore(end) } fun getTickSize(price: Double): Double { return when { price < 2000 -> 1.0 price < 5000 -> 5.0 price < 20000 -> 10.0 price < 50000 -> 50.0 price < 200000 -> 100.0 price < 500000 -> 500.0 else -> 1000.0 } } fun roundToTickSize(price: Double): Double { val tick = when { price < 2000 -> 1.0 price < 5000 -> 5.0 price < 20000 -> 10.0 price < 50000 -> 50.0 price < 200000 -> 100.0 price < 500000 -> 500.0 else -> 1000.0 } // 가장 가까운 호가 단위로 반올림 return Math.round(price / tick) * tick } }