This commit is contained in:
lunaticbum 2026-03-26 15:27:34 +09:00
parent d6cfcbd579
commit 9ff088bf6b
4 changed files with 39 additions and 11 deletions

View File

@ -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) { synchronized(this) {
if (decisionLogs.size > 1000) decisionLogs.removeAt(0) if (decisionLogs.size > 1000) decisionLogs.removeAt(0)
decisionLogs.add( decisionLogs.add(
LogEntry( LogEntry(
time = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")), time = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")),
stockName = "$name[$code] 분석", stockName = "$name[$code] 분석",
decision = "ANALYZER", decision = if(positive) "ANALYZER" else "PASS",
confidence = 100.0, confidence = 100.0,
reason = log reason = log
) )

View File

@ -215,7 +215,7 @@ object RagService {
) )
tradingDecision.newsContext = searchResult.matches().joinToString("\n") { it.embedded().text() } tradingDecision.newsContext = searchResult.matches().joinToString("\n") { it.embedded().text() }
result(tradingDecision, false) 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()}") println("${stockName}[${stockCode}] : ${FinancialAnalyzer.toString(financialStmt)}${scores.toString()}")
result(decideTrading(stockCode, scores, financialStmt, tradingDecision), true) result(decideTrading(stockCode, scores, financialStmt, tradingDecision), true)
} else { } else {

View File

@ -271,7 +271,9 @@ fun IntegratedOrderSection(
println("[$stockCode] 매수 추천 resultCheck: ${completeTradingDecision?.reason}") println("[$stockCode] 매수 추천 resultCheck: ${completeTradingDecision?.reason}")
resultCheck(completeTradingDecision) resultCheck(completeTradingDecision)
} }
"SELL" -> println("[$stockCode] 매도: ${completeTradingDecision?.reason}") "SELL" -> {
println("[$stockCode] 매도: ${completeTradingDecision?.reason}")
}
"HOLD" -> { "HOLD" -> {
append = 0.0 append = 0.0
resultCheck(completeTradingDecision) resultCheck(completeTradingDecision)

View File

@ -30,8 +30,8 @@ import service.AutoTradingManager
@Composable @Composable
fun TradingDecisionLog() { fun TradingDecisionLog() {
var searchQuery by remember { mutableStateOf("") } var searchQuery by remember { mutableStateOf("") }
var selectedFilter by remember { mutableStateOf("전체") } var selectedFilters by remember { mutableStateOf(setOf("전체")) }
val filterOptions = listOf("전체", "BUY", "SELL", "HOLD", "SETTING","ANALYZER") val filterOptions = listOf("전체", "BUY", "SELL", "HOLD", "SETTING","ANALYZER","PASS")
var llmAnalyser by remember { mutableStateOf(AutoTradingManager.llmAnalyser) } var llmAnalyser by remember { mutableStateOf(AutoTradingManager.llmAnalyser) }
LaunchedEffect(AutoTradingManager.llmAnalyser) { LaunchedEffect(AutoTradingManager.llmAnalyser) {
llmAnalyser = AutoTradingManager.llmAnalyser llmAnalyser = AutoTradingManager.llmAnalyser
@ -52,7 +52,11 @@ fun TradingDecisionLog() {
// [핵심] 원본 로그에서 필터 조건에 맞는 리스트만 산출 // [핵심] 원본 로그에서 필터 조건에 맞는 리스트만 산출
val filteredLogs = TradingLogStore.decisionLogs.filter { log -> 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) || val matchesQuery = log.stockName.contains(searchQuery, ignoreCase = true) ||
log.reason.contains(searchQuery, ignoreCase = true) log.reason.contains(searchQuery, ignoreCase = true)
matchesType && matchesQuery matchesType && matchesQuery
@ -88,10 +92,31 @@ fun TradingDecisionLog() {
// 2. 필터 버튼 그룹 (Chip 형태) // 2. 필터 버튼 그룹 (Chip 형태)
Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) { Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) {
filterOptions.forEach { option -> filterOptions.forEach { option ->
val isSelected = selectedFilter == option val isSelected = selectedFilters.contains(option)
FilterChip( FilterChip(
selected = isSelected, 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( colors = ChipDefaults.filterChipColors(
selectedBackgroundColor = Color(0xFF0E62CF), selectedBackgroundColor = Color(0xFF0E62CF),
selectedContentColor = Color.White selectedContentColor = Color.White
@ -121,9 +146,10 @@ fun TradingDecisionLog() {
"BUY" -> Color.Red "BUY" -> Color.Red
"SETTING" -> Color(0xFFFFA500) "SETTING" -> Color(0xFFFFA500)
"SELL" -> Color(0xFF800080) "SELL" -> Color(0xFF800080)
"HOLD" -> Color.Gray "HOLD" -> Color.DarkGray
"ANALYZER" -> Color.Green "ANALYZER" -> Color.Green
else -> Color.Gray "PASS" -> Color.Yellow
else -> Color.DarkGray
}, },
fontWeight = FontWeight.ExtraBold fontWeight = FontWeight.ExtraBold
) )