package model import AutoTradeItem import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable data class StockBalanceResponse( val rt_cd: String = "", val msg1: String = "", val output1: List = emptyList(), val output2: List = emptyList() ) @Serializable data class StockHolding( val pdno: String = "", // 상품번호 val prdt_name: String = "", // 상품명 val hldg_qty: String = "0", // 보유수량 val pchs_avg_pric: String = "0", // 매입평균가 val prpr: String = "0", // 현재가 val evlu_pfls_rt: String = "0.0", // 평가손익률 val evlu_amt: String = "0" // 평가금액 ) @Serializable data class BalanceSummary( val tot_evlu_amt: String = "0", // 총 평가금액 val evlu_pfls_rt: String = "0.0", // 총 수익률 (에러 발생 지점: 기본값 추가로 해결) val asst_icrt: String = "0.0", // 일부 환경에서 수익률 필드명 val nass_amt: String = "0" // 순자산 금액 ) @Serializable data class RankingResponse( var rt_cd : String, var msg1 : String, var msg_cd : String, val output1: List = emptyList(), val output: List = emptyList() ) { val list = output + output1 + emptyList() } enum class RankingType( val title: String, val trId: String, val scrNo: String, val path: String, val sortCode: String // 추가: 각 TR ID에 맞는 정렬 코드 ) { VOLUME("거래량순", "FHPST01710000", "20171", "/uapi/domestic-stock/v1/quotations/volume-rank", "0"), VALUE("거래대금순", "FHPST01710000", "20171", "/uapi/domestic-stock/v1/quotations/volume-rank", "3"), RISE("상승률순", "FHPST01700000", "20170", "/uapi/domestic-stock/v1/ranking/fluctuation", "0"), FALL("하락률순", "FHPST01700000", "20170", "/uapi/domestic-stock/v1/ranking/fluctuation", "1"), // MARKET_CAP("시가총액순", "FHPST01740000", "20174", "/uapi/domestic-stock/v1/quotations/market-cap", "0"), // HTS_TOP20("HTS조회상위", "HHMCM000100C0", "20175", "/uapi/domestic-stock/v1/ranking/hts-top-view", "0"), // 링크로 전달주신 추가 기능 보완 VOLUME_POWER("체결강도순", "FHPST01680000", "20168", "/uapi/domestic-stock/v1/ranking/volume-power", "0"), // BEFORE("장전예상", "FHPST01820000", "20182", "/uapi/domestic-stock/v1/ranking/exp-trans-updown", "0"), // AFTER("장후예상", "FHPST01820000", "20182", "/uapi/domestic-stock/v1/ranking/exp-trans-updown", "1") } @Serializable data class RankingStock( val hts_kor_isnm: String = "", // 종목명 val hts_kor_alph_nm: String = "", // 종목명 val mkrtc_objt_iscd: String = "", // 종목코드 val mksc_shrn_iscd: String = "", // 종목코드 val stck_shrn_iscd: String = "", // 종목코드 val stck_prpr: String = "0", // 현재가 val prdy_ctrt: String = "0.0", // 등락률 val mrkt_div_cls_code : String = "J", ) { val name : String get() = listOf(hts_kor_isnm , hts_kor_alph_nm , mkrtc_objt_iscd).firstOrNull { it.isNotBlank() } ?: "" val code : String get() = listOf(mksc_shrn_iscd , mkrtc_objt_iscd , stck_shrn_iscd , hts_kor_isnm).firstOrNull { it.isNotBlank() } ?: "" } @Serializable data class OverseasRankingResponse( val rt_cd: String = "", val msg1: String = "", val output: List = emptyList() ) @Serializable data class OverseasRankingStock( val hts_kor_alph_nm: String, // 종목명 val mkrtc_objt_iscd: String, // 종목코드 (Ticker) val last: String, // 현재가 val diff: String, // 전일대비 val rate: String // 등락률 ) { // 국내용 RankingStock과 호환되도록 변환 함수 추가 fun toRankingStock() = RankingStock( hts_kor_alph_nm = hts_kor_alph_nm, mkrtc_objt_iscd = mkrtc_objt_iscd, stck_prpr = last, prdy_ctrt = rate ) } @Serializable data class UnifiedStockHolding( val code: String, // 종목코드 val name: String, // 종목명 val quantity: String, // 보유수량 val avgPrice: String, // 매입단가 val currentPrice: String, // 현재가 val profitRate: String, // 수익률 val evalAmount: String, // 평가금액 val isDomestic: Boolean // 국내/해외 구분 ) @Serializable data class UnifiedBalance( val totalAsset: String, // 총 평가자산 val totalProfitRate: String, // 총 수익률 val holdings: List // 통합 보유 종목 리스트 ) @Serializable data class UnfilledOrder( val orgn_odno: String, @SerialName("odno") val ord_no: String, // JSON의 odno를 ord_no로 매핑 val pdno: String, @SerialName("prdt_name") val prdt_name: String, val ord_unpr: String, // JSON이 문자열이므로 String 권장 @SerialName("psbl_qty") val rmnd_qty: String, // JSON의 psbl_qty를 rmnd_qty로 매핑 val ord_dvsn_name: String, val rvse_cncl_dvsn_name: String ) @Serializable data class UnfilledResponse( val rt_cd: String, val msg1: String, val output: List = emptyList() ) fun UnfilledOrder.toAutoTradeItem(isDomestic: Boolean): AutoTradeItem { return AutoTradeItem( orderNo = this.ord_no, code = this.pdno, name = this.prdt_name, orderedPrice = this.ord_unpr.toDoubleOrNull() ?: 0.0, quantity = 0, // 미체결 내역에서는 원 주문 수량을 알기 어려우므로 0 또는 별도 처리 remainedQuantity = this.rmnd_qty.toIntOrNull() ?: 0, status = "PENDING_BUY", // 기본적으로 미체결은 매수/매도 대기 상태 isDomestic = isDomestic ) } // 단순 정보 전달용 데이터 클래스 data class StockBasicInfo( val code: String, val name: String, val isDomestic: Boolean, val quantity: String = "0" )