....
This commit is contained in:
@@ -102,93 +102,119 @@ object AutoTradingManager {
|
||||
}
|
||||
}
|
||||
|
||||
val globalCallback = { completeTradingDecision: TradingDecision?, isSuccess: Boolean ->
|
||||
if (isSuccess && completeTradingDecision != null) {
|
||||
// 1. 로그 저장소에 기록 (UI에서 이걸 읽음)
|
||||
TradingLogStore.addLog(completeTradingDecision)
|
||||
// val globalCallback = { completeTradingDecision: TradingDecision?, isSuccess: Boolean ->
|
||||
// if (isSuccess && completeTradingDecision != null) {
|
||||
// // 1. 로그 저장소에 기록 (UI에서 이걸 읽음)
|
||||
// TradingLogStore.addLog(completeTradingDecision)
|
||||
//
|
||||
// println("🚀 [자동매수 실행] ${completeTradingDecision.stockName}")
|
||||
// if (completeTradingDecision.confidence < 10) {
|
||||
// addToReanalysis(RankingStock(mksc_shrn_iscd = completeTradingDecision.stockCode,hts_kor_isnm = completeTradingDecision.stockName))
|
||||
// TradingLogStore.addLog(completeTradingDecision,"RETRY","분석 신뢰도 오류 인지로 재분석 대기열에 추가")
|
||||
// }else if (completeTradingDecision != null && !completeTradingDecision.stockCode.isNullOrEmpty()) {
|
||||
// var basePrice = completeTradingDecision.currentPrice
|
||||
// var stockCode = completeTradingDecision.stockCode
|
||||
// println("basePrice $basePrice")
|
||||
// val minScore = KisSession.config.getValues(ConfigIndex.MIN_PURCHASE_SCORE_INDEX)
|
||||
// var maxBudget = KisSession.config.getValues(ConfigIndex.MAX_BUDGET_INDEX)
|
||||
// val buyWeight = KisSession.config.getValues(ConfigIndex.BUY_WEIGHT_INDEX)
|
||||
// val baseProfit = KisSession.config.getValues(ConfigIndex.PROFIT_INDEX)
|
||||
//
|
||||
// fun resultCheck(completeTradingDecision :TradingDecision) {
|
||||
// val weights = mapOf(
|
||||
// "short" to 0.2, // 초단기 점수가 낮아도 전체에 미치는 영향 감소
|
||||
// "profit" to 0.4,
|
||||
// "safe" to 0.4 // 중장기 점수 비중 강화
|
||||
// )
|
||||
//
|
||||
// val totalScore =
|
||||
// ((completeTradingDecision.shortPossible() + append) * weights["short"]!!) +
|
||||
// ((completeTradingDecision.profitPossible() + append) * weights["profit"]!!) +
|
||||
// ((completeTradingDecision.safePossible() + append) * weights["safe"]!!)
|
||||
//
|
||||
// if (totalScore >= minScore && completeTradingDecision.confidence >= MIN_CONFIDENCE) {
|
||||
// var investmentGrade = completeTradingDecision.investmentGrade ?: InvestmentGrade.LEVEL_1_SPECULATIVE
|
||||
//
|
||||
// val finalMargin = baseProfit * KisSession.config.getValues(investmentGrade.profitGuide)
|
||||
// println("🚀 [매수 진행] 토탈 스코어: ${String.format("%.1f", totalScore)} -> 종목: ${completeTradingDecision.stockCode}")
|
||||
//
|
||||
// // basePrice(현재가 혹은 지정가)를 기준으로 매수 가능 수량 산출 (최소 1주 보장)
|
||||
// val gradeRate = KisSession.config.getValues(investmentGrade.allocationRate)
|
||||
// val maxQty = (KisSession.config.getValues(ConfigIndex.MAX_COUNT_INDEX) * gradeRate).roundToInt()
|
||||
// maxBudget = maxBudget * gradeRate
|
||||
// val calculatedQty = if (basePrice > 0) {
|
||||
// (maxBudget / basePrice).toInt().coerceAtLeast(1)
|
||||
// } else {
|
||||
// 1
|
||||
// }
|
||||
// // 5. 매수 실행 (계산된 finalMargin 전달)
|
||||
// excuteTrade(
|
||||
// decision = completeTradingDecision,
|
||||
// orderQty = min(calculatedQty, maxQty).toString(),
|
||||
// profitRate1 = finalMargin,
|
||||
// investmentGrade = investmentGrade,
|
||||
// )
|
||||
//
|
||||
// } else if(totalScore >= (minScore * 0.9) && completeTradingDecision.confidence + append >= (MIN_CONFIDENCE * 0.9)) {
|
||||
// addToReanalysis(RankingStock(mksc_shrn_iscd = completeTradingDecision.stockCode,hts_kor_isnm = completeTradingDecision.stockName))
|
||||
// TradingLogStore.addLog(completeTradingDecision,"RETRY","✋ [관망] 토탈 스코어[$totalScore] 또는 신뢰도[${completeTradingDecision.confidence}] 미달 이나 약간의 오차로 재분석 대기열에 추가")
|
||||
// } else {
|
||||
// TradingLogStore.addLog(completeTradingDecision,"HOLD","✋ [관망] 토탈 스코어(${String.format("%.1f[${minScore}]", totalScore)}) 또는 신뢰도 (${String.format("%.1f[${MIN_CONFIDENCE}]", completeTradingDecision.confidence)}) 미달")
|
||||
// }
|
||||
// }
|
||||
// if (completeTradingDecision?.decision?.contains("매수") == true) {
|
||||
// completeTradingDecision.decision = "BUY"
|
||||
// }
|
||||
// when (completeTradingDecision?.decision) {
|
||||
// "BUY","매수" -> {
|
||||
// append = buyWeight
|
||||
// TradingLogStore.addLog(completeTradingDecision,"BUY","[$stockCode] 매수 추천 : ${completeTradingDecision?.reason}")
|
||||
// resultCheck(completeTradingDecision)
|
||||
// }
|
||||
// "SELL" -> {
|
||||
// TradingLogStore.addLog(completeTradingDecision,"SELL","[$stockCode] 매도 추천 : ${completeTradingDecision?.reason}")
|
||||
// println("[$stockCode] 매도: ${completeTradingDecision?.reason}")
|
||||
// }
|
||||
// "HOLD" -> {
|
||||
// append = 0.0
|
||||
// TradingLogStore.addLog(completeTradingDecision,"HOLD","[$stockCode] 관망 유지 : ${completeTradingDecision?.reason}")
|
||||
// resultCheck(completeTradingDecision)
|
||||
// }
|
||||
// else -> {
|
||||
// append = 0.0
|
||||
// println("[$stockCode] ${completeTradingDecision?.decision} : ${completeTradingDecision?.reason}")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
val globalCallback = { completeTradingDecision: TradingDecision?, isSuccess: Boolean ->
|
||||
if (isSuccess && completeTradingDecision != null) {
|
||||
val decision = completeTradingDecision
|
||||
|
||||
println("🚀 [자동매수 실행] ${completeTradingDecision.stockName}")
|
||||
if (completeTradingDecision.confidence < 10) {
|
||||
addToReanalysis(RankingStock(mksc_shrn_iscd = completeTradingDecision.stockCode,hts_kor_isnm = completeTradingDecision.stockName))
|
||||
TradingLogStore.addLog(completeTradingDecision,"RETRY","분석 신뢰도 오류 인지로 재분석 대기열에 추가")
|
||||
}else if (completeTradingDecision != null && !completeTradingDecision.stockCode.isNullOrEmpty()) {
|
||||
var basePrice = completeTradingDecision.currentPrice
|
||||
var stockCode = completeTradingDecision.stockCode
|
||||
println("basePrice $basePrice")
|
||||
val minScore = KisSession.config.getValues(ConfigIndex.MIN_PURCHASE_SCORE_INDEX)
|
||||
var maxBudget = KisSession.config.getValues(ConfigIndex.MAX_BUDGET_INDEX)
|
||||
val buyWeight = KisSession.config.getValues(ConfigIndex.BUY_WEIGHT_INDEX)
|
||||
val baseProfit = KisSession.config.getValues(ConfigIndex.PROFIT_INDEX)
|
||||
// 1. 이미 AI가 결정한 decision과 confidence를 신뢰함
|
||||
if (decision.decision == "BUY") {
|
||||
val minScore = KisSession.config.getValues(ConfigIndex.MIN_PURCHASE_SCORE_INDEX)
|
||||
|
||||
fun resultCheck(completeTradingDecision :TradingDecision) {
|
||||
val weights = mapOf(
|
||||
"short" to 0.2, // 초단기 점수가 낮아도 전체에 미치는 영향 감소
|
||||
"profit" to 0.4,
|
||||
"safe" to 0.4 // 중장기 점수 비중 강화
|
||||
)
|
||||
// AI가 이미 검증한 등급을 사용 (재계산 불필요)
|
||||
val grade = decision.investmentGrade ?: InvestmentGrade.LEVEL_1_SPECULATIVE
|
||||
|
||||
val totalScore =
|
||||
((completeTradingDecision.shortPossible() + append) * weights["short"]!!) +
|
||||
((completeTradingDecision.profitPossible() + append) * weights["profit"]!!) +
|
||||
((completeTradingDecision.safePossible() + append) * weights["safe"]!!)
|
||||
// 2. 최종 매수 실행
|
||||
val gradeRate = KisSession.config.getValues(grade.allocationRate)
|
||||
val maxBudget = KisSession.config.getValues(ConfigIndex.MAX_BUDGET_INDEX) * gradeRate
|
||||
val calculatedQty = (maxBudget / decision.currentPrice).toInt().coerceAtLeast(1)
|
||||
|
||||
if (totalScore >= minScore && completeTradingDecision.confidence >= MIN_CONFIDENCE) {
|
||||
var investmentGrade = completeTradingDecision.investmentGrade ?: InvestmentGrade.LEVEL_1_SPECULATIVE
|
||||
|
||||
val finalMargin = baseProfit * KisSession.config.getValues(investmentGrade.profitGuide)
|
||||
println("🚀 [매수 진행] 토탈 스코어: ${String.format("%.1f", totalScore)} -> 종목: ${completeTradingDecision.stockCode}")
|
||||
|
||||
// basePrice(현재가 혹은 지정가)를 기준으로 매수 가능 수량 산출 (최소 1주 보장)
|
||||
val gradeRate = KisSession.config.getValues(investmentGrade.allocationRate)
|
||||
val maxQty = (KisSession.config.getValues(ConfigIndex.MAX_COUNT_INDEX) * gradeRate).roundToInt()
|
||||
maxBudget = maxBudget * gradeRate
|
||||
val calculatedQty = if (basePrice > 0) {
|
||||
(maxBudget / basePrice).toInt().coerceAtLeast(1)
|
||||
} else {
|
||||
1
|
||||
}
|
||||
// 5. 매수 실행 (계산된 finalMargin 전달)
|
||||
excuteTrade(
|
||||
decision = completeTradingDecision,
|
||||
orderQty = min(calculatedQty, maxQty).toString(),
|
||||
profitRate1 = finalMargin,
|
||||
investmentGrade = investmentGrade,
|
||||
)
|
||||
|
||||
} else if(totalScore >= (minScore * 0.9) && completeTradingDecision.confidence + append >= (MIN_CONFIDENCE * 0.9)) {
|
||||
addToReanalysis(RankingStock(mksc_shrn_iscd = completeTradingDecision.stockCode,hts_kor_isnm = completeTradingDecision.stockName))
|
||||
TradingLogStore.addLog(completeTradingDecision,"RETRY","✋ [관망] 토탈 스코어[$totalScore] 또는 신뢰도[${completeTradingDecision.confidence}] 미달 이나 약간의 오차로 재분석 대기열에 추가")
|
||||
} else {
|
||||
TradingLogStore.addLog(completeTradingDecision,"HOLD","✋ [관망] 토탈 스코어(${String.format("%.1f[${minScore}]", totalScore)}) 또는 신뢰도 (${String.format("%.1f[${MIN_CONFIDENCE}]", completeTradingDecision.confidence)}) 미달")
|
||||
}
|
||||
}
|
||||
if (completeTradingDecision?.decision?.contains("매수") == true) {
|
||||
completeTradingDecision.decision = "BUY"
|
||||
}
|
||||
when (completeTradingDecision?.decision) {
|
||||
"BUY","매수" -> {
|
||||
append = buyWeight
|
||||
TradingLogStore.addLog(completeTradingDecision,"BUY","[$stockCode] 매수 추천 : ${completeTradingDecision?.reason}")
|
||||
resultCheck(completeTradingDecision)
|
||||
}
|
||||
"SELL" -> {
|
||||
TradingLogStore.addLog(completeTradingDecision,"SELL","[$stockCode] 매도 추천 : ${completeTradingDecision?.reason}")
|
||||
println("[$stockCode] 매도: ${completeTradingDecision?.reason}")
|
||||
}
|
||||
"HOLD" -> {
|
||||
append = 0.0
|
||||
TradingLogStore.addLog(completeTradingDecision,"HOLD","[$stockCode] 관망 유지 : ${completeTradingDecision?.reason}")
|
||||
resultCheck(completeTradingDecision)
|
||||
}
|
||||
else -> {
|
||||
append = 0.0
|
||||
println("[$stockCode] ${completeTradingDecision?.decision} : ${completeTradingDecision?.reason}")
|
||||
}
|
||||
}
|
||||
}
|
||||
excuteTrade(
|
||||
decision = decision,
|
||||
orderQty = calculatedQty.toString(),
|
||||
profitRate1 = KisSession.config.getValues(ConfigIndex.PROFIT_INDEX) * KisSession.config.getValues(grade.profitGuide),
|
||||
investmentGrade = grade
|
||||
)
|
||||
} else if (decision.confidence >= 60.0) { // 아까운 종목만 재분석
|
||||
addToReanalysis(RankingStock(decision.stockCode, decision.stockName))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
val MIN_CONFIDENCE = 60.0 // 최소 신뢰도
|
||||
var append = 0.0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user