This commit is contained in:
lunaticbum 2026-04-03 17:47:56 +09:00
parent d512919d41
commit 8a6897fa0e
3 changed files with 55 additions and 34 deletions

View File

@ -501,6 +501,21 @@ object TradingLogStore {
}
}
fun addAfterMarketLog(name : String, code : String, log: String) {
synchronized(this) {
if (decisionLogs.size > 1000) decisionLogs.removeAt(0)
decisionLogs.add(
LogEntry(
time = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")),
stockName = "$name[$code] 분석",
decision = "AFTER",
confidence = 100.0,
reason = log
)
)
}
}
fun addSettingLog(settingDesc : String, old : String, new : String, log: String) {
synchronized(this) {
if (decisionLogs.size > 1000) decisionLogs.removeAt(0)

View File

@ -377,33 +377,39 @@ object AutoTradingManager {
)
} else {
println("${holding.name} - 매수 : ${holding.avgPrice} - 현재 : ${holding.currentPrice} , 주문 가능 : ${holding.availOrderCount}, 수익율 : ${holding.profitRate}")
if (holding != null && holding.quantity.toInt() > 0 && holding.availOrderCount.toInt() > 0 && holding.profitRate.toDouble() > KisSession.config.SELL_PROFIT) {
if (holding != null && holding.quantity.toInt() > 0 && holding.availOrderCount.toInt() > 0 && holding.profitRate.toDouble() > 0.5) {
println("${holding.name} - 매수 : ${holding.avgPrice} - 현재 : ${holding.currentPrice} ")
var targetPrice = holding.currentPrice.toDouble()
TradingLogStore.addAfterMarketLog(
holding.name,
holding.code,
"${if ("Y".equals(marketCode)) "시간외 단일가" else "대체거래소"} 시세로 ${holding.profitRate} 수익 예상"
)
targetPrice = MarketUtil.roundToTickSize(targetPrice)
tradeService.postOrder(
stockCode = holding.code,
qty = holding.availOrderCount,
price = targetPrice.toInt().toString(),
isBuy = false,
orderDivision = if (marketCode.equals("Y")) "07" else "",
marketCode = if (marketCode.equals("Y")) "KRX" else "SOR"
).onSuccess { newOrderNo ->
println("✅ [재주문 완료] ${holding.name}: $newOrderNo")
TradingLogStore.addSellLog(
holding.code,
targetPrice.toString(),
"SELL",
"🎊 시간외 단일가 주식 재고털이 주문 완료"
)
}.onFailure {
TradingLogStore.addSellLog(
holding.code,
targetPrice.toString(),
"SELL",
"🎊 시간외 단일가 주식 재고털이 주문 실패[${it.message}] "
)
}
// tradeService.postOrder(
// stockCode = holding.code,
// qty = holding.availOrderCount,
// price = targetPrice.toInt().toString(),
// isBuy = false,
// orderDivision = if (marketCode.equals("Y")) "07" else "",
// marketCode = if (marketCode.equals("Y")) "KRX" else "SOR"
// ).onSuccess { newOrderNo ->
// println("✅ [재주문 완료] ${holding.name}: $newOrderNo")
// TradingLogStore.addSellLog(
// holding.code,
// targetPrice.toString(),
// "SELL",
// "🎊 시간외 단일가 주식 재고털이 주문 완료"
// )
// }.onFailure {
// TradingLogStore.addSellLog(
// holding.code,
// targetPrice.toString(),
// "SELL",
// "🎊 시간외 단일가 주식 재고털이 주문 실패[${it.message}] "
// )
// }
}
delay(300) // API 호출 부하 방지
}
@ -619,12 +625,12 @@ object AutoTradingManager {
if (AUTOSELL) balance?.let { resumePendingSellOrders(KisTradeService, it) }
return balance
} else {
// listOf<String>("Y","X").forEach { code ->
// KisTradeService.fetchIntegratedBalance(code).getOrNull()?.let {
// sellingAfterMarketOnePrice(KisTradeService, it, code)
// }
// delay(1000)
// }
listOf<String>("Y","X").forEach { code ->
KisTradeService.fetchIntegratedBalance(code).getOrNull()?.let {
sellingAfterMarketOnePrice(KisTradeService, it, code)
}
delay(1000)
}
}
return null
}
@ -710,15 +716,14 @@ object AutoTradingManager {
lastForceCheckMinute = currentMinute // 실행 완료 기록
}
}
else if((now.hour == 16 || now.hour == 17) && (currentMinute == 31 || currentMinute == 36)) {
else if((now.hour == 16 || now.hour == 17) && (currentMinute % 10 == 3 || currentMinute % 10 == 9)) {
if (lastForceCheckMinute != currentMinute) {
TradingLogStore.addAnalyzer(
" - ",
" - ",
"⏰ [강제 스케줄 실행] 오후 ${now.hour}${currentMinute}분 - 보유주식 시간외 단일가 매도 체크를 시작합니다.",
"⏰ [강제 스케줄 실행] 오후 ${now.hour}${currentMinute}분 - 보유주식 시간외 단일가 또는 대체마켓 체크를 시작합니다.",
true
)
println("⏰ [강제 스케줄 실행] 오후 ${now.hour}${currentMinute}분 - 보유주식 시간외 단일가 매도 체크를 시작합니다.")
checkBalance(false)
lastForceCheckMinute = currentMinute // 실행 완료 기록
}

View File

@ -35,7 +35,7 @@ fun TradingDecisionLog() {
val coroutineScope = rememberCoroutineScope()
var searchQuery by remember { mutableStateOf("") }
var selectedFilters by remember { mutableStateOf(setOf("전체")) }
val filterOptions = listOf("전체", "BUY", "SELL", "HOLD", "SETTING","ANALYZER","PASS","WATCH","RETRY")
val filterOptions = listOf("전체", "BUY", "SELL", "HOLD", "SETTING","ANALYZER","PASS","WATCH","RETRY","AFTER")
var llmAnalyser by remember { mutableStateOf(AutoTradingManager.llmAnalyser) }
LaunchedEffect(AutoTradingManager.llmAnalyser) {
llmAnalyser = AutoTradingManager.llmAnalyser
@ -164,6 +164,7 @@ fun TradingDecisionLog() {
"PASS" -> Color.Yellow
"RETRY" -> Color(0xFF00BCD4) // [추가] 하늘색 (재분석/대기열)
"WATCH" -> Color(0xFF4CAF50) // [추가] 연초록 (관심 종목 감시)
"AFTER" -> Color.Red
else -> Color.DarkGray
},
fontWeight = FontWeight.ExtraBold