...
This commit is contained in:
@@ -201,16 +201,6 @@ object RagService {
|
||||
println("⏱️ [$stockName] 재무 분석 소요: ${financialDuration}ms")
|
||||
|
||||
if (FinancialAnalyzer.isSafetyBeltMet(financialStmt)) {
|
||||
// 2. 뉴스 스크래핑 및 학습 시간 측정
|
||||
val newsIngestStartTime = System.currentTimeMillis()
|
||||
corpInfo?.let {
|
||||
try {
|
||||
NewsService.fetchAndIngestNews(it)
|
||||
} catch (e: Exception) {}
|
||||
}
|
||||
val newsIngestDuration = System.currentTimeMillis() - newsIngestStartTime
|
||||
println("⏱️ [$stockName] 뉴스 수집/인덱싱 소요: ${newsIngestDuration}ms")
|
||||
|
||||
// 3. 기술적 지표 계산 시간 측정
|
||||
val techStartTime = System.currentTimeMillis()
|
||||
val financialScore = FinancialAnalyzer.calculateScore(financialStmt)
|
||||
@@ -218,6 +208,16 @@ object RagService {
|
||||
val techDuration = System.currentTimeMillis() - techStartTime
|
||||
println("⏱️ [$stockName] 기술적 지표 계산 소요: ${techDuration}ms")
|
||||
if (scores.avg() > 50) {
|
||||
// 2. 뉴스 스크래핑 및 학습 시간 측정
|
||||
val newsIngestStartTime = System.currentTimeMillis()
|
||||
corpInfo?.let {
|
||||
try {
|
||||
NewsService.fetchAndIngestNews(it)
|
||||
} catch (e: Exception) {}
|
||||
}
|
||||
val newsIngestDuration = System.currentTimeMillis() - newsIngestStartTime
|
||||
println("⏱️ [$stockName] 뉴스 수집/인덱싱 소요: ${newsIngestDuration}ms")
|
||||
|
||||
result(tradingDecision, false)
|
||||
tradingDecision.techSummary = technicalAnalyzer.generateComprehensiveReport()
|
||||
result(tradingDecision, false)
|
||||
@@ -566,4 +566,84 @@ confidence: $confidence
|
||||
재무재표: $financialData
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
object FinancialMapper {
|
||||
/**
|
||||
* 제공된 텍스트 데이터를 파싱하여 FinancialStatement 객체로 변환
|
||||
*/
|
||||
fun mapRawTextToStatement(rawText: String): FinancialStatement {
|
||||
if (rawText.isBlank()) {
|
||||
return FinancialStatement()
|
||||
}
|
||||
// println(rawText)
|
||||
val currentValues = extractYearlyValues(rawText, "당기")
|
||||
val previousValues = extractYearlyValues(rawText, "전기")
|
||||
|
||||
// 1. 영업이익 증가율: (당기 - 전기) / |전기| * 100
|
||||
val opCurrent = currentValues["영업이익"] ?: 0.0
|
||||
val opPrevious = previousValues["영업이익"] ?: 0.0
|
||||
val opGrowth = if (opPrevious != 0.0) ((opCurrent - opPrevious) / Math.abs(opPrevious)) * 100 else 0.0
|
||||
|
||||
// 2. 당기순이익 증가율
|
||||
val niCurrent = currentValues["당기순이익(손실)"] ?: 0.0
|
||||
val niPrevious = previousValues["당기순이익(손실)"] ?: 0.0
|
||||
val niGrowth = if (niPrevious != 0.0) ((niCurrent - niPrevious) / Math.abs(niPrevious)) * 100 else 0.0
|
||||
|
||||
// 3. ROE: 당기순이익 / 당기 자본총계 * 100
|
||||
val equityCurrent = currentValues["자본총계"] ?: 1.0
|
||||
val roe = (niCurrent / equityCurrent) * 100
|
||||
|
||||
// 4. 부채비율: 당기 부채총계 / 당기 자본총계 * 100
|
||||
val debtCurrent = currentValues["부채총계"] ?: 0.0
|
||||
val debtRatio = (debtCurrent / equityCurrent) * 100
|
||||
|
||||
// 5. 당좌비율(유동성): 당기 유동자산 / 당기 유동부채 * 100
|
||||
val currentAssets = currentValues["유동자산"] ?: 0.0
|
||||
val currentLiabilities = currentValues["유동부채"] ?: 1.0
|
||||
val quickRatio = (currentAssets / currentLiabilities) * 100
|
||||
|
||||
return FinancialStatement(
|
||||
operatingProfitGrowth = opGrowth,
|
||||
netIncomeGrowth = niGrowth,
|
||||
roe = roe,
|
||||
debtRatio = debtRatio,
|
||||
quickRatio = quickRatio,
|
||||
isOperatingProfitPositive = opCurrent > 0,
|
||||
isNetIncomePositive = niCurrent > 0
|
||||
).apply {
|
||||
println("당기순이익: ${niCurrent} , isSafetyBeltMet ${FinancialAnalyzer.isSafetyBeltMet(this)}")
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
// 숫자 내 쉼표 제거 후 Double 변환
|
||||
val rawValue = match.groupValues[2].replace(",", "").toDoubleOrNull() ?: 0.0
|
||||
result[key] = rawValue
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@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
|
||||
)
|
||||
Reference in New Issue
Block a user