atrade/src/main/kotlin/analyzer/FinancialMapper.kt

75 lines
3.2 KiB
Kotlin
Raw Normal View History

2026-04-07 17:32:21 +09:00
package analyzer
import kotlinx.serialization.Serializable
import kotlin.Double
import kotlin.math.abs
@Serializable
data class FinancialStatement(
val revenueGrowth: Double = 0.0, // 매출액 증가율
val operatingProfitGrowth: Double = 0.0, // 영업이익 증가율
val netIncomeGrowth: Double = 0.0, // 당기순이익 증가율
val roe: Double = 0.0, // ROE
val debtRatio: Double = 0.0, // 부채비율
val quickRatio: Double = 0.0, // 당좌비율
val isOperatingProfitPositive: Boolean = false, // 당기 영업이익 흑자 여부
val isNetIncomePositive: Boolean = false,
val capitalImpairmentRate: Double = 0.0,
val debtAccelerationRate: Double = 0.0,
val lossToSalesRatio: Double = 0.0
)
object FinancialMapper {
fun mapRawTextToStatement(rawText: String): FinancialStatement {
if (rawText.isBlank()) return FinancialStatement()
val current = extractYearlyValues(rawText, "당기")
val previous = extractYearlyValues(rawText, "전기")
// 기본 수치 추출
val opCurrent = current["영업이익"] ?: 0.0
val opPrevious = previous["영업이익"] ?: 0.0
val salesCurrent = current["매출액"] ?: 1.0
val niCurrent = current["당기순이익(손실)"] ?: 0.0
val equityCurrent = current["자본총계"] ?: 1.0
val capitalStock = current["자본금"] ?: 1.0
val debtCurrent = current["부채총계"] ?: 0.0
val debtPrevious = previous["부채총계"] ?: 1.0
val currentAssets = current["유동자산"] ?: 0.0
val currentLiabilities = current["유동부채"] ?: 1.0
// [강화] 자본잠식률: (자본금 - 자본총계) / 자본금
val capitalImpairment = (capitalStock - equityCurrent) / capitalStock * 100
// [강화] 부채 가속도: 전년 대비 부채 증가율
val debtAcceleration = ((debtCurrent - debtPrevious) / debtPrevious) * 100
// [강화] 매출 대비 영업손실률
val lossToSalesRatio = if (opCurrent < 0) (abs(opCurrent) / salesCurrent) * 100 else 0.0
return FinancialStatement(
operatingProfitGrowth = if (opPrevious != 0.0) ((opCurrent - opPrevious) / abs(opPrevious)) * 100 else 0.0,
roe = (niCurrent / equityCurrent) * 100,
debtRatio = (debtCurrent / equityCurrent) * 100,
quickRatio = (currentAssets / currentLiabilities) * 100,
isOperatingProfitPositive = opCurrent > 0,
isNetIncomePositive = niCurrent > 0,
// 추가된 정교화 지표
capitalImpairmentRate = capitalImpairment,
debtAccelerationRate = debtAcceleration,
lossToSalesRatio = lossToSalesRatio
)
}
private fun extractYearlyValues(text: String, type: String): Map<String, Double> {
val result = mutableMapOf<String, Double>()
val regex = Regex("""([가-힣\s()]+)\s\($type\)([-0-9,.]+)""")
regex.findAll(text).forEach { match ->
val key = match.groupValues[1].trim()
val rawValue = match.groupValues[2].replace(",", "").toDoubleOrNull() ?: 0.0
result[key] = rawValue
}
return result
}
}