This commit is contained in:
2026-01-23 17:05:09 +09:00
parent ac50737ea8
commit d89d793efa
16 changed files with 665 additions and 256 deletions
+32 -28
View File
@@ -2,15 +2,10 @@ package ui
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import TradingDecision
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items // 반드시 수동 import 확인
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.*
import io.ktor.client.engine.cio.CIO
// 아래 두 import가 'delegate' 에러를 해결합니다.
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
@@ -18,20 +13,15 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import model.AppConfig
import model.BalanceSummary
import model.CandleData
import model.RankingStock
import model.StockHolding
import network.DartCodeManager
import network.KisTradeService
import network.KisWebSocketManager
import network.NewsService
import service.TechnicalAnalyzer
import java.time.LocalTime
import java.time.format.DateTimeFormatter
@@ -41,11 +31,12 @@ import kotlin.collections.isNotEmpty
fun StockDetailSection(
stockCode: String,
stockName: String,
holdingQuantity : String,
holdingQuantity: String,
isDomestic: Boolean,
tradeService: KisTradeService,
wsManager: KisWebSocketManager,
onOrderSaved: (String) -> Unit
onOrderSaved: (String) -> Unit,
completeTradingDecision: TradingDecision?
) {
var openPrice by remember { mutableStateOf("0") }
@@ -65,11 +56,7 @@ fun StockDetailSection(
if (daySummary.size >= 2) daySummary[daySummary.size - 2].stck_prpr else "0"
}
fun calculateAvg(data: List<CandleData>): String {
if (data.isEmpty()) return "0"
val avg = data.map { it.stck_prpr.toDoubleOrNull() ?: 0.0 }.average()
return String.format("%,d", avg.toLong())
}
// 이전 종목 코드를 기억하기 위한 상태
var previousCode by remember { mutableStateOf("") }
@@ -88,6 +75,7 @@ fun StockDetailSection(
wsManager.subscribeStock(stockCode)
previousCode = stockCode
// 2. 차트 데이터 로드 (KisSession 기반으로 파라미터 간소화)
coroutineScope {
@@ -101,18 +89,33 @@ fun StockDetailSection(
.onFailure { error ->
println("❌ 차트 데이터 로드 실패: ${error.localizedMessage}")
chartData = emptyList()
}}
}
}
launch { tradeService.fetchPeriodChartData(stockCode, "D").onSuccess {
daySummary = it.takeLast(7) }
TechnicalAnalyzer.daily = daySummary
daySummary = it.takeLast(7)
TechnicalAnalyzer.daily = it
println("daySummary ${daySummary.size} total: ${it.size} ${it.firstOrNull()?.toString()}")
}
} // 최근 7일
launch { tradeService.fetchPeriodChartData(stockCode, "W").onSuccess { weekSummary = it.takeLast(4) }
TechnicalAnalyzer.weekly = weekSummary} // 최근 4주
launch { tradeService.fetchPeriodChartData(stockCode, "W").onSuccess {
weekSummary = it.takeLast(4)
TechnicalAnalyzer.weekly = it
println("weekSummary ${weekSummary.size} total: ${it.size} ${it.firstOrNull()?.toString()}")
}
} // 최근 4주
launch { tradeService.fetchPeriodChartData(stockCode, "M").onSuccess {
monthSummary = it.takeLast(6) // 최근 6개월
yearSummary = it.takeLast(36) // 최근 3년
TechnicalAnalyzer.monthly = yearSummary
}}
TechnicalAnalyzer.monthly = it
println("monthSummary ${monthSummary.size} yearSummary ${yearSummary.size} total: ${it.size} ${it.firstOrNull()?.toString()}")
}
}
launch {
DartCodeManager.getCorpCode(stockCode)?.let {
it.stockName = stockName
NewsService.fetchAndIngestNews(it)
}
}
}
isLoading = false
}
@@ -230,7 +233,8 @@ fun StockDetailSection(
onOrderResult = { msg, success ->
resultMessage = msg
isSuccess = success
}
},
completeTradingDecision
)
}
}