....
This commit is contained in:
@@ -237,7 +237,7 @@ object RagService {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processStock(currentPrice: Double, technicalAnalyzer: TechnicalAnalyzer, stockName: String, stockCode: String, result: TradingDecisionCallback) {
|
||||
suspend fun processStock(currentPrice: Double, technicalAnalyzer: TechnicalAnalyzer, stockName: String, stockCode: String, isWatering : Boolean, result: TradingDecisionCallback) {
|
||||
val totalStartTime = System.currentTimeMillis()
|
||||
|
||||
coroutineScope {
|
||||
@@ -246,6 +246,7 @@ object RagService {
|
||||
this.stockCode = stockCode
|
||||
this.analyzer = technicalAnalyzer
|
||||
this.currentPrice = currentPrice
|
||||
this.isWatering = isWatering
|
||||
}
|
||||
|
||||
if (isSafetyBeltStockCodes.contains(stockCode)) {
|
||||
@@ -277,8 +278,10 @@ object RagService {
|
||||
isSafetyBeltStockCodes.add(stockCode)
|
||||
return@coroutineScope
|
||||
}
|
||||
|
||||
if ((tradingDecision.signalModel?.compositeScore ?: 0) < 40) {
|
||||
val techScore = tradingDecision.signalModel?.compositeScore ?: 0
|
||||
// 🌟 신규 매수는 40점 컷오프, 물타기는 20점(또는 제한 없음)으로 하향
|
||||
val minTechCutoff = if (tradingDecision.isWatering) 15 else 40
|
||||
if (techScore < minTechCutoff) {
|
||||
logTime(stockName, "기술 점수 미달 조기 종료 ${tradingDecision.signalModel?.compositeScore} , ${tradingDecision.signalModel?.successProbPct} ", techDuration, System.currentTimeMillis() - totalStartTime)
|
||||
if (FinancialAnalyzer.isBuyConsiderationMet(financialStmt) && financialScore > 70) {
|
||||
TradingLogStore.addAnalyzer(stockName, stockCode, "매수 타점 미도달 (재무 우량주로 감시 지속)", true)
|
||||
@@ -487,9 +490,27 @@ object RagService {
|
||||
val synthStartTime = System.currentTimeMillis()
|
||||
val sysScore100 = calculateSystemPoint(scores) * 4.0
|
||||
|
||||
// 가중치 합성 (Tech 35% : Fin 25% : News 20% : Sys 20%)
|
||||
var finalConfidence = (finScore100 * 0.25) + (techScore100 * 0.25) + (newsScore100 * 0.30) + (sysScore100 * 0.20)
|
||||
// var finalConfidence = (finScore100 * 0.25) + (techScore100 * 0.35) + (newsScore100 * 0.20) + (sysScore100 * 0.20)
|
||||
val hasNews = tempDecision.newsContext != null && tempDecision.newsContext!!.isNotBlank()
|
||||
|
||||
var finalConfidence = if (hasNews) {
|
||||
// 뉴스가 있을 때: 원래 로직
|
||||
(finScore100 * 0.25) + (techScore100 * 0.25) + (newsScore100 * 0.30) + (sysScore100 * 0.20)
|
||||
} else {
|
||||
// 뉴스가 없을 때: 기술 45%, 재무 35%, 시스템 20%로 배분 (뉴스 영향력 제거)
|
||||
(finScore100 * 0.35) + (techScore100 * 0.45) + (sysScore100 * 0.20)
|
||||
}
|
||||
|
||||
if (tempDecision.isWatering) {
|
||||
// 물타기 대상이 여기까지 왔다는 건 '볼린저 하단 터치'나 '초과매도(RSI<35)' 등 바닥 확인이 끝났다는 뜻임.
|
||||
// 깎인 기술 점수를 보완하기 위해 강한 턴어라운드 기대 가점을 부여
|
||||
finalConfidence += 20.0
|
||||
|
||||
// 물타기 전용 등급 강제 상향 (잡주가 아니라는 전제 하에)
|
||||
if (finalConfidence >= KisSession.config.getValues(ConfigIndex.MIN_PURCHASE_SCORE_INDEX) * 0.8) {
|
||||
// 물타기 전용 등급(예: 신규 매수 로직에 안 잡히게 LEVEL_3 정도로 고정)
|
||||
tempDecision.investmentGrade = InvestmentGrade.LEVEL_3_CAUTIOUS_RECOMMEND
|
||||
}
|
||||
}
|
||||
|
||||
// 보너스 및 패널티 로직
|
||||
if (finScore100 >= 80.0 && techScore100 >= 70.0) finalConfidence += 8.0
|
||||
@@ -569,6 +590,7 @@ object RagService {
|
||||
this.stockName = stockName
|
||||
this.currentPrice = tempDecision.currentPrice
|
||||
this.techSummary = tempDecision.techSummary
|
||||
this.isWatering = tempDecision.isWatering
|
||||
this.ultraShortScore = scores.ultraShort.toDouble()
|
||||
this.shortTermScore = scores.shortTerm.toDouble()
|
||||
this.midTermScore = scores.midTerm.toDouble()
|
||||
|
||||
Reference in New Issue
Block a user