Implement candle period

This commit is contained in:
2023-06-02 02:19:32 +09:00
parent 7bf087b3ed
commit f80a2ffb0c
5 changed files with 108 additions and 15 deletions

View File

@@ -10,6 +10,7 @@ import Foundation
public struct Domestic {
public typealias Candle = MinutePriceResult.OutputPrice
public typealias CandlePeriod = PeriodPriceResult.OutputPrice
}

View File

@@ -40,7 +40,7 @@ public enum MarketWarning: String, Codable {
///
public enum PeriodDivision: String, Codable {
public enum PeriodDivision: String, Codable, CustomStringConvertible {
///
case daily = "D"
///
@@ -49,6 +49,15 @@ public enum PeriodDivision: String, Codable {
case monthly = "M"
///
case yearly = "Y"
public var description: String {
switch self {
case .daily: return "daily"
case .weekly: return "weekly"
case .monthly: return "monthly"
case .yearly: return "yearly"
}
}
}
@@ -543,6 +552,10 @@ public struct MinutePriceResult: Codable {
case conclusionVolume = "cntg_vol"
}
public var stockFullDate: String {
return stockBusinessDate + stockConclusionTime
}
public init(array: [String]) {
self.stockBusinessDate = array[0]
self.stockConclusionTime = array[1]
@@ -562,7 +575,7 @@ public struct PeriodPriceResult: Codable {
public let messageCode: String
public let message: String
public let output1: OutputSummary?
public let output2: [OutputPrice]
public let output2: [OutputPrice]?
private enum CodingKeys: String, CodingKey {
case resultCode = "rt_cd"
@@ -753,5 +766,21 @@ public struct PeriodPriceResult: Codable {
case previousDayVariableRatio = "prdy_vrss"
case revaluationIssueReason = "revl_issu_reas"
}
public init(array: [String]) {
self.stockBusinessDate = array[0]
self.stockClosingPrice = array[1]
self.stockOpenningPrice = array[2]
self.highestStockPrice = array[3]
self.lowestStockPrice = array[4]
self.accumulatedVolume = array[5]
self.accumulatedTradingAmount = array[6]
self.exDivision = ExDivision(rawValue: array[7])!
self.partitionRate = array[8]
self.partitionModifiable = YesNo(rawValue: array[9])!
self.previousDayVariableRatioSign = array[10]
self.previousDayVariableRatio = array[11]
self.revaluationIssueReason = array[12]
}
}
}

View File

@@ -60,7 +60,7 @@ extension KissConsole {
}
static func writeShop(_ shopItems: [DomesticShop.Product], fileUrl: URL) {
var stringCsv: String = ""
var stringCsv = ""
let header = "baseDate,shortCode,isinCode,marketCategory,itemName,corporationNo\n"
stringCsv.append(header)
for item in shopItems {
@@ -83,8 +83,8 @@ extension KissConsole {
}
static func writeCandle(_ prices: [Domestic.Candle], fileUrl: URL) {
var stringCsv: String = "stockBusinessDate,stockConclusionTime,accumulatedTradingAmount,currentStockPrice,secondStockPrice,highestStockPrice,lowestStockPrice,conclusionVolume\n"
let header = ""
var stringCsv = ""
let header = "stockBusinessDate,stockConclusionTime,accumulatedTradingAmount,currentStockPrice,secondStockPrice,highestStockPrice,lowestStockPrice,conclusionVolume\n"
stringCsv.append(header)
for item in prices {
let stringItem = [item.stockBusinessDate,
@@ -106,6 +106,35 @@ extension KissConsole {
}
}
static func writeCandle(_ prices: [Domestic.CandlePeriod], fileUrl: URL) {
var stringCsv = ""
let header = "stockBusinessDate,stockClosingPrice,stockOpenningPrice,highestStockPrice,lowestStockPrice,accumulatedVolume,accumulatedTradingAmount,exDivision,partitionRate,partitionModifiable,previousDayVariableRatioSign,previousDayVariableRatio,revaluationIssueReason\n"
stringCsv.append(header)
for item in prices {
let stringItem = [item.stockBusinessDate,
item.stockClosingPrice,
item.stockOpenningPrice,
item.highestStockPrice,
item.lowestStockPrice,
item.accumulatedVolume,
item.accumulatedTradingAmount,
item.exDivision.rawValue,
item.partitionRate,
item.partitionModifiable.rawValue,
item.previousDayVariableRatioSign,
item.previousDayVariableRatio,
item.revaluationIssueReason].joined(separator: ",")
stringCsv.append(stringItem)
stringCsv.append("\n")
}
do {
try stringCsv.write(toFile: fileUrl.path, atomically: true, encoding: .utf8)
print("wrote \(fileUrl.lastPathComponent) with \(prices.count)")
} catch {
print(error)
}
}
enum CandleValidation: CustomStringConvertible {
case ok

View File

@@ -60,16 +60,37 @@ extension KissConsole {
defer {
currentCandleShortCode = nil
}
var nextTime = Date()
var candles = [Domestic.Candle]()
var nextTime = startDate
var candles = [Domestic.CandlePeriod]()
var count = 0
let result = try await account!.getPeriodPrice(productNo: productNo, startDate: startDate, endDate: endDate, period: .daily)
while true {
count += 1
let result = try await account!.getPeriodPrice(productNo: productNo, startDate: startDate, endDate: endDate, period: period)
if let prices = result.output2, prices.isEmpty == false {
candles.append(contentsOf: prices)
if let last = prices.last {
// TODO: nextTime ...
}
try await Task.sleep(nanoseconds: 1_000_000_000 / PreferredCandleTPS)
}
else {
print("\(period) price finished")
}
}
// let fileUrl = candleFileUrl(productNo: productNo, period: "min", day: minTime)
// KissConsole.writeCandle(candles, fileUrl: fileUrl)
candles.sort(by: { $0.stockBusinessDate > $1.stockBusinessDate })
guard let maxTime = candles.first?.stockBusinessDate else {
print("No price items")
return false
}
let fileUrl = candleFileUrl(productNo: productNo, period: period.filePeriod, day: maxTime)
KissConsole.writeCandle(candles, fileUrl: fileUrl)
return true
} catch {
print(error)
@@ -125,13 +146,13 @@ extension KissConsole {
}
}
candles.sort(by: { $0.stockBusinessDate < $1.stockBusinessDate })
guard let minTime = candles.first?.stockBusinessDate else {
candles.sort(by: { $0.stockFullDate > $1.stockFullDate })
guard let maxTime = candles.first?.stockBusinessDate else {
print("No price items")
return false
}
let fileUrl = candleFileUrl(productNo: productNo, period: .minute, day: minTime)
let fileUrl = candleFileUrl(productNo: productNo, period: .minute, day: maxTime)
KissConsole.writeCandle(candles, fileUrl: fileUrl)
return true
} catch {
@@ -140,3 +161,16 @@ extension KissConsole {
}
}
}
extension PeriodDivision {
var filePeriod: KissConsole.CandleFilePeriod {
switch self {
case .daily: return .day
case .weekly: return .weak
case .monthly: assertionFailure()
case .yearly: assertionFailure()
}
return .minute
}
}