// src/main/kotlin/ui/IntegratedOrderSection.kt package ui import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* import androidx.compose.runtime.* 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.unit.dp import androidx.compose.ui.unit.sp import kotlinx.coroutines.launch import network.KisTradeService @Composable fun IntegratedOrderSection( stockCode: String, currentPrice: String, tradeService: KisTradeService, onOrderResult: (String, Boolean) -> Unit ) { val scope = rememberCoroutineScope() var orderQty by remember { mutableStateOf("1") } var orderPrice by remember { mutableStateOf("") } // 빈 값이면 시장가 // 자동 매도 설정 var isAutoSellEnabled by remember { mutableStateOf(false) } var profitRate by remember { mutableStateOf("5.0") } var stopLossRate by remember { mutableStateOf("-3.0") } val basePrice = (if (orderPrice.isEmpty()) currentPrice.replace(",", "") else orderPrice).toDoubleOrNull() ?: 0.0 val qty = orderQty.toDoubleOrNull() ?: 0.0 Column(modifier = Modifier.fillMaxWidth().padding(8.dp)) { Text("주문 및 자동 매도 설정", style = MaterialTheme.typography.subtitle2, fontWeight = FontWeight.Bold) // 1. 가격 및 수량 입력 Row(modifier = Modifier.fillMaxWidth().padding(vertical = 8.dp)) { OutlinedTextField( value = orderQty, onValueChange = { if (it.all { c -> c.isDigit() }) orderQty = it }, label = { Text("수량") }, modifier = Modifier.weight(1f).padding(end = 4.dp) ) OutlinedTextField( value = orderPrice, onValueChange = { if (it.all { c -> c.isDigit() }) orderPrice = it }, label = { Text("가격") }, placeholder = { Text("시장가 (${currentPrice})") }, modifier = Modifier.weight(1f) ) } // 2. 수익률 시뮬레이션 표 (신규 추가) if (basePrice > 0 && qty > 0) { Text("익절/손절 시뮬레이션 (수수료/세금 약 0.22% 반영)", fontSize = 11.sp, color = Color.Gray, modifier = Modifier.padding(bottom = 4.dp)) Card(backgroundColor = Color(0xFFF1F3F5), shape = RoundedCornerShape(4.dp), elevation = 0.dp) { Column(modifier = Modifier.padding(8.dp)) { Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { SimulationColumn("수익률", listOf("+5%", "+3%", "+1%", "-1%", "-3%", "-5%"), true) SimulationColumn("목표가", listOf(1.05, 1.03, 1.01, 0.99, 0.97, 0.95).map { (basePrice * it).toLong().toString() }, false) SimulationColumn("예상수령액", listOf(1.05, 1.03, 1.01, 0.99, 0.97, 0.95).map { rate -> val sellPrice = basePrice * rate val totalAmount = sellPrice * qty val netAmount = totalAmount * (1 - 0.0022) // 수수료+세금 약 0.22% 차감 String.format("%,d", netAmount.toLong()) }, false) } } } } Spacer(modifier = Modifier.height(12.dp)) // 3. 자동 매도 옵션 Card(backgroundColor = Color(0xFFF8F9FA), elevation = 0.dp) { Column(modifier = Modifier.padding(8.dp)) { Row(verticalAlignment = Alignment.CenterVertically) { Checkbox(checked = isAutoSellEnabled, onCheckedChange = { isAutoSellEnabled = it }) Text("매수 체결 시 자동 매도 감시 시작", fontSize = 12.sp) } if (isAutoSellEnabled) { Row { OutlinedTextField( value = profitRate, onValueChange = { profitRate = it }, label = { Text("익절 %") }, modifier = Modifier.weight(1f).padding(end = 4.dp) ) OutlinedTextField( value = stopLossRate, onValueChange = { stopLossRate = it }, label = { Text("손절 %") }, modifier = Modifier.weight(1f) ) } } } } Spacer(modifier = Modifier.height(12.dp)) // 4. 매수/매도 버튼 Row(modifier = Modifier.fillMaxWidth()) { Button( onClick = { scope.launch { val finalPrice = if (orderPrice.isBlank()) "0" else orderPrice tradeService.postOrder(stockCode, orderQty, finalPrice, isBuy = true) .onSuccess { onOrderResult(it, true) if (isAutoSellEnabled) { /* 자동매도 등록 로직 호출 */ } } .onFailure { onOrderResult(it.message ?: "에러", false) } } }, modifier = Modifier.weight(1f).padding(end = 4.dp), colors = ButtonDefaults.buttonColors(backgroundColor = Color(0xFFE03E2D)) ) { Text("매수", color = Color.White) } Button( onClick = { /* 매도 로직동일 */ }, modifier = Modifier.weight(1f), colors = ButtonDefaults.buttonColors(backgroundColor = Color(0xFF0E62CF)) ) { Text("매도", color = Color.White) } } } } @Composable fun SimulationColumn(title: String, items: List, isHeader: Boolean) { Column(horizontalAlignment = Alignment.CenterHorizontally) { Text(title, fontSize = 10.sp, fontWeight = FontWeight.Bold, color = Color.DarkGray) items.forEach { text -> Text( text = text, fontSize = 11.sp, color = if (text.contains("+")) Color(0xFFE03E2D) else if (text.contains("-")) Color(0xFF0E62CF) else Color.Black, modifier = Modifier.padding(vertical = 1.dp) ) } } }