...
This commit is contained in:
@@ -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()}")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user