Fix bugs on candle day request
This commit is contained in:
@@ -57,6 +57,7 @@ public protocol Request {
|
||||
var result: KResult? { get set }
|
||||
var timeout: TimeInterval { get }
|
||||
var responseDataLoggable: Bool { get }
|
||||
var traceable: Bool { get }
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +73,7 @@ extension Request {
|
||||
public var header: [String: String?] { [:] }
|
||||
public var timeout: TimeInterval { 15 }
|
||||
public var responseDataLoggable: Bool { true }
|
||||
public var traceable: Bool { false }
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +114,7 @@ extension Request {
|
||||
|
||||
case .get:
|
||||
var queryItems = [URLQueryItem]()
|
||||
for item in body {
|
||||
for item in body.sorted(by: { $0.key < $1.key }) {
|
||||
if let value = item.value as? String {
|
||||
queryItems.append(URLQueryItem(name: item.key, value: value))
|
||||
}
|
||||
@@ -121,6 +123,10 @@ extension Request {
|
||||
request.url?.append(queryItems: queryItems)
|
||||
}
|
||||
|
||||
if traceable, let url = request.url {
|
||||
print("REQUEST \(method) \(url)")
|
||||
}
|
||||
|
||||
request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
|
||||
request.setValue("JSON", forHTTPHeaderField: "Format")
|
||||
request.setValue(userAgent, forHTTPHeaderField: "User-Agent")
|
||||
|
||||
@@ -139,9 +139,8 @@ extension Domestic {
|
||||
}
|
||||
public var result: KResult? = nil
|
||||
public let credential: Credential
|
||||
public var responseDataLoggable: Bool {
|
||||
return true
|
||||
}
|
||||
public var responseDataLoggable: Bool { true }
|
||||
public var traceable: Bool { true }
|
||||
|
||||
|
||||
private var trId: String {
|
||||
@@ -160,7 +159,7 @@ extension Domestic {
|
||||
self.accessToken = accessToken
|
||||
self.productNo = productNo
|
||||
self.startDate = startDate
|
||||
self.endDate = startDate
|
||||
self.endDate = endDate
|
||||
self.period = period
|
||||
self.priceType = priceType
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Foundation
|
||||
|
||||
|
||||
public enum DivisionClassCode: String {
|
||||
public enum DivisionClassCode: String, Codable {
|
||||
/// 전체
|
||||
case all = "0"
|
||||
/// 보통주
|
||||
@@ -18,6 +18,24 @@ public enum DivisionClassCode: String {
|
||||
}
|
||||
|
||||
|
||||
public enum WeekdayDivision: String, Codable {
|
||||
/// 일요일
|
||||
case sunday = "01"
|
||||
/// 월요일
|
||||
case monday = "02"
|
||||
/// 화요일
|
||||
case tueday = "03"
|
||||
/// 수요일
|
||||
case wednesday = "04"
|
||||
/// 목요일
|
||||
case thursday = "05"
|
||||
/// 금요일
|
||||
case friday = "06"
|
||||
/// 토요일
|
||||
case saturday = "07"
|
||||
}
|
||||
|
||||
|
||||
public enum BelongClassCode: String, CustomStringConvertible {
|
||||
/// 평균거래량
|
||||
case averageVolume = "0"
|
||||
@@ -102,6 +120,49 @@ extension Domestic {
|
||||
self.belongClass = belongClass
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// 국내주식주문 - 국내휴장일조회
|
||||
///
|
||||
public struct HolidayRequest: OrderRequest {
|
||||
public typealias KResult = HolidyResult
|
||||
|
||||
public var url: String { "/uapi/domestic-stock/v1/quotations/chk-holiday" }
|
||||
public var method: Method { .post }
|
||||
|
||||
public var header: [String: String?] {
|
||||
[
|
||||
"authorization": "Bearer \(accessToken)",
|
||||
"appkey": credential.appKey,
|
||||
"appsecret": credential.appSecret,
|
||||
"tr_id": trId,
|
||||
"custtype": CustomerType.personal.rawValue,
|
||||
]
|
||||
}
|
||||
public var body: [String: Any] {
|
||||
[
|
||||
"BASS_DT": baseDate,
|
||||
"CTX_AREA_NK": String(repeating: " ", count: 20),
|
||||
"CTX_AREA_FK": String(repeating: " ", count: 20),
|
||||
]
|
||||
}
|
||||
public var result: KResult? = nil
|
||||
public let credential: Credential
|
||||
|
||||
|
||||
private var trId: String {
|
||||
"CTCA0903R"
|
||||
}
|
||||
|
||||
public let accessToken: String
|
||||
let baseDate: String /// yyyyMMdd
|
||||
|
||||
public init(credential: Credential, accessToken: String, baseDate: String) {
|
||||
self.credential = credential
|
||||
self.accessToken = accessToken
|
||||
self.baseDate = baseDate
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,8 +180,9 @@ public struct RankingOption {
|
||||
// MARK: Stock Search
|
||||
extension KissAccount {
|
||||
|
||||
/// 상위 거래량 가져오기
|
||||
///
|
||||
public func getVolumeRanking(option: RankingOption) async throws -> VolumeRankResult {
|
||||
|
||||
return try await withUnsafeThrowingContinuation { continuation in
|
||||
guard let accessToken = accessToken else {
|
||||
continuation.resume(throwing: GeneralError.invalidAccessToken)
|
||||
@@ -138,4 +200,25 @@ extension KissAccount {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 휴장일 확인하기
|
||||
///
|
||||
public func getHolyday(baseDate: Date) async throws -> HolidyResult {
|
||||
return try await withUnsafeThrowingContinuation { continuation in
|
||||
guard let accessToken = accessToken else {
|
||||
continuation.resume(throwing: GeneralError.invalidAccessToken)
|
||||
return
|
||||
}
|
||||
|
||||
let request = Domestic.HolidayRequest(credential: credential, accessToken: accessToken, baseDate: baseDate.yyyyMMdd)
|
||||
request.query { result in
|
||||
switch result {
|
||||
case .success(let result):
|
||||
continuation.resume(returning: result)
|
||||
case .failure(let error):
|
||||
continuation.resume(throwing: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,3 +104,47 @@ public struct VolumeRankResult: Codable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public struct HolidyResult: 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 = "output"
|
||||
}
|
||||
|
||||
public struct OutputDetail: Codable {
|
||||
/// 기준일자
|
||||
public let baseDate: String
|
||||
|
||||
/// 요일구분코드
|
||||
public let weekday: WeekdayDivision
|
||||
|
||||
/// 영업일여부
|
||||
public let businessDayOpened: YesNo
|
||||
|
||||
/// 거래일여부
|
||||
public let tradingDayOpened: YesNo
|
||||
|
||||
/// 개장일여부
|
||||
public let peningDay: YesNo
|
||||
|
||||
/// 결제일여부
|
||||
public let settlementDay: YesNo
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case baseDate = "bass_dt"
|
||||
case weekday = "wday_dvsn_cd"
|
||||
case businessDayOpened = "bzdy_yn"
|
||||
case tradingDayOpened = "tr_day_yn"
|
||||
case peningDay = "opnd_yn"
|
||||
case settlementDay = "sttl_day_yn"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ extension KissConsole {
|
||||
|
||||
|
||||
func candleFileUrl(productNo: String, period: CandleFilePeriod, day: String) -> URL {
|
||||
assert(day.count == 6)
|
||||
assert(day.count == 8)
|
||||
let subPath = "data/\(productNo)/\(period.rawValue)"
|
||||
let subFile = "\(subPath)/candle-\(day).csv"
|
||||
let fileUrl = URL.currentDirectory().appending(path: subFile)
|
||||
|
||||
@@ -584,8 +584,8 @@ extension KissConsole {
|
||||
}
|
||||
|
||||
let (startDate, endDate) = last250Days
|
||||
// let startDate = Date().changing(year: 2022, month: 12, day: 1)!
|
||||
// let endDate = Date().changing(year: 2022, month: 12, day: 30)!
|
||||
//let startDate = Date().changing(year: 2023, month: 5, day: 1)!
|
||||
//let endDate = Date().changing(year: 2023, month: 6, day: 1)!
|
||||
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
Task {
|
||||
|
||||
Reference in New Issue
Block a user