先製作出簡單的一個 VC 上面顯示取得的三大法人資料的日期。
拉出兩個 Button、一個 state label、一個裝載 pie chart view 的 container view。
這邊需要了解三大法人成交金額的數據出來的時間,是在下午三點。而前面所做的每日市場成交資訊的公佈時間,並不一定和三大法人成交金額同時出來(詳細時間要測測看)。因為這樣的時間差,有可能在你滑進三大法人頁面時,取得的資料還在前一個交易日,但當下已經有現在交易日的台股總成交量金額。所以計算的時候,不可以拿最新的台股成交量當分母,一定要用拉取最新的三大法人資訊日期為 key,然後去查這個 key 的當日台股成交值是多少。
也因為有可能當下手機的時間和三大法人資料的日期不同,所以這個頁面最上方的 Label 是用來顯示資料的時間。
從 csv 檔來的資料有下面這六項
case dealersForProprietary //自營商自行買賣
case dealersHedge//自營商(避險)
case securitiesInvestorForTrust//投信
case foreignInvestorWithoutForeignDealer // 外資及陸資不含外資自營商
case foreignDealers //外資自營商
case total //總計
但是,我們要的是[自營商]、[投信]、[外資]、[總計] 這四項而已,所以數據要處理。
宣告一個專門用於這個 pie chart 的 data model
/// 只有三大法人,沒有細項
enum ThreeMajorInvestorType {
case dealers //自營商
case securitiesInvestorForTrust //投信
case foreign //外資
case total //總計
}
class ThreeMajorInvestorInfo {
let type : ThreeMajorInvestorType
var totalBuy: Double = 0
var totalSell: Double = 0
var difference: Double = 0
init(type: ThreeMajorInvestorType) {
self.type = type
}
func getItemName() -> String {
switch type {
case .foreign:
return "外資"
case .dealers:
return "自營"
case .securitiesInvestorForTrust:
return "投資"
case .total:
return "總合"
}
}
}
totalBuy, totalSell, difference 需要宣告成 var 的原因,是在合併的時候,我們要累加。
計算的 func 如下,在計算上,可以看到重複且類似的程式碼,這邊就讓讀都自行優化了
/// 取得三大法人 自營商的總和項目
private func getDealerInfo(detailMajorInfos: [MajorInvestor]) -> ThreeMajorInvestorInfo {
let info = ThreeMajorInvestorInfo(type: .dealers)
for each in detailMajorInfos {
// Dealer 自營商有兩項 1.自行買賣 2.避險
if each.typeString.contains("Dealer") {
info.totalBuy += each.totalBuy
info.totalSell += each.totalSell
info.difference += each.difference
}
}
return info
}
/// 取得三大法人 投信的總和項目
private func getSecuritiesTrustCompany(detailMajorInfos: [MajorInvestor]) -> ThreeMajorInvestorInfo {
let info = ThreeMajorInvestorInfo(type: .securitiesInvestorForTrust)
for each in detailMajorInfos {
// 投信
if each.typeString.contains("Securities") {
info.totalBuy += each.totalBuy
info.totalSell += each.totalSell
info.difference += each.difference
}
}
return info
}
/// 取得三大法人 外資的總和項目
private func getForeignInvestor(detailMajorInfos: [MajorInvestor]) -> ThreeMajorInvestorInfo {
let info = ThreeMajorInvestorInfo(type: .foreign)
for each in detailMajorInfos {
// 外資
if each.typeString.contains("Foreign") {
info.totalBuy += each.totalBuy
info.totalSell += each.totalSell
info.difference += each.difference
}
}
return info
}
/// 取得三大法人 total 的項目
private func getTotalInfo(detailMajorInfos: [MajorInvestor]) -> ThreeMajorInvestorInfo {
let info = ThreeMajorInvestorInfo(type: .total)
for each in detailMajorInfos {
if each.typeString.contains("Total") {
info.totalBuy = each.totalBuy
info.totalSell = each.totalSell
info.difference = each.difference
}
}
return info
}
/// 這邊有可優化空間
private func calculate(detailMajorInfos: [MajorInvestor]) -> TotalMajorInvestorInfo {
let dealer = getDealerInfo(detailMajorInfos: detailMajorInfos)
let securitiesTrustCompany = getSecuritiesTrustCompany(detailMajorInfos: detailMajorInfos)
let foreign = getForeignInvestor(detailMajorInfos: detailMajorInfos)
let total = getTotalInfo(detailMajorInfos: detailMajorInfos)
let threeMajor = TotalMajorInvestorInfo(dealers: dealer, securitiesInvestorForTrust: securitiesTrustCompany, foreign: foreign, total: total)
return threeMajor
}
接著在 VC 加上一個 property
private var totalMajorInvestorInfo: TotalMajorInvestorInfo?
左邊的按鈕在計算完,把值賦於 totalMajorInvestorInfo
// MARK: - IBAction
@IBAction func calculateButtonDidTap(_ sender: Any) {
let threeMajorInvestors = calculate(detailMajorInfos: self.majorInvestors)
self.totalMajorInvestorInfo = threeMajorInvestors
}
可以再順手做一下三大法人進出總金額的計算,並把結果放在 UI 上
private func updateCalculateUI() {
var text = "計算完畢 "
let unit = 100_000_000 //億
if let total = totalMajorInvestorInfo?.total {
let item = total.getItemName()
let buy = Int(total.totalBuy) / unit
let sell = Int(total.totalSell) / unit
let diff = Int(total.difference) / unit
text += " \(item): - 買進:\(buy) 億, 賣出:\(sell) 億, 買賣差:\(diff) 億,"
}
calculateLabel.text = text
}
那 button 發動的程式碼如下
// MARK: - IBAction
@IBAction func calculateButtonDidTap(_ sender: Any) {
let threeMajorInvestors = calculate(detailMajorInfos: self.majorInvestors)
self.totalMajorInvestorInfo = threeMajorInvestors
updateCalculateUI() // 和前面的 button 程式碼比起來,只差這一行
}