....
This commit is contained in:
parent
74c3e2462d
commit
3fcce5e5c6
@ -256,10 +256,10 @@ class TradeConfig {
|
|||||||
var autoSellOrder : Boolean = false
|
var autoSellOrder : Boolean = false
|
||||||
var excuteMinCheck : Int = 2
|
var excuteMinCheck : Int = 2
|
||||||
var noticeGapTime : Int = 60
|
var noticeGapTime : Int = 60
|
||||||
var lowerAveragePrice : Boolean = false
|
var lowerAveragePrice : Boolean = true
|
||||||
var lowerAverageStockCount : Int = 1
|
var lowerAverageStockCount : Int = 1
|
||||||
var lowerAverageMaxRate : Double = 1.0
|
var lowerAverageMaxRate : Double = 15.0
|
||||||
var lowerAverageMinRate : Double = 40.0
|
var lowerAverageMinRate : Double = 25.0
|
||||||
var lowerAverageTargetCount : Int = 2
|
var lowerAverageTargetCount : Int = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -219,7 +219,7 @@ object AutoTradingManager {
|
|||||||
var stockName = decision.stockName
|
var stockName = decision.stockName
|
||||||
val finalPrice = MarketUtil.roundToTickSize(oneTickLowerPrice.toDouble())
|
val finalPrice = MarketUtil.roundToTickSize(oneTickLowerPrice.toDouble())
|
||||||
val maxStocks = KisSession.config.getValues(ConfigIndex.MAX_HOLDING_COUNT).toInt()
|
val maxStocks = KisSession.config.getValues(ConfigIndex.MAX_HOLDING_COUNT).toInt()
|
||||||
|
var hasCodes = currentBalance?.getHoldings()?.any { it.code.equals(decision.stockCode) && it.quantity.toInt() > 2 && !it.isTodayEntry}
|
||||||
if (!canAddNewPosition(maxStocks)) {
|
if (!canAddNewPosition(maxStocks)) {
|
||||||
|
|
||||||
TradingLogStore.addNotice("SYSTEM", "LIMIT", "최대 보유 종목 도달로 신규 매수 일시 중단")
|
TradingLogStore.addNotice("SYSTEM", "LIMIT", "최대 보유 종목 도달로 신규 매수 일시 중단")
|
||||||
@ -702,7 +702,7 @@ object AutoTradingManager {
|
|||||||
|
|
||||||
|
|
||||||
// 현재 노출 수가 최대 허용치보다 작을 때만 true(매수 가능) 반환
|
// 현재 노출 수가 최대 허용치보다 작을 때만 true(매수 가능) 반환
|
||||||
return true//myOredsAndBalanceCodes.size < maxAllowedStocks
|
return true //(currentBalance?.getHoldings()?.count { it.availOrderCount.toInt() > 0 } ?: 0) > maxAllowedStocks
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun tryRefreshToken() {
|
suspend fun tryRefreshToken() {
|
||||||
@ -942,7 +942,10 @@ object AutoTradingManager {
|
|||||||
reanalysisList.clear()
|
reanalysisList.clear()
|
||||||
if (KisSession.tradeConfig.lowerAveragePrice) {
|
if (KisSession.tradeConfig.lowerAveragePrice) {
|
||||||
currentBalance?.getHoldings()?.map {
|
currentBalance?.getHoldings()?.map {
|
||||||
if(!it.isTodayEntry && it.quantity.toInt() > KisSession.tradeConfig.lowerAverageTargetCount && it.profitRate.toDouble() < (KisSession.tradeConfig.lowerAverageMaxRate * -1) && it.profitRate.toDouble() > (KisSession.tradeConfig.lowerAverageMinRate * -1) ) {
|
if(!it.isTodayEntry &&
|
||||||
|
it.quantity.toInt() > KisSession.tradeConfig.lowerAverageTargetCount &&
|
||||||
|
it.profitRate.toDouble() < (KisSession.tradeConfig.lowerAverageMaxRate * -1) &&
|
||||||
|
it.profitRate.toDouble() > (KisSession.tradeConfig.lowerAverageMinRate * -1) ) {
|
||||||
remainingCandidates.add(RankingStock(mksc_shrn_iscd = it.code, hts_kor_isnm = it.name))
|
remainingCandidates.add(RankingStock(mksc_shrn_iscd = it.code, hts_kor_isnm = it.name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -571,7 +571,56 @@ fun TradingDecisionLog() {
|
|||||||
},
|
},
|
||||||
helperText = "본인의 텔레그램 아뒤"
|
helperText = "본인의 텔레그램 아뒤"
|
||||||
)
|
)
|
||||||
|
SettingSwitchField(
|
||||||
|
label = "물타기",
|
||||||
|
initialChecked = tradeConfig.lowerAveragePrice,
|
||||||
|
onCheckedChange = { tradeConfig.lowerAveragePrice = it
|
||||||
|
KisSession.saveTradeConfig() }
|
||||||
|
)
|
||||||
|
Row(horizontalArrangement = Arrangement.SpaceEvenly) {
|
||||||
|
SettingInputField(
|
||||||
|
modifier = Modifier.weight(1.0f, true),
|
||||||
|
label = "물타기 최저선",
|
||||||
|
initialValue = (tradeConfig.lowerAverageMaxRate).toString(),
|
||||||
|
onSave = {
|
||||||
|
tradeConfig.lowerAverageMaxRate = it.toDouble()
|
||||||
|
KisSession.saveTradeConfig()
|
||||||
|
},
|
||||||
|
helperText = "이것보다 커야 삼"
|
||||||
|
)
|
||||||
|
SettingInputField(
|
||||||
|
modifier = Modifier.weight(1.0f, true),
|
||||||
|
label = "물타기 최고선",
|
||||||
|
initialValue = (tradeConfig.lowerAverageMinRate).toString(),
|
||||||
|
onSave = {
|
||||||
|
tradeConfig.lowerAverageMinRate = it.toDouble()
|
||||||
|
KisSession.saveTradeConfig()
|
||||||
|
},
|
||||||
|
helperText = "이것보다 작아야 삼"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Row(horizontalArrangement = Arrangement.SpaceEvenly) {
|
||||||
|
SettingInputField(
|
||||||
|
modifier = Modifier.weight(1.0f, true),
|
||||||
|
label = "물타기 기준 최소 보유 수량",
|
||||||
|
initialValue = (tradeConfig.lowerAverageTargetCount).toString(),
|
||||||
|
onSave = {
|
||||||
|
tradeConfig.lowerAverageTargetCount = it.toInt()
|
||||||
|
KisSession.saveTradeConfig()
|
||||||
|
},
|
||||||
|
helperText = "이거 이상 갖고 있어야 삼"
|
||||||
|
)
|
||||||
|
SettingInputField(
|
||||||
|
modifier = Modifier.weight(1.0f, true),
|
||||||
|
label = "물타기 개수",
|
||||||
|
initialValue = (tradeConfig.lowerAverageStockCount).toString(),
|
||||||
|
onSave = {
|
||||||
|
tradeConfig.lowerAverageStockCount = it.toInt()
|
||||||
|
KisSession.saveTradeConfig()
|
||||||
|
},
|
||||||
|
helperText = "1만큼 사고 팜"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -716,9 +765,61 @@ fun CsvDropZone(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//@OptIn(ExperimentalMaterialApi::class)
|
||||||
|
//@Composable
|
||||||
|
//fun SettingInputField(
|
||||||
|
// label: String,
|
||||||
|
// initialValue: String, // 💡 value -> initialValue 로 변경
|
||||||
|
// placeholder: String = "",
|
||||||
|
// helperText: String = "",
|
||||||
|
// onSave: (String) -> Unit // 💡 타자 칠 때마다가 아니라, 완료 시 저장하도록 콜백 변경
|
||||||
|
//) {
|
||||||
|
// // 💡 화면에 즉시 글자를 그려주기 위한 로컬 상태 (핵심 해결책)
|
||||||
|
// var localText by remember { mutableStateOf(initialValue) }
|
||||||
|
//
|
||||||
|
// Column(modifier = Modifier.fillMaxWidth()) {
|
||||||
|
// OutlinedTextField(
|
||||||
|
// value = localText,
|
||||||
|
// onValueChange = { localText = it }, // 타자 칠 때 화면 즉시 반영
|
||||||
|
// label = { Text(label, fontWeight = FontWeight.Bold) },
|
||||||
|
// placeholder = { Text(placeholder) },
|
||||||
|
// modifier = Modifier
|
||||||
|
// .fillMaxWidth()
|
||||||
|
// .onFocusChanged { focusState ->
|
||||||
|
// // 💡 포커스를 잃었을 때 (다른 칸을 클릭했을 때) 저장
|
||||||
|
// if (!focusState.isFocused) {
|
||||||
|
// onSave(localText)
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// singleLine = true,
|
||||||
|
// keyboardOptions = KeyboardOptions(
|
||||||
|
// imeAction = ImeAction.Done,
|
||||||
|
// keyboardType = KeyboardType.Decimal
|
||||||
|
// ),
|
||||||
|
// keyboardActions = KeyboardActions(
|
||||||
|
// // 💡 모바일 키보드나 키보드에서 엔터(Done) 쳤을 때 저장
|
||||||
|
// onDone = {
|
||||||
|
// onSave(localText)
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// if (helperText.isNotEmpty()) {
|
||||||
|
// Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
// Text(
|
||||||
|
// text = helperText,
|
||||||
|
// color = Color.Gray,
|
||||||
|
// fontSize = 11.sp,
|
||||||
|
// modifier = Modifier.padding(start = 4.dp)
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterialApi::class)
|
@OptIn(ExperimentalMaterialApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingInputField(
|
fun SettingInputField(
|
||||||
|
modifier: Modifier? = null,
|
||||||
label: String,
|
label: String,
|
||||||
initialValue: String, // 💡 value -> initialValue 로 변경
|
initialValue: String, // 💡 value -> initialValue 로 변경
|
||||||
placeholder: String = "",
|
placeholder: String = "",
|
||||||
@ -728,7 +829,7 @@ fun SettingInputField(
|
|||||||
// 💡 화면에 즉시 글자를 그려주기 위한 로컬 상태 (핵심 해결책)
|
// 💡 화면에 즉시 글자를 그려주기 위한 로컬 상태 (핵심 해결책)
|
||||||
var localText by remember { mutableStateOf(initialValue) }
|
var localText by remember { mutableStateOf(initialValue) }
|
||||||
|
|
||||||
Column(modifier = Modifier.fillMaxWidth()) {
|
Column(modifier = modifier ?: Modifier.fillMaxWidth()) {
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
value = localText,
|
value = localText,
|
||||||
onValueChange = { localText = it }, // 타자 칠 때 화면 즉시 반영
|
onValueChange = { localText = it }, // 타자 칠 때 화면 즉시 반영
|
||||||
@ -767,6 +868,7 @@ fun SettingInputField(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingSwitchField(
|
fun SettingSwitchField(
|
||||||
label: String,
|
label: String,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user