- 支持MA、EMA、BOLL、KDJ、MACD、RSI、WR等技术指标,支持更多指标扩展
- 支持运行于iOS、MacOS上
- OC开发,如需Swift可直接翻译
| 普通K线+MACD | 分时图+MACD |
|---|---|
| 普通K线+MACD | 分时图+MACD |
| 普通K线+KDJ | 分时图 |
| 普通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线数据源。