iOS股票K线和指标绘制总结
2018-01-26 本文已影响1265人
ParadiseKiss
如果接触到股票、期货或者现货方面的项目的话,那么K线和指标是必须要有的,K线
表示商品价格的走势,指标则是反映价格运行趋势的重要标识。常见的K线图
有1分钟K线
,3分钟K线
,5分钟K线
,15分钟K线
,30分钟K线
,60分钟K线
,日K
,周K
,月K
,季K
,年K
。指标也有很多种,比如VOL
,MACD
,BOLL
,KDJ
,RSI
,三线出击
,庄家潜伏
,短线操盘
,中线操盘
,王牌狙击
等上百种指标。
由于项目的需要,笔者在今年6月份重构了K线库
,后面又做了一次性能优化,目前框架比较稳定,公司项目在用。
分时图

K线和指标





K线和指标绘制用到的类
CAShapeLayer + UIBezierPath
优点:
- 渲染速度快,
CAShapeLayer
使用了硬件加速,绘制图像比用Core Graphics
快。 - 高效使用内存。
- 效率高,滑动流畅,无明显卡顿,
FPS
在50
以上。
K线类的设计
#pragma mark - K线
/// K线数据源
@property (nonatomic, strong) NSArray<KLKlineData *> *klineDataArray;
/// 可视区域显示多少根k线
@property (nonatomic, assign) NSInteger displayCount;
/// k线图主体宽度
@property (nonatomic, assign, readonly) CGFloat klineWidth;
/// k线之间的空隙
@property (nonatomic, assign, readonly) CGFloat klineSpaceWidth;
/// 是否支持缩放
@property (nonatomic, assign, getter=isZoomEnable) BOOL zoomEnable;
/// 是否支持长按
@property (nonatomic, assign, getter=isLongPressEnable) BOOL longPressEnable;
#pragma mark - 指标
/// 主图指标
@property (nonatomic, strong) KLIndexTechnicalResult *mainTechnicalResult;
/// 附图指标
@property (nonatomic, strong) KLIndexTechnicalResult *subTechnicalResult;
#pragma mark -
/// 绘制k线
- (void)drawKlineView;
指标形状
为了对指标绘制进行封装,把所有的指标按照形状进行归类。以前需求中只有几种指标,可以对每种指标进行单独绘制,也就是每添加一种指标就需要重新创建一个类。但是后续需求添加了几十种指标,所以单独绘制的做法已经行不通了。目前比较好的做法就是根据形状进行绘制,从上百种指标来看,类型也就10多种
。
//指标形状
typedef NS_ENUM(NSInteger, KLKlineTechnicalShapeType)
{
KLKlineTechnicalShapeTypeCurveLine, /* 线 */
KLKlineTechnicalShapeTypeFillVol, /* 成交量(实心柱子) */
KLKlineTechnicalShapeTypeStrokeVol, /* 成交量(空心柱子) */
KLKlineTechnicalShapeTypeFillCandle, /* 实心柱状 */
KLKlineTechnicalShapeTypeStrokeCandle, /* 空心柱状 */
KLKlineTechnicalShapeTypeCircle, /* 圆形 */
KLKlineTechnicalShapeTypeImage, /*图片*/
KLKlineTechnicalShapeTypeTitle, /*文字*/
KLKlineTechnicalShapeTypeTitleImage /*图片文字组合*/
//......其它形状
};
指标类型
定义具体的指标类型,方便指标切换。
/***************** 指标 ********************/
typedef NS_ENUM(NSInteger, KLKlineIndexType)
{
KLKlineIndexVolume, /* 成交量 */
KLKlineIndexTypeMacd, /* MACD */
KLKlineIndexTypeKDJ, /* KDJ */
KLKlineIndexTypeRSI, /* RSI */
KLKlineIndexTypeThreeLineAttack, /* 三线出击 */
KLKlineIndexTypeBankerLurking, /* 庄家潜伏 */
KLKlineIndexTypeThreeLineAttack2, /* 三线出击2 */
KLKlineIndexTypeMA, /* MA */
KLKlineIndexTypeShortOperate, /* 短线操盘 */
KLKlineIndexTypeMidOperate, /* 中线操盘 */
KLKlineIndexTypeAceSniper /* 王牌阻击 */
//......其它指标
};
指标绘制
绘制交给一个单独的类来处理,根据不同的形状来绘制不同的指标。
/// 绘制指标
- (void)setupIndexShapeForTechnicalWithShapeLayer:(CAShapeLayer *)shapeLayer
drawStyleData:(KLIndexDrawStyleData *)drawStyleData
startIndex:(NSInteger)startIndex
xOffset:(CGFloat)xOffset
{
KLKlineTechnicalShapeType shapeType = drawStyleData.shapeType;
if (shapeType == KLKlineTechnicalShapeTypeCurveLine)
{
[self setupCurveLineShapeForTechnicalWithShapeLayer:shapeLayer drawStyleData:drawStyleData startIndex:startIndex xOffset:xOffset];
}
else if (shapeType == KLKlineTechnicalShapeTypeFillVol ||
shapeType == KLKlineTechnicalShapeTypeStrokeVol)
{
[self setupVolShapeForTechnicalWithShapeLayer:shapeLayer shapeType:shapeType drawStyleData:drawStyleData startIndex:startIndex xOffset:xOffset];
}
else if (shapeType == KLKlineTechnicalShapeTypeFillCandle ||
shapeType == KLKlineTechnicalShapeTypeStrokeCandle)
{
[self setupFillStrokeCandleShapeForTechnicalWithShapeLayer:shapeLayer shapeType:shapeType drawStyleData:drawStyleData startIndex:startIndex xOffset:xOffset];
}
else if (shapeType == KLKlineTechnicalShapeTypeImage ||
shapeType == KLKlineTechnicalShapeTypeTitle ||
shapeType == KLKlineTechnicalShapeTypeTitleImage)
{
[self setupTitleImageShapeForTechnicalWithShapeLayer:shapeLayer shapeType:shapeType drawStyleData:drawStyleData startIndex:startIndex xOffset:xOffset];
}
//其它形状
}
绘制注意点
- 为了提高性能,只需要绘制当前一屏即可。因为
K线
数据量非常大,全部绘制出来不太现实。 - 指标一定要根据形状来绘制。
其他
经测试,当前框架的FPS
在50
以上,滑动比较流畅。
