iOS股票K线和指标绘制总结

作者: ParadiseKiss | 来源:发表于2018-01-26 16:00 被阅读1265次

    如果接触到股票、期货或者现货方面的项目的话,那么K线和指标是必须要有的,K线表示商品价格的走势,指标则是反映价格运行趋势的重要标识。常见的K线图1分钟K线3分钟K线5分钟K线15分钟K线30分钟K线60分钟K线日K周K月K季K年K。指标也有很多种,比如VOLMACDBOLLKDJRSI三线出击庄家潜伏短线操盘中线操盘王牌狙击等上百种指标。

    由于项目的需要,笔者在今年6月份重构了K线库,后面又做了一次性能优化,目前框架比较稳定,公司项目在用。

    分时图

    分时图.png

    K线和指标

    MA-VOL.png 短线-VOL.png MA-MACD.png MA-KDJ.png MA-三线出击.png

    K线和指标绘制用到的类

    CAShapeLayer + UIBezierPath
    

    优点:

    • 渲染速度快,CAShapeLayer使用了硬件加速,绘制图像比用Core Graphics快。
    • 高效使用内存。
    • 效率高,滑动流畅,无明显卡顿,FPS50以上。

    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线数据量非常大,全部绘制出来不太现实。
    • 指标一定要根据形状来绘制。

    其他

    经测试,当前框架的FPS50以上,滑动比较流畅。

    FPS测试

    相关文章

      网友评论

        本文标题:iOS股票K线和指标绘制总结

        本文链接:https://www.haomeiwen.com/subject/bapugxtx.html