..
This commit is contained in:
parent
0413fa3e2e
commit
d7efc433bd
@ -328,6 +328,7 @@ fun main() = application {
|
||||
// DashboardScreen()
|
||||
}
|
||||
AppScreen.TradingDecision -> {
|
||||
|
||||
TradingDecisionLog()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,16 @@
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.Serializable
|
||||
import model.AppConfig
|
||||
import model.TradingDecision
|
||||
import network.NewsService
|
||||
import org.jetbrains.exposed.sql.*
|
||||
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
|
||||
import org.jetbrains.exposed.sql.javatime.datetime
|
||||
import org.jetbrains.exposed.sql.transactions.experimental.suspendedTransactionAsync
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import report.TradingReportManager
|
||||
import report.TradingReportService
|
||||
@ -509,11 +515,21 @@ object TradingLogStore {
|
||||
decisionLogs.add(
|
||||
LogEntry(
|
||||
time = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")),
|
||||
stockName = "${tradingDecision.stockName}[${tradingDecision.currentPrice}][]",
|
||||
stockName = "${tradingDecision.stockName}[${tradingDecision.currentPrice}]",
|
||||
decision = decision,
|
||||
confidence = tradingDecision.confidence,
|
||||
reason = log
|
||||
)
|
||||
).apply {
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
println("CALLED sendTelegramMessage -1")
|
||||
if (decision.contains("WATCH") || ((tradingDecision.investmentGrade?.ordinal
|
||||
?: 0) < 2)
|
||||
) {
|
||||
println("CALLED sendTelegramMessage OK")
|
||||
NewsService.sendTelegramMessage("${this@apply.decision} ${tradingDecision.stockName}[${tradingDecision.currentPrice}] ${log}")
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -545,8 +561,14 @@ object TradingLogStore {
|
||||
decision = "NOTICE",
|
||||
confidence = 100.0,
|
||||
reason = log
|
||||
)
|
||||
).apply {
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
println("CALLED sendTelegramMessage")
|
||||
NewsService.sendTelegramMessage("${this@apply.decision}$name[$code] ${log}")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -240,6 +240,7 @@ class TradeConfig {
|
||||
var start_buy_time : String = "08:55"
|
||||
var end_buy_time : String = "15:10"
|
||||
var enableOverSea : Boolean = false
|
||||
var tlg_id : String = ""
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ object KisTradeService {
|
||||
// [수정] 모든 로그(Headers + Body)를 찍도록 설정
|
||||
install(Logging) {
|
||||
logger = Logger.DEFAULT
|
||||
level = LogLevel.NONE
|
||||
level = LogLevel.ALL
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,10 +17,14 @@ import io.ktor.client.request.post
|
||||
import io.ktor.client.request.setBody
|
||||
import io.ktor.client.statement.HttpResponse
|
||||
import io.ktor.client.statement.bodyAsText
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.ContentType.Application.Json
|
||||
import io.ktor.http.HttpHeaders
|
||||
import io.ktor.http.HttpStatusCode
|
||||
import io.ktor.http.Parameters
|
||||
import io.ktor.http.Url
|
||||
import io.ktor.http.contentType
|
||||
import io.ktor.network.tls.TLSConfigBuilder
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
@ -29,10 +33,16 @@ import model.KisSession
|
||||
import model.NaverNewsResponse
|
||||
import service.SafeScraper
|
||||
import service.UrlCacheManager
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import java.net.URL
|
||||
import java.net.URLEncoder
|
||||
import java.time.ZonedDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.temporal.ChronoUnit
|
||||
import java.util.Locale
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
import javax.net.ssl.SSLContext
|
||||
import kotlin.Double
|
||||
|
||||
object NewsService {
|
||||
@ -122,4 +132,62 @@ object NewsService {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun sendTelegramMessage(data: String) {
|
||||
Thread {
|
||||
try {
|
||||
|
||||
var chatId = KisSession.tradeConfig.tlg_id
|
||||
println("sendTelegramMessage $chatId")
|
||||
sendViaSystemCurl("https://lunaticbum.kr/tlg/sendToMe.bjx",chatId,data)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}.start()
|
||||
}
|
||||
|
||||
fun sendViaSystemCurl(url : String, chatId: String, message: String) {
|
||||
try {
|
||||
// 메시지 내 공백이나 한글이 깨지지 않도록 인코딩 (필수)
|
||||
val encodedMessage = URLEncoder.encode(message, "UTF-8")
|
||||
|
||||
// OS 확인
|
||||
val isWindows = System.getProperty("os.name").lowercase().contains("win")
|
||||
|
||||
val command = if (isWindows) {
|
||||
// 윈도우용: 큰따옴표 이스케이프에 주의해야 합니다.
|
||||
val jsonBody = "{\"id\":\"$chatId\",\"message\":\"$encodedMessage\"}"
|
||||
listOf("cmd", "/c", "curl -s -X POST $url -H \"Content-Type: application/json\" -d \"$jsonBody\"")
|
||||
} else {
|
||||
// 맥/리눅스용: 홑따옴표를 사용하여 JSON 구조를 보호합니다.
|
||||
val jsonBody = "{\"id\":\"$chatId\",\"message\":\"$message\"}"
|
||||
listOf("curl", "-s", "-X", "POST", url, "-H", "Content-Type: application/json", "-d", jsonBody)
|
||||
}
|
||||
|
||||
val process = ProcessBuilder(command)
|
||||
.redirectErrorStream(true) // 에러 출력(stderr)을 표준 출력(stdout)으로 합침
|
||||
.start()
|
||||
|
||||
// 프로세스의 출력을 읽어오는 블록
|
||||
BufferedReader(InputStreamReader(process.inputStream)).use { reader ->
|
||||
val output = StringBuilder()
|
||||
var line: String?
|
||||
while (reader.readLine().also { line = it } != null) {
|
||||
output.append(line).append("\n")
|
||||
}
|
||||
|
||||
val exitCode = process.waitFor() // 프로세스가 종료될 때까지 대기
|
||||
|
||||
println("--- Telegram Curl Log Start ---")
|
||||
println("Exit Code: $exitCode") // 0이면 성공, 그 외는 curl 에러 코드
|
||||
println("Response:\n$output")
|
||||
println("--- Telegram Curl Log End ---")
|
||||
}
|
||||
|
||||
} catch (e: Exception) {
|
||||
println("시스템 명령어 실행 중 예외 발생: ${e.message}")
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -45,6 +45,7 @@ import java.awt.Toolkit
|
||||
import java.awt.datatransfer.DataFlavor
|
||||
import java.io.File
|
||||
import androidx.compose.ui.input.key.*
|
||||
import network.NewsService
|
||||
|
||||
fun getPastedPathFromClipboard(): String? {
|
||||
val clipboard = Toolkit.getDefaultToolkit().systemClipboard
|
||||
@ -138,6 +139,7 @@ fun SettingsScreen(onAuthSuccess: () -> Unit) {
|
||||
SystemSleepPreventer.wakeDisplay() // 모니터 켜기
|
||||
statusMessage = "⏰ 자동 실행 시간(08:30)입니다. 시스템을 가동합니다."
|
||||
authenticateAndStart()
|
||||
|
||||
break // 성공하면 루프 탈출
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,10 +42,13 @@ import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import model.ConfigIndex
|
||||
import model.KisSession
|
||||
import network.KisTradeService
|
||||
import network.NewsService
|
||||
import network.StockUniverseLoader
|
||||
import service.AutoTradingManager
|
||||
import java.io.File
|
||||
@ -62,7 +65,13 @@ fun TradingDecisionLog() {
|
||||
var llmAnalyser by remember { mutableStateOf(AutoTradingManager.llmAnalyser) }
|
||||
val tradeConfig by remember {
|
||||
KisSession.tradeConfig = KisSession.loadTradeConfig()
|
||||
CoroutineScope(Dispatchers.Default).launch {
|
||||
println("CALLED sendTelegramMessage -1")
|
||||
val now = java.time.LocalTime.now(java.time.ZoneId.of("Asia/Seoul"))
|
||||
NewsService.sendTelegramMessage("⏰ 자동 실행 시간(${now.hour}:${now.minute})입니다. 시스템을 가동합니다.")
|
||||
}
|
||||
mutableStateOf(KisSession.tradeConfig)
|
||||
|
||||
}
|
||||
LaunchedEffect(AutoTradingManager.llmAnalyser) {
|
||||
llmAnalyser = AutoTradingManager.llmAnalyser
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user