...
This commit is contained in:
parent
eee4f1bab7
commit
f830163940
@ -444,5 +444,10 @@ object TradingLogStore {
|
||||
}
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
synchronized(this) {
|
||||
decisionLogs.clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ package service
|
||||
import AutoTradeItem
|
||||
import network.TradingDecision
|
||||
import TradingLogStore
|
||||
import TradingLogStore.decisionLogs
|
||||
import getLlamaBinPath
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@ -395,9 +396,13 @@ object AutoTradingManager {
|
||||
} catch (e: Exception) {}
|
||||
}
|
||||
|
||||
var onMarketClosed: (() -> Unit)? = null
|
||||
|
||||
var now = LocalTime.now(ZoneId.of("Asia/Seoul"))
|
||||
var currentTimeMillis = System.currentTimeMillis()
|
||||
var waitTime = 0.2
|
||||
val H16 = LocalTime.of(16, 0)
|
||||
val H08M50 = LocalTime.of(8, 50)
|
||||
private fun runDiscoveryLoop(tradeService: KisTradeService, callback: TradingDecisionCallback) {
|
||||
discoveryJob = scope.launch {
|
||||
println("🚀 [AutoTrading] 발굴 루프 시작: ${LocalDateTime.now()}")
|
||||
@ -406,9 +411,22 @@ object AutoTradingManager {
|
||||
now = LocalTime.now(ZoneId.of("Asia/Seoul"))
|
||||
currentTimeMillis = System.currentTimeMillis()
|
||||
lastTickTime.set(System.currentTimeMillis()) // 생존 신고
|
||||
// [수정] 16시 이후이거나 8시 30분 이전이면 모든 로직 중단 및 초기화
|
||||
if (now.isAfter(LocalTime.of(16, 0)) || now.isBefore(LocalTime.of(8, 30))) {
|
||||
println("🌙 [System] 마감 시간 도달. 자원 정리 후 대기 모드(설정 화면)로 전환합니다.")
|
||||
SystemSleepPreventer.sleepDisplay() // 모니터 끄기
|
||||
KisWebSocketManager.disconnect()
|
||||
BrowserManager.closeIfIdle(0)
|
||||
LlamaServerManager.stopAll() // AI 서버 완전 종료
|
||||
TradingLogStore.clear()
|
||||
onMarketClosed?.invoke() // Main.kt에 설정 화면으로 가라고 신호 전송
|
||||
stopDiscovery() // 발굴 루프 완전 폭파 (내일 8시 30분에 다시 켜짐)
|
||||
return@launch
|
||||
}
|
||||
when {
|
||||
|
||||
//장중
|
||||
now.isBefore(LocalTime.of(16, 0)) && now.isAfter(LocalTime.of(8, 50)) -> {
|
||||
now.isBefore(H16) && now.isAfter(H08M50) -> {
|
||||
waitTime = 0.2
|
||||
if (now.isAfter(LocalTime.of(8, 0)) && now.isBefore(LocalTime.of(15, 30))) {
|
||||
if (!KisSession.isMarketTokenValid() || !KisSession.isTradeTokenValid()) {
|
||||
@ -491,7 +509,7 @@ object AutoTradingManager {
|
||||
}
|
||||
|
||||
//장외
|
||||
now.isAfter(LocalTime.of(18, 0)) || now.isBefore(LocalTime.of(8, 50)) -> {
|
||||
now.isAfter(H16) || now.isBefore(H08M50) -> {
|
||||
when {
|
||||
(now.hour == 0 && now.minute == 0 && (isSystemReadyToday || isSystemCleanedUpToday)) -> {
|
||||
waitTime = 10.0
|
||||
|
||||
@ -35,6 +35,7 @@ import network.KisTradeService
|
||||
import org.jetbrains.exposed.sql.deleteAll
|
||||
import org.jetbrains.exposed.sql.insert
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import service.SystemSleepPreventer
|
||||
|
||||
|
||||
// src/main/kotlin/ui/SettingsScreen.kt
|
||||
@ -45,6 +46,61 @@ fun SettingsScreen(onAuthSuccess: () -> Unit) {
|
||||
var config by remember { mutableStateOf(KisSession.config) }
|
||||
var statusMessage by remember { mutableStateOf("정보를 입력하세요.") }
|
||||
|
||||
val authenticateAndStart: suspend () -> Unit = {
|
||||
var retryCount = 0
|
||||
val maxRetries = 3
|
||||
val totalDelaySeconds = 90
|
||||
var isAuthCompleted = false
|
||||
|
||||
while (retryCount <= maxRetries && !isAuthCompleted) {
|
||||
if (retryCount > 0) {
|
||||
for (secondsLeft in totalDelaySeconds downTo 1) {
|
||||
statusMessage = "⚠️ 인증 실패. ${secondsLeft}초 후 자동으로 다시 시도합니다. (시도 ${retryCount}/${maxRetries})"
|
||||
delay(1000L)
|
||||
}
|
||||
}
|
||||
statusMessage = if (retryCount == 0) "⏳ 인증 시도 중..." else "⏳ ${retryCount}차 재시도 중..."
|
||||
|
||||
KisSession.config = config
|
||||
DatabaseFactory.saveConfig(config)
|
||||
|
||||
DartCodeManager.updateCorpCodes(HttpClient(CIO) {
|
||||
install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true }) }
|
||||
})
|
||||
|
||||
val authSuccess = KisAuthService.refreshAllTokens()
|
||||
val wsKeySuccess = KisTradeService.refreshWebsocketKey()
|
||||
|
||||
if (authSuccess && wsKeySuccess) {
|
||||
statusMessage = "✅ 인증 성공! LLM 시작 중..."
|
||||
isAuthCompleted = true
|
||||
onAuthSuccess() // 여기서 대시보드로 넘어감
|
||||
} else {
|
||||
retryCount++
|
||||
if (retryCount > maxRetries) {
|
||||
statusMessage = "❌ 인증 실패. 3회 재시도 후 중단되었습니다."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(config) {
|
||||
while (true) {
|
||||
val now = java.time.LocalTime.now(java.time.ZoneId.of("Asia/Seoul"))
|
||||
// 08:30 ~ 15:30 사이이고, 키값이 최소한 하나라도 존재할 때 자동 실행
|
||||
if (now.isAfter(java.time.LocalTime.of(8, 30)) && now.isBefore(java.time.LocalTime.of(15, 30))) {
|
||||
if (config.realAppKey.isNotEmpty() || config.vtsAppKey.isNotEmpty()) {
|
||||
SystemSleepPreventer.wakeDisplay() // 모니터 켜기
|
||||
statusMessage = "⏰ 자동 실행 시간(08:30)입니다. 시스템을 가동합니다."
|
||||
authenticateAndStart()
|
||||
break // 성공하면 루프 탈출
|
||||
}
|
||||
}
|
||||
delay(60_000 * 2) // 1분마다 시간 체크
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 계좌번호 입력 시 데이터 자동 로드 함수
|
||||
fun checkAndLoadConfig(accountNo: String, isReal: Boolean) {
|
||||
val loaded = DatabaseFactory.findConfigByAccount(accountNo)
|
||||
@ -190,47 +246,7 @@ fun SettingsScreen(onAuthSuccess: () -> Unit) {
|
||||
modifier = Modifier.fillMaxWidth().height(50.dp),
|
||||
onClick = {
|
||||
scope.launch {
|
||||
var retryCount = 0
|
||||
val maxRetries = 3
|
||||
val totalDelaySeconds = 90 // 1분 30초 = 90초
|
||||
var isAuthCompleted = false
|
||||
|
||||
while (retryCount <= maxRetries && !isAuthCompleted) {
|
||||
// 재시도 시 대기 및 카운트다운 표시
|
||||
if (retryCount > 0) {
|
||||
for (secondsLeft in totalDelaySeconds downTo 1) {
|
||||
statusMessage = "⚠️ 인증 실패. ${secondsLeft}초 후 자동으로 다시 시도합니다. (시도 ${retryCount}/${maxRetries})"
|
||||
delay(1000L) // 1초 대기
|
||||
}
|
||||
}
|
||||
|
||||
statusMessage = if (retryCount == 0) "⏳ 인증 시도 중..." else "⏳ ${retryCount}차 재시도 중..."
|
||||
|
||||
// 1. 설정값 저장
|
||||
KisSession.config = config
|
||||
DatabaseFactory.saveConfig(config)
|
||||
|
||||
// 2. 법인코드 업데이트
|
||||
DartCodeManager.updateCorpCodes(HttpClient(CIO) {
|
||||
install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true }) }
|
||||
})
|
||||
|
||||
// 3. 토큰 및 웹소켓 키 갱신
|
||||
val authSuccess = KisAuthService.refreshAllTokens()
|
||||
val wsKeySuccess = KisTradeService.refreshWebsocketKey()
|
||||
|
||||
if (authSuccess && wsKeySuccess) {
|
||||
statusMessage = "✅ 인증 성공! LLM 시작 중..."
|
||||
isAuthCompleted = true
|
||||
onAuthSuccess()
|
||||
} else {
|
||||
retryCount++
|
||||
if (retryCount > maxRetries) {
|
||||
statusMessage = "❌ 인증 실패. 3회 재시도 후 중단되었습니다. 키 정보를 확인하세요."
|
||||
}
|
||||
// 다음 루프에서 카운트다운 진입
|
||||
}
|
||||
}
|
||||
authenticateAndStart()
|
||||
}
|
||||
}
|
||||
) { Text("설정 저장 및 실행") }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user