This commit is contained in:
lunaticbum 2026-06-02 14:40:33 +09:00
parent 9d43c04670
commit ada0d9d6fe
3 changed files with 16 additions and 21 deletions

View File

@ -242,7 +242,7 @@ object DatabaseFactory {
fun findAllMonitoringTrades(): List<AutoTradeItem> {
return transaction(mainDb) {
AutoTradeTable.select {
AutoTradeTable.status neq "COMPLETED"
AutoTradeTable.status notInList listOf(TradeStatus.COMPLETED, TradeStatus.EXPIRED)
}.map { mapToAutoTradeItem(it) }
}
}

View File

@ -654,7 +654,7 @@ object KisTradeService {
pageCount++
trCont = "N"
println("⏳ [연속 조회] 250ms 대기 후 다음 페이지 요청...")
delay(350) // API 과부하 방지
delay(400) // API 과부하 방지
}
} while (trCont == "N")

View File

@ -1,7 +1,6 @@
package service
import AutoTradeItem
import Defines.AUTOSELL
import Defines.BLACKLISTEDSTOCKCODES
import Defines.EMBEDDING_PORT
import Defines.LLM_PORT
@ -40,7 +39,6 @@ import network.KisWebSocketManager
import network.RagService
import network.RagService.isSafetyBeltStockCodes
import network.StockUniverseLoader
import report.SnapshotType
import report.TradingReportManager
import util.MarketUtil
import java.time.LocalDate
@ -771,8 +769,9 @@ object AutoTradingManager {
}
withTimeout(CYCLE_TIMEOUT) {
println("⏱️ [Cycle Start] ${LocalTime.now()}")
if (now.isAfter(KisSession.endTime())) {
executeClosingLiquidation(KisTradeService)
val activeTrades = DatabaseFactory.findAllMonitoringTrades()
if (now.isAfter(LocalTime.of(15, 30)) && activeTrades.isNotEmpty()) {
executeClosingLiquidation(activeTrades)
} else {
executeMarketLoop()
}
@ -818,7 +817,7 @@ object AutoTradingManager {
}
}
var loadedTops = mutableListOf<Pair<String, String>>()
var defaultStockCount = 200
var defaultStockCount = 150
fun poll100Stocks(): List<Pair<String, String>> {
loadedTops.shuffle()
val count = minOf(loadedTops.size, defaultStockCount)
@ -946,9 +945,13 @@ object AutoTradingManager {
if(
it.quantity.toInt() > KisSession.tradeConfig.lowerAverageTargetCount &&
it.profitRate.toDouble() < (KisSession.tradeConfig.lowerAverageMaxRate * -1) &&
it.profitRate.toDouble() > (KisSession.tradeConfig.lowerAverageMinRate * -1) )
it.profitRate.toDouble() > (KisSession.tradeConfig.lowerAverageMinRate * -1) &&
it.code !in pendingStocks &&
it.code !in executionCache.values.map { it.code } &&
it.code !in failList &&
it.code !in isSafetyBeltStockCodes)
{
candidates.add(RankingStock(mksc_shrn_iscd = it.code, hts_kor_isnm = it.name))
remainingCandidates.add(RankingStock(mksc_shrn_iscd = it.code, hts_kor_isnm = it.name))
}
}
}
@ -982,7 +985,7 @@ object AutoTradingManager {
iterator.remove()
}
println("남은 후보군 개수 : ${totalCount}")
delay(100)
delay(500)
}
}
sellSchedule()
@ -1089,7 +1092,7 @@ object AutoTradingManager {
val currentPrice = today.stck_prpr.toDouble()
if ((myCash > 10L && currentPrice > myCash) || currentPrice > maxBudget || currentPrice > maxPrice || currentPrice < minPrice) {
print("-> 가격 정책으로 제외 [1주:${currentPrice}, 자산:${myCash}, 최소 기준:${minPrice}, 최대 기준:${maxPrice}] | ")
print("-> [${stock.name}] 가격 정책으로 제외 [1주:${currentPrice}, 자산:${myCash}, 최소 기준:${minPrice}, 최대 기준:${maxPrice}] | ")
return@withTimeout
}
@ -1174,18 +1177,10 @@ object AutoTradingManager {
}
private suspend fun executeClosingLiquidation(tradeService: KisTradeService) {
val activeTrades = DatabaseFactory.findAllMonitoringTrades()
val balanceResult = tradeService.fetchIntegratedBalance().getOrNull()
val realHoldings = balanceResult?.getHoldings()?.associateBy { it.code } ?: emptyMap()
private suspend fun executeClosingLiquidation(activeTrades: List<AutoTradeItem>) {
activeTrades.forEach { trade ->
try {
if (!realHoldings.containsKey(trade.code)) {
DatabaseFactory.updateStatusAndOrderNo(trade.id!!, TradeStatus.EXPIRED)
return@forEach
}
// 마감 정리 로직 (필요 시 주석 해제하여 사용)
println("📢 [마감 정리 체크] ${trade.name}")
} catch (e: Exception) {
println("⚠️ [마감 에러] ${trade.name}: ${e.message}")