atrade/src/main/kotlin/model/AppConfig.kt

225 lines
9.5 KiB
Kotlin
Raw Normal View History

2026-01-10 18:16:50 +09:00
package model
2026-01-13 16:04:25 +09:00
import java.time.LocalDateTime
2026-01-10 18:16:50 +09:00
2026-02-19 15:47:31 +09:00
enum class ConfigIndex(val index : Int,val label : String) {
TAX_INDEX(0,"세금 및 수수료"),
PROFIT_INDEX(TAX_INDEX.index + 1 , "기준 수익률"),
BUY_WEIGHT_INDEX(PROFIT_INDEX.index + 1, "매수 가중치"),
MAX_BUDGET_INDEX(BUY_WEIGHT_INDEX.index + 1, "종목 당 최대 투자금"),
MAX_PRICE_INDEX(MAX_BUDGET_INDEX.index + 1 , "단일 종목 주당 최대 금액"),
MIN_PRICE_INDEX(MAX_PRICE_INDEX.index + 1, "단일 종목 주당 최소 금액"),
MIN_PURCHASE_SCORE_INDEX(MIN_PRICE_INDEX.index + 1, "주문 최소 기준 점수"),
2026-03-13 16:37:53 +09:00
MAX_COUNT_INDEX(MIN_PURCHASE_SCORE_INDEX.index + 1, "단일 종목 최대 주문 개수"),
SELL_PROFIT(MAX_COUNT_INDEX.index + 1, "보유 주식 매도 기준 수익율"),
2026-02-19 15:47:31 +09:00
2026-03-13 16:37:53 +09:00
GRADE_5_BUY(SELL_PROFIT.index + 1, "강력 추천 투자 매수 기준"),
2026-02-19 15:47:31 +09:00
GRADE_4_BUY(GRADE_5_BUY.index + 1, "안정적 투자 매수 기준"),
GRADE_3_BUY(GRADE_4_BUY.index + 1, "보수적 투자 매수 기준"),
GRADE_2_BUY(GRADE_3_BUY.index + 10, "하이리스크,리턴 매수 기준"),
GRADE_1_BUY(GRADE_2_BUY.index + 1, "공격적초단기 매수 기준"),
GRADE_5_PROFIT(GRADE_1_BUY.index + 1, "강력 추천 투자 목표 수익 비율"),
GRADE_4_PROFIT(GRADE_5_PROFIT.index + 1, "안정적 투자 목표 수익 비율"),
GRADE_3_PROFIT(GRADE_4_PROFIT.index + 1, "보수적 투자 목표 수익 비율"),
GRADE_2_PROFIT(GRADE_3_PROFIT.index + 1, "하이리스크,리턴 목표 수익 비율"),
2026-04-02 14:05:14 +09:00
GRADE_1_PROFIT(GRADE_2_PROFIT.index + 1, "공격적초단기 목표 수익 비율"),
GRADE_5_ALLOCATIONRATE(GRADE_1_PROFIT.index + 1, "강력 추천 투자 목표 투자금 비율"),
GRADE_4_ALLOCATIONRATE(GRADE_5_ALLOCATIONRATE.index + 1, "안정적 투자 목표 투자금 비율"),
GRADE_3_ALLOCATIONRATE(GRADE_4_ALLOCATIONRATE.index + 1, "보수적 투자 목표 투자금 비율"),
GRADE_2_ALLOCATIONRATE(GRADE_3_ALLOCATIONRATE.index + 1, "하이리스크,리턴 목표 투자금 비율"),
2026-04-02 15:22:38 +09:00
GRADE_1_ALLOCATIONRATE(GRADE_2_ALLOCATIONRATE.index + 1, "공격적초단기 목표 투자금 비율"),
TAKE_PROFIT(GRADE_1_ALLOCATIONRATE.index + 1, "보유 주식 자동 매매 활성") ,
STOP_LOSS(TAKE_PROFIT.index + 1, "손절 활성 여부 (최소율~최대율 사이의 최대 금액 이하로 자동 손절)") ,
LOSS_MINRATE(STOP_LOSS.index + 1, "손절 최소 기준") ,
LOSS_MAXRATE(LOSS_MINRATE.index + 1, "손절 최소 기준") ,
LOSS_MAX_MONEY(LOSS_MAXRATE.index + 1, "손절 최대 금액") ,
;
2026-04-02 14:05:14 +09:00
2026-02-19 15:47:31 +09:00
companion object {
fun get(index : Int) = ConfigIndex.entries[index]
}
}
2026-01-10 18:16:50 +09:00
data class AppConfig(
2026-01-13 16:04:25 +09:00
// [DB 저장 데이터]
// 실전 3종
val realAppKey: String = "",
val realSecretKey: String = "",
val realAccountNo: String = "",
// 모의 3종
val vtsAppKey: String = "",
val vtsSecretKey: String = "",
val vtsAccountNo: String = "",
2026-03-13 11:06:20 +09:00
// 모의 3종
val nAppKey: String = "",
val nSecretKey: String = "",
val dAppKey: String = "",
2026-01-13 16:04:25 +09:00
// [세션 데이터 - 메모리에서만 관리]
var marketToken: String = "",
var marketTokenExpiredAt: LocalDateTime? = null, // 만료 시간 추가
var tradeToken: String = "",
var tradeTokenExpiredAt: LocalDateTime? = null,
2026-01-14 15:42:26 +09:00
val htsId: String = "",
2026-01-13 16:04:25 +09:00
var websocketToken: String = "",
2026-01-10 18:16:50 +09:00
val isSimulation: Boolean = true,
2026-01-21 18:30:03 +09:00
val modelPath: String = "",
2026-02-19 15:47:31 +09:00
val embedModelPath: String = "",
var FEES_AND_TAXRATE: Double = 0.33,
var MINIMUM_NET_PROFIT: Double = 0.8,
var BUY_WEIGHT: Double = 2.0,
var MAX_BUDGET: Double = 80000.0,
var MAX_PRICE: Double = 40000.0,
var MIN_PRICE: Double = 800.0,
var MIN_PURCHASE_SCORE: Double = 65.0,
2026-03-13 16:37:53 +09:00
var SELL_PROFIT: Double = 1.3,
2026-02-19 15:47:31 +09:00
var GRADE_5_BUY : Int = 0,
var GRADE_4_BUY : Int = 1,
var GRADE_3_BUY : Int = 2,
var GRADE_2_BUY : Int = 2,
var GRADE_1_BUY : Int = 3,
var GRADE_5_PROFIT : Double = 1.8,
var GRADE_4_PROFIT : Double = 1.3,
var GRADE_3_PROFIT : Double = 0.9,
var GRADE_2_PROFIT : Double = 0.7,
var GRADE_1_PROFIT : Double = 0.5,
2026-04-02 14:05:14 +09:00
2026-04-02 15:22:38 +09:00
var GRADE_5_ALLOCATIONRATE : Double = 1.0,
var GRADE_4_ALLOCATIONRATE : Double = 0.8,
var GRADE_3_ALLOCATIONRATE : Double = 0.6,
var GRADE_2_ALLOCATIONRATE : Double = 0.4,
var GRADE_1_ALLOCATIONRATE : Double = 0.3,
2026-02-19 15:47:31 +09:00
var MAX_COUNT : Int = 20,
2026-04-02 15:22:38 +09:00
var take_profit : Boolean = false,
var stop_Loss : Boolean = false,
var loss_min : Double = 3.5,
var loss_max : Double = 10.0,
var loss_money : Double = 10000.0,
2026-02-19 15:47:31 +09:00
) {
2026-01-13 16:04:25 +09:00
val accountNo : String
get() {
return if (isSimulation) vtsAccountNo else realAccountNo
}
2026-02-19 15:47:31 +09:00
fun setValues(index :ConfigIndex , value : Double) {
when (index) {
ConfigIndex.TAX_INDEX -> {FEES_AND_TAXRATE = value}
ConfigIndex.PROFIT_INDEX -> {MINIMUM_NET_PROFIT = value}
ConfigIndex.MAX_PRICE_INDEX -> {MAX_PRICE = value}
ConfigIndex.MIN_PRICE_INDEX -> {MIN_PRICE = value}
ConfigIndex.BUY_WEIGHT_INDEX -> {BUY_WEIGHT = value}
ConfigIndex.MAX_BUDGET_INDEX -> {MAX_BUDGET = value}
ConfigIndex.MIN_PURCHASE_SCORE_INDEX -> {MIN_PURCHASE_SCORE = value}
2026-03-13 16:37:53 +09:00
ConfigIndex.SELL_PROFIT -> {SELL_PROFIT = value}
2026-02-19 15:47:31 +09:00
ConfigIndex.GRADE_5_PROFIT -> {GRADE_5_PROFIT = value}
ConfigIndex.GRADE_4_PROFIT -> {GRADE_4_PROFIT = value}
ConfigIndex.GRADE_3_PROFIT -> {GRADE_3_PROFIT = value}
ConfigIndex.GRADE_2_PROFIT -> {GRADE_2_PROFIT = value}
ConfigIndex.GRADE_1_PROFIT -> {GRADE_1_PROFIT = value}
ConfigIndex.GRADE_5_BUY -> {GRADE_5_BUY = value.toInt()}
ConfigIndex.GRADE_4_BUY -> {GRADE_4_BUY = value.toInt()}
ConfigIndex.GRADE_3_BUY -> {GRADE_3_BUY = value.toInt()}
ConfigIndex.GRADE_2_BUY -> {GRADE_2_BUY = value.toInt()}
ConfigIndex.GRADE_1_BUY -> {GRADE_1_BUY = value.toInt()}
2026-04-02 14:05:14 +09:00
2026-02-19 15:47:31 +09:00
ConfigIndex.MAX_COUNT_INDEX -> {MAX_COUNT = value.toInt()}
2026-04-02 14:05:14 +09:00
2026-04-02 15:22:38 +09:00
ConfigIndex.GRADE_5_ALLOCATIONRATE -> {GRADE_5_ALLOCATIONRATE = value}
ConfigIndex.GRADE_4_ALLOCATIONRATE -> {GRADE_4_ALLOCATIONRATE = value}
ConfigIndex.GRADE_3_ALLOCATIONRATE -> {GRADE_3_ALLOCATIONRATE = value}
ConfigIndex.GRADE_2_ALLOCATIONRATE -> {GRADE_2_ALLOCATIONRATE = value}
ConfigIndex.GRADE_1_ALLOCATIONRATE -> {GRADE_1_ALLOCATIONRATE = value}
ConfigIndex.LOSS_MAXRATE -> { loss_max = value}
ConfigIndex.LOSS_MINRATE -> { loss_min = value}
ConfigIndex.LOSS_MAX_MONEY -> { loss_money = value}
ConfigIndex.STOP_LOSS -> { stop_Loss = value > 0.1}
ConfigIndex.TAKE_PROFIT -> { take_profit = value > 0.1 }
2026-02-19 15:47:31 +09:00
}
}
fun getValues(index :ConfigIndex) : Double {
return when (index) {
ConfigIndex.TAX_INDEX -> {
FEES_AND_TAXRATE
}
ConfigIndex.PROFIT_INDEX -> {
MINIMUM_NET_PROFIT
}
ConfigIndex.MAX_PRICE_INDEX -> {
MAX_PRICE
}
ConfigIndex.MIN_PRICE_INDEX -> {
MIN_PRICE
}
ConfigIndex.BUY_WEIGHT_INDEX -> {
BUY_WEIGHT
}
ConfigIndex.MAX_BUDGET_INDEX -> {
MAX_BUDGET
}
ConfigIndex.MIN_PURCHASE_SCORE_INDEX -> {
MIN_PURCHASE_SCORE
}
2026-03-13 16:37:53 +09:00
ConfigIndex.SELL_PROFIT -> {SELL_PROFIT }
2026-02-19 15:47:31 +09:00
ConfigIndex.GRADE_5_BUY -> {GRADE_5_BUY.toDouble()}
ConfigIndex.GRADE_4_BUY -> {GRADE_4_BUY.toDouble()}
ConfigIndex.GRADE_3_BUY -> {GRADE_3_BUY.toDouble()}
ConfigIndex.GRADE_2_BUY -> {GRADE_2_BUY.toDouble()}
ConfigIndex.GRADE_1_BUY -> {GRADE_1_BUY.toDouble()}
ConfigIndex.GRADE_5_PROFIT -> {GRADE_5_PROFIT}
ConfigIndex.GRADE_4_PROFIT -> {GRADE_4_PROFIT}
ConfigIndex.GRADE_3_PROFIT -> {GRADE_3_PROFIT}
ConfigIndex.GRADE_2_PROFIT -> {GRADE_2_PROFIT}
ConfigIndex.GRADE_1_PROFIT -> {GRADE_1_PROFIT}
2026-04-02 14:05:14 +09:00
ConfigIndex.GRADE_5_ALLOCATIONRATE -> {GRADE_5_ALLOCATIONRATE}
ConfigIndex.GRADE_4_ALLOCATIONRATE -> {GRADE_4_ALLOCATIONRATE}
ConfigIndex.GRADE_3_ALLOCATIONRATE -> {GRADE_3_ALLOCATIONRATE}
ConfigIndex.GRADE_2_ALLOCATIONRATE -> {GRADE_2_ALLOCATIONRATE}
ConfigIndex.GRADE_1_ALLOCATIONRATE -> {GRADE_1_ALLOCATIONRATE}
2026-04-02 15:22:38 +09:00
ConfigIndex.LOSS_MAXRATE -> { loss_max}
ConfigIndex.LOSS_MINRATE -> { loss_min}
ConfigIndex.LOSS_MAX_MONEY -> { loss_money }
ConfigIndex.STOP_LOSS -> {if(!stop_Loss) 0.0 else 1.0}
ConfigIndex.TAKE_PROFIT -> {if(!take_profit) 0.0 else 1.0}
2026-02-19 15:47:31 +09:00
ConfigIndex.MAX_COUNT_INDEX -> {MAX_COUNT.toDouble()}
}
}
2026-01-13 16:04:25 +09:00
}
// [신규] 전역에서 참조할 단일 세션 객체
object KisSession {
var config: AppConfig = AppConfig()
2026-01-19 17:09:37 +09:00
fun getWebSocketKey() = config.websocketToken
2026-01-13 16:04:25 +09:00
// 시장 데이터 토큰 유효성 검사 (만료 5분 전부터는 유효하지 않은 것으로 간주)
fun isMarketTokenValid(): Boolean {
return config.marketToken.isNotEmpty() &&
config.marketTokenExpiredAt?.isAfter(LocalDateTime.now().plusMinutes(5)) ?: false
}
// 매매용 토큰 유효성 검사
fun isTradeTokenValid(): Boolean {
return config.tradeToken.isNotEmpty() &&
config.tradeTokenExpiredAt?.isAfter(LocalDateTime.now().plusMinutes(5)) ?: false
}
}