From 9ff088bf6bdd2fe8e507fa471afd7a30eb5c3e70 Mon Sep 17 00:00:00 2001 From: lunaticbum Date: Thu, 26 Mar 2026 15:27:34 +0900 Subject: [PATCH] .. --- src/main/kotlin/database/DatabaseFactory.kt | 4 +- src/main/kotlin/network/RagService.kt | 2 +- src/main/kotlin/ui/IntegratedOrderSection.kt | 4 +- src/main/kotlin/ui/TradingDecisionLog.kt | 40 ++++++++++++++++---- 4 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/database/DatabaseFactory.kt b/src/main/kotlin/database/DatabaseFactory.kt index 006cce8..dc7b44e 100644 --- a/src/main/kotlin/database/DatabaseFactory.kt +++ b/src/main/kotlin/database/DatabaseFactory.kt @@ -448,14 +448,14 @@ object TradingLogStore { } } - fun addAnalyzer(name : String, code : String, log: String) { + fun addAnalyzer(name : String, code : String, log: String, positive : Boolean = false) { synchronized(this) { if (decisionLogs.size > 1000) decisionLogs.removeAt(0) decisionLogs.add( LogEntry( time = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")), stockName = "$name[$code] 분석", - decision = "ANALYZER", + decision = if(positive) "ANALYZER" else "PASS", confidence = 100.0, reason = log ) diff --git a/src/main/kotlin/network/RagService.kt b/src/main/kotlin/network/RagService.kt index ecd42de..bede04e 100644 --- a/src/main/kotlin/network/RagService.kt +++ b/src/main/kotlin/network/RagService.kt @@ -215,7 +215,7 @@ object RagService { ) tradingDecision.newsContext = searchResult.matches().joinToString("\n") { it.embedded().text() } result(tradingDecision, false) - TradingLogStore.addAnalyzer(stockName,stockCode, "${FinancialAnalyzer.toString(financialStmt)}${scores.toString()}") + TradingLogStore.addAnalyzer(stockName,stockCode, "${FinancialAnalyzer.toString(financialStmt)}${scores.toString()}",true) println("${stockName}[${stockCode}] : ${FinancialAnalyzer.toString(financialStmt)}${scores.toString()}") result(decideTrading(stockCode, scores, financialStmt, tradingDecision), true) } else { diff --git a/src/main/kotlin/ui/IntegratedOrderSection.kt b/src/main/kotlin/ui/IntegratedOrderSection.kt index 0980b72..59467ce 100644 --- a/src/main/kotlin/ui/IntegratedOrderSection.kt +++ b/src/main/kotlin/ui/IntegratedOrderSection.kt @@ -271,7 +271,9 @@ fun IntegratedOrderSection( println("[$stockCode] 매수 추천 resultCheck: ${completeTradingDecision?.reason}") resultCheck(completeTradingDecision) } - "SELL" -> println("[$stockCode] 매도: ${completeTradingDecision?.reason}") + "SELL" -> { + println("[$stockCode] 매도: ${completeTradingDecision?.reason}") + } "HOLD" -> { append = 0.0 resultCheck(completeTradingDecision) diff --git a/src/main/kotlin/ui/TradingDecisionLog.kt b/src/main/kotlin/ui/TradingDecisionLog.kt index 5a62c43..557a7d9 100644 --- a/src/main/kotlin/ui/TradingDecisionLog.kt +++ b/src/main/kotlin/ui/TradingDecisionLog.kt @@ -30,8 +30,8 @@ import service.AutoTradingManager @Composable fun TradingDecisionLog() { var searchQuery by remember { mutableStateOf("") } - var selectedFilter by remember { mutableStateOf("전체") } - val filterOptions = listOf("전체", "BUY", "SELL", "HOLD", "SETTING","ANALYZER") + var selectedFilters by remember { mutableStateOf(setOf("전체")) } + val filterOptions = listOf("전체", "BUY", "SELL", "HOLD", "SETTING","ANALYZER","PASS") var llmAnalyser by remember { mutableStateOf(AutoTradingManager.llmAnalyser) } LaunchedEffect(AutoTradingManager.llmAnalyser) { llmAnalyser = AutoTradingManager.llmAnalyser @@ -52,7 +52,11 @@ fun TradingDecisionLog() { // [핵심] 원본 로그에서 필터 조건에 맞는 리스트만 산출 val filteredLogs = TradingLogStore.decisionLogs.filter { log -> - val matchesType = if (selectedFilter == "전체") true else log.decision == selectedFilter + val matchesType = if (selectedFilters.contains("전체")) { + true + } else { + selectedFilters.contains(log.decision) + } val matchesQuery = log.stockName.contains(searchQuery, ignoreCase = true) || log.reason.contains(searchQuery, ignoreCase = true) matchesType && matchesQuery @@ -88,10 +92,31 @@ fun TradingDecisionLog() { // 2. 필터 버튼 그룹 (Chip 형태) Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) { filterOptions.forEach { option -> - val isSelected = selectedFilter == option + val isSelected = selectedFilters.contains(option) FilterChip( selected = isSelected, - onClick = { selectedFilter = option }, + onClick = { + val newFilters = selectedFilters.toMutableSet() + if (option == "전체") { + // "전체" 클릭 시 나머지는 다 지우고 전체만 남김 + newFilters.clear() + newFilters.add("전체") + } else { + // 다른 필터 클릭 시 + newFilters.remove("전체") + if (newFilters.contains(option)) { + newFilters.remove(option) + } else { + newFilters.add(option) + } + + // 만약 아무것도 선택 안 된 상태라면 다시 "전체" 선택 + if (newFilters.isEmpty()) { + newFilters.add("전체") + } + } + selectedFilters = newFilters + }, colors = ChipDefaults.filterChipColors( selectedBackgroundColor = Color(0xFF0E62CF), selectedContentColor = Color.White @@ -121,9 +146,10 @@ fun TradingDecisionLog() { "BUY" -> Color.Red "SETTING" -> Color(0xFFFFA500) "SELL" -> Color(0xFF800080) - "HOLD" -> Color.Gray + "HOLD" -> Color.DarkGray "ANALYZER" -> Color.Green - else -> Color.Gray + "PASS" -> Color.Yellow + else -> Color.DarkGray }, fontWeight = FontWeight.ExtraBold )