纯Swift4.0代码编写的K线图表组件,支持:MA,EMA,KDJ,MACD,RSI等技术指标显示。集成使用简单,二次开发扩展强大。
- 完美支持Swift4.0编译。
- 线图丰富,蜡烛图,时分图,柱状图,提供画线扩展模型。
- 目前支持MA,EMA,BOLL,SAR,KDJ,MACD,RSI等技术指标,提供指标算法扩展模型。
- 支持使用代码创建视图或使用xib/storyboard创建视图。
- 样式提供更多配置,满足更多商业定制。
- 底层采用CALayer+UIBezierPath绘制图表,大大提高性能。
- iOS 8+
- Xcode 8+
- Swift 4.0+
- iPhone/iPad
CocoaPods is a dependency manager for Cocoa projects.
You can install it with the following command:
$ gem install cocoapods
To integrate Log into your Xcode project using CocoaPods, specify it in your Podfile:
use_frameworks!
pod 'CHKLineChartKit'
打开文件夹/CHKLineChart/Carthage/Build/iOS/,复制CHKLineChartKit.framework到你的项目文件夹中。在Project -> Target -> General -> Embedded Binaries,点+,导入CHKLineChartKit.framework。
详细例子,打开Example/Example.xcworkspace,参考ChartCustomViewController的例子。
应用代码片段:
import CHKLineChartKit
class ChartCustomViewController: UIViewController {
/// 数据源
var klineDatas = [KlineChartData]()
/// 图表
lazy var chartView: CHKLineChartView = {
let chartView = CHKLineChartView(frame: CGRect.zero)
chartView.style = .base //默认样式
chartView.delegate = self
return chartView
}()
override func viewDidLoad() {
self.view.addSubview(self.chartView)
}
override func viewDidLayoutSubviews() {
self.chartView.frame = self.view.bounds
}
}
// MARK: - 实现K线图表的委托方法
extension ChartCustomViewController: CHKLineChartDelegate {
/// 图表显示数据总数
func numberOfPointsInKLineChart(chart: CHKLineChartView) -> Int {
return self.klineDatas.count
}
/// 提供图表数据源
func kLineChart(chart: CHKLineChartView, valueForPointAtIndex index: Int) -> CHChartItem {
let data = self.klineDatas[index]
let item = CHChartItem()
item.time = data.time
item.openPrice = CGFloat(data.openPrice)
item.highPrice = CGFloat(data.highPrice)
item.lowPrice = CGFloat(data.lowPrice)
item.closePrice = CGFloat(data.closePrice)
item.vol = CGFloat(data.vol)
return item
}
/// 自定义Y轴坐标值显示内容
func kLineChart(chart: CHKLineChartView, labelOnYAxisForValue value: CGFloat, atIndex index: Int, section: CHSection) -> String {
var strValue = ""
if section.key == "volume" {
if value / 1000 > 1 {
strValue = (value / 1000).ch_toString(maxF: section.decimal) + "K"
} else {
strValue = value.ch_toString(maxF: section.decimal)
}
} else {
strValue = value.ch_toString(maxF: section.decimal)
}
return strValue
}
/// 自定义X轴坐标值显示内容
func kLineChart(chart: CHKLineChartView, labelOnXAxisForIndex index: Int) -> String {
let data = self.klineDatas[index]
let timestamp = data.time
let dayText = Date.ch_getTimeByStamp(timestamp, format: "MM-dd")
let timeText = Date.ch_getTimeByStamp(timestamp, format: "HH:mm")
var text = ""
//跨日,显示日期
if dayText != self.chartXAxisPrevDay && index > 0 {
text = dayText
} else {
text = timeText
}
self.chartXAxisPrevDay = dayText
return text
}
/// 调整每个分区的小数位保留数
///
/// - parameter chart:
/// - parameter section:
///
/// - returns:
func kLineChart(chart: CHKLineChartView, decimalAt section: Int) -> Int {
return 2
}
}
本K线图表最大的一个亮点就是提供了非常容易的指标开发入口。 如何开发自己的指标呢?步骤如下:
1. 开发者需要实现�CHChartAlgorithmProtocol。例子参考CHChartAlgorithm�枚举。
/**
常用技术指标算法
*/
public enum CHChartAlgorithm: CHChartAlgorithmProtocol {
case none //无算法
case timeline //时分
case ma(Int) //简单移动平均数
case ema(Int) //指数移动平均数
case kdj(Int, Int, Int) //随机指标
case macd(Int, Int, Int) //指数平滑异同平均线
case boll(Int, Int) //布林线
case sar(Int, CGFloat, CGFloat) //停损转向操作点指标(判定周期,加速因子初值,加速因子最大值)
case sam(Int) //SAM指标公式
/**
处理算法
- parameter datas:
- returns:
*/
public func handleAlgorithm(_ datas: [CHChartItem]) -> [CHChartItem] {
switch self {
case .none:
return datas
case .timeline:
return self.handleTimeline(datas: datas)
case let .ma(num):
return self.handleMA(num, datas: datas)
case let .ema(num):
return self.handleEMA(num, datas: datas)
case let .kdj(p1, p2, p3):
return self.handleKDJ(p1, p2: p2, p3: p3, datas: datas)
case let .macd(p1, p2, p3):
return self.handleMACD(p1, p2: p2, p3: p3, datas: datas)
case let .boll(num, k):
return self.handleBOLL(num, k: k, datas: datas)
case let .sar(num, minAF, maxAF):
return self.handleSAR(num,minAF: minAF, maxAF: maxAF, datas: datas)
case let .sam(num):
return self.handleSAM(num, datas: datas)
}
}
......
}
2. extension CHSeries,编写自己的线组。
// MARK: - 工厂方法
extension CHSeries {
/**
返回一个MACD系列样式
*/
public class func getMACD(_ difc: UIColor,
deac: UIColor,
barc: UIColor,
upStyle: (color: UIColor, isSolid: Bool),
downStyle: (color: UIColor, isSolid: Bool),
section: CHSection) -> CHSeries {
let series = CHSeries()
series.key = CHSeriesKey.macd
let dif = CHChartModel.getLine(difc, title: "DIF", key: "\(CHSeriesKey.macd)_DIF")
dif.section = section
let dea = CHChartModel.getLine(deac, title: "DEA", key: "\(CHSeriesKey.macd)_DEA")
dea.section = section
let bar = CHChartModel.getBar(upStyle: upStyle, downStyle: downStyle, titleColor: barc, title: "MACD", key: "\(CHSeriesKey.macd)_BAR")
bar.section = section
series.chartModels = [bar, dif, dea]
return series
}
}
3. 如果现有的线模型无法满足你,你可以新建类继承CHChartModel,重载drawSerie方法。
/**
* 圆点样式模型
*/
open class CHRoundModel: CHChartModel {
open override func drawSerie(_ startIndex: Int, endIndex: Int) -> CAShapeLayer {
......
}
}
// MARK: - 工厂方法
extension CHChartModel {
//生成一个圆点样式
class func getRound(upStyle: (color: UIColor, isSolid: Bool),
downStyle: (color: UIColor, isSolid: Bool),
titleColor: UIColor, title: String,
plotPaddingExt: CGFloat,
key: String) -> CHRoundModel {
let model = CHRoundModel(upStyle: upStyle, downStyle: downStyle,
titleColor: titleColor, plotPaddingExt: plotPaddingExt)
model.title = title
model.key = key
return model
}
}
4. 自定义自己的图表CHKLineChartStyle,把指标算法和线组加入。
let style = CHKLineChartStyle()
......
//配置图表处理算法
style.algorithms = [
CHChartAlgorithm.ema(12), //计算MACD,必须先计算到同周期的EMA
CHChartAlgorithm.ema(26), //计算MACD,必须先计算到同周期的EMA
CHChartAlgorithm.macd(12, 26, 9),
]
let trendSection = CHSection()
let macdSeries = CHSeries.getMACD(
UIColor.ch_hex(0xDDDDDD),
deac: UIColor.ch_hex(0xF9EE30),
barc: UIColor.ch_hex(0xF600FF),
upStyle: upcolor, downStyle: downcolor,
section: trendSection)
macdSeries.title = "MACD(12,26,9)"
macdSeries.symmetrical = true
trendSection.series = [macdSeries]
style.sections = [priceSection, volumeSection, trendSection]
let chartView = CHKLineChartView(frame: CGRect.zero)
chartView.style = style
......
5. 运行程序调试你的指标是否计算对了。
通用的方案是,扩展CHKLineChartStyle编写自己的样式。
// MARK: - 扩展样式
public extension CHKLineChartStyle {
//实现一个最基本的样式,开发者可以自由扩展配置样式
public static var best: CHKLineChartStyle {
let style = CHKLineChartStyle()
......
return style
}
self.chartView.style = .best
}
如果你对本K线指标的开发感兴趣,请fork项目,给大家Pull requests更多技术指标。
Released under MIT License.