....
This commit is contained in:
parent
74c3e2462d
commit
3fcce5e5c6
@ -256,10 +256,10 @@ class TradeConfig {
|
||||
var autoSellOrder : Boolean = false
|
||||
var excuteMinCheck : Int = 2
|
||||
var noticeGapTime : Int = 60
|
||||
var lowerAveragePrice : Boolean = false
|
||||
var lowerAveragePrice : Boolean = true
|
||||
var lowerAverageStockCount : Int = 1
|
||||
var lowerAverageMaxRate : Double = 1.0
|
||||
var lowerAverageMinRate : Double = 40.0
|
||||
var lowerAverageMaxRate : Double = 15.0
|
||||
var lowerAverageMinRate : Double = 25.0
|
||||
var lowerAverageTargetCount : Int = 2
|
||||
}
|
||||
|
||||
|
||||
@ -219,9 +219,9 @@ object AutoTradingManager {
|
||||
var stockName = decision.stockName
|
||||
val finalPrice = MarketUtil.roundToTickSize(oneTickLowerPrice.toDouble())
|
||||
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)) {
|
||||
|
||||
|
||||
TradingLogStore.addNotice("SYSTEM", "LIMIT", "최대 보유 종목 도달로 신규 매수 일시 중단")
|
||||
AutoTradingManager.addToReanalysis(RankingStock(mksc_shrn_iscd = stockCode,hts_kor_isnm = stockName))
|
||||
TradingLogStore.addWatchLog(decision,"WATCH","매수 실패 : 최대 보유 종목 도달로 신규 매수 일시 중단 => 재분석 대기열에 추가")
|
||||
@ -702,7 +702,7 @@ object AutoTradingManager {
|
||||
|
||||
|
||||
// 현재 노출 수가 최대 허용치보다 작을 때만 true(매수 가능) 반환
|
||||
return true//myOredsAndBalanceCodes.size < maxAllowedStocks
|
||||
return true //(currentBalance?.getHoldings()?.count { it.availOrderCount.toInt() > 0 } ?: 0) > maxAllowedStocks
|
||||
}
|
||||
|
||||
suspend fun tryRefreshToken() {
|
||||
@ -942,7 +942,10 @@ object AutoTradingManager {
|
||||
reanalysisList.clear()
|
||||
if (KisSession.tradeConfig.lowerAveragePrice) {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
||||
@ -571,7 +571,56 @@ fun TradingDecisionLog() {
|
||||
},
|
||||
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)
|
||||
@Composable
|
||||
fun SettingInputField(
|
||||
modifier: Modifier? = null,
|
||||
label: String,
|
||||
initialValue: String, // 💡 value -> initialValue 로 변경
|
||||
placeholder: String = "",
|
||||
@ -728,7 +829,7 @@ fun SettingInputField(
|
||||
// 💡 화면에 즉시 글자를 그려주기 위한 로컬 상태 (핵심 해결책)
|
||||
var localText by remember { mutableStateOf(initialValue) }
|
||||
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
Column(modifier = modifier ?: Modifier.fillMaxWidth()) {
|
||||
OutlinedTextField(
|
||||
value = localText,
|
||||
onValueChange = { localText = it }, // 타자 칠 때 화면 즉시 반영
|
||||
@ -767,6 +868,7 @@ fun SettingInputField(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun SettingSwitchField(
|
||||
label: String,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user