MPAndroidChart的K线图上添加均线-阿里云开发者社区

开发者社区> 啊啊啊88jdk> 正文

MPAndroidChart的K线图上添加均线

简介: MPAndroidChart的K线图上添加均线 效果图 均线计算方法: 通常说的5日均线,10日均线,其实就是根据当前K线节点的时间维度来说的,当前每个节点代表一天,那么上面...
+关注继续查看

MPAndroidChart的K线图上添加均线

  • 效果图
    这里写图片描述

均线计算方法:

通常说的5日均线,10日均线,其实就是根据当前K线节点的时间维度来说的,当前每个节点代表一天,那么上面的均线就叫做日均线(几日均线),下面就统一说成几节点均线

那么5节点均线,10节点均线等等,是怎么计算出来的呢

5节点均线为例,5节点均线是从第五根柱子开始画,一直画到最后一柱子(10节点均线就是从第10根柱子开始画,画到最后一根)

用第1、2、3、4、5个节点的收盘价之和,算出一个平均值,点在第5个节点上
用第2、3、4、5、6个节点的收盘价之和,算出一个平均值,点在低6个节点上
依此类推……

最后将画在5、6、7、8……上的点连起来,就是5节点均线。(如果当前一个节点代表一天,那这条线就是5日均线)


源码

MPAndroidChart地址:https://github.com/PhilJay/MPAndroidChart

在CandleStickChartRenderer.java下添加画均线的方法

思路:在draw K线柱子的时候获取每个柱子的收盘值,根据收盘值,计算均值

Demo Code

均线的实现,请移步到在MPAndroidChart库K线图的基础上画均线

下面实现的均线是第一版,见效果图,实现逻辑上略有问题,可直接忽略

@Override
public void drawData(Canvas c) {

    CandleData candleData = mChart.getCandleData();

    for (CandleDataSet set : candleData.getDataSets()) {

        if (set.isVisible() && set.getEntryCount() > 0)
            drawDataSet(c, set);
    }
}

protected void drawDataSet(Canvas c, CandleDataSet dataSet) {

    Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());

    float phaseX = mAnimator.getPhaseX();
    float phaseY = mAnimator.getPhaseY();

    int dataSetIndex = mChart.getCandleData().getIndexOfDataSet(dataSet);

    List<CandleEntry> entries = dataSet.getYVals();

    int minx = Math.max(mMinX, 0);
    int maxx = Math.min(mMaxX + 1, entries.size());

    int range = (maxx - minx) * 4;
    int to = (int) Math.ceil((maxx - minx) * phaseX + minx);

    CandleBodyBuffer bodyBuffer = mBodyBuffers[dataSetIndex];
    bodyBuffer.setBodySpace(dataSet.getBodySpace());
    bodyBuffer.setPhases(phaseX, phaseY);
    bodyBuffer.limitFrom(minx);
    bodyBuffer.limitTo(maxx);
    bodyBuffer.feed(entries);

    trans.pointValuesToPixel(bodyBuffer.buffer);

    CandleShadowBuffer shadowBuffer = mShadowBuffers[dataSetIndex];
    shadowBuffer.setPhases(phaseX, phaseY);
    shadowBuffer.limitFrom(minx);
    shadowBuffer.limitTo(maxx);
    shadowBuffer.feed(entries);

    trans.pointValuesToPixel(shadowBuffer.buffer);

    mRenderPaint.setStrokeWidth(dataSet.getShadowWidth());

    ArrayList<Float> closes = new ArrayList<Float>();
    ArrayList<Float> jx = new ArrayList<Float>();
    // draw the body
    for (int j = 0; j < range; j += 4) {

        // get the entry
        CandleEntry e = entries.get(j / 4 + minx);

        if (!fitsBounds(e.getXIndex(), mMinX, to))
            continue;

        if (dataSet.getShadowColorSameAsCandle()) {

            if (e.getOpen() > e.getClose())
                mRenderPaint.setColor(
                        dataSet.getDecreasingColor() == ColorTemplate.COLOR_NONE ?
                                dataSet.getColor(j) :
                                dataSet.getDecreasingColor()
                );

            else if (e.getOpen() < e.getClose())
                mRenderPaint.setColor(
                        dataSet.getIncreasingColor() == ColorTemplate.COLOR_NONE ?
                                dataSet.getColor(j) :
                                dataSet.getIncreasingColor()
                );

            else
                mRenderPaint.setColor(
                        dataSet.getShadowColor() == ColorTemplate.COLOR_NONE ?
                                dataSet.getColor(j) :
                                dataSet.getShadowColor()
                );

        } else {
            mRenderPaint.setColor(
                    dataSet.getShadowColor() == ColorTemplate.COLOR_NONE ?
                            dataSet.getColor(j) :
                            dataSet.getShadowColor()
            );
        }

        mRenderPaint.setStyle(Paint.Style.STROKE);

        // draw the shadow
        c.drawLine(shadowBuffer.buffer[j], shadowBuffer.buffer[j + 1],
                shadowBuffer.buffer[j + 2], shadowBuffer.buffer[j + 3],
                mRenderPaint);

        float leftBody = bodyBuffer.buffer[j];
        float open = bodyBuffer.buffer[j + 1];
        float rightBody = bodyBuffer.buffer[j + 2];
        float close = bodyBuffer.buffer[j + 3];
        closes.add(close);
        jx.add((leftBody + rightBody) / 2);

        // draw body differently for increasing and decreasing entry
        if (open > close) { // decreasing

            if (dataSet.getDecreasingColor() == ColorTemplate.COLOR_NONE) {
                mRenderPaint.setColor(dataSet.getColor(j / 4 + minx));
            } else {
                mRenderPaint.setColor(dataSet.getDecreasingColor());
            }

            mRenderPaint.setStyle(dataSet.getDecreasingPaintStyle());
            // draw the body
            c.drawRect(leftBody, close, rightBody, open, mRenderPaint);

        } else if (open < close) {

            if (dataSet.getIncreasingColor() == ColorTemplate.COLOR_NONE) {
                mRenderPaint.setColor(dataSet.getColor(j / 4 + minx));
            } else {
                mRenderPaint.setColor(dataSet.getIncreasingColor());
            }

            mRenderPaint.setStyle(dataSet.getIncreasingPaintStyle());
            // draw the body
            c.drawRect(leftBody, open, rightBody, close, mRenderPaint);
        } else { // equal values

            mRenderPaint.setColor(dataSet.getShadowColor());
            c.drawLine(leftBody, open, rightBody, close, mRenderPaint);
        }

        // 5节点均线
        drawLine(c, 5, closes, jx);
        // 10节点均线
        drawLine(c, 10, closes, jx);
        // 30节点均线
        drawLine(c, 30, closes, jx);
    }
}

/**
 * 画均线
 * @param c
 * @param i
 * @param closes
 * @param jx
 */
private void drawLine(Canvas c, int i, ArrayList<Float> closes, ArrayList<Float> jx) {
    Paint paint = new Paint();
    // 画线宽度
    paint.setStrokeWidth(1);
    // 画线颜色
    if (5 == i) {
        paint.setColor(Color.BLUE);
    } else if (10 == i) {
        paint.setColor(Color.RED);
    } else if (30 == i) {
        paint.setColor(Color.BLACK);
    } else {
        paint.setColor(Color.GREEN);
    }

    if (closes.size() >= i + 1) {
        float startX = jx.get(closes.size() - 2);
        float startY = 0;
        for (int x = 0; x < i; x++) {
            startY += closes.get(closes.size() - 2 - x);
        }
        startY = startY / i;
        float endX = jx.get(closes.size() - 1);
        float endY = 0;
        for (int y = 0; y < i; y++) {
            endY += closes.get(closes.size() - 1 - y);
        }
        endY = endY / i;
        c.drawLine(startX, startY, endX, endY, paint);
    }
}

图形联动

博客MPAndroidChart图形联动

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
9497 0
SpannableString 给TextView添加不同的显示样式
TextView是用来显示文本的,有时需要给TextView中的个别字设置为超链接,或者设置个别字的颜色、字体等,那就需要用到Spannable对象,可以借助Spannable对象实现以上设置myTextView = (TextView) this.findViewById(R.id.myTextView);  //创建一个 SpannableString对象     SpannableS
779 0
如何查看自己的appid是已上线,开发中,接口功能是否添加
第一步:查看appid应用是否已上线     1.登陆开发者管理中心:[url]https://openhome.alipay.com/platform/appManage.htm[/url],查看每一个应用的状态    第二步:查看自己需要的功能是否已经添加:   1.
362 0
使用FastDFS在CentOS 7.6.1810中进行域名访问和添加HTTPS安全协议
FastDFS分布式文件存储配置域名和HTTPS协议
70 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13186 0
RecyclerView添加头部和底部视图的实现
ListView是有addHeaderView和 addFooterView两个方法的. 但是作为官方推荐的ListView的升级版RecyclerView缺无法实现这两个方法。 那么如果使用RecyclerView实现这两个方法的效果该怎么做呢? 网上查询了很久,试过各种各样的实现方式,终于让我发现一个还不错的实现方法,那么就给大家推荐一下。
616 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
11508 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
6895 0
206
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载