- 支持MA、EMA、BOLL、KDJ、MACD、RSI、WR等技术指标,支持更多指标扩展
- 支持运行于iOS、MacOS上
- OC开发,如需Swift可直接翻译
普通K线+MACD | 分时图+MACD |
---|---|
普通K线+KDJ | 分时图 |
更多指标 | 综合演示 |
- 下载Demo项目,将Y_Kline文件夹拖入需要的工程中
- 参考Demo,将YYKlineView添加到需要展示的view即可,其他部分(如指标)可参考Demo中Y_StockChartView进行配置。
- 实现YYPainterProtocol,可参考Painter文件夹下的其他已有指标。
@protocol YYPainterProtocol <NSObject>
// 绘制
+ (void)drawToLayer:(CALayer *)layer area:(CGRect)area models:(NSArray <YYKlineModel *> *)models minMax: (YYMinMaxModel *)minMaxModel;
// 获取边界值
+ (YYMinMaxModel *)getMinMaxValue:(NSArray <YYKlineModel *> *)data;
@end
- 以绘制KDJ图为例,新建YYKDJPainter,实现YYPainterProtocol
+ (YYMinMaxModel *)getMinMaxValue:(NSArray <YYKlineModel *> *)data {
if(!data) {
return [YYMinMaxModel new];
}
__block CGFloat minAssert = 999999999999.f;
__block CGFloat maxAssert = 0.f;
[data enumerateObjectsUsingBlock:^(YYKlineModel * _Nonnull m, NSUInteger idx, BOOL * _Nonnull stop) {
maxAssert = MAX(maxAssert, MAX(m.KDJ.J.floatValue, MAX(m.KDJ.K.floatValue, m.KDJ.D.floatValue)));
minAssert = MIN(minAssert, MIN(m.KDJ.J.floatValue, MIN(m.KDJ.K.floatValue, m.KDJ.D.floatValue)));
}];
return [YYMinMaxModel modelWithMin:minAssert max:maxAssert];
}
+ (void)drawToLayer:(CALayer *)layer area:(CGRect)area models:(NSArray <YYKlineModel *> *)models minMax: (YYMinMaxModel *)minMaxModel {
if(!models) {
return;
}
CGFloat maxH = CGRectGetHeight(area);
CGFloat unitValue = maxH/minMaxModel.distance;
YYKDJPainter *sublayer = [[YYKDJPainter alloc] init];
sublayer.frame = area;
UIBezierPath *path1 = [UIBezierPath bezierPath];
UIBezierPath *path2 = [UIBezierPath bezierPath];
UIBezierPath *path3 = [UIBezierPath bezierPath];
[models enumerateObjectsUsingBlock:^(YYKlineModel * _Nonnull m, NSUInteger idx, BOOL * _Nonnull stop) {
CGFloat w = [Y_StockChartGlobalVariable kLineWidth];
CGFloat x = idx * (w + [Y_StockChartGlobalVariable kLineGap]);
CGPoint point1 = CGPointMake(x+w/2, maxH - (m.KDJ.K.floatValue - minMaxModel.min)*unitValue);
CGPoint point2 = CGPointMake(x+w/2, maxH - (m.KDJ.D.floatValue - minMaxModel.min)*unitValue);
CGPoint point3 = CGPointMake(x+w/2, maxH - (m.KDJ.J.floatValue - minMaxModel.min)*unitValue);
if (idx == 0) {
[path1 moveToPoint:point1];
[path2 moveToPoint:point2];
[path3 moveToPoint:point3];
} else {
[path1 addLineToPoint:point1];
[path2 addLineToPoint:point2];
[path3 addLineToPoint:point3];
}
}];
{
CAShapeLayer *l = [CAShapeLayer layer];
l.path = path1.CGPath;
l.lineWidth = Y_StockChartLineWidth;
l.strokeColor = UIColor.line1Color.CGColor;
l.fillColor = [UIColor clearColor].CGColor;
[sublayer addSublayer:l];
}
{
CAShapeLayer *l = [CAShapeLayer layer];
l.path = path2.CGPath;
l.lineWidth = Y_StockChartLineWidth;
l.strokeColor = UIColor.line2Color.CGColor;
l.fillColor = [UIColor clearColor].CGColor;
[sublayer addSublayer:l];
}
{
CAShapeLayer *l = [CAShapeLayer layer];
l.path = path3.CGPath;
l.lineWidth = Y_StockChartLineWidth;
l.strokeColor = UIColor.line3Color.CGColor;
l.fillColor = [UIColor clearColor].CGColor;
[sublayer addSublayer:l];
}
[layer addSublayer:sublayer];
}
- 实现对应的Model,参考YYIndicatorModel,计算指标数据
- 在Y_StockChartView.m中加上该Painter对应的case
- (void)y_StockChartSegmentView:(Y_StockChartSegmentView *)segmentView clickSegmentButtonIndex:(NSInteger)index {
...
case YYKlineIncicatorKDJ:
self.kLineView.indicator2Painter = YYKDJPainter.class;
break;
...
}
- 运行查看效果
感谢@牛眼行情的K线数据源。