package analyzer import kotlin.compareTo object FinancialAnalyzer { /** * [매수 고려] 우량 기업 요건 확인 * 모든 조건 충족 시 적극적인 분석(AI/차트) 단계로 진입합니다. */ fun isSafetyBeltMet(fs: FinancialStatement): Boolean { // 1. 유동성 위기 체크 (이건 유지하는 것이 좋습니다) val isDebtSafe = fs.debtRatio < 300.0 // 200% -> 300%로 완화 val isLiquiditySafe = fs.quickRatio > 60.0 // 80% -> 60%로 완화 (급전이 필요한 수준만 차단) // 2. 턴어라운드 허용 (적자여도 개선 중이면 통과) val isTurningAround = !fs.isNetIncomePositive && fs.operatingProfitGrowth > 50.0 val isNotFatalDeficit = fs.isNetIncomePositive || isTurningAround // 3. 상장폐지 요건 중심 필터 val isNotCapitalImpaired = fs.capitalImpairmentRate < 50.0 // 자본잠식 50% 이상 차단 val isNotLossExploding = fs.lossToSalesRatio < 150.0 // 매출보다 손실이 너무 크면 차단 // 최종: 정말 위험한 경우가 아니면 분석 단계(AI/뉴스)로 보냄 return isDebtSafe && isLiquiditySafe && isNotFatalDeficit && isNotCapitalImpaired } 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 // 당기순이익은 일단 흑자여야 함 val isNotCrashing = fs.netIncomeGrowth > -40.0 if ((isDebtSafe && isLiquiditySafe && isNotDeficit) == false) { if (!isDebtSafe)buffer.appendLine( "부채비율 200% 이상") if (!isLiquiditySafe)buffer.appendLine( "당좌비율 80% 미만") if (!isNotDeficit)buffer.appendLine( "당기순이익 적자") if (!isNotCrashing) { buffer.appendLine("당기순이익 급감(${String.format("%.1f", fs.netIncomeGrowth)}%)") } 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() } fun calculateScore(fs: FinancialStatement): Int { var score = 50.0 // 중립 시작 // 1. 수익성 및 성장 추세 (Max 50) score += when { fs.isOperatingProfitPositive && fs.operatingProfitGrowth > 20.0 -> 30.0 // 우량 성장 fs.isOperatingProfitPositive && fs.operatingProfitGrowth < -30.0 -> -20.0 // 쇠퇴 위험 !fs.isOperatingProfitPositive && fs.operatingProfitGrowth > 50.0 -> 20.0 // 턴어라운드 신호 !fs.isOperatingProfitPositive && fs.operatingProfitGrowth < -20.0 -> -30.0 // 적자 심화 else -> 0.0 } // 2. 수익 효율 ROE (Max 30) score += (fs.roe.coerceIn(-20.0, 20.0) * 1.5) // 3. 안정성 (Max 20) if (fs.debtRatio <= 100.0) score += 20.0 else if (fs.debtRatio <= 150.0) score += 10.0 // 4. 감점 페널티 (위험 징후 시 최대 -50) if (fs.capitalImpairmentRate > 20.0) score -= 30.0 if (fs.debtAccelerationRate > 100.0) score -= 20.0 return score.coerceIn(0.0, 100.0).toInt() } /** * 상황별 상태 메시지 정교화 */ fun getInvestmentStatus(fs: FinancialStatement): String { return when { fs.isOperatingProfitPositive && fs.operatingProfitGrowth > 10.0 -> "🚀 [성장중] 실적 개선세 뚜렷" !fs.isOperatingProfitPositive && fs.operatingProfitGrowth > 40.0 -> "☀️ [회복중] 적자폭 급감, 턴어라운드 가시화" fs.isOperatingProfitPositive && fs.operatingProfitGrowth < -40.0 -> "⚠️ [쇠퇴중] 이익 급감, 적자전환 유의" else -> "🚨 [부실] 재무 구조 악화 지속" } } } object FinancialAnalyzer2 { fun isSafetyBeltMet(fs: FinancialStatement): Boolean { val isDebtSafe = fs.debtRatio < 200.0 // 부채비율 200% 미만 val isLiquiditySafe = fs.quickRatio > 80.0 // 당좌비율 80% 이상 val isNotDeficit = fs.isNetIncomePositive // 당기순이익은 일단 흑자여야 함 val isNotCrashing = fs.netIncomeGrowth > -40.0 return isDebtSafe && isLiquiditySafe && isNotDeficit && isNotCrashing } /** * [매수 고려] 우량 기업 요건 확인 * 모든 조건 충족 시 적극적인 분석(AI/차트) 단계로 진입합니다. */ fun isBuyConsiderationMet(fs: FinancialStatement): Boolean { 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 // 본업(영업이익)이 흑자 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 // 당기순이익은 일단 흑자여야 함 val isNotCrashing = fs.netIncomeGrowth > -40.0 if ((isDebtSafe && isLiquiditySafe && isNotDeficit) == false) { if (!isDebtSafe)buffer.appendLine( "부채비율 200% 이상") if (!isLiquiditySafe)buffer.appendLine( "당좌비율 80% 미만") if (!isNotDeficit)buffer.appendLine( "당기순이익 적자") if (!isNotCrashing) { buffer.appendLine("당기순이익 급감(${String.format("%.1f", fs.netIncomeGrowth)}%)") } 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 또는 로그용) */ fun getInvestmentStatus(fs: FinancialStatement): String { return when { isBuyConsiderationMet(fs) -> "🚀 [매수 검토 권장] 재무 건전성 및 성장성 우수" isSafetyBeltMet(fs) -> "⚖️ [관망/보류] 생존 요건은 충족하나 성장성 부족" else -> "🚨 [위험/제외] 재무 안정성 미달 또는 적자 기업" } } fun calculateScore(fs: FinancialStatement): Int { var score = 50.0 // 기본 점수 // 성장성 (영업이익 증가율) score += when { fs.operatingProfitGrowth > 20 -> 20 fs.operatingProfitGrowth > 0 -> 10 else -> -10 // 역성장 시 감점 } // 수익성 (ROE) score += when { fs.roe > 15 -> 15 fs.roe > 5 -> 5 fs.roe < 0 -> -15 // 적자 시 큰 감점 else -> 0 } // 안정성 (부채비율) score += when { fs.debtRatio < 100 -> 15 fs.debtRatio < 200 -> 5 else -> -10 } // 유동성 (당좌비율) if (fs.quickRatio < 100) score -= 10 // 단기 채무 지급 능력 부족 시 감점 return score.coerceIn(0.0, 100.0).toInt() } }