diff --git a/KissMe/Sources/Domestic/DomesticFutures.swift b/KissMe/Sources/Domestic/Futures/DomesticFutures.swift similarity index 100% rename from KissMe/Sources/Domestic/DomesticFutures.swift rename to KissMe/Sources/Domestic/Futures/DomesticFutures.swift diff --git a/KissMe/Sources/Domestic/New Group/DomesticStock.swift b/KissMe/Sources/Domestic/Stock/DomesticStock.swift similarity index 98% rename from KissMe/Sources/Domestic/New Group/DomesticStock.swift rename to KissMe/Sources/Domestic/Stock/DomesticStock.swift index dad1e42..5c5516d 100644 --- a/KissMe/Sources/Domestic/New Group/DomesticStock.swift +++ b/KissMe/Sources/Domestic/Stock/DomesticStock.swift @@ -311,7 +311,7 @@ extension KissAccount { /// 주식 주문하기 /// - public func orderStock(contract: Contract) async throws -> OrderResult { + public func orderStock(contract: Contract) async throws -> Domestic.OrderResult { return try await withUnsafeThrowingContinuation { continuation in guard let accessToken = accessToken else { @@ -332,7 +332,7 @@ extension KissAccount { } - public func cancelOrder(cancel: ContractCancel) async throws -> OrderRevisionResult { + public func cancelOrder(cancel: ContractCancel) async throws -> Domestic.OrderRevisionResult { return try await withUnsafeThrowingContinuation { continuation in guard let accessToken = accessToken else { @@ -368,7 +368,7 @@ extension KissAccount { /// 주식 잔고 조회하기 /// - public func getStockBalance() async throws -> BalanceResult { + public func getStockBalance() async throws -> Domestic.BalanceResult { return try await withUnsafeThrowingContinuation { continuation in guard let accessToken = accessToken else { @@ -391,7 +391,7 @@ extension KissAccount { /// 주문 가능한 주식 수량 판단하기 /// - public func canOrderStock(productNo: String, division: OrderDivision, price: Int) async throws -> PossibleOrderResult { + public func canOrderStock(productNo: String, division: OrderDivision, price: Int) async throws -> Domestic.PossibleOrderResult { return try await withUnsafeThrowingContinuation { continuation in guard let accessToken = accessToken else { diff --git a/KissMe/Sources/Domestic/Stock/DomesticStockResult.swift b/KissMe/Sources/Domestic/Stock/DomesticStockResult.swift index 2d917cc..2c55418 100644 --- a/KissMe/Sources/Domestic/Stock/DomesticStockResult.swift +++ b/KissMe/Sources/Domestic/Stock/DomesticStockResult.swift @@ -14,434 +14,437 @@ public enum CustomerType: String, Codable { } -public struct OrderResult: Codable { - public let resultCode: String - public let messageCode: String - public let message: String - public let output: OutputDetail? +extension Domestic { - private enum CodingKeys: String, CodingKey { - case resultCode = "rt_cd" - case messageCode = "msg_cd" - case message = "msg1" - case output - } - - public struct OutputDetail: Codable { - public let orderOrganizationNo: String - public let orderNo: String - public let orderTime: String + public struct OrderResult: Codable { + public let resultCode: String + public let messageCode: String + public let message: String + public let output: OutputDetail? private enum CodingKeys: String, CodingKey { - case orderOrganizationNo = "KRX_FWDG_ORD_ORGNO" - case orderNo = "ODNO" - case orderTime = "ORD_TMD" - } - } -} - - -public struct OrderRevisionResult: Codable { - public let resultCode: String - public let messageCode: String - public let message: String - public let output: OutputDetail? - - private enum CodingKeys: String, CodingKey { - case resultCode = "rt_cd" - case messageCode = "msg_cd" - case message = "msg1" - case output - } - - public struct OutputDetail: Codable { - public let orderOrganizationNo: String - public let orderNo: String - public let orderTime: String - - private enum CodingKeys: String, CodingKey { - case orderOrganizationNo = "KRX_FWDG_ORD_ORGNO" - case orderNo = "ODNO" - case orderTime = "ORD_TMD" - } - } -} - - -public struct BalanceResult: Codable { - public let resultCode: String - public let messageCode: String - public let message: String - public let straightInqueryCondition: String? - public let straightInqueryKey: String? - public let output1: [OutputStock]? - public let output2: [OutputAmount]? - - private enum CodingKeys: String, CodingKey { - case resultCode = "rt_cd" - case messageCode = "msg_cd" - case message = "msg1" - case straightInqueryCondition = "ctx_area_fk100" - case straightInqueryKey = "ctx_area_nk100" - case output1 = "output1" - case output2 = "output2" - } - - public struct OutputStock: Codable, PropertyIterable { - /// 상품번호 - public let productNo: String - - /// 상품명 - public let productName: String - - /// 매매구분명 (매수매도구분) - public let tradeDivisionCode: String - - /// 전일매수수량 - public let previousDayBuyQuantity: String - - /// 전일매도수량 - public let previousDaySellQuantity: String - - /// 금일매수수량 - public let todayBuyQuantity: String - - /// 금일매도수량 - public let todaySellQuantity: String - - /// 보유수량 - public let holdingQuantity: String - - /// 주문가능수량 - public let orderPossibleQuantity: String - - /// 매입평균가격 (매입금액 / 보유수량) - public let averagePurchasePrice: String - - /// 매입금액 - public let purchaseAmount: String - - /// 현재가 - public let currentPrice: String - - /// 평가금액 - public let evaluationAmount: String - - /// 평가손익금액 (평가금액 - 매입금액) - public let evaluationProfitLossAmount: String - - /// 평가손익율 - public let evaluationProfitLossRate: String - - /// 평가수익율 - public let evaluationEarningRate: String - - /// 대출일자 - public let loanDate: String - - /// 대출금액 - public let loanAmount: String - - /// 대주매각대금 - public let shortSellingAmount: String - - /// 만기일자 - public let expiredDate: String - - /// 등락율 - public let fluctuationRate: String - - /// 전일대비증감 - public let netChangeFluctuation: String - - /// 종목증거금율명 - public let marginRequirementRatioName: String - - /// 보증금율명 - public let depositRateName: String - - /// 대용가격 - public let substitutePrice: String - - /// 주식대출단가 - public let stockLoanPrice: String - - private enum CodingKeys: String, CodingKey { - case productNo = "pdno" - case productName = "prdt_name" - case tradeDivisionCode = "trad_dvsn_name" - case previousDayBuyQuantity = "bfdy_buy_qty" - case previousDaySellQuantity = "bfdy_sll_qty" - case todayBuyQuantity = "thdt_buyqty" - case todaySellQuantity = "thdt_sll_qty" - case holdingQuantity = "hldg_qty" - case orderPossibleQuantity = "ord_psbl_qty" - case averagePurchasePrice = "pchs_avg_pric" - case purchaseAmount = "pchs_amt" - case currentPrice = "prpr" - case evaluationAmount = "evlu_amt" - case evaluationProfitLossAmount = "evlu_pfls_amt" - case evaluationProfitLossRate = "evlu_pfls_rt" - case evaluationEarningRate = "evlu_erng_rt" - case loanDate = "loan_dt" - case loanAmount = "loan_amt" - case shortSellingAmount = "stln_slng_chgs" - case expiredDate = "expd_dt" - case fluctuationRate = "fltt_rt" - case netChangeFluctuation = "bfdy_cprs_icdc" - case marginRequirementRatioName = "item_mgna_rt_name" - case depositRateName = "grta_rt_name" - case substitutePrice = "sbst_pric" - case stockLoanPrice = "stck_loan_unpr" + case resultCode = "rt_cd" + case messageCode = "msg_cd" + case message = "msg1" + case output } - init(array: [String], source: String.SubSequence) throws { - guard array.count == 26 else { - throw GeneralError.incorrectArrayItems(String(source), array.count, 26) + public struct OutputDetail: Codable { + public let orderOrganizationNo: String + public let orderNo: String + public let orderTime: String + + private enum CodingKeys: String, CodingKey { + case orderOrganizationNo = "KRX_FWDG_ORD_ORGNO" + case orderNo = "ODNO" + case orderTime = "ORD_TMD" } - self.productNo = array[0] - self.productName = array[1] - self.tradeDivisionCode = array[2] - self.previousDayBuyQuantity = array[3] - self.previousDaySellQuantity = array[4] - self.todayBuyQuantity = array[5] - self.todaySellQuantity = array[6] - self.holdingQuantity = array[7] - self.orderPossibleQuantity = array[8] - self.averagePurchasePrice = array[9] - self.purchaseAmount = array[10] - self.currentPrice = array[11] - self.evaluationAmount = array[12] - self.evaluationProfitLossAmount = array[13] - self.evaluationProfitLossRate = array[14] - self.evaluationEarningRate = array[15] - self.loanDate = array[16] - self.loanAmount = array[17] - self.shortSellingAmount = array[18] - self.expiredDate = array[19] - self.fluctuationRate = array[20] - self.netChangeFluctuation = array[21] - self.marginRequirementRatioName = array[22] - self.depositRateName = array[23] - self.substitutePrice = array[24] - self.stockLoanPrice = array[25] - } - - public static func symbols() -> [String] { - let i = try! OutputStock(array: Array(repeating: "", count: 26), source: #function) - return Mirror(reflecting: i).children.compactMap { $0.label } - } - - public static func localizedSymbols() -> [String: String] { - [:] } } - public struct OutputAmount: Codable, PropertyIterable { - /// 예수금총금액 (예수금) - public let depositTotalAmount: String - - /// 익일정산금액 (D+1 예수금) - public let nextDayCalcAmount: String - - /// 가수도정산금액 (D+2 예수금) - public let nextTwoDayCalcAmount: String - - /// CMA평가금액 - public let cmaEvaluationAmount: String - - /// 전일매수금액 - public let previousDayBuyAmount: String - - /// 금일매수금액 - public let todayBuyAmount: String - - /// 익일자동상환금액 - public let nextDayAutoRedemptionAmount: String - - /// 전일매도금액 - public let previousDaySellAmount: String - - /// 금일매도금액 - public let todaySellAmount: String - - /// D+2자동상환금액 - public let nextTwoDayAutoRedemptionAmount: String - - /// 전일제비용금액 - public let previousDayExpensesAmount: String - - /// 금일제비용금액 - public let todayExpensesAmount: String - - /// 총대출금액 - public let totalLoanAmount: String - - /// 유가평가금액 - public let securitiesEvaluationAmount: String - - /// 총평가금액 - public let totalEvaluationAmount: String - - /// 순자산금액 - public let netAssetAmount: String - - /// 융자금자동상환여부 - public let loanAutoRedemptionAllowable: YesNo - - /// 매입금액합계금액 - public let purchaseAmountSum: String - - /// 평가금액합계금액 - public let evaluationAmountSum: String - - /// 평가손익합계금액 - public let evaluationProfitLossAmountSum: String - - /// 총대주매각대금 - public let shortSellingAmountSum: String - - /// 전일총자산평가금액 - public let previousDayAssetEvalutionSum: String - - /// 자산증감액 - public let assetFluctuationAmount: String - - /// 자산증감수익율 - public let assetFluctuationRate: String + + public struct OrderRevisionResult: Codable { + public let resultCode: String + public let messageCode: String + public let message: String + public let output: OutputDetail? private enum CodingKeys: String, CodingKey { - case depositTotalAmount = "dnca_tot_amt" - case nextDayCalcAmount = "nxdy_excc_amt" - case nextTwoDayCalcAmount = "prvs_rcdl_excc_amt" - case cmaEvaluationAmount = "cma_evlu_amt" - case previousDayBuyAmount = "bfdy_buy_amt" - case todayBuyAmount = "thdt_buy_amt" - case nextDayAutoRedemptionAmount = "nxdy_auto_rdpt_amt" - case previousDaySellAmount = "bfdy_sll_amt" - case todaySellAmount = "thdt_sll_amt" - case nextTwoDayAutoRedemptionAmount = "d2_auto_rdpt_amt" - case previousDayExpensesAmount = "bfdy_tlex_amt" - case todayExpensesAmount = "thdt_tlex_amt" - case totalLoanAmount = "tot_loan_amt" - case securitiesEvaluationAmount = "scts_evlu_amt" - case totalEvaluationAmount = "tot_evlu_amt" - case netAssetAmount = "nass_amt" - case loanAutoRedemptionAllowable = "fncg_gld_auto_rdpt_yn" - case purchaseAmountSum = "pchs_amt_smtl_amt" - case evaluationAmountSum = "evlu_amt_smtl_amt" - case evaluationProfitLossAmountSum = "evlu_pfls_smtl_amt" - case shortSellingAmountSum = "tot_stln_slng_chgs" - case previousDayAssetEvalutionSum = "bfdy_tot_asst_evlu_amt" - case assetFluctuationAmount = "asst_icdc_amt" - case assetFluctuationRate = "asst_icdc_erng_rt" + case resultCode = "rt_cd" + case messageCode = "msg_cd" + case message = "msg1" + case output } - init(array: [String], source: String.SubSequence) throws { - guard array.count == 24 else { - throw GeneralError.incorrectArrayItems(String(source), array.count, 24) + public struct OutputDetail: Codable { + public let orderOrganizationNo: String + public let orderNo: String + public let orderTime: String + + private enum CodingKeys: String, CodingKey { + case orderOrganizationNo = "KRX_FWDG_ORD_ORGNO" + case orderNo = "ODNO" + case orderTime = "ORD_TMD" } - self.depositTotalAmount = array[0] - self.nextDayCalcAmount = array[1] - self.nextTwoDayCalcAmount = array[2] - self.cmaEvaluationAmount = array[3] - self.previousDayBuyAmount = array[4] - self.todayBuyAmount = array[5] - self.nextDayAutoRedemptionAmount = array[6] - self.previousDaySellAmount = array[7] - self.todaySellAmount = array[8] - self.nextTwoDayAutoRedemptionAmount = array[9] - self.previousDayExpensesAmount = array[10] - self.todayExpensesAmount = array[11] - self.totalLoanAmount = array[12] - self.securitiesEvaluationAmount = array[13] - self.totalEvaluationAmount = array[14] - self.netAssetAmount = array[15] - self.loanAutoRedemptionAllowable = YesNo(rawValue: array[16])! - self.purchaseAmountSum = array[17] - self.evaluationAmountSum = array[18] - self.evaluationProfitLossAmountSum = array[19] - self.shortSellingAmountSum = array[20] - self.previousDayAssetEvalutionSum = array[21] - self.assetFluctuationAmount = array[22] - self.assetFluctuationRate = array[23] } - - public static func symbols() -> [String] { - let i = try! OutputAmount(array: Array(repeating: "", count: 24), source: #function) - return Mirror(reflecting: i).children.compactMap { $0.label } - } - - public static func localizedSymbols() -> [String: String] { - [:] - } - } -} - - -public struct PossibleOrderResult: Codable { - public let resultCode: String - public let messageCode: String - public let message: String - public let output: OutputPossibleDetail? - - private enum CodingKeys: String, CodingKey { - case resultCode = "rt_cd" - case messageCode = "msg_cd" - case message = "msg1" - case output } - public struct OutputPossibleDetail: Codable { - /// 주문가능현금 - public let orderPossibleCash: String - - /// 주문가능대용 - public let orderPossibleSubstitute: String - - /// 재사용가능금액 - public let reusePossibleAmount: String - - /// 펀드환매대금 - public let fundRepurchaseChanges: String - - /// 가능수량계산단가 - public let possibleQuantityCalcPrice: String - - /// 미수없는매수금액 - public let nonrechargeableBuyAmount: String - - /// 미수없는매수수량 - public let nonrechargeableBuyQuantity: String - - /// 최대매수금액 - public let maxBuyAmount: String - - /// 최대매수수량 - public let maxBuyQuantity: String - - /// CMA평가금액 - public let cmaEvaluationAmount: String - - /// 해외재사용금액원화 - public let overseasReuseAmountWon: String - - /// 주문가능외화금액원화 - public let orderPossibleForeignCurrencyAmountWon: String + + public struct BalanceResult: Codable { + public let resultCode: String + public let messageCode: String + public let message: String + public let straightInqueryCondition: String? + public let straightInqueryKey: String? + public let output1: [OutputStock] + public let output2: [OutputAmount] private enum CodingKeys: String, CodingKey { - case orderPossibleCash = "ord_psbl_cash" - case orderPossibleSubstitute = "ord_psbl_sbst" - case reusePossibleAmount = "ruse_psbl_amt" - case fundRepurchaseChanges = "fund_rpch_chgs" - case possibleQuantityCalcPrice = "psbl_qty_calc_unpr" - case nonrechargeableBuyAmount = "nrcvb_buy_amt" - case nonrechargeableBuyQuantity = "nrcvb_buy_qty" - case maxBuyAmount = "max_buy_amt" - case maxBuyQuantity = "max_buy_qty" - case cmaEvaluationAmount = "cma_evlu_amt" - case overseasReuseAmountWon = "ovrs_re_use_amt_wcrc" - case orderPossibleForeignCurrencyAmountWon = "ord_psbl_frcr_amt_wcrc" + case resultCode = "rt_cd" + case messageCode = "msg_cd" + case message = "msg1" + case straightInqueryCondition = "ctx_area_fk100" + case straightInqueryKey = "ctx_area_nk100" + case output1 = "output1" + case output2 = "output2" + } + + public struct OutputStock: Codable, PropertyIterable { + /// 상품번호 + public let productNo: String + + /// 상품명 + public let productName: String + + /// 매매구분명 (매수매도구분) + public let tradeDivisionCode: String + + /// 전일매수수량 + public let previousDayBuyQuantity: String + + /// 전일매도수량 + public let previousDaySellQuantity: String + + /// 금일매수수량 + public let todayBuyQuantity: String + + /// 금일매도수량 + public let todaySellQuantity: String + + /// 보유수량 + public let holdingQuantity: String + + /// 주문가능수량 + public let orderPossibleQuantity: String + + /// 매입평균가격 (매입금액 / 보유수량) + public let averagePurchasePrice: String + + /// 매입금액 + public let purchaseAmount: String + + /// 현재가 + public let currentPrice: String + + /// 평가금액 + public let evaluationAmount: String + + /// 평가손익금액 (평가금액 - 매입금액) + public let evaluationProfitLossAmount: String + + /// 평가손익율 + public let evaluationProfitLossRate: String + + /// 평가수익율 + public let evaluationEarningRate: String + + /// 대출일자 + public let loanDate: String + + /// 대출금액 + public let loanAmount: String + + /// 대주매각대금 + public let shortSellingAmount: String + + /// 만기일자 + public let expiredDate: String + + /// 등락율 + public let fluctuationRate: String + + /// 전일대비증감 + public let netChangeFluctuation: String + + /// 종목증거금율명 + public let marginRequirementRatioName: String + + /// 보증금율명 + public let depositRateName: String + + /// 대용가격 + public let substitutePrice: String + + /// 주식대출단가 + public let stockLoanPrice: String + + private enum CodingKeys: String, CodingKey { + case productNo = "pdno" + case productName = "prdt_name" + case tradeDivisionCode = "trad_dvsn_name" + case previousDayBuyQuantity = "bfdy_buy_qty" + case previousDaySellQuantity = "bfdy_sll_qty" + case todayBuyQuantity = "thdt_buyqty" + case todaySellQuantity = "thdt_sll_qty" + case holdingQuantity = "hldg_qty" + case orderPossibleQuantity = "ord_psbl_qty" + case averagePurchasePrice = "pchs_avg_pric" + case purchaseAmount = "pchs_amt" + case currentPrice = "prpr" + case evaluationAmount = "evlu_amt" + case evaluationProfitLossAmount = "evlu_pfls_amt" + case evaluationProfitLossRate = "evlu_pfls_rt" + case evaluationEarningRate = "evlu_erng_rt" + case loanDate = "loan_dt" + case loanAmount = "loan_amt" + case shortSellingAmount = "stln_slng_chgs" + case expiredDate = "expd_dt" + case fluctuationRate = "fltt_rt" + case netChangeFluctuation = "bfdy_cprs_icdc" + case marginRequirementRatioName = "item_mgna_rt_name" + case depositRateName = "grta_rt_name" + case substitutePrice = "sbst_pric" + case stockLoanPrice = "stck_loan_unpr" + } + + init(array: [String], source: String.SubSequence) throws { + guard array.count == 26 else { + throw GeneralError.incorrectArrayItems(String(source), array.count, 26) + } + self.productNo = array[0] + self.productName = array[1] + self.tradeDivisionCode = array[2] + self.previousDayBuyQuantity = array[3] + self.previousDaySellQuantity = array[4] + self.todayBuyQuantity = array[5] + self.todaySellQuantity = array[6] + self.holdingQuantity = array[7] + self.orderPossibleQuantity = array[8] + self.averagePurchasePrice = array[9] + self.purchaseAmount = array[10] + self.currentPrice = array[11] + self.evaluationAmount = array[12] + self.evaluationProfitLossAmount = array[13] + self.evaluationProfitLossRate = array[14] + self.evaluationEarningRate = array[15] + self.loanDate = array[16] + self.loanAmount = array[17] + self.shortSellingAmount = array[18] + self.expiredDate = array[19] + self.fluctuationRate = array[20] + self.netChangeFluctuation = array[21] + self.marginRequirementRatioName = array[22] + self.depositRateName = array[23] + self.substitutePrice = array[24] + self.stockLoanPrice = array[25] + } + + public static func symbols() -> [String] { + let i = try! OutputStock(array: Array(repeating: "", count: 26), source: #function) + return Mirror(reflecting: i).children.compactMap { $0.label } + } + + public static func localizedSymbols() -> [String: String] { + [:] + } + } + + public struct OutputAmount: Codable, PropertyIterable { + /// 예수금총금액 (예수금) + public let depositTotalAmount: String + + /// 익일정산금액 (D+1 예수금) + public let nextDayCalcAmount: String + + /// 가수도정산금액 (D+2 예수금) + public let nextTwoDayCalcAmount: String + + /// CMA평가금액 + public let cmaEvaluationAmount: String + + /// 전일매수금액 + public let previousDayBuyAmount: String + + /// 금일매수금액 + public let todayBuyAmount: String + + /// 익일자동상환금액 + public let nextDayAutoRedemptionAmount: String + + /// 전일매도금액 + public let previousDaySellAmount: String + + /// 금일매도금액 + public let todaySellAmount: String + + /// D+2자동상환금액 + public let nextTwoDayAutoRedemptionAmount: String + + /// 전일제비용금액 + public let previousDayExpensesAmount: String + + /// 금일제비용금액 + public let todayExpensesAmount: String + + /// 총대출금액 + public let totalLoanAmount: String + + /// 유가평가금액 + public let securitiesEvaluationAmount: String + + /// 총평가금액 + public let totalEvaluationAmount: String + + /// 순자산금액 + public let netAssetAmount: String + + /// 융자금자동상환여부 + public let loanAutoRedemptionAllowable: YesNo + + /// 매입금액합계금액 + public let purchaseAmountSum: String + + /// 평가금액합계금액 + public let evaluationAmountSum: String + + /// 평가손익합계금액 + public let evaluationProfitLossAmountSum: String + + /// 총대주매각대금 + public let shortSellingAmountSum: String + + /// 전일총자산평가금액 + public let previousDayAssetEvalutionSum: String + + /// 자산증감액 + public let assetFluctuationAmount: String + + /// 자산증감수익율 + public let assetFluctuationRate: String + + private enum CodingKeys: String, CodingKey { + case depositTotalAmount = "dnca_tot_amt" + case nextDayCalcAmount = "nxdy_excc_amt" + case nextTwoDayCalcAmount = "prvs_rcdl_excc_amt" + case cmaEvaluationAmount = "cma_evlu_amt" + case previousDayBuyAmount = "bfdy_buy_amt" + case todayBuyAmount = "thdt_buy_amt" + case nextDayAutoRedemptionAmount = "nxdy_auto_rdpt_amt" + case previousDaySellAmount = "bfdy_sll_amt" + case todaySellAmount = "thdt_sll_amt" + case nextTwoDayAutoRedemptionAmount = "d2_auto_rdpt_amt" + case previousDayExpensesAmount = "bfdy_tlex_amt" + case todayExpensesAmount = "thdt_tlex_amt" + case totalLoanAmount = "tot_loan_amt" + case securitiesEvaluationAmount = "scts_evlu_amt" + case totalEvaluationAmount = "tot_evlu_amt" + case netAssetAmount = "nass_amt" + case loanAutoRedemptionAllowable = "fncg_gld_auto_rdpt_yn" + case purchaseAmountSum = "pchs_amt_smtl_amt" + case evaluationAmountSum = "evlu_amt_smtl_amt" + case evaluationProfitLossAmountSum = "evlu_pfls_smtl_amt" + case shortSellingAmountSum = "tot_stln_slng_chgs" + case previousDayAssetEvalutionSum = "bfdy_tot_asst_evlu_amt" + case assetFluctuationAmount = "asst_icdc_amt" + case assetFluctuationRate = "asst_icdc_erng_rt" + } + + init(array: [String], source: String.SubSequence) throws { + guard array.count == 24 else { + throw GeneralError.incorrectArrayItems(String(source), array.count, 24) + } + self.depositTotalAmount = array[0] + self.nextDayCalcAmount = array[1] + self.nextTwoDayCalcAmount = array[2] + self.cmaEvaluationAmount = array[3] + self.previousDayBuyAmount = array[4] + self.todayBuyAmount = array[5] + self.nextDayAutoRedemptionAmount = array[6] + self.previousDaySellAmount = array[7] + self.todaySellAmount = array[8] + self.nextTwoDayAutoRedemptionAmount = array[9] + self.previousDayExpensesAmount = array[10] + self.todayExpensesAmount = array[11] + self.totalLoanAmount = array[12] + self.securitiesEvaluationAmount = array[13] + self.totalEvaluationAmount = array[14] + self.netAssetAmount = array[15] + self.loanAutoRedemptionAllowable = YesNo(rawValue: array[16])! + self.purchaseAmountSum = array[17] + self.evaluationAmountSum = array[18] + self.evaluationProfitLossAmountSum = array[19] + self.shortSellingAmountSum = array[20] + self.previousDayAssetEvalutionSum = array[21] + self.assetFluctuationAmount = array[22] + self.assetFluctuationRate = array[23] + } + + public static func symbols() -> [String] { + let i = try! OutputAmount(array: Array(repeating: "", count: 24), source: #function) + return Mirror(reflecting: i).children.compactMap { $0.label } + } + + public static func localizedSymbols() -> [String: String] { + [:] + } + } + } + + + public struct PossibleOrderResult: Codable { + public let resultCode: String + public let messageCode: String + public let message: String + public let output: OutputPossibleDetail? + + private enum CodingKeys: String, CodingKey { + case resultCode = "rt_cd" + case messageCode = "msg_cd" + case message = "msg1" + case output + } + + public struct OutputPossibleDetail: Codable { + /// 주문가능현금 + public let orderPossibleCash: String + + /// 주문가능대용 + public let orderPossibleSubstitute: String + + /// 재사용가능금액 + public let reusePossibleAmount: String + + /// 펀드환매대금 + public let fundRepurchaseChanges: String + + /// 가능수량계산단가 + public let possibleQuantityCalcPrice: String + + /// 미수없는매수금액 + public let nonrechargeableBuyAmount: String + + /// 미수없는매수수량 + public let nonrechargeableBuyQuantity: String + + /// 최대매수금액 + public let maxBuyAmount: String + + /// 최대매수수량 + public let maxBuyQuantity: String + + /// CMA평가금액 + public let cmaEvaluationAmount: String + + /// 해외재사용금액원화 + public let overseasReuseAmountWon: String + + /// 주문가능외화금액원화 + public let orderPossibleForeignCurrencyAmountWon: String + + private enum CodingKeys: String, CodingKey { + case orderPossibleCash = "ord_psbl_cash" + case orderPossibleSubstitute = "ord_psbl_sbst" + case reusePossibleAmount = "ruse_psbl_amt" + case fundRepurchaseChanges = "fund_rpch_chgs" + case possibleQuantityCalcPrice = "psbl_qty_calc_unpr" + case nonrechargeableBuyAmount = "nrcvb_buy_amt" + case nonrechargeableBuyQuantity = "nrcvb_buy_qty" + case maxBuyAmount = "max_buy_amt" + case maxBuyQuantity = "max_buy_qty" + case cmaEvaluationAmount = "cma_evlu_amt" + case overseasReuseAmountWon = "ovrs_re_use_amt_wcrc" + case orderPossibleForeignCurrencyAmountWon = "ord_psbl_frcr_amt_wcrc" + } } } } diff --git a/KissMe/Sources/Overseas/OverseasStock.swift b/KissMe/Sources/Overseas/OverseasStock.swift index 9b05924..bec6162 100644 --- a/KissMe/Sources/Overseas/OverseasStock.swift +++ b/KissMe/Sources/Overseas/OverseasStock.swift @@ -9,7 +9,6 @@ import Foundation public struct Overseas { - } @@ -244,4 +243,326 @@ extension Overseas { self.isNext = isNext } } + + + /// 해외주식 예약주문접수[v1_해외주식-002] + /// + public struct StockPreorderRequest: OrderRequest { + public typealias KResult = PreorderResult + + public var url: String { + "/uapi/overseas-stock/v1/trading/order-resv" + } + public var method: Method { .post } + + public var header: [String: String?] { + [ + "authorization": "Bearer \(accessToken)", + "appkey": credential.appKey, + "appsecret": credential.appSecret, + "tr_id": trId, + "tr_cont": isNext ? "N": " ", + "custtype": CustomerType.personal.rawValue, + ] + } + public var body: [String: Any] { + var predefined: [String: Any] = [ + "CANNO": accountNo8, + "ACNT_PRDT_CD": accountNo2, + "PDNO": productNo, + "OVRS_EXCG_CD": overseasExchangeCode, + "FT_ORD_QTY": "", + "FT_ORD_UNPR3": "", + "ORD_SVR_DVSN_CD": "0", + ] + if trId == "TTTS3013U" { + predefined["SLL_BUY_DVSN_CD"] = (orderType == .sell ? "01": "02") + predefined["RVSE_CNCL_DVSN_CD"] = (orderCancel == nil ? "00": "02") + predefined["PRDT_TYPE_CD"] = productTypeCode + predefined["RSVN_ORD_RCIT_DT"] = orderDate + predefined["OVRS_RSVN_ODNO"] = reservationOrderNo + } + if trId == "TTTT3016U" { + predefined["ORD_DVSN"] = (orderDivision == .limits ? "00": "31") + } + return predefined + } + public var result: KResult? = nil + public let credential: Credential + + + private var trId: String { + if credential.isMock { + switch overseasExchangeCode { + case .nasdaq, .newyork, .amex: // 미국 + switch orderType { + case .buy: return "VTTT3014U" + case .sell: return "VTTT3016U" + } + case .tokyo: // 일본 + fallthrough + case .shanghai, .shenzhen: // 중국 + fallthrough + case .hongkong: // 홍콩 + fallthrough + case .hanoi, .hochiminh: // 베트남 + return "VTTS3013U" + } + } + else { + switch overseasExchangeCode { + case .nasdaq, .newyork, .amex: // 미국 + switch orderType { + case .buy: return "TTTT3014U" + case .sell: return "TTTT3016U" + } + case .tokyo: // 일본 + fallthrough + case .shanghai, .shenzhen: // 중국 + fallthrough + case .hongkong: // 홍콩 + fallthrough + case .hanoi, .hochiminh: // 베트남 + return "TTTS3013U" + } + } + } + private var productTypeCode: String { + switch overseasExchangeCode { + case .hongkong: + switch hongkongProductType! { + case .`default`: return "501" + case .cny: return "543" + case .usd: return "558" + } + case .shanghai: return "551" + case .shenzhen: return "552" + case .tokyo: return "515" + case .hanoi: return "507" + case .hochiminh: return "508" + default: + assertionFailure() + return "" + } + } + + public let accessToken: String + let overseasExchangeCode: OverseasExchangeType + let productNo: String + + let orderType: OrderType + let orderCancel: Bool? + let orderDate: String? + let orderDivision: OrderDivision? + let hongkongProductType: HongkongProductType? + let reservationOrderNo: String? + let isNext: Bool + + init(credential: Credential, accessToken: String, overseasExchangeCode: OverseasExchangeType, productNo: String, orderType: OrderType, orderCancel: Bool?, orderDate: String?, orderDivision: OrderDivision?, hongkongProductType: HongkongProductType?, reservationOrderNo: String?, isNext: Bool) { + self.credential = credential + self.accessToken = accessToken + self.overseasExchangeCode = overseasExchangeCode + self.productNo = productNo + self.orderType = orderType + self.orderCancel = orderCancel + self.orderDate = orderDate + self.orderDivision = orderDivision + self.hongkongProductType = hongkongProductType + self.reservationOrderNo = reservationOrderNo + self.isNext = isNext + } + } + + + /// 해외주식 예약주문접수취소[v1_해외주식-004] + /// + public struct StockPreorderCancelRequest: OrderRequest { + public typealias KResult = PreorderCancelResult + + public var url: String { + "/uapi/overseas-stock/v1/trading/order-resv-ccnl" + } + public var method: Method { .post } + + public var header: [String : String?] { + [ + "authorization": "Bearer \(accessToken)", + "appkey": credential.appKey, + "appsecret": credential.appSecret, + "tr_id": trId, + "tr_cont": isNext ? "N": " ", + "custtype": CustomerType.personal.rawValue, + ] + } + public var body: [String : Any] { + [ + "CANNO": accountNo8, + "ACNT_PRDT_CD": accountNo2, + "RSYN_ORD_RCTT_DT": orderDate, + "OVRS_RSVN_ODNO": reservationOrderNo + ] + } + public var result: KResult? = nil + public let credential: Credential + + private var trId: String { + if credential.isMock { + switch overseasExchangeCode { + case .nasdaq, .newyork, .amex: // 미국 + return "VTTT3017U" + default: + assertionFailure("unsupported yet") + return "" + } + } + else { + switch overseasExchangeCode { + case .nasdaq, .newyork, .amex: // 미국 + return "TTTT3017U" + default: + assertionFailure("unsupported yet") + return "" + } + } + } + + public let accessToken: String + let overseasExchangeCode: OverseasExchangeType + + let orderDate: String + let reservationOrderNo: String + let isNext: Bool + + init(credential: Credential, accessToken: String, overseasExchangeCode: OverseasExchangeType, orderDate: String, reservationOrderNo: String, isNext: Bool) { + self.credential = credential + self.accessToken = accessToken + self.overseasExchangeCode = overseasExchangeCode + self.orderDate = orderDate + self.reservationOrderNo = reservationOrderNo + self.isNext = isNext + } + } + + + /// 해외주식 미체결내역[v1_해외주식-005] + /// + public struct StockOutstandingDetailRequest: OrderRequest { + public typealias KResult = OutstandingDetailResult + + public var url: String { + "/uapi/overseas-stock/v1/trading/inquire-nccs" + } + public var method: Method { .get } + + public var header: [String : String?] { + [ + "authorization": "Bearer \(accessToken)", + "appkey": credential.appKey, + "appsecret": credential.appSecret, + "tr_id": trId, + "tr_cont": isNext ? "N": " ", + "custtype": CustomerType.personal.rawValue, + ] + } + public var body: [String : Any] { + [ + "CANNO": accountNo8, + "ACNT_PRDT_CD": accountNo2, + "OVRS_EXCG_CD": overseasExchangeCode, + "SORT_SQN": ascending ? "DS": "", + "CTX_AREA_FK200": "", + "CTX_AREA_NK200": "", + ] + } + public var result: KResult? = nil + public let credential: Credential + + private var trId: String { + if credential.isMock { + return "VTTS3018R" + } + else { + return "TTTS3018R" + } + } + + public let accessToken: String + let overseasExchangeCode: OverseasExchangeType + + let ascending: Bool + let isNext: Bool + + init(credential: Credential, accessToken: String, overseasExchangeCode: OverseasExchangeType, ascending: Bool, isNext: Bool) { + self.credential = credential + self.accessToken = accessToken + self.overseasExchangeCode = overseasExchangeCode + self.ascending = ascending + self.isNext = isNext + } + } + + + /// 해외주식 잔고[v1_해외주식-006] + /// + public struct StockBalanceRequest: OrderRequest { + public typealias KResult = BalanceResult + + public var url: String { + "/uapi/overseas-stock/v1/trading/inquire-balance" + } + public var method: Method { .get } + + public var header: [String : String?] { + [ + "authorization": "Bearer \(accessToken)", + "appkey": credential.appKey, + "appsecret": credential.appSecret, + "tr_id": trId, + "tr_cont": isNext ? "N": " ", + "custtype": CustomerType.personal.rawValue, + ] + } + public var body: [String : Any] { + [ + "CANNO": accountNo8, + "ACNT_PRDT_CD": accountNo2, + "OVRS_EXCG_CD": overseasExchangeCode, + "TR_CRCY_CD": tradeCurrencyCode.rawValue, + "CTX_AREA_FK200": "", + "CTX_AREA_NK200": "", + ] + } + public var result: KResult? = nil + public let credential: Credential + + private var trId: String { + if credential.isMock { + return "VTTS3012R" + } + else { + return "TTTS3012R" + } + } + + public let accessToken: String + let overseasExchangeCode: OverseasExchangeType + + let tradeCurrencyCode: CurrencyCode + let isNext: Bool + + init(credential: Credential, accessToken: String, overseasExchangeCode: OverseasExchangeType, tradeCurrencyCode: CurrencyCode, isNext: Bool) { + self.credential = credential + self.accessToken = accessToken + self.overseasExchangeCode = overseasExchangeCode + self.tradeCurrencyCode = tradeCurrencyCode + self.isNext = isNext + } + } +} + + +enum HongkongProductType { + case `default` + case cny + case usd } diff --git a/KissMe/Sources/Overseas/OverseasStockResult.swift b/KissMe/Sources/Overseas/OverseasStockResult.swift index 8b6f399..70253fa 100644 --- a/KissMe/Sources/Overseas/OverseasStockResult.swift +++ b/KissMe/Sources/Overseas/OverseasStockResult.swift @@ -7,10 +7,23 @@ import Foundation + +public enum CurrencyCode: String, Codable { + case usd = "USD" + case hkd = "HKD" + case cny = "CNY" + case jpy = "JPY" + case vnd = "VND" +} + + extension Overseas { - /* - public struct OrderResult: Codable { + public typealias OrderResult = Domestic.OrderResult + public typealias OrderRevisionResult = Domestic.OrderRevisionResult + + + public struct PreorderResult: Codable { public let resultCode: String public let messageCode: String public let message: String @@ -24,16 +37,267 @@ extension Overseas { } public struct OutputDetail: Codable { - public let orderOrganizationNo: String + /// 한국거래소전송주문조직번호 public let orderNo: String - public let orderTime: String + /// 예약주문접수일자 + public let reservationOrderReceiptDate: String + /// 해외예약주문번호 + public let reservationOrderNo: String private enum CodingKeys: String, CodingKey { - case orderOrganizationNo = "KRX_FWDG_ORD_ORGNO" case orderNo = "ODNO" - case orderTime = "ORD_TMD" + case reservationOrderReceiptDate = "RSVN_ORD_RCIT_DT" + case reservationOrderNo = "OVRS_RSVN_ODNO" + } + } + } + + + public struct PreorderCancelResult: Codable { + public let resultCode: String + public let messageCode: String + public let message: String + public let output: OutputDetail? + + private enum CodingKeys: String, CodingKey { + case resultCode = "rt_cd" + case messageCode = "msg_cd" + case message = "msg1" + case output + } + + public struct OutputDetail: Codable { + /// 해외예약주문번호 + public let reservationOrderNo: String + + private enum CodingKeys: String, CodingKey { + case reservationOrderNo = "OVRS_RSVN_ODNO" + } + } + } + + + public struct OutstandingDetailResult: Codable { + public let resultCode: String + public let messageCode: String + public let message: String + public let output: OutputDetail + /// 연속조회검색조건200 + public let continuousQuerySearchCondition200: String + /// 연속조회키200 + public let continuousQueryKey200: String + + private enum CodingKeys: String, CodingKey { + case resultCode = "rt_cd" + case messageCode = "msg_cd" + case message = "msg1" + case output + case continuousQuerySearchCondition200 = "ctx_area_fk200" + case continuousQueryKey200 = "ctx_area_nk200" + } + + public struct OutputDetail: Codable { + /// 주문일자 + public let orderDate: String + /// 주문채번지점번호 + public let branchNo: String + /// 주문번호 + public let orderNo: String + /// 원주문번호 + public let originalOrderNo: String + /// 상품번호 + public let productNo: String + /// 상품명 + public let productName: String + /// 매도매수구분코드 + public let sellBuyDivisionCode: String + /// 매도매수구분코드명 + public let sellBuyDivisionCodeName: String + /// 정정취소구분코드 + public let reviseCancelDivisionCode: String + /// 정정취소구분코드명 + public let reviseCancelDivisionCodeName: String + /// 거부사유 + public let rejectReason: String + /// 거부사유명 + public let rejectReasonName: String + /// 주문시각 + public let orderTime: String + /// 거래시장명 + public let tradeMarketName: String + /// 거래통화코드 + public let tradeCurrencyCode: CurrencyCode + /// 국가코드 + public let nationCode: String + /// 국가한글명 + public let nationKoreanName: String + /// FT주문수량 + public let futureOrderQuantity: String + /// FT체결수량 + public let futureConclusionQuantity: String + /// 미체결수량 + public let outstandingQuantity: String + /// FT주문단가3 + public let futureOrderUnitPrice3: String + /// FT체결단가3 + public let futureConclusionUnitPrice3: String + /// FT체결금액3 + public let futureConclusionAmount3: String + /// 해외거래소코드 + public let foreignExchangeCode: String + /// 처리상태명 + public let processStateName: String + /// 대출유형코드 + public let loanTypeCode: String + /// 대출일자 + public let loadDate: String + /// 미국애프터마켓연장신청여부 + public let usaAfterMarketExtensionRequested: YesNo + + private enum CodingKeys: String, CodingKey { + case orderDate = "ord_dt" + case branchNo = "ord_gno_brno" + case orderNo = "odno" + case originalOrderNo = "orgn_odno" + case productNo = "pdno" + case productName = "prdt_name" + case sellBuyDivisionCode = "sll_buy_dvsn_cd" + case sellBuyDivisionCodeName = "sll_buy_dvsn_cd_name" + case reviseCancelDivisionCode = "rvse_cncl_dvsn_cd" + case reviseCancelDivisionCodeName = "rvse_cncl_dvsn_cd_name" + case rejectReason = "rjct_rson" + case rejectReasonName = "rjct_rson_name" + case orderTime = "ord_tmd" + case tradeMarketName = "tr_mket_name" + case tradeCurrencyCode = "tr_crcy_cd" + case nationCode = "natn_cd" + case nationKoreanName = "natn_kor_name" + case futureOrderQuantity = "ft_ord_qty" + case futureConclusionQuantity = "ft_ccld_qty" + case outstandingQuantity = "nccs_qty" + case futureOrderUnitPrice3 = "ft_ord_unpr3" + case futureConclusionUnitPrice3 = "ft_ccld_unpr3" + case futureConclusionAmount3 = "ft_ccld_amt3" + case foreignExchangeCode = "ovrs_excg_cd" + case processStateName = "prcs_stat_name" + case loanTypeCode = "loan_type_cd" + case loadDate = "loan_dt" + case usaAfterMarketExtensionRequested = "usa_amk_exts_rqst_yn" + } + } + } + + + public struct BalanceResult: Codable { + public let resultCode: String + public let messageCode: String + public let message: String + public let continuousQuerySearchCondition200: String? + public let continuousQueryKey200: String? + public let output1: [OutputStock] + public let output2: [OutputProfit] + + private enum CodingKeys: String, CodingKey { + case resultCode = "rt_cd" + case messageCode = "msg_cd" + case message = "msg1" + case continuousQuerySearchCondition200 = "ctx_area_fk200" + case continuousQueryKey200 = "ctx_area_nk200" + case output1 = "output1" + case output2 = "output2" + } + + public struct OutputStock: Codable { + /// 종합계좌번호 + public let accountNo8: String + /// 계좌상품코드 + public let accountNo2: String + /// 상품유형코드 + public let productTypeCode: String + /// 해외상품번호 + public let foreignProductNo: String + /// 해외종목명 + public let foreignItemName: String + /// 외화평가손익금액 + public let foreignCurrencyEvaluationProfitLossAmount: String + /// 평가손익율 + public let evaluationProfitLossRate: String + /// 매입평균가격 + public let averagePurchasePrice: String + /// 해외잔고수량 + public let foreignBalanceQuantity: String + /// 주문가능수량 + public let orderPossibleQuantity: String + /// 외화매입금액1 + public let foreignCurrencyPurchaseAmount1: String + /// 해외주식평가금액 + public let foreignStockEvaluationAmount: String + /// 현재가격2 + public let currentPrice2: String + /// 거래통화코드 + public let tradeCurrencyCode: CurrencyCode + /// 해외거래소코드 + public let foreignExchangeCode: String + /// 대출유형코드 + public let loanTypeCode: String + /// 대출일자 + public let loadDate: String + /// 만기일자 + public let expiredDate: String + + private enum CodingKeys: String, CodingKey { + case accountNo8 = "cano" + case accountNo2 = "acnt_prdt_cd" + case productTypeCode = "prdt_type_cd" + case foreignProductNo = "ovrs_pdno" + case foreignItemName = "ovrs_item_name" + case foreignCurrencyEvaluationProfitLossAmount = "frcr_evlu_pfls_amt" + case evaluationProfitLossRate = "evlu_pfls_rt" + case averagePurchasePrice = "pchs_avg_pric" + case foreignBalanceQuantity = "ovrs_cblc_qty" + case orderPossibleQuantity = "ord_psbl_qty" + case foreignCurrencyPurchaseAmount1 = "frcr_pchs_amt1" + case foreignStockEvaluationAmount = "ovrs_stck_evlu_amt" + case currentPrice2 = "now_pric2" + case tradeCurrencyCode = "tr_crcy_cd" + case foreignExchangeCode = "ovrs_excg_cd" + case loanTypeCode = "loan_type_cd" + case loadDate = "loan_dt" + case expiredDate = "expd_dt" + } + } + + public struct OutputProfit: Codable { + /// 외화매입금액1 + public let foreignCurrencyPurchaseAmount1: String + /// 해외실현손익금액 + public let foreignRealizedProfitLossAmount: String + /// 해외총손익 + public let foreignTotalProfitLoss: String + /// 실현수익율 + public let realizedEarningRate: String + /// 총평가손익금액 + public let totalEvaluationProfitLossAmount: String + /// 총수익률 + public let totalProfitRate: String + /// 외화매수금액합계1 + public let foreignCurrencyTotalPurchaseAmount1: String + /// 해외실현손익금액2 + public let foreignRealizedProfitLossAmount2: String + /// 외화매수금액합계2 + public let foreignCurrencyTotalPurchaseAmount2: String + + private enum CodingKeys: String, CodingKey { + case foreignCurrencyPurchaseAmount1 = "frcr_pchs_amt1" + case foreignRealizedProfitLossAmount = "ovrs_rlzt_pfls_amt" + case foreignTotalProfitLoss = "ovrs_tot_pfls" + case realizedEarningRate = "rlzt_erng_rt" + case totalEvaluationProfitLossAmount = "tot_evlu_pfls_amt" + case totalProfitRate = "tot_pftrt" + case foreignCurrencyTotalPurchaseAmount1 = "frcr_buy_amt_smtl1" + case foreignRealizedProfitLossAmount2 = "ovrs_rlzt_pfls_amt2" + case foreignCurrencyTotalPurchaseAmount2 = "frcr_buy_amt_smtl2" } } } - */ } diff --git a/KissMeSacks/README.md b/KissMeSacks/README.md index 5bf5d5e..6b61710 100644 --- a/KissMeSacks/README.md +++ b/KissMeSacks/README.md @@ -26,3 +26,7 @@ KissMeSacks 는 분봉을 바탕으로 가상의 매매를 시뮬레이션 해 ### SP design * + +### FieldBuf design + +### WorldBuf design diff --git a/README.md b/README.md index 84e641f..ea17263 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,23 @@ KissMeGolder 는 KissMeMatrix model 을 충실하게 따르면서, 자동으로 사용하고자 하는 model 에 따라서 다양한 투자 성향을 가질 수 있도록 설계할 것입니다. +# KissMeSacks + +KissMeSacks 는 단타 매매를 자동으로 검증해주는 시뮬레이션 로봇입니다. + +완성도가 높아지면 나중에 KissGoblin UI 기능으로 연동될 것입니다. + +# KissGram + +KissGram 은 텔레그램 봇과 연동하여 다양한 정보 창구로 쓰일 수 있도록 고안된 인터페이스 툴입니다. + +# KissGoblin + +디아블로의 보물 고블린의 아이디어에서 따온 것입니다. + +매수 시점에 고블린이 스폰되고, 매도 시점에 고블린이 아이템을 드랍하고 사라지는 컨셉입니다. + +매수와 매도 사이의 재미있는 인터페이스를 제공하는 것이 목표입니다. # Credential json diff --git a/projects/macos/KissMe.xcodeproj/project.pbxproj b/projects/macos/KissMe.xcodeproj/project.pbxproj index c0e7cd6..6255c0b 100644 --- a/projects/macos/KissMe.xcodeproj/project.pbxproj +++ b/projects/macos/KissMe.xcodeproj/project.pbxproj @@ -17,12 +17,10 @@ 341F5EBC2A0A80EC00962D48 /* KissMe.h in Headers */ = {isa = PBXBuildFile; fileRef = 341F5EAE2A0A80EC00962D48 /* KissMe.h */; settings = {ATTRIBUTES = (Public, ); }; }; 341F5EDE2A0F300100962D48 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EDD2A0F300100962D48 /* Request.swift */; }; 341F5EE12A0F373B00962D48 /* Login.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EE02A0F373B00962D48 /* Login.swift */; }; - 341F5EE52A0F3EF400962D48 /* DomesticStock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EE42A0F3EF400962D48 /* DomesticStock.swift */; }; 341F5EE92A0F87FB00962D48 /* DomesticStockPrice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EE82A0F87FB00962D48 /* DomesticStockPrice.swift */; }; 341F5EEC2A0F883900962D48 /* OverseasStock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EEB2A0F883900962D48 /* OverseasStock.swift */; }; 341F5EEE2A0F884300962D48 /* OverseasStockPrice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EED2A0F884300962D48 /* OverseasStockPrice.swift */; }; 341F5EF02A0F886600962D48 /* OverseasFutures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EEF2A0F886600962D48 /* OverseasFutures.swift */; }; - 341F5EF22A0F887200962D48 /* DomesticFutures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EF12A0F887200962D48 /* DomesticFutures.swift */; }; 341F5EF52A0F891200962D48 /* KissAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EF42A0F891200962D48 /* KissAccount.swift */; }; 341F5EF72A0F8B0500962D48 /* DomesticStockResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EF62A0F8B0500962D48 /* DomesticStockResult.swift */; }; 341F5EF92A0F907300962D48 /* DomesticStockPriceResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EF82A0F907300962D48 /* DomesticStockPriceResult.swift */; }; @@ -38,6 +36,8 @@ 341F5F112A1685E700962D48 /* ShopRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5F102A1685E700962D48 /* ShopRequest.swift */; }; 341F5F142A16CD7A00962D48 /* DomesticShopProduct.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5F132A16CD7A00962D48 /* DomesticShopProduct.swift */; }; 3435A7F72A35D82000D604F1 /* DomesticShortSelling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3435A7F62A35D82000D604F1 /* DomesticShortSelling.swift */; }; + 34942F562CCA9AD200F85B79 /* DomesticStock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34942F552CCA9AD200F85B79 /* DomesticStock.swift */; }; + 34942F5A2CCA9B2700F85B79 /* DomesticFutures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34942F592CCA9B2700F85B79 /* DomesticFutures.swift */; }; 349B05172C25B7C600378D55 /* OverseasStockResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349B05162C25B7C600378D55 /* OverseasStockResult.swift */; }; 349C26AB2A1EAE2400F3EC91 /* KissProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349C26AA2A1EAE2400F3EC91 /* KissProfile.swift */; }; 349F5D142A6BC8D3009A0526 /* String+Html.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349F5D132A6BC8D3009A0526 /* String+Html.swift */; }; @@ -164,12 +164,10 @@ 341F5EBA2A0A80EC00962D48 /* KissMeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissMeTests.swift; sourceTree = ""; }; 341F5EDD2A0F300100962D48 /* Request.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Request.swift; sourceTree = ""; }; 341F5EE02A0F373B00962D48 /* Login.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Login.swift; sourceTree = ""; }; - 341F5EE42A0F3EF400962D48 /* DomesticStock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DomesticStock.swift; path = "../New Group/DomesticStock.swift"; sourceTree = ""; }; 341F5EE82A0F87FB00962D48 /* DomesticStockPrice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStockPrice.swift; sourceTree = ""; }; 341F5EEB2A0F883900962D48 /* OverseasStock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasStock.swift; sourceTree = ""; }; 341F5EED2A0F884300962D48 /* OverseasStockPrice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasStockPrice.swift; sourceTree = ""; }; 341F5EEF2A0F886600962D48 /* OverseasFutures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasFutures.swift; sourceTree = ""; }; - 341F5EF12A0F887200962D48 /* DomesticFutures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticFutures.swift; sourceTree = ""; }; 341F5EF42A0F891200962D48 /* KissAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissAccount.swift; sourceTree = ""; }; 341F5EF62A0F8B0500962D48 /* DomesticStockResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStockResult.swift; sourceTree = ""; }; 341F5EF82A0F907300962D48 /* DomesticStockPriceResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStockPriceResult.swift; sourceTree = ""; }; @@ -185,6 +183,8 @@ 341F5F102A1685E700962D48 /* ShopRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShopRequest.swift; sourceTree = ""; }; 341F5F132A16CD7A00962D48 /* DomesticShopProduct.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticShopProduct.swift; sourceTree = ""; }; 3435A7F62A35D82000D604F1 /* DomesticShortSelling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticShortSelling.swift; sourceTree = ""; }; + 34942F552CCA9AD200F85B79 /* DomesticStock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStock.swift; sourceTree = ""; }; + 34942F592CCA9B2700F85B79 /* DomesticFutures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticFutures.swift; sourceTree = ""; }; 349B05162C25B7C600378D55 /* OverseasStockResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasStockResult.swift; sourceTree = ""; }; 349C26AA2A1EAE2400F3EC91 /* KissProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissProfile.swift; sourceTree = ""; }; 349F5D132A6BC8D3009A0526 /* String+Html.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Html.swift"; sourceTree = ""; }; @@ -368,12 +368,12 @@ isa = PBXGroup; children = ( 34BC44772A86566D0052D8EB /* Stock */, + 34942F582CCA9B1000F85B79 /* Futures */, 34BC44742A8656250052D8EB /* Realtime */, 34F8449E2A683A1700152D98 /* News */, 34C1BA4B2A595A5F00423D64 /* DART */, 34E7B90F2A4994AF00B3AB9F /* KRX300 */, 341F5F122A16CD3C00962D48 /* Shop */, - 341F5EF12A0F887200962D48 /* DomesticFutures.swift */, ); path = Domestic; sourceTree = ""; @@ -416,6 +416,14 @@ path = Shop; sourceTree = ""; }; + 34942F582CCA9B1000F85B79 /* Futures */ = { + isa = PBXGroup; + children = ( + 34942F592CCA9B2700F85B79 /* DomesticFutures.swift */, + ); + path = Futures; + sourceTree = ""; + }; 34BC44742A8656250052D8EB /* Realtime */ = { isa = PBXGroup; children = ( @@ -432,7 +440,7 @@ 34BC44772A86566D0052D8EB /* Stock */ = { isa = PBXGroup; children = ( - 341F5EE42A0F3EF400962D48 /* DomesticStock.swift */, + 34942F552CCA9AD200F85B79 /* DomesticStock.swift */, 341F5EF62A0F8B0500962D48 /* DomesticStockResult.swift */, 341F5EE82A0F87FB00962D48 /* DomesticStockPrice.swift */, 341F5EF82A0F907300962D48 /* DomesticStockPriceResult.swift */, @@ -836,10 +844,10 @@ 341F5EB02A0A80EC00962D48 /* KissMe.docc in Sources */, 341F5EFD2A10931B00962D48 /* DomesticStockSearch.swift in Sources */, 349F5D142A6BC8D3009A0526 /* String+Html.swift in Sources */, - 341F5EE52A0F3EF400962D48 /* DomesticStock.swift in Sources */, 341F5EF72A0F8B0500962D48 /* DomesticStockResult.swift in Sources */, 34F1900F2A426D150068C697 /* ShopContext.swift in Sources */, 341F5F0F2A15223A00962D48 /* SeibroRequest.swift in Sources */, + 34942F562CCA9AD200F85B79 /* DomesticStock.swift in Sources */, 341F5EF02A0F886600962D48 /* OverseasFutures.swift in Sources */, 34F1900C2A41982A0068C697 /* KissIndexResult.swift in Sources */, 341F5EEC2A0F883900962D48 /* OverseasStock.swift in Sources */, @@ -855,7 +863,7 @@ 349C26AB2A1EAE2400F3EC91 /* KissProfile.swift in Sources */, 341F5F012A11155100962D48 /* DomesticStockSearchResult.swift in Sources */, 341F5F142A16CD7A00962D48 /* DomesticShopProduct.swift in Sources */, - 341F5EF22A0F887200962D48 /* DomesticFutures.swift in Sources */, + 34942F5A2CCA9B2700F85B79 /* DomesticFutures.swift in Sources */, 34C1BA4D2A59CD3400423D64 /* DomesticDartNotice.swift in Sources */, 34D3680F2A2AA0BE005E6756 /* PropertyIterable.swift in Sources */, 341F5F112A1685E700962D48 /* ShopRequest.swift in Sources */,