...
This commit is contained in:
@@ -11,6 +11,9 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import model.CandleData
|
||||
import model.ExecutionData
|
||||
@@ -22,6 +25,7 @@ import network.KisTradeService
|
||||
import network.KisWebSocketManager
|
||||
import service.AutoTradingManager
|
||||
import service.TechnicalAnalyzer
|
||||
import service.TradingDecisionCallback
|
||||
import util.MarketUtil
|
||||
import kotlin.collections.mutableListOf
|
||||
|
||||
@@ -46,11 +50,18 @@ fun DashboardScreen() {
|
||||
var monthSummary by remember { mutableStateOf<MutableList<CandleData>>(mutableListOf()) }
|
||||
var yearSummary by remember { mutableStateOf<MutableList<CandleData>>(mutableListOf()) }
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
// 1. 화면 진입 시: 자동 발굴 루프 시작
|
||||
// AI 분석 결과(decision)가 나오면 completeTradingDecision 상태를 업데이트하여
|
||||
// IntegratedOrderSection에서 자동으로 매수 로직이 실행되도록 연결합니다.
|
||||
AutoTradingManager.startAutoDiscoveryLoop(tradeService) { decision, isSuccess ->
|
||||
fun setupAutoTradingWatchdog(tradeService: KisTradeService, callback: TradingDecisionCallback) {
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
// while (true) {
|
||||
// delay(60000) // 1분마다 체크
|
||||
AutoTradingManager.checkAndRestart(tradeService, callback)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var callback = object : TradingDecisionCallback {
|
||||
override fun invoke(decision: TradingDecision?, isSuccess: Boolean) {
|
||||
if (!isSuccess && decision?.confidence ?: 0.0 < 0.0) {
|
||||
decision?.stockCode?.let { stockCode ->
|
||||
decision?.stockName?.let { stockName ->
|
||||
@@ -70,6 +81,13 @@ fun DashboardScreen() {
|
||||
completeTradingDecision = decision
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DisposableEffect(Unit) {
|
||||
// 1. 화면 진입 시: 자동 발굴 루프 시작
|
||||
// AI 분석 결과(decision)가 나오면 completeTradingDecision 상태를 업데이트하여
|
||||
// IntegratedOrderSection에서 자동으로 매수 로직이 실행되도록 연결합니다.
|
||||
AutoTradingManager.startAutoDiscoveryLoop(tradeService,callback)
|
||||
|
||||
// 2. 화면 이탈 시(앱 종료 등): 루프 중단 (리소스 정리)
|
||||
onDispose {
|
||||
@@ -83,6 +101,11 @@ fun DashboardScreen() {
|
||||
val executionCache = remember { mutableMapOf<String, ExecutionData>() }
|
||||
val processingIds = remember { mutableSetOf<String>() } // 주문번호 기준 잠금
|
||||
// [중앙 관리 함수] 체결 정보와 DB 정보를 매칭하여 실행
|
||||
|
||||
LaunchedEffect(refreshTrigger) {
|
||||
setupAutoTradingWatchdog(tradeService,callback)
|
||||
}
|
||||
|
||||
suspend fun syncAndExecute(orderNo: String) {
|
||||
if (processingIds.contains(orderNo)) return
|
||||
processingIds.add(orderNo)
|
||||
|
||||
@@ -177,13 +177,13 @@ fun IntegratedOrderSection(
|
||||
// 토탈 스코어가 85점 이상이면 마진을 3.0으로 고정하거나 추가 가산(append) 적용
|
||||
val finalMargin = if (totalScore >= HIGH_QUALITY_SCORE) {
|
||||
println("💎 [우량주 포착] 토탈 스코어($totalScore)가 매우 높아 목표 마진을 3.0%로 상향합니다.")
|
||||
minimumNetProfit + (append * 1.5)
|
||||
minimumNetProfit * 1.5
|
||||
} else {
|
||||
minimumNetProfit + append
|
||||
minimumNetProfit
|
||||
}
|
||||
|
||||
println("🚀 [매수 진행] 토탈 스코어: ${String.format("%.1f", totalScore)} -> 종목: ${completeTradingDecision.stockCode}")
|
||||
val MAX_BUDGET = 25000.0
|
||||
val MAX_BUDGET = 30000.0
|
||||
// basePrice(현재가 혹은 지정가)를 기준으로 매수 가능 수량 산출 (최소 1주 보장)
|
||||
val calculatedQty = if (basePrice > 0) {
|
||||
(MAX_BUDGET / basePrice).toInt().coerceAtLeast(1)
|
||||
|
||||
Reference in New Issue
Block a user