mirror of
https://github.com/VGEAREN/Stockbar.git
synced 2026-10-06 14:33:11 +08:00
feat(korea): add Market.krStock + KRW currency + chart x-axis
Adding Market.krStock cascades into several exhaustive switches that must all update together: ExchangeRates.convert, DisplayCurrency, StockChartView ranges and labels. Bundles tasks 2/3/4/5/14 into one build-passing landing. - Market enum: add krStock case + kr_ prefix routing in Market.from - ExchangeRates: add usdToKrw (fallback 1380), krwToCny derived, KRW path in convert - DisplayCurrency: add .krw (₩), display name 韩元 - CurrencyService.fetchRates: include fx_susdkrw in Sina FX batch URL - StockChartView: KR fullDayRange 0...389 (KST 09:00-15:30, 390 min); KR axis labels 09:00/10:30/12:00/13:30/15:30 Tests: +5 Stock cases for KR, +8 CurrencyKRWTests covering all KR↔CNY/USD/HKD/KRW conversion paths and fallback constant.
This commit is contained in:
@@ -4,12 +4,14 @@ enum DisplayCurrency: String, Codable, CaseIterable {
|
||||
case cny = "CNY"
|
||||
case hkd = "HKD"
|
||||
case usd = "USD"
|
||||
case krw = "KRW"
|
||||
|
||||
var symbol: String {
|
||||
switch self {
|
||||
case .cny: return "¥"
|
||||
case .hkd: return "HK$"
|
||||
case .usd: return "$"
|
||||
case .krw: return "₩"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +20,7 @@ enum DisplayCurrency: String, Codable, CaseIterable {
|
||||
case .cny: return "人民币 ¥"
|
||||
case .hkd: return "港币 HK$"
|
||||
case .usd: return "美元 $"
|
||||
case .krw: return "韩元 ₩"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,12 @@ enum Market: String, Codable, CaseIterable {
|
||||
case aStock = "A股"
|
||||
case hkStock = "港股"
|
||||
case usStock = "美股"
|
||||
case krStock = "韩股"
|
||||
|
||||
static func from(code: String) -> Market {
|
||||
if code.hasPrefix("hk") { return .hkStock }
|
||||
if code.hasPrefix("usr_") { return .usStock }
|
||||
if code.hasPrefix("kr_") { return .krStock }
|
||||
return .aStock
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import Foundation
|
||||
|
||||
struct ExchangeRates {
|
||||
var usdToCny: Double = 7.28 // 默认兜底值
|
||||
var usdToCny: Double = 7.28 // 默认兜底值
|
||||
var usdToHkd: Double = 7.78
|
||||
var usdToKrw: Double = 1380.0 // 默认兜底(2026 年初均值);CurrencyService 拉成功后覆盖
|
||||
|
||||
/// HKD/CNY = USD/CNY ÷ USD/HKD
|
||||
var hkdToCny: Double { usdToCny / usdToHkd }
|
||||
/// KRW/CNY = USD/CNY ÷ USD/KRW
|
||||
var krwToCny: Double { usdToCny / usdToKrw }
|
||||
|
||||
/// 将 amount(native 货币)转换为目标货币
|
||||
func convert(_ amount: Double, from market: Market, to currency: DisplayCurrency) -> Double {
|
||||
@@ -15,21 +18,23 @@ struct ExchangeRates {
|
||||
case .aStock: inCny = amount
|
||||
case .hkStock: inCny = amount * hkdToCny
|
||||
case .usStock: inCny = amount * usdToCny
|
||||
case .krStock: inCny = amount * krwToCny
|
||||
}
|
||||
// 再从 CNY 转出去
|
||||
switch currency {
|
||||
case .cny: return inCny
|
||||
case .hkd: return inCny / hkdToCny
|
||||
case .usd: return inCny / usdToCny
|
||||
case .krw: return inCny / krwToCny
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class CurrencyService {
|
||||
|
||||
/// 从新浪财经获取 USD/CNY、USD/HKD 汇率,失败时返回内置兜底值
|
||||
/// 从新浪财经获取 USD/CNY、USD/HKD、USD/KRW 汇率,失败时返回内置兜底值
|
||||
static func fetchRates() async -> ExchangeRates {
|
||||
let urlStr = "https://hq.sinajs.cn/list=fx_susdcny,fx_susdhkd"
|
||||
let urlStr = "https://hq.sinajs.cn/list=fx_susdcny,fx_susdhkd,fx_susdkrw"
|
||||
guard let url = URL(string: urlStr) else { return ExchangeRates() }
|
||||
var req = URLRequest(url: url)
|
||||
req.setValue("https://finance.sina.com.cn", forHTTPHeaderField: "Referer")
|
||||
@@ -41,6 +46,7 @@ final class CurrencyService {
|
||||
for line in body.components(separatedBy: "\n") {
|
||||
if let r = parseFirstPositiveDouble(from: line, code: "fx_susdcny") { rates.usdToCny = r }
|
||||
if let r = parseFirstPositiveDouble(from: line, code: "fx_susdhkd") { rates.usdToHkd = r }
|
||||
if let r = parseFirstPositiveDouble(from: line, code: "fx_susdkrw") { rates.usdToKrw = r }
|
||||
}
|
||||
return rates
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ struct StockChartView: View {
|
||||
case .aStock: return 0...239
|
||||
case .hkStock: return 0...329
|
||||
case .usStock: return 0...959
|
||||
case .krStock: return 0...389
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +36,9 @@ struct StockChartView: View {
|
||||
case .usStock:
|
||||
// 基准 04:00 ET;330=09:30;720=16:00;959=19:59
|
||||
return [(0, "04:00"), (330, "09:30"), (570, "13:30"), (720, "16:00"), (959, "20:00")]
|
||||
case .krStock:
|
||||
// 基准 09:00 KST;180=12:00;389=15:29
|
||||
return [(0, "09:00"), (90, "10:30"), (180, "12:00"), (270, "13:30"), (389, "15:30")]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user