리포팅 테스트
This commit is contained in:
@@ -5,7 +5,6 @@ import Defines.AUTOSELL
|
||||
import Defines.BLACKLISTEDSTOCKCODES
|
||||
import Defines.EMBEDDING_PORT
|
||||
import Defines.LLM_PORT
|
||||
import network.TradingDecision
|
||||
import TradingLogStore
|
||||
import analyzer.AdvancedTradeAssistant
|
||||
import analyzer.TechnicalAnalyzer
|
||||
@@ -30,6 +29,7 @@ import model.ExecutionData
|
||||
import model.KisSession
|
||||
import model.RankingStock
|
||||
import model.RankingType
|
||||
import model.TradingDecision
|
||||
import model.UnifiedBalance
|
||||
import model.UnifiedStockHolding
|
||||
import network.DartCodeManager
|
||||
@@ -38,6 +38,8 @@ import network.KisTradeService
|
||||
import network.KisWebSocketManager
|
||||
import network.RagService
|
||||
import network.StockUniverseLoader
|
||||
import report.SnapshotType
|
||||
import report.TradingReportManager
|
||||
import util.MarketUtil
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
@@ -222,6 +224,7 @@ object AutoTradingManager {
|
||||
TradingLogStore.addLog(decision,"WATCH","매수 실패 : 최대 보유 종목 도달로 신규 매수 일시 중단 => 재분석 대기열에 추가")
|
||||
} else {
|
||||
println("basePrice : $basePrice, oneTickLowerPrice : $oneTickLowerPrice, finalPrice : $finalPrice")
|
||||
|
||||
KisTradeService.postOrder(stockCode, orderQty, finalPrice.toLong().toString(), isBuy = true)
|
||||
.onSuccess { realOrderNo ->
|
||||
// 💡 [개선 1] 첫 번째 성공 로그에 등급 이름 추가
|
||||
@@ -250,6 +253,17 @@ object AutoTradingManager {
|
||||
status = "PENDING_BUY",
|
||||
isDomestic = true
|
||||
))
|
||||
|
||||
TradingReportManager.recordTradeDecision(
|
||||
orderNo = realOrderNo,
|
||||
stockCode = stockCode,
|
||||
stockName = stockName,
|
||||
isBuy = true,
|
||||
orderQty = inputQty,
|
||||
reason = decision.reason ?: "", // AI 이유
|
||||
decision = decision // AI 객체 통째로 전달
|
||||
)
|
||||
|
||||
syncAndExecute(realOrderNo)
|
||||
|
||||
// 💡 [개선 3] 감시 설정 로그에도 등급 정보 노출
|
||||
@@ -296,7 +310,7 @@ object AutoTradingManager {
|
||||
// 3. 실제 체결가 기준 익절 가격 재계산 및 틱 사이즈 보정
|
||||
val finalTargetPrice = MarketUtil.roundToTickSize(actualBuyPrice * (1 + finalProfitRate / 100.0))
|
||||
|
||||
|
||||
TradingReportManager.updateExecution(orderNo,finalTargetPrice,dbItem.quantity)
|
||||
println("🎯 [매칭 성공] 익절 주문 실행: ${dbItem.name} | 매수가: ${actualBuyPrice.toInt()} -> 목표가: ${finalTargetPrice.toInt()} (${String.format("%.2f", finalProfitRate)}% 적용)")
|
||||
|
||||
KisTradeService.postOrder(
|
||||
@@ -306,6 +320,15 @@ object AutoTradingManager {
|
||||
isBuy = false
|
||||
).onSuccess { newSellOrderNo ->
|
||||
// 익절가 업데이트 및 상태 변경
|
||||
TradingReportManager.recordTradeDecision(
|
||||
orderNo = newSellOrderNo,
|
||||
stockCode = dbItem.code,
|
||||
stockName = dbItem.name,
|
||||
isBuy = false,
|
||||
orderQty = dbItem.quantity,
|
||||
reason = "🎯 [매칭 성공] 익절 주문 실행: ${dbItem.name} | 매수가: ${actualBuyPrice.toInt()} -> 목표가: ${finalTargetPrice.toInt()} (${String.format("%.2f", finalProfitRate)}% 적용)", // AI 이유
|
||||
decision = null // AI 객체 통째로 전달
|
||||
)
|
||||
DatabaseFactory.updateStatusAndOrderNo(dbItem.id!!, TradeStatus.SELLING, newSellOrderNo)
|
||||
TradingLogStore.addSellLog(dbItem.name,finalTargetPrice.toString(),"SELL","🎯 [매칭 성공] 익절 주문 실행: ${dbItem.name} | 매수가: ${actualBuyPrice.toInt()} -> 목표가: ${finalTargetPrice.toInt()} (${String.format("%.2f", finalProfitRate)}% 적용)")
|
||||
executionCache.remove(orderNo)
|
||||
@@ -316,6 +339,8 @@ object AutoTradingManager {
|
||||
} else if (dbItem.status == TradeStatus.SELLING) {
|
||||
println("🎊 [매칭 성공] 매도 완료 처리: ${dbItem.name}")
|
||||
myOredsAndBalanceCodes.remove(dbItem.code)
|
||||
|
||||
TradingReportManager.updateExecution(orderNo,execData.price.toDouble(),execData.qty.toInt())
|
||||
TradingLogStore.addSellLog(dbItem.name,execData.price,"SELL","🎊 [매칭 성공] 매도 완료 처리")
|
||||
DatabaseFactory.updateStatusAndOrderNo(dbItem.id!!, TradeStatus.COMPLETED)
|
||||
executionCache.remove(orderNo)
|
||||
@@ -350,7 +375,7 @@ object AutoTradingManager {
|
||||
}
|
||||
|
||||
suspend fun sellingAfterMarketOnePrice(tradeService: KisTradeService,balance : UnifiedBalance,marketCode : String = "Y") {
|
||||
balance.holdings.forEach { holding ->
|
||||
balance.getHolldings().forEach { holding ->
|
||||
if (BLACKLISTEDSTOCKCODES.contains(holding.code)){
|
||||
println("❌ 차단 처리된 주식 : ${holding.name}")
|
||||
TradingLogStore.addAnalyzer(
|
||||
@@ -389,6 +414,19 @@ object AutoTradingManager {
|
||||
"SELL",
|
||||
"🎊 ${if(marketCode.equals("Y"))"시간외 단일가" else "대체거래소"} 주식 재고털이 주문 완료"
|
||||
)
|
||||
DatabaseFactory.saveAutoTrade(AutoTradeItem(
|
||||
orderNo = newOrderNo,
|
||||
code = holding.code,
|
||||
name = holding.name,
|
||||
quantity = holding.quantity.toInt(),
|
||||
profitRate = 0.0,
|
||||
stopLossRate = 0.0,
|
||||
targetPrice = targetPrice.toDouble(),
|
||||
stopLossPrice = 0.0,
|
||||
status = "SELLING",
|
||||
isDomestic = true
|
||||
))
|
||||
syncAndExecute(newOrderNo)
|
||||
}.onFailure {
|
||||
TradingLogStore.addSellLog(
|
||||
"${holding.name}[${holding.code}]",
|
||||
@@ -415,7 +453,7 @@ object AutoTradingManager {
|
||||
|
||||
|
||||
println("resumePendingSellOrders")
|
||||
balance.holdings.forEach { holding ->
|
||||
balance.getHolldings().forEach { holding ->
|
||||
if (BLACKLISTEDSTOCKCODES.contains(holding.code)){
|
||||
println("❌ 차단 처리된 주식 : ${holding.name}")
|
||||
TradingLogStore.addAnalyzer(
|
||||
@@ -678,6 +716,10 @@ object AutoTradingManager {
|
||||
suspend fun checkBalance(isMorning: Boolean = true) {
|
||||
if (isMorning) {
|
||||
currentBalance = KisTradeService.fetchIntegratedBalance().getOrNull()
|
||||
currentBalance?.let { currentBalance ->
|
||||
TradingReportManager.recordAssetSnapshot(if (LocalTime.now().isAfter(LocalTime.of(17,58))) SnapshotType.END else SnapshotType.MIDDLE ,currentBalance,"")
|
||||
}
|
||||
|
||||
if (AUTOSELL) currentBalance?.let { resumePendingSellOrders(KisTradeService, it) }
|
||||
} else {
|
||||
}
|
||||
@@ -687,7 +729,7 @@ object AutoTradingManager {
|
||||
myOredsAndBalanceCodes.clear()
|
||||
checkBalance()
|
||||
val myCash = currentBalance?.deposit?.replace(",", "")?.toLongOrNull() ?: 0L
|
||||
val myHoldings = currentBalance?.holdings?.filter { it.quantity.toInt() > 0 }?.map {
|
||||
val myHoldings = currentBalance?.getHolldings()?.map {
|
||||
myOredsAndBalanceCodes.add(it.code)
|
||||
it.code }?.toSet() ?: emptySet()
|
||||
val pendingStocks = DatabaseFactory.findAllMonitoringTrades().map {
|
||||
@@ -790,53 +832,6 @@ object AutoTradingManager {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun finalizeMarketClose(now: LocalTime) {
|
||||
when {
|
||||
(AutoTradingManager.now.hour == 0 && AutoTradingManager.now.minute == 0 && (isSystemReadyToday || isSystemCleanedUpToday)) -> {
|
||||
waitTime = 10.0
|
||||
isSystemReadyToday = false
|
||||
isSystemCleanedUpToday = false
|
||||
}
|
||||
|
||||
(AutoTradingManager.now.isAfter(LocalTime.of(8, 0)) && !isSystemReadyToday) -> {
|
||||
waitTime = 3.0
|
||||
if (!KisSession.isMarketTokenValid() || !KisSession.isTradeTokenValid()) {
|
||||
KisWebSocketManager.disconnect()
|
||||
tryRefreshToken()
|
||||
}
|
||||
}
|
||||
|
||||
(AutoTradingManager.now.isAfter(LocalTime.of(18, 20))) -> {
|
||||
try {
|
||||
waitTime = 5.0
|
||||
println("current SystemCleanedUpToday is $isSystemCleanedUpToday")
|
||||
if (!isSystemCleanedUpToday) {
|
||||
println("🌙 [System] 업무 종료 및 자원 정리 시작...")
|
||||
SystemSleepPreventer.sleepDisplay() // 모니터 끄기
|
||||
KisWebSocketManager.disconnect()
|
||||
BrowserManager.closeIfIdle(0) // 즉시 닫기
|
||||
if (LlamaServerManager.stopAll()) {
|
||||
isSystemCleanedUpToday = true
|
||||
}
|
||||
|
||||
}
|
||||
println("✅ [System] 오늘의 모든 정리가 완료되었습니다.")
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
(AutoTradingManager.now.isAfter(LocalTime.of(18, 15)) && AutoTradingManager.now.minute % 15 == 0) -> {
|
||||
try {
|
||||
waitTime = 5.0
|
||||
SystemSleepPreventer.sleepDisplay() // 모니터 끄기
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
waitTime = 5.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addToReanalysis(stock: RankingStock) {
|
||||
val count = retryCountMap.getOrDefault(stock.code, 0)
|
||||
@@ -953,7 +948,7 @@ 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()
|
||||
val realHoldings = balanceResult?.getHolldings()?.associateBy { it.code } ?: emptyMap()
|
||||
|
||||
activeTrades.forEach { trade ->
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user