This commit is contained in:
2026-03-27 17:54:21 +09:00
parent 681472df58
commit 62e408230e
5 changed files with 84 additions and 47 deletions
+59 -37
View File
@@ -1,6 +1,10 @@
package service
import AutoTradeItem
import Defines.AUTOSELL
import Defines.BLACKLISTEDSTOCKCODES
import Defines.EMBEDDING_PORT
import Defines.LLM_PORT
import network.TradingDecision
import TradingLogStore
import androidx.compose.runtime.getValue
@@ -49,9 +53,8 @@ import kotlin.math.*
// service/AutoTradingManager.kt
typealias TradingDecisionCallback = (TradingDecision?, Boolean)->Unit
object AutoTradingManager {
val DETAILLOG = true
val LLM_PORT = 13080
val EMBEDDING_PORT = 13081
private val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())
private var discoveryJob: Job? = null
@@ -368,34 +371,47 @@ object AutoTradingManager {
// 1. DB에서 매도 중(SELLING)이거나 만료(EXPIRED)된 매도 건을 가져옵니다.
println("resumePendingSellOrders")
balance.holdings.forEach { holding ->
if (holding != null && holding.quantity.toInt() > 0 && holding.availOrderCount.toInt() > 0 && holding.profitRate.toDouble() > KisSession.config.SELL_PROFIT) {
println("${holding.name} - 매수 : ${holding.avgPrice} - 현재 : ${holding.currentPrice} ")
// 3. 기존 목표가(targetPrice)로 다시 매도 주문 전송
var targetPrice = holding.currentPrice.toDouble()
targetPrice = MarketUtil.roundToTickSize(targetPrice + MarketUtil.getTickSize(targetPrice))
println("🔄 [재주문] ${holding.name} (${holding.code}) 매도 목표 ${targetPrice} 미체결 매도 건 재주문 시도")
// TradingLogStore.addSellLog(holding.code,targetPrice.toString(),"SELL","🎊 보유 주식 매도 주문[예상수익 : ${holding.profitRate}] ")
tradeService.postOrder(
stockCode = holding.code,
qty = holding.availOrderCount,
price = targetPrice.toInt().toString(),
isBuy = false
).onSuccess { newOrderNo ->
// 4. 새로운 주문번호로 DB 업데이트 및 상태를 SELLING으로 유지
// DatabaseFactory.updateStatusAndOrderNo(item.id!!, TradeStatus.SELLING, newOrderNo)
println("✅ [재주문 완료] ${holding.name}: $newOrderNo")
TradingLogStore.addSellLog(holding.code,targetPrice.toString(),"SELL","🎊 보유 주식 매도 주문 완료[예상수익 : ${holding.profitRate}] ")
}.onFailure {
TradingLogStore.addSellLog(holding.code,targetPrice.toString(),"SELL","🎊 보유 주식 매도 주문 실패[${it.message}] ")
// println("❌ [재주문 실패] ${holding.name}: ${it.message}")
}
if (BLACKLISTEDSTOCKCODES.contains(holding.code)){
println("❌ 차단 처리된 주식 : ${holding.name}")
} else {
if (holding != null && holding.quantity.toInt() > 0 && holding.availOrderCount.toInt() > 0 && holding.profitRate.toDouble() > KisSession.config.SELL_PROFIT) {
println("${holding.name} - 매수 : ${holding.avgPrice} - 현재 : ${holding.currentPrice} ")
// 3. 기존 목표가(targetPrice)로 다시 매도 주문 전송
var targetPrice = holding.currentPrice.toDouble()
targetPrice = MarketUtil.roundToTickSize(targetPrice + MarketUtil.getTickSize(targetPrice))
println("🔄 [재주문] ${holding.name} (${holding.code}) 매도 목표 ${targetPrice} 미체결 매도 건 재주문 시도")
// TradingLogStore.addSellLog(holding.code,targetPrice.toString(),"SELL","🎊 보유 주식 매도 주문[예상수익 : ${holding.profitRate}] ")
tradeService.postOrder(
stockCode = holding.code,
qty = holding.availOrderCount,
price = targetPrice.toInt().toString(),
isBuy = false
).onSuccess { newOrderNo ->
// 4. 새로운 주문번호로 DB 업데이트 및 상태를 SELLING으로 유지
// DatabaseFactory.updateStatusAndOrderNo(item.id!!, TradeStatus.SELLING, newOrderNo)
println("✅ [재주문 완료] ${holding.name}: $newOrderNo")
TradingLogStore.addSellLog(
holding.code,
targetPrice.toString(),
"SELL",
"🎊 보유 주식 매도 주문 완료[예상수익 : ${holding.profitRate}] "
)
}.onFailure {
TradingLogStore.addSellLog(
holding.code,
targetPrice.toString(),
"SELL",
"🎊 보유 주식 매도 주문 실패[${it.message}] "
)
// println("❌ [재주문 실패] ${holding.name}: ${it.message}")
}
} else {
}
delay(200) // API 호출 부하 방지
}
delay(200) // API 호출 부하 방지
}
}
var isSystemReadyToday = false
@@ -537,7 +553,9 @@ object AutoTradingManager {
suspend fun executeMarketLoop() {
val balance = KisTradeService.fetchIntegratedBalance().getOrNull()
balance?.let { resumePendingSellOrders(KisTradeService, it) }
if (AUTOSELL) balance?.let { resumePendingSellOrders(KisTradeService, it) }
val myCash = balance?.deposit?.replace(",", "")?.toLongOrNull() ?: 0L
val myHoldings = balance?.holdings?.filter { it.quantity.toInt() > 0 }?.map { it.code }?.toSet() ?: emptySet()
val pendingStocks = DatabaseFactory.findAllMonitoringTrades().map { it.code }
@@ -582,15 +600,19 @@ object AutoTradingManager {
while (iterator.hasNext()) {
totalCount--
val stock = iterator.next()
try {
processSingleStock(stock, myCash, KisTradeService, globalCallback)
} catch (e: Exception) {
println("❌ 처리 중 오류 발생 (건너뜀): ${stock.name}")
} finally {
iterator.remove()
if (BLACKLISTEDSTOCKCODES.contains(stock.code)){
println("❌ 차단 처리된 주식 : ${stock.name}")
} else {
try {
processSingleStock(stock, myCash, KisTradeService, globalCallback)
} catch (e: Exception) {
println("❌ 처리 중 오류 발생 (건너뜀): ${stock.name}")
} finally {
iterator.remove()
}
println("남은 후보군 개수 : ${totalCount}")
delay(100)
}
println("남은 후보군 개수 : ${totalCount}")
delay(100)
}
println("⏱️ [Cycle End] ${LocalTime.now()}")
}