Android原生股票图-中各指标(MA ,BOLL ,RSI,KDJ ,MACD)的计算公式

Android原生股票图-分时图讲解(一)
Android原生股票图-分时图讲解(二)
Android原生股票图-K线图讲解和绘制(一)

包含(MA ,BOLL ,RSI,KDJ ,MACD)指标。

     public class DataHelper {

        /**
         * 计算RSI
         *
         * @param datas
         */
        static void calculateRSI(List<KLineEntity> datas) {
            float rsi1 = 0;
            float rsi2 = 0;
            float rsi3 = 0;
            float rsi1ABSEma = 0;
            float rsi2ABSEma = 0;
            float rsi3ABSEma = 0;
            float rsi1MaxEma = 0;
            float rsi2MaxEma = 0;
            float rsi3MaxEma = 0;
            for (int i = 0; i < datas.size(); i++) {
                KLineEntity point = datas.get(i);
                final float closePrice = point.getClosePrice();
                if (i == 0) {
                    rsi1 = 0;
                    rsi2 = 0;
                    rsi3 = 0;
                    rsi1ABSEma = 0;
                    rsi2ABSEma = 0;
                    rsi3ABSEma = 0;
                    rsi1MaxEma = 0;
                    rsi2MaxEma = 0;
                    rsi3MaxEma = 0;
                } else {
                    float Rmax = Math.max(0, closePrice - datas.get(i - 1).getClosePrice()); //收盘价
                    float RAbs = Math.abs(closePrice - datas.get(i - 1).getClosePrice()); //收盘价
                    rsi1MaxEma = (Rmax + (6f - 1) * rsi1MaxEma) / 6f;
                    rsi1ABSEma = (RAbs + (6f - 1) * rsi1ABSEma) / 6f;

                    rsi2MaxEma = (Rmax + (12f - 1) * rsi2MaxEma) / 12f;
                    rsi2ABSEma = (RAbs + (12f - 1) * rsi2ABSEma) / 12f;

                    rsi3MaxEma = (Rmax + (24f - 1) * rsi3MaxEma) / 24f;
                    rsi3ABSEma = (RAbs + (24f - 1) * rsi3ABSEma) / 24f;

                    rsi1 = (rsi1MaxEma / rsi1ABSEma) * 100;
                    rsi2 = (rsi2MaxEma / rsi2ABSEma) * 100;
                    rsi3 = (rsi3MaxEma / rsi3ABSEma) * 100;
                }
                point.rsi1 = rsi1;
                point.rsi2 = rsi2;
                point.rsi3 = rsi3;
            }
        }

        /**
         * 计算kdj
         *
         * @param datas
         */
        static void calculateKDJ(List<KLineEntity> datas) {
            float k = 0;
            float d = 0;

            for (int i = 0; i < datas.size(); i++) {
                KLineEntity point = datas.get(i);
                final float closePrice = point.getClosePrice(); //收盘价
                int startIndex = i - 8;
                if (startIndex < 0) {
                    startIndex = 0;
                }
                float max9 = Float.MIN_VALUE;
                float min9 = Float.MAX_VALUE;
                for (int index = startIndex; index <= i; index++) {
                    max9 = Math.max(max9, datas.get(index).getHighPrice());//最高价
                    min9 = Math.min(min9, datas.get(index).getLowPrice());//最低价

                }
                float rsv = 100f * (closePrice - min9) / (max9 - min9);
                if (i == 0) {
                    k = rsv;
                    d = rsv;
                } else {
                    k = (rsv + 2f * k) / 3f;
                    d = (k + 2f * d) / 3f;
                }
                point.k = k;
                point.d = d;
                point.j = 3f * k - 2 * d;
            }

        }

        /**
         * 计算macd
         *
         * @param datas
         */
        static void calculateMACD(List<KLineEntity> datas) {
            float ema12 = 0;
            float ema26 = 0;
            float dif = 0;
            float dea = 0;
            float macd = 0;

            for (int i = 0; i < datas.size(); i++) {
                KLineEntity point = datas.get(i);
                final float closePrice = point.getClosePrice(); //收盘价
                if (i == 0) {
                    ema12 = closePrice;
                    ema26 = closePrice;
                } else {
    //                EMA(12) = 前一日EMA(12) X 11/13 + 今日收盘价 X 2/13
    //                EMA(26) = 前一日EMA(26) X 25/27 + 今日收盘价 X 2/27
                    ema12 = ema12 * 11f / 13f + closePrice * 2f / 13f;
                    ema26 = ema26 * 25f / 27f + closePrice * 2f / 27f;
                }
    //            DIF = EMA(12) - EMA(26) 。
    //            今日DEA = (前一日DEA X 8/10 + 今日DIF X 2/10)
    //            用(DIF-DEA)*2即为MACD柱状图。
                dif = ema12 - ema26;
                dea = dea * 8f / 10f + dif * 2f / 10f;
                macd = (dif - dea) * 2f;
                point.dif = dif;
                point.dea = dea;
                point.macd = macd;
            }

        }

        /**
         * 计算 BOLL 需要在计算ma之后进行
         *
         * @param datas
         */
        static void calculateBOLL(List<KLineEntity> datas) {
            for (int i = 0; i < datas.size(); i++) {
                KLineEntity point = datas.get(i);
                final float closePrice = point.getClosePrice(); //收盘价
                if (i == 0) {
                    point.mb = closePrice;
                    point.up = Float.NaN;
                    point.dn = Float.NaN;
                } else {
                    int n = 20;
                    if (i < 20) {
                        n = i + 1;
                    }
                    float md = 0;
                    for (int j = i - n + 1; j <= i; j++) {
                        float c = datas.get(j).getClosePrice(); //收盘价
                        float m = point.getMA20Price(); //二十(月,日,时,分,5分等)均价
                        float value = c - m;
                        md += value * value;
                    }
                    md = md / (n - 1);
                    md = (float) Math.sqrt(md);
                    point.mb = point.getMA20Price();
                    point.up = point.mb + 2f * md;
                    point.dn = point.mb - 2f * md;
                }
            }

        }

        /**
         * 计算ma
         *
         * @param datas
         */
        static void calculateMA(List<KLineEntity> datas) {
            float ma5 = 0;
            float ma10 = 0;
            float ma20 = 0;
            float ma40 = 0;
            float ma60 = 0;
            for (int i = 0; i < datas.size(); i++) {
                KLineEntity point = datas.get(i);
                final float closePrice = point.getClosePrice(); //收盘价

                ma5 += closePrice;
                ma10 += closePrice;
                ma20 += closePrice;
                ma40 += closePrice;
                ma60 += closePrice;
                if (i >= 5) {
                    ma5 -= datas.get(i - 5).getClosePrice();
                    point.MA5Price = ma5 / 5f;
                } else {
                    point.MA5Price = ma5 / (i + 1f);
                }
                if (i >= 10) {
                    ma10 -= datas.get(i - 10).getClosePrice();
                    point.MA10Price = ma10 / 10f;
                } else {
                    point.MA10Price = ma10 / (i + 1f);
                }
                if (i >= 20) {
                    ma20 -= datas.get(i - 20).getClosePrice();
                    point.MA20Price = ma20 / 20f;
                } else {
                    point.MA20Price = ma20 / (i + 1f);
                }
                if (i >= 40) {
                    ma40 -= datas.get(i - 40).getClosePrice();
                    point.MA40Price = ma40 / 40f;
                } else {
                point.MA40Price = ma40 / (i + 1f);
                }
                if (i >= 60) {
                    ma60 -= datas.get(i - 60).getClosePrice();
                    point.MA60Price = ma60 / 60f;
                } else {
                    point.MA60Price = ma60 / (i + 1f);
                }
            }
        }

        /**
         * 计算MA BOLL RSI KDJ MACD
         *
         * @param datas
         */
        static void calculate(List<KLineEntity> datas) {
            calculateMA(datas);
            calculateMACD(datas);
            calculateBOLL(datas);
            calculateRSI(datas);
            calculateKDJ(datas);
            calculateVolumeMA(datas);
        }

        //成交量MA 平滑线
        private static void calculateVolumeMA(List<KLineEntity> entries) {
            float volumeMa5 = 0;
            float volumeMa10 = 0;

            for (int i = 0; i < entries.size(); i++) {
                KLineEntity entry = entries.get(i);

                volumeMa5 += entry.getVolume(); //成交量
                volumeMa10 += entry.getVolume();

                  if (i >= 5) {

                  volumeMa5 -= entries.get(i - 5).getVolume();
                    entry.MA5Volume = (volumeMa5 / 5f);
                } else {

                    entry.MA5Volume = (volumeMa5 / (i + 1f));
                }

                if (i >= 10) {
                    volumeMa10 -= entries.get(i - 10).getVolume();
                    entry.MA10Volume = (volumeMa10 / 5f);
                } else {
                    entry.MA10Volume = (volumeMa10 / (i + 1f));
                }
            }
        }
    }

参数和接口

  • *k线实体接口
    public interface IKLine extends ICandle, IMACD, IKDJ, IRSI,IVolume,IBOLL {
    }  
  • 布林线指标接口
    public interface IBOLL {

        /**
         * 上轨线
         */
        float getUp();

        /**
         * 中轨线
         */
        float getMb();

        /**
         * 下轨线
         */
        float getDn();
    }
  • 成交量接口
    public interface IVolume {

        /**
         * 开盘价
         */
        float getOpenPrice();

        /**
         * 收盘价
         */
        float getClosePrice();

        /**
         * 成交量
         */
        float getVolume();


        /**
         * 持仓量
         */
        float getInterest();

        /**
         * 五(月,日,时,分,5分等)均量
         */
        float getMA5Volume();

        /**
         * 十(月,日,时,分,5分等)均量
         */
        float getMA10Volume();
    }
  • RSI指标接口
    public interface IRSI {

        /**
         * RSI1值
         */
        float getRsi1();
        /**
         * RSI2值
         */
        float getRsi2();
        /**
         * RSI3值
         */
        float getRsi3();
    }
  • KDJ指标(随机指标)接口
    public interface IKDJ {

        /**
         * K值
         */
        float getK();

        /**
         * D值
         */
        float getD();

        /**
         * J值
         */
        float getJ();

    }
  • MACD指标(指数平滑移动平均线)接口
    public interface IMACD {


        /**
         * DEA值
         */
        float getDea();

        /**
         * DIF值
         */
        float getDif();

        /**
         * MACD值
         */
        float getMacd();

    }
  • 蜡烛图实体接口
    public interface ICandle {

        /**
         * 开盘价
         */
        float getOpenPrice();

        /**
         * 最高价
         */
        float getHighPrice();

        /**
         * 最低价
         */
        float getLowPrice();

        /**
         * 收盘价
         */
        float getClosePrice();


        /**
         * 五(月,日,时,分,5分等)均价
         */
        float getMA5Price();

        /**
         * 十(月,日,时,分,5分等)均价
         */
        float getMA10Price();

        /**
         * 二十(月,日,时,分,5分等)均价
         */
        float getMA20Price();
    }
  • KLineEntity
    public class KLineEntity implements IKLine {

        public String getDatetime() {
            return Date;
        }

        @Override
        public float getOpenPrice() {
            return Open;
        }

        @Override
        public float getHighPrice() {
            return High;
        }
        @Override
        public float getLowPrice() {
            return Low;
        }

        @Override
        public float getClosePrice() {
            return Close;
        }

        @Override
        public float getMA5Price() {
            return MA5Price;
        }
        @Override
        public float getMA10Price() {
            return MA10Price;
        }
        @Override
        public float getMA20Price() {
            return MA20Price;
          }

        @Override
        public float getDea() {
            return dea;
        }

        @Override
        public float getDif() {
            return dif;
        }

        @Override
        public float getMacd() {
            return macd;
        }

        @Override
        public float getK() {
            return k;
        }

        @Override
        public float getD() {
            return d;
        }

        @Override
        public float getJ() {
            return j;
        }

        @Override
        public float getRsi1() {
            return rsi1;
        }

        @Override
        public float getRsi2() {
            return rsi2;
        }

        @Override
        public float getRsi3() {
            return rsi3;
        }

        @Override
        public float getUp() {
            return up;
        }

        @Override
        public float getMb() {
            return mb;
        }

        @Override
        public float getDn() {
            return dn;
        }

        @Override
        public float getVolume() {
            return Volume;
        }


        @Override
        public float getMA5Volume() {
            return MA5Volume;
        }
        @Override
        public float getMA10Volume() {
            return MA10Volume;
        }

        public String Date;
        public float Open; //开盘价
        public float Close; //收盘价
        public float High; //最高价
        public float Low; //最低价
        public float Volume; //成交量

        //ma
        public float MA5Price;
        public float MA10Price;
        public float MA20Price;

        //MACD
        public float dea; //DEA值
        public float dif; //DIF值
        public float macd; //MACD值

        //KDJ
        public float k;
        public float d;
        public float j;

        //RSI
        public float rsi1; //RSI1值
        public float rsi2; //RSI2值
        public float rsi3; //RSI3值

        //BOLL
        public float up; //上轨线
        public float mb; //中轨线
        public float dn; //下轨线

        public float MA5Volume;
        public float MA10Volume;
    }

源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,968评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,601评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,220评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,416评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,425评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,144评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,432评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,088评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,586评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,028评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,137评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,783评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,343评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,333评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,559评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,595评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,901评论 2 345

推荐阅读更多精彩内容