This commit is contained in:
2026-02-20 15:21:38 +09:00
parent d5ab55b336
commit 55b82c23af
5 changed files with 101 additions and 80 deletions
+39 -28
View File
@@ -89,13 +89,13 @@ object AutoTradingManager {
// val balance = tradeService.fetchIntegratedBalance().getOrNull()
val holding = balance?.holdings?.find { it.code == item.code }
if (holding != null && holding.quantity.toInt() > 0) {
if (holding != null && holding.quantity.toInt() > 0 && holding.availOrderCount.toInt() > 0) {
var final = MarketUtil.roundToTickSize(item.targetPrice)
println("🔄 [재주문] ${item.name} (${item.code}) ${item.orderedPrice} ${final} 전날 미체결 매도 건 재주문 시도")
// 3. 기존 목표가(targetPrice)로 다시 매도 주문 전송
tradeService.postOrder(
stockCode = item.code,
qty = item.quantity.toString(),
qty = min(item.quantity,holding.availOrderCount.toInt()).toString(),
price = final.toLong().toString(),
isBuy = false
).onSuccess { newOrderNo ->
@@ -125,12 +125,12 @@ object AutoTradingManager {
println("⏱️ [Cycle Start] ${LocalTime.now()}")
// [프로세스 1] 장 마감 및 잔고 체크
// val now = LocalTime.now(ZoneId.of("Asia/Seoul"))
// //&& now.isBefore(LocalTime.of(15, 30))
// if (now.isAfter(LocalTime.of(15, 30)) ) {
//// executeClosingLiquidation(tradeService)
// return@withTimeout
// }
val now = LocalTime.now(ZoneId.of("Asia/Seoul"))
//&& now.isBefore(LocalTime.of(15, 30))
if (now.isAfter(LocalTime.of(15, 15)) ) {
executeClosingLiquidation(tradeService)
return@withTimeout
}
val balance = tradeService.fetchIntegratedBalance().getOrNull()
@@ -142,7 +142,18 @@ object AutoTradingManager {
if (remainingCandidates.isEmpty()) {
val candidates: MutableList<RankingStock> = fetchCandidates(tradeService).apply {
println("후보군 총 개수 : $size")
}.filter { !it.name.contains("호스팩", true) }
}.filter {
val rate = it.prdy_ctrt.toDouble()
val corpInfo = DartCodeManager.getCorpCode(it.code)
val isOk = (rate > 0 && rate < 15) || (rate < 0 && rate > -15)
// if (isOk) {println("${it.name} : ${it.prdy_ctrt}")}
if (corpInfo?.cName.isNullOrEmpty()) {
false
}else {
isOk
}
}
.filter { !it.name.contains("호스팩", true) }
.sortedBy { (it.prdy_ctrt.toDoubleOrNull() ?: 0.0) }
.toMutableList()
@@ -299,25 +310,25 @@ object AutoTradingManager {
// private suspend fun executeClosingLiquidation(tradeService: KisTradeService) {
// val activeTrades = DatabaseFactory.findAllMonitoringTrades()
// val balanceResult = tradeService.fetchIntegratedBalance().getOrNull()
// val realHoldings = balanceResult?.holdings?.associateBy { it.code } ?: emptyMap()
//
// activeTrades.forEach { trade ->
// try {
// if (!realHoldings.containsKey(trade.code)) {
// DatabaseFactory.updateStatusAndOrderNo(trade.id!!, TradeStatus.COMPLETED)
// return@forEach
// }
// // 마감 정리 로직 (필요 시 주석 해제하여 사용)
// println("📢 [마감 정리 체크] ${trade.name}")
// } catch (e: Exception) {
// println("⚠️ [마감 에러] ${trade.name}: ${e.message}")
// }
// delay(200)
// }
// }
private suspend fun executeClosingLiquidation(tradeService: KisTradeService) {
val activeTrades = DatabaseFactory.findAllMonitoringTrades()
val balanceResult = tradeService.fetchIntegratedBalance().getOrNull()
val realHoldings = balanceResult?.holdings?.associateBy { it.code } ?: emptyMap()
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}")
}
delay(200)
}
}
fun stopDiscovery() {
discoveryJob?.cancel()