iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0
Mobile Development

使用 Swift 和公開資訊,打造投資理財的 Apps系列 第 19

D18 - 用 Swift 和公開資訊,打造投資理財的 Apps { 移動平均線(MA線)實作.1 }

  • 分享至 

  • twitterImage
  •  

"The shortest distance between two points is a straight line." - Archimedes

要做出移動平均線,在 Charts 裡面最直觀拿來達成這個任務用的物件,就是 LineCartView。但這個物件只能吃 LineChartData 的資料。我們要做的是在圖上,同時呈現 K 線和均線,同時,也不排除新的隕石級需求砸下來的狀況。所以,我們要使用的類別就是 CombinedChartView。CombinedChartView 裡面的 Data 可以塞 candleData, lineData 未來有 barData 也是塞的進去。

step1 - 先宣告「點」這個概念的物件

import Foundation

/// MA 線的點
struct MovingAveragePoint {
    
    let x: Double
    let y: Double
}

step2 - 宣告專門處理移動平均線計算的物件

這個物件專門處理 SockKLine array → MovingAveragePoint Array

注意,裡面有個處理五個收盤價總合的地方。如果讀者會 dynamic programming 的手法,當總合往前算的時候,減去最後一根 k 棒的收盤價,再加上前一根 k 棒的收盤價。理論上來說,效能會比較好。

但我現在在趕稿和趕專案的狀態,所以這一段的優化就留給讀者進行了。

import Foundation

/// 專門處理移動平均線的物件
struct MovingAverageUtility {
    
    /// 將已得到的 K 棒,轉出 5 MA 的資料
    /// - Parameter stockTicks: 傳入的 K 棒需先保證 date 從遠排到近
    /// - Returns: 回傳的 MA 點也保證會是 x 從小排到大
    func get5MAPoints(from stockTicks: [StockKLine]) -> [MovingAveragePoint] {
        
        let maPeriod = 5 // 5MA
        
        let tickIndices = Array(stockTicks.indices).sorted { $0 > $1 } // 先拿出 index 並把 index 從大到小排
        
        var maPoints = [MovingAveragePoint]()
        
        for tickIndex in tickIndices {

            let startIndex = tickIndex - 5 + 1
            
            if !stockTicks.indices.contains(startIndex) || !stockTicks.indices.contains(tickIndex) {
                break
            }
            
            let needCalculateTicks = Array(stockTicks[startIndex...tickIndex])
            
            // 從這裡開始計算 n 日內收盤價的平均,有更有效率的做法,像是動態規畫的方式實作。這一段就留給讀者自行優化
            let closePriceList = needCalculateTicks.map { tick in
                
                return tick.close ?? 0 // 這邊先不考慮如果沒有收盤價(暫停交易)的情況,如果有,應該把這個點去除掉,使用 filter 即可
            }
            
            let sum = closePriceList.reduce(0, +) //總合
            let maValue = sum / Double(maPeriod)
            
            let point = MovingAveragePoint(x: Double(tickIndex), y: maValue)
            maPoints.append(point)
        }
        
        return maPoints.sorted { $0.x < $1.x }
    }
}

當做出 MA Point 物件,和專門處理 MA 計算的工具,剩下的就是在 CandleStickData 算完後,把 K 線資料丟進 MA 計算工具,就會得到 LineChartData 了。

台股申購日曆
IT鐵人賽Demo App

下方是這次 D1 ~ D12 的完成品,可以下載來試
App Store - 台股申購日曆

https://ithelp.ithome.com.tw/upload/images/20210924/20140622ypOBM0tgrZ.png


上一篇
D17- 用 Swift 和公開資訊,打造投資理財的 Apps { 移動平均線(MA線)分析 }
下一篇
D19 - 用 Swift 和公開資訊,打造投資理財的 Apps { 移動平均線(MA線)實作.2 }
系列文
使用 Swift 和公開資訊,打造投資理財的 Apps37
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言