2026-01-13 16:04:25 +09:00
|
|
|
import model.AppConfig
|
2026-01-10 18:16:50 +09:00
|
|
|
import org.jetbrains.exposed.sql.*
|
|
|
|
|
import org.jetbrains.exposed.sql.javatime.datetime
|
|
|
|
|
import org.jetbrains.exposed.sql.transactions.transaction
|
|
|
|
|
import java.io.File
|
|
|
|
|
import java.time.LocalDateTime
|
|
|
|
|
|
|
|
|
|
// 1. 앱 설정 테이블
|
|
|
|
|
object ConfigTable : Table("app_config") {
|
|
|
|
|
val id = integer("id").autoIncrement()
|
2026-01-13 16:04:25 +09:00
|
|
|
val realAppKey = varchar("real_app_key", 255).default("")
|
|
|
|
|
val realSecretKey = varchar("real_secret_key", 255).default("")
|
|
|
|
|
val realAccountNo = varchar("real_account_no", 20).default("")
|
|
|
|
|
val vtsAppKey = varchar("vts_app_key", 255).default("")
|
|
|
|
|
val vtsSecretKey = varchar("vts_secret_key", 255).default("")
|
|
|
|
|
val vtsAccountNo = varchar("vts_account_no", 20).default("")
|
|
|
|
|
val isSimulation = bool("is_simulation").default(true)
|
|
|
|
|
val modelPath = varchar("model_path", 512).default("")
|
2026-01-10 18:16:50 +09:00
|
|
|
override val primaryKey = PrimaryKey(id)
|
|
|
|
|
}
|
2026-01-13 16:04:25 +09:00
|
|
|
|
2026-01-10 18:16:50 +09:00
|
|
|
// 2. 거래 내역 테이블 (대량 데이터용)
|
|
|
|
|
object TradeLogTable : Table("trade_logs") {
|
|
|
|
|
val id = long("id").autoIncrement()
|
|
|
|
|
val stockCode = varchar("stock_code", 20) // 종목코드
|
|
|
|
|
val stockName = varchar("stock_name", 50) // 종목명
|
|
|
|
|
val tradeType = varchar("trade_type", 10) // 매수/매도
|
|
|
|
|
val price = double("price") // 체결가
|
|
|
|
|
val quantity = integer("quantity") // 수량
|
|
|
|
|
val timestamp = datetime("timestamp") // 거래 시간
|
|
|
|
|
val logMessage = text("log_message") // Ollama의 판단 근거 등 상세 정보
|
|
|
|
|
override val primaryKey = PrimaryKey(id)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
object DatabaseFactory {
|
|
|
|
|
fun init() {
|
|
|
|
|
|
|
|
|
|
val dbPath =File("db/autotrade_db").absolutePath
|
|
|
|
|
// 드라이버를 org.h2.Driver로 설정
|
|
|
|
|
Database.connect(
|
|
|
|
|
"jdbc:h2:$dbPath;DB_CLOSE_DELAY=-1;",
|
|
|
|
|
driver = "org.h2.Driver"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
transaction {
|
|
|
|
|
SchemaUtils.create(ConfigTable, TradeLogTable)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun saveTradeLog(code: String, name: String, type: String, price: Double, qty: Int, msg: String) {
|
|
|
|
|
transaction {
|
|
|
|
|
TradeLogTable.insert {
|
|
|
|
|
it[stockCode] = code
|
|
|
|
|
it[stockName] = name
|
|
|
|
|
it[tradeType] = type
|
|
|
|
|
it[TradeLogTable.price] = price
|
|
|
|
|
it[quantity] = qty
|
|
|
|
|
it[timestamp] = LocalDateTime.now()
|
|
|
|
|
it[logMessage] = msg
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-13 16:04:25 +09:00
|
|
|
fun findConfigByAccount(accountNo: String): AppConfig? {
|
|
|
|
|
return transaction {
|
|
|
|
|
ConfigTable.select {
|
|
|
|
|
(ConfigTable.realAccountNo eq accountNo) or (ConfigTable.vtsAccountNo eq accountNo)
|
|
|
|
|
}.lastOrNull()?.let {
|
|
|
|
|
AppConfig(
|
|
|
|
|
realAppKey = it[ConfigTable.realAppKey],
|
|
|
|
|
realSecretKey = it[ConfigTable.realSecretKey],
|
|
|
|
|
realAccountNo = it[ConfigTable.realAccountNo],
|
|
|
|
|
vtsAppKey = it[ConfigTable.vtsAppKey],
|
|
|
|
|
vtsSecretKey = it[ConfigTable.vtsSecretKey],
|
|
|
|
|
vtsAccountNo = it[ConfigTable.vtsAccountNo],
|
|
|
|
|
isSimulation = it[ConfigTable.isSimulation],
|
|
|
|
|
modelPath = it[ConfigTable.modelPath]
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun saveConfig(config: AppConfig) {
|
|
|
|
|
transaction {
|
|
|
|
|
// 기존 설정을 모두 지우고 최신 설정 하나만 유지
|
|
|
|
|
ConfigTable.deleteAll()
|
|
|
|
|
ConfigTable.insert {
|
|
|
|
|
it[realAppKey] = config.realAppKey
|
|
|
|
|
it[realSecretKey] = config.realSecretKey
|
|
|
|
|
it[vtsAppKey] = config.vtsAppKey
|
|
|
|
|
it[vtsSecretKey] = config.vtsSecretKey
|
|
|
|
|
it[realAccountNo] = config.realAccountNo
|
|
|
|
|
it[vtsAccountNo] = config.vtsAccountNo
|
|
|
|
|
it[isSimulation] = config.isSimulation
|
|
|
|
|
it[modelPath] = config.modelPath
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-10 18:16:50 +09:00
|
|
|
}
|