This commit is contained in:
2026-03-26 14:42:39 +09:00
parent af0dc6b15f
commit d6cfcbd579
7 changed files with 151 additions and 19 deletions
+60 -15
View File
@@ -5,6 +5,7 @@ import network.TradingDecision
import TradingLogStore
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import getLlamaBinPath
import kotlinx.coroutines.CoroutineScope
@@ -35,6 +36,7 @@ import network.KisTradeService
import network.KisWebSocketManager
import network.RagService
import network.StockUniverseLoader
import org.jetbrains.skia.ImageFilter
import util.MarketUtil
import java.time.LocalDateTime
import java.time.LocalTime
@@ -64,6 +66,12 @@ object AutoTradingManager {
private val reanalysisList = mutableListOf<RankingStock>()
private val retryCountMap = mutableMapOf<String, Int>()
var shouldShowFullWindow by mutableStateOf(false)
var llmAnalyser by mutableStateOf(false)
var llmNews by mutableStateOf(false)
var tradeToken by mutableStateOf(false)
var webSocketConnect by mutableStateOf(false)
fun startBackgroundScheduler() {
// scope.launch {
// while (isActive) {
@@ -123,15 +131,15 @@ object AutoTradingManager {
var investmentGrade : InvestmentGrade = AutoTradingManager.getInvestmentGrade(completeTradingDecision,totalScore, completeTradingDecision.confidence)
val finalMargin = baseProfit * KisSession.config.getValues(investmentGrade.profitGuide)
println("""
사명 : ${completeTradingDecision.corpName}
신뢰도 : ${completeTradingDecision.confidence + append}
단기성 : ${completeTradingDecision.shortPossible() + append}
수익성 : ${completeTradingDecision.profitPossible()+ append}
안전성 : ${completeTradingDecision.safePossible()+ append}
${investmentGrade.displayName} : ${investmentGrade.description}
총점 : ${totalScore}
""".trimIndent())
// println("""
// 사명 : ${completeTradingDecision.corpName}
// 신뢰도 : ${completeTradingDecision.confidence + append}
// 단기성 : ${completeTradingDecision.shortPossible() + append}
// 수익성 : ${completeTradingDecision.profitPossible()+ append}
// 안전성 : ${completeTradingDecision.safePossible()+ append}
// ${investmentGrade.displayName} : ${investmentGrade.description}
// 총점 : ${totalScore}
// """.trimIndent())
println("🚀 [매수 진행] 토탈 스코어: ${String.format("%.1f", totalScore)} -> 종목: ${completeTradingDecision.stockCode}")
// basePrice(현재가 혹은 지정가)를 기준으로 매수 가능 수량 산출 (최소 1주 보장)
@@ -167,7 +175,10 @@ object AutoTradingManager {
TradingLogStore.addLog(completeTradingDecision,"BUY","[$stockCode] 매수 추천 resultCheck: ${completeTradingDecision?.reason}")
resultCheck(completeTradingDecision)
}
"SELL" -> println("[$stockCode] 매도: ${completeTradingDecision?.reason}")
"SELL" -> {
TradingLogStore.addLog(completeTradingDecision,"SELL","[$stockCode] 매도 추천 resultCheck: ${completeTradingDecision?.reason}")
println("[$stockCode] 매도: ${completeTradingDecision?.reason}")
}
"HOLD" -> {
append = 0.0
TradingLogStore.addLog(completeTradingDecision,"HOLD","[$stockCode] 관망 유지 resultCheck: ${completeTradingDecision?.reason}")
@@ -830,6 +841,40 @@ object FinancialAnalyzer {
return highProfitability && strongGrowth && verySafeDebt && goodLiquidity && businessHealthy
}
fun toString(fs : FinancialStatement): String {
var buffer = StringBuffer()
val isDebtSafe = fs.debtRatio < 200.0 // 부채비율 200% 미만
val isLiquiditySafe = fs.quickRatio > 80.0 // 당좌비율 80% 이상
val isNotDeficit = fs.isNetIncomePositive // 당기순이익은 일단 흑자여야 함
if ((isDebtSafe && isLiquiditySafe && isNotDeficit) == false) {
if (isDebtSafe)buffer.appendLine( "부채비율 200% 이상")
if (isLiquiditySafe)buffer.appendLine( "당좌비율 80% 미만")
if (isNotDeficit)buffer.appendLine( "당기순이익 적자")
buffer.appendLine("최소 기준 미달")
} else {
buffer.appendLine("최소 기준 충족")
}
val highProfitability = fs.roe >= 10.0 // ROE 10% 이상
val strongGrowth = fs.netIncomeGrowth >= 15.0 // 이익 성장률 15% 이상
val verySafeDebt = fs.debtRatio <= 100.0 // 부채비율 100% 이하 (안전)
val goodLiquidity = fs.quickRatio >= 120.0 // 당좌비율 120% 이상 (여유)
val businessHealthy = fs.isOperatingProfitPositive // 본업(영업이익)이 흑자
if ((highProfitability && strongGrowth && verySafeDebt && goodLiquidity && businessHealthy) == false) {
if(!highProfitability) buffer.appendLine( "ROE 10% 미만")
if(!strongGrowth) buffer.appendLine( "이익 성장률 15% 미만")
if(!verySafeDebt) buffer.appendLine( "부채비율 100% 이상 (안전성 미달)")
if(!goodLiquidity) buffer.appendLine( "당좌비율 120% 이하 (여유 없음)")
if(!businessHealthy) buffer.appendLine( "본업(영업이익)이 적자")
buffer.appendLine("재무 건전성 및 성장성 미달")
} else {
buffer.appendLine("재무 건전성 및 성장성 충족")
}
return buffer.toString()
}
/**
* 종합 상태 반환 (UI 또는 로그용)
*/
@@ -881,11 +926,11 @@ data class InvestmentScores(
) {
override fun toString(): String {
return """
AVG : ${avg()}
ultraShort : $ultraShort
shortTerm : $shortTerm
midTerm : $midTerm
longTerm : $longTerm
평점 : ${avg()}
초단 : $ultraShort
단기 : $shortTerm
중기 : $midTerm
장기 : $longTerm
""".trimIndent()
}
@@ -106,6 +106,12 @@ object LlamaServerManager {
// println("[Server $port] $line")
if (line?.contains("server is listening") == true) {
println("🚀 AI 서버 준비 완료 (Port: $port)")
if (port == 8080){
AutoTradingManager.llmAnalyser = true
}
if (port == 8081){
AutoTradingManager.llmNews = true
}
if (processes.size > 1) {
println("[Cache] ${processes.size}")
RagService.active()