Add oversea APIs (4 kind)
This commit is contained in:
@@ -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
|
return try await withUnsafeThrowingContinuation { continuation in
|
||||||
|
|
||||||
guard let accessToken = accessToken else {
|
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
|
return try await withUnsafeThrowingContinuation { continuation in
|
||||||
|
|
||||||
guard let accessToken = accessToken else {
|
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
|
return try await withUnsafeThrowingContinuation { continuation in
|
||||||
|
|
||||||
guard let accessToken = accessToken else {
|
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
|
return try await withUnsafeThrowingContinuation { continuation in
|
||||||
|
|
||||||
guard let accessToken = accessToken else {
|
guard let accessToken = accessToken else {
|
||||||
@@ -14,434 +14,437 @@ public enum CustomerType: String, Codable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public struct OrderResult: Codable {
|
extension Domestic {
|
||||||
public let resultCode: String
|
|
||||||
public let messageCode: String
|
|
||||||
public let message: String
|
|
||||||
public let output: OutputDetail?
|
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
public struct OrderResult: Codable {
|
||||||
case resultCode = "rt_cd"
|
public let resultCode: String
|
||||||
case messageCode = "msg_cd"
|
public let messageCode: String
|
||||||
case message = "msg1"
|
public let message: String
|
||||||
case output
|
public let output: OutputDetail?
|
||||||
}
|
|
||||||
|
|
||||||
public struct OutputDetail: Codable {
|
|
||||||
public let orderOrganizationNo: String
|
|
||||||
public let orderNo: String
|
|
||||||
public let orderTime: String
|
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case orderOrganizationNo = "KRX_FWDG_ORD_ORGNO"
|
case resultCode = "rt_cd"
|
||||||
case orderNo = "ODNO"
|
case messageCode = "msg_cd"
|
||||||
case orderTime = "ORD_TMD"
|
case message = "msg1"
|
||||||
}
|
case output
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init(array: [String], source: String.SubSequence) throws {
|
public struct OutputDetail: Codable {
|
||||||
guard array.count == 26 else {
|
public let orderOrganizationNo: String
|
||||||
throw GeneralError.incorrectArrayItems(String(source), array.count, 26)
|
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 struct OrderRevisionResult: Codable {
|
||||||
public let depositTotalAmount: String
|
public let resultCode: String
|
||||||
|
public let messageCode: String
|
||||||
/// 익일정산금액 (D+1 예수금)
|
public let message: String
|
||||||
public let nextDayCalcAmount: String
|
public let output: OutputDetail?
|
||||||
|
|
||||||
/// 가수도정산금액 (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 {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case depositTotalAmount = "dnca_tot_amt"
|
case resultCode = "rt_cd"
|
||||||
case nextDayCalcAmount = "nxdy_excc_amt"
|
case messageCode = "msg_cd"
|
||||||
case nextTwoDayCalcAmount = "prvs_rcdl_excc_amt"
|
case message = "msg1"
|
||||||
case cmaEvaluationAmount = "cma_evlu_amt"
|
case output
|
||||||
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 {
|
public struct OutputDetail: Codable {
|
||||||
guard array.count == 24 else {
|
public let orderOrganizationNo: String
|
||||||
throw GeneralError.incorrectArrayItems(String(source), array.count, 24)
|
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 struct BalanceResult: Codable {
|
||||||
public let orderPossibleCash: String
|
public let resultCode: String
|
||||||
|
public let messageCode: String
|
||||||
/// 주문가능대용
|
public let message: String
|
||||||
public let orderPossibleSubstitute: String
|
public let straightInqueryCondition: String?
|
||||||
|
public let straightInqueryKey: String?
|
||||||
/// 재사용가능금액
|
public let output1: [OutputStock]
|
||||||
public let reusePossibleAmount: String
|
public let output2: [OutputAmount]
|
||||||
|
|
||||||
/// 펀드환매대금
|
|
||||||
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 {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case orderPossibleCash = "ord_psbl_cash"
|
case resultCode = "rt_cd"
|
||||||
case orderPossibleSubstitute = "ord_psbl_sbst"
|
case messageCode = "msg_cd"
|
||||||
case reusePossibleAmount = "ruse_psbl_amt"
|
case message = "msg1"
|
||||||
case fundRepurchaseChanges = "fund_rpch_chgs"
|
case straightInqueryCondition = "ctx_area_fk100"
|
||||||
case possibleQuantityCalcPrice = "psbl_qty_calc_unpr"
|
case straightInqueryKey = "ctx_area_nk100"
|
||||||
case nonrechargeableBuyAmount = "nrcvb_buy_amt"
|
case output1 = "output1"
|
||||||
case nonrechargeableBuyQuantity = "nrcvb_buy_qty"
|
case output2 = "output2"
|
||||||
case maxBuyAmount = "max_buy_amt"
|
}
|
||||||
case maxBuyQuantity = "max_buy_qty"
|
|
||||||
case cmaEvaluationAmount = "cma_evlu_amt"
|
public struct OutputStock: Codable, PropertyIterable {
|
||||||
case overseasReuseAmountWon = "ovrs_re_use_amt_wcrc"
|
/// 상품번호
|
||||||
case orderPossibleForeignCurrencyAmountWon = "ord_psbl_frcr_amt_wcrc"
|
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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import Foundation
|
|||||||
|
|
||||||
|
|
||||||
public struct Overseas {
|
public struct Overseas {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -244,4 +243,326 @@ extension Overseas {
|
|||||||
self.isNext = isNext
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,23 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
public enum CurrencyCode: String, Codable {
|
||||||
|
case usd = "USD"
|
||||||
|
case hkd = "HKD"
|
||||||
|
case cny = "CNY"
|
||||||
|
case jpy = "JPY"
|
||||||
|
case vnd = "VND"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
extension Overseas {
|
extension Overseas {
|
||||||
|
|
||||||
/*
|
public typealias OrderResult = Domestic.OrderResult
|
||||||
public struct OrderResult: Codable {
|
public typealias OrderRevisionResult = Domestic.OrderRevisionResult
|
||||||
|
|
||||||
|
|
||||||
|
public struct PreorderResult: Codable {
|
||||||
public let resultCode: String
|
public let resultCode: String
|
||||||
public let messageCode: String
|
public let messageCode: String
|
||||||
public let message: String
|
public let message: String
|
||||||
@@ -24,16 +37,267 @@ extension Overseas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public struct OutputDetail: Codable {
|
public struct OutputDetail: Codable {
|
||||||
public let orderOrganizationNo: String
|
/// 한국거래소전송주문조직번호
|
||||||
public let orderNo: String
|
public let orderNo: String
|
||||||
public let orderTime: String
|
/// 예약주문접수일자
|
||||||
|
public let reservationOrderReceiptDate: String
|
||||||
|
/// 해외예약주문번호
|
||||||
|
public let reservationOrderNo: String
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case orderOrganizationNo = "KRX_FWDG_ORD_ORGNO"
|
|
||||||
case orderNo = "ODNO"
|
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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,3 +26,7 @@ KissMeSacks 는 분봉을 바탕으로 가상의 매매를 시뮬레이션 해
|
|||||||
### SP design
|
### SP design
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
|
### FieldBuf design
|
||||||
|
|
||||||
|
### WorldBuf design
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -142,6 +142,23 @@ KissMeGolder 는 KissMeMatrix model 을 충실하게 따르면서, 자동으로
|
|||||||
|
|
||||||
사용하고자 하는 model 에 따라서 다양한 투자 성향을 가질 수 있도록 설계할 것입니다.
|
사용하고자 하는 model 에 따라서 다양한 투자 성향을 가질 수 있도록 설계할 것입니다.
|
||||||
|
|
||||||
|
# KissMeSacks
|
||||||
|
|
||||||
|
KissMeSacks 는 단타 매매를 자동으로 검증해주는 시뮬레이션 로봇입니다.
|
||||||
|
|
||||||
|
완성도가 높아지면 나중에 KissGoblin UI 기능으로 연동될 것입니다.
|
||||||
|
|
||||||
|
# KissGram
|
||||||
|
|
||||||
|
KissGram 은 텔레그램 봇과 연동하여 다양한 정보 창구로 쓰일 수 있도록 고안된 인터페이스 툴입니다.
|
||||||
|
|
||||||
|
# KissGoblin
|
||||||
|
|
||||||
|
디아블로의 보물 고블린의 아이디어에서 따온 것입니다.
|
||||||
|
|
||||||
|
매수 시점에 고블린이 스폰되고, 매도 시점에 고블린이 아이템을 드랍하고 사라지는 컨셉입니다.
|
||||||
|
|
||||||
|
매수와 매도 사이의 재미있는 인터페이스를 제공하는 것이 목표입니다.
|
||||||
|
|
||||||
# Credential json
|
# Credential json
|
||||||
|
|
||||||
|
|||||||
@@ -17,12 +17,10 @@
|
|||||||
341F5EBC2A0A80EC00962D48 /* KissMe.h in Headers */ = {isa = PBXBuildFile; fileRef = 341F5EAE2A0A80EC00962D48 /* KissMe.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
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 */; };
|
341F5EDE2A0F300100962D48 /* Request.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EDD2A0F300100962D48 /* Request.swift */; };
|
||||||
341F5EE12A0F373B00962D48 /* Login.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EE02A0F373B00962D48 /* Login.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 */; };
|
341F5EE92A0F87FB00962D48 /* DomesticStockPrice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EE82A0F87FB00962D48 /* DomesticStockPrice.swift */; };
|
||||||
341F5EEC2A0F883900962D48 /* OverseasStock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EEB2A0F883900962D48 /* OverseasStock.swift */; };
|
341F5EEC2A0F883900962D48 /* OverseasStock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EEB2A0F883900962D48 /* OverseasStock.swift */; };
|
||||||
341F5EEE2A0F884300962D48 /* OverseasStockPrice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EED2A0F884300962D48 /* OverseasStockPrice.swift */; };
|
341F5EEE2A0F884300962D48 /* OverseasStockPrice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EED2A0F884300962D48 /* OverseasStockPrice.swift */; };
|
||||||
341F5EF02A0F886600962D48 /* OverseasFutures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EEF2A0F886600962D48 /* OverseasFutures.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 */; };
|
341F5EF52A0F891200962D48 /* KissAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EF42A0F891200962D48 /* KissAccount.swift */; };
|
||||||
341F5EF72A0F8B0500962D48 /* DomesticStockResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EF62A0F8B0500962D48 /* DomesticStockResult.swift */; };
|
341F5EF72A0F8B0500962D48 /* DomesticStockResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EF62A0F8B0500962D48 /* DomesticStockResult.swift */; };
|
||||||
341F5EF92A0F907300962D48 /* DomesticStockPriceResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5EF82A0F907300962D48 /* DomesticStockPriceResult.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 */; };
|
341F5F112A1685E700962D48 /* ShopRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5F102A1685E700962D48 /* ShopRequest.swift */; };
|
||||||
341F5F142A16CD7A00962D48 /* DomesticShopProduct.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5F132A16CD7A00962D48 /* DomesticShopProduct.swift */; };
|
341F5F142A16CD7A00962D48 /* DomesticShopProduct.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341F5F132A16CD7A00962D48 /* DomesticShopProduct.swift */; };
|
||||||
3435A7F72A35D82000D604F1 /* DomesticShortSelling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3435A7F62A35D82000D604F1 /* DomesticShortSelling.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 */; };
|
349B05172C25B7C600378D55 /* OverseasStockResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349B05162C25B7C600378D55 /* OverseasStockResult.swift */; };
|
||||||
349C26AB2A1EAE2400F3EC91 /* KissProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 349C26AA2A1EAE2400F3EC91 /* KissProfile.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 */; };
|
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 = "<group>"; };
|
341F5EBA2A0A80EC00962D48 /* KissMeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissMeTests.swift; sourceTree = "<group>"; };
|
||||||
341F5EDD2A0F300100962D48 /* Request.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Request.swift; sourceTree = "<group>"; };
|
341F5EDD2A0F300100962D48 /* Request.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Request.swift; sourceTree = "<group>"; };
|
||||||
341F5EE02A0F373B00962D48 /* Login.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Login.swift; sourceTree = "<group>"; };
|
341F5EE02A0F373B00962D48 /* Login.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Login.swift; sourceTree = "<group>"; };
|
||||||
341F5EE42A0F3EF400962D48 /* DomesticStock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = DomesticStock.swift; path = "../New Group/DomesticStock.swift"; sourceTree = "<group>"; };
|
|
||||||
341F5EE82A0F87FB00962D48 /* DomesticStockPrice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStockPrice.swift; sourceTree = "<group>"; };
|
341F5EE82A0F87FB00962D48 /* DomesticStockPrice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStockPrice.swift; sourceTree = "<group>"; };
|
||||||
341F5EEB2A0F883900962D48 /* OverseasStock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasStock.swift; sourceTree = "<group>"; };
|
341F5EEB2A0F883900962D48 /* OverseasStock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasStock.swift; sourceTree = "<group>"; };
|
||||||
341F5EED2A0F884300962D48 /* OverseasStockPrice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasStockPrice.swift; sourceTree = "<group>"; };
|
341F5EED2A0F884300962D48 /* OverseasStockPrice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasStockPrice.swift; sourceTree = "<group>"; };
|
||||||
341F5EEF2A0F886600962D48 /* OverseasFutures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasFutures.swift; sourceTree = "<group>"; };
|
341F5EEF2A0F886600962D48 /* OverseasFutures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasFutures.swift; sourceTree = "<group>"; };
|
||||||
341F5EF12A0F887200962D48 /* DomesticFutures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticFutures.swift; sourceTree = "<group>"; };
|
|
||||||
341F5EF42A0F891200962D48 /* KissAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissAccount.swift; sourceTree = "<group>"; };
|
341F5EF42A0F891200962D48 /* KissAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissAccount.swift; sourceTree = "<group>"; };
|
||||||
341F5EF62A0F8B0500962D48 /* DomesticStockResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStockResult.swift; sourceTree = "<group>"; };
|
341F5EF62A0F8B0500962D48 /* DomesticStockResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStockResult.swift; sourceTree = "<group>"; };
|
||||||
341F5EF82A0F907300962D48 /* DomesticStockPriceResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStockPriceResult.swift; sourceTree = "<group>"; };
|
341F5EF82A0F907300962D48 /* DomesticStockPriceResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStockPriceResult.swift; sourceTree = "<group>"; };
|
||||||
@@ -185,6 +183,8 @@
|
|||||||
341F5F102A1685E700962D48 /* ShopRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShopRequest.swift; sourceTree = "<group>"; };
|
341F5F102A1685E700962D48 /* ShopRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShopRequest.swift; sourceTree = "<group>"; };
|
||||||
341F5F132A16CD7A00962D48 /* DomesticShopProduct.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticShopProduct.swift; sourceTree = "<group>"; };
|
341F5F132A16CD7A00962D48 /* DomesticShopProduct.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticShopProduct.swift; sourceTree = "<group>"; };
|
||||||
3435A7F62A35D82000D604F1 /* DomesticShortSelling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticShortSelling.swift; sourceTree = "<group>"; };
|
3435A7F62A35D82000D604F1 /* DomesticShortSelling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticShortSelling.swift; sourceTree = "<group>"; };
|
||||||
|
34942F552CCA9AD200F85B79 /* DomesticStock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticStock.swift; sourceTree = "<group>"; };
|
||||||
|
34942F592CCA9B2700F85B79 /* DomesticFutures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomesticFutures.swift; sourceTree = "<group>"; };
|
||||||
349B05162C25B7C600378D55 /* OverseasStockResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasStockResult.swift; sourceTree = "<group>"; };
|
349B05162C25B7C600378D55 /* OverseasStockResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverseasStockResult.swift; sourceTree = "<group>"; };
|
||||||
349C26AA2A1EAE2400F3EC91 /* KissProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissProfile.swift; sourceTree = "<group>"; };
|
349C26AA2A1EAE2400F3EC91 /* KissProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KissProfile.swift; sourceTree = "<group>"; };
|
||||||
349F5D132A6BC8D3009A0526 /* String+Html.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Html.swift"; sourceTree = "<group>"; };
|
349F5D132A6BC8D3009A0526 /* String+Html.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Html.swift"; sourceTree = "<group>"; };
|
||||||
@@ -368,12 +368,12 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
34BC44772A86566D0052D8EB /* Stock */,
|
34BC44772A86566D0052D8EB /* Stock */,
|
||||||
|
34942F582CCA9B1000F85B79 /* Futures */,
|
||||||
34BC44742A8656250052D8EB /* Realtime */,
|
34BC44742A8656250052D8EB /* Realtime */,
|
||||||
34F8449E2A683A1700152D98 /* News */,
|
34F8449E2A683A1700152D98 /* News */,
|
||||||
34C1BA4B2A595A5F00423D64 /* DART */,
|
34C1BA4B2A595A5F00423D64 /* DART */,
|
||||||
34E7B90F2A4994AF00B3AB9F /* KRX300 */,
|
34E7B90F2A4994AF00B3AB9F /* KRX300 */,
|
||||||
341F5F122A16CD3C00962D48 /* Shop */,
|
341F5F122A16CD3C00962D48 /* Shop */,
|
||||||
341F5EF12A0F887200962D48 /* DomesticFutures.swift */,
|
|
||||||
);
|
);
|
||||||
path = Domestic;
|
path = Domestic;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -416,6 +416,14 @@
|
|||||||
path = Shop;
|
path = Shop;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
34942F582CCA9B1000F85B79 /* Futures */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
34942F592CCA9B2700F85B79 /* DomesticFutures.swift */,
|
||||||
|
);
|
||||||
|
path = Futures;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
34BC44742A8656250052D8EB /* Realtime */ = {
|
34BC44742A8656250052D8EB /* Realtime */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -432,7 +440,7 @@
|
|||||||
34BC44772A86566D0052D8EB /* Stock */ = {
|
34BC44772A86566D0052D8EB /* Stock */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
341F5EE42A0F3EF400962D48 /* DomesticStock.swift */,
|
34942F552CCA9AD200F85B79 /* DomesticStock.swift */,
|
||||||
341F5EF62A0F8B0500962D48 /* DomesticStockResult.swift */,
|
341F5EF62A0F8B0500962D48 /* DomesticStockResult.swift */,
|
||||||
341F5EE82A0F87FB00962D48 /* DomesticStockPrice.swift */,
|
341F5EE82A0F87FB00962D48 /* DomesticStockPrice.swift */,
|
||||||
341F5EF82A0F907300962D48 /* DomesticStockPriceResult.swift */,
|
341F5EF82A0F907300962D48 /* DomesticStockPriceResult.swift */,
|
||||||
@@ -836,10 +844,10 @@
|
|||||||
341F5EB02A0A80EC00962D48 /* KissMe.docc in Sources */,
|
341F5EB02A0A80EC00962D48 /* KissMe.docc in Sources */,
|
||||||
341F5EFD2A10931B00962D48 /* DomesticStockSearch.swift in Sources */,
|
341F5EFD2A10931B00962D48 /* DomesticStockSearch.swift in Sources */,
|
||||||
349F5D142A6BC8D3009A0526 /* String+Html.swift in Sources */,
|
349F5D142A6BC8D3009A0526 /* String+Html.swift in Sources */,
|
||||||
341F5EE52A0F3EF400962D48 /* DomesticStock.swift in Sources */,
|
|
||||||
341F5EF72A0F8B0500962D48 /* DomesticStockResult.swift in Sources */,
|
341F5EF72A0F8B0500962D48 /* DomesticStockResult.swift in Sources */,
|
||||||
34F1900F2A426D150068C697 /* ShopContext.swift in Sources */,
|
34F1900F2A426D150068C697 /* ShopContext.swift in Sources */,
|
||||||
341F5F0F2A15223A00962D48 /* SeibroRequest.swift in Sources */,
|
341F5F0F2A15223A00962D48 /* SeibroRequest.swift in Sources */,
|
||||||
|
34942F562CCA9AD200F85B79 /* DomesticStock.swift in Sources */,
|
||||||
341F5EF02A0F886600962D48 /* OverseasFutures.swift in Sources */,
|
341F5EF02A0F886600962D48 /* OverseasFutures.swift in Sources */,
|
||||||
34F1900C2A41982A0068C697 /* KissIndexResult.swift in Sources */,
|
34F1900C2A41982A0068C697 /* KissIndexResult.swift in Sources */,
|
||||||
341F5EEC2A0F883900962D48 /* OverseasStock.swift in Sources */,
|
341F5EEC2A0F883900962D48 /* OverseasStock.swift in Sources */,
|
||||||
@@ -855,7 +863,7 @@
|
|||||||
349C26AB2A1EAE2400F3EC91 /* KissProfile.swift in Sources */,
|
349C26AB2A1EAE2400F3EC91 /* KissProfile.swift in Sources */,
|
||||||
341F5F012A11155100962D48 /* DomesticStockSearchResult.swift in Sources */,
|
341F5F012A11155100962D48 /* DomesticStockSearchResult.swift in Sources */,
|
||||||
341F5F142A16CD7A00962D48 /* DomesticShopProduct.swift in Sources */,
|
341F5F142A16CD7A00962D48 /* DomesticShopProduct.swift in Sources */,
|
||||||
341F5EF22A0F887200962D48 /* DomesticFutures.swift in Sources */,
|
34942F5A2CCA9B2700F85B79 /* DomesticFutures.swift in Sources */,
|
||||||
34C1BA4D2A59CD3400423D64 /* DomesticDartNotice.swift in Sources */,
|
34C1BA4D2A59CD3400423D64 /* DomesticDartNotice.swift in Sources */,
|
||||||
34D3680F2A2AA0BE005E6756 /* PropertyIterable.swift in Sources */,
|
34D3680F2A2AA0BE005E6756 /* PropertyIterable.swift in Sources */,
|
||||||
341F5F112A1685E700962D48 /* ShopRequest.swift in Sources */,
|
341F5F112A1685E700962D48 /* ShopRequest.swift in Sources */,
|
||||||
|
|||||||
Reference in New Issue
Block a user