Files
KissMe/KissMeConsole/Sources/KissConsole+Price.swift

154 lines
6.4 KiB
Swift

//
// KissConsole+Price.swift
// KissMeConsole
//
// Created by ened-book-m1 on 2023/06/11.
//
import Foundation
import KissMe
extension KissConsole {
func getCurrentPrice(productNo: String, printConsole: Bool = false) async -> Bool {
do {
let result = try await account!.getCurrentPrice(productNo: productNo)
guard let output = result.output else {
print("Invalid result's output for \(productNo)")
return false
}
if printConsole {
printCurrentPrice(output)
}
let price = CapturePrice(captureTime: Date(), price: output)
let yyyyMM = String(price.stockBusinessDate.prefix(6))
let fileUrl = KissConsole.priceFileUrl(productNo: productNo, day: yyyyMM+"01")
try [price].mergeCsv(toFile: fileUrl, merging: { this, file in
var merged = this
for old in file {
if nil == this.first(where: { $0.stockDateTime == old.stockDateTime }) {
merged.append(old)
}
}
merged.sort(by: { $0.stockDateTime > $1.stockDateTime })
return merged
}, localized: false)
try await Task.sleep(nanoseconds: 1_000_000_000 / PreferredNowTPS)
} catch {
print(error)
return false
}
return true
}
private func printCurrentPrice(_ output: Domestic.CurrentPrice) {
let productName = getProduct(shortCode: output.shortProductCode)?.itemName ?? ""
print("\t종목명: ", productName)
print("\t업종명: ", output.koreanMarketName, output.koreanBusinessTypeName ?? "")
print("\t주식 현재가: ", output.currentStockPrice)
print("\t전일 대비: ", output.previousDayVariableRatio)
print("\t누적 거래 대금: ", output.accumulatedTradingAmount)
print("\t누적 거래량: ", output.accumulatedVolume)
print("\t전일 대비 거래량 비율: ", output.previousDayDiffVolumeRatio)
print("\t주식 시가: ", output.stockOpenningPrice)
print("\t주식 최고가: ", output.highestStockPrice)
print("\t주식 최저가: ", output.lowestStockPrice)
print("\t외국인 순매수 수량: ", output.foreignNetBuyingQuantity)
print("\t외국인 보유 수량: ", output.foreignHoldQuantity)
print("\t최종 공매도 체결 수량: ", output.lastShortSellingConclusionQuantity)
print("\t프로그램매매 순매수 수량: ", output.programTradeNetBuyingQuantity)
print("\t자본금: ", output.capital)
print("\t상장 주수: ", output.listedStockCount)
print("\tHTS 시가총액: ", output.htsTotalMarketValue)
print("\tPER: ", output.per)
print("\tPBR: ", output.pbr)
print("\t주식 단축 종목코드", output.shortProductCode)
}
func getShortsLastDate(productNo: String) -> Date? {
let startDate = Date().addingTimeInterval(-365 * SecondsForOneDay)
var backDate = Date()
/// -29 , csv .
while startDate < backDate {
let day = backDate.yyyyMM01
let fileUrl = KissConsole.shortsFileUrl(productNo: productNo, day: day)
guard fileUrl.isFileExists == true else {
backDate = backDate.addingTimeInterval(-29 * SecondsForOneDay)
continue
}
guard let shorts = try? [DomesticExtra.Shorts].readCsv(fromFile: fileUrl) else {
return Date.date(yyyyMMdd: day, HHmmss: "000000")
}
guard let (yyyy, mm, dd) = shorts.first?.stockBusinessDate.yyyyMMdd else {
return Date.date(yyyyMMdd: day, HHmmss: "000000")
}
guard let newDate = backDate.changing(year: yyyy, month: mm, day: dd) else {
return Date.date(yyyyMMdd: day, HHmmss: "000000")
}
return newDate.addingTimeInterval(SecondsForOneDay)
}
return nil
}
func getShorts(productNo: String, startAt: Date?) async throws -> Bool {
guard let product = getProduct(shortCode: productNo) else {
print("Invalid product \(productNo)")
return false
}
let endDate = Date()
let startDate: Date
if let startAt = startAt {
startDate = startAt
}
else {
startDate = endDate.addingTimeInterval(-365 * SecondsForOneDay)
}
print("Getting \(product.isinCode), \(startDate.yyyyMMdd) ~ \(endDate.yyyyMMdd)")
let result = try await KissAccount.getShortSellingBalance(isinCode: product.isinCode, startDate: startDate, endDate: endDate)
if let outBlock = result.outBlock {
print("Total block: \(outBlock.count) productNo: \(productNo)")
var monthBlock = [String: [DomesticExtra.Shorts]]()
for block in outBlock {
let yyyyMM = String(block.stockBusinessDate.prefix(6))
if let _ = monthBlock[yyyyMM] {
monthBlock[yyyyMM]!.append(block)
}
else {
monthBlock[yyyyMM] = [block]
}
}
for (month, blocks) in monthBlock {
let descBlock = blocks.sorted(by: { $0.stockBusinessDate > $1.stockBusinessDate })
guard descBlock.count > 0 else {
continue
}
let fileUrl = KissConsole.shortsFileUrl(productNo: productNo, day: month+"01")
try descBlock.mergeCsv(toFile: fileUrl, merging: { this, file in
var merged = this
for old in file {
if nil == this.first(where: { $0.stockBusinessDate == old.stockBusinessDate }) {
merged.append(old)
}
}
merged.sort(by: { $0.stockBusinessDate > $1.stockBusinessDate })
return merged
}, localized: localized)
}
}
try await Task.sleep(nanoseconds: 1_000_000_000 / PreferredShortsTPS)
return true
}
}