Android绘制股票k线图系列4-指标计算


import java.util.List;
import java.util.Vector;

public class IndexCalculation {
    /**
     * 计算成交量包含ma5、ma10、ma20
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationVol(Vector<KLineData> data) {
        data = indexDayMovingAverage(data);
        double ma5s = 0;
        double ma10s = 0;
        double ma20s = 0;
        for (int i = 0; i < data.size(); i++) {
            double num = data.get(i).getCjl();
            double ma5 = 0;
            double ma10 = 0;
            double ma20 = 0;
            ma5s += data.get(i).getCjl();
            ma10s += data.get(i).getCjl();
            ma20s += data.get(i).getCjl();
            if (i >= 4) {
                ma5 = ma5s / 5;
                ma5s -= data.get(i - 4).getCjl();
                if (i >= 9) {
                    ma10 = ma10s / 10;
                    ma10s -= data.get(i - 9).getCjl();
                    if (i >= 19) {
                        ma20 = ma20s / 20;
                        ma20s -= data.get(i - 19).getCjl();
                    }
                }
            }
            Volume vol = new Volume(num, ma5, ma10, ma20);
            data.get(i).setVolume(vol);
        }
        return data;
    }

    /**
     * 计算MACD指标
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationMACD(Vector<KLineData> data) {
        // MACD:参数快线移动平均、慢线移动平均、移动平均,
        // 参数值12、26、9。
        // 公式:⒈首先分别计算出收盘价12日指数平滑移动平均线与26日指数平滑移动平均线,分别记为EMA(12)与EMA(26)。
        // ⒉求这两条指数平滑移动平均线的差,即:DIFF=EMA(SHORT)-EMA(LONG)。
        // ⒊再计算DIFF的M日的平均的指数平滑移动平均线,记为DEA。
        // ⒋最后用DIFF减DEA,得MACD。MACD通常绘制成围绕零轴线波动的柱形图。MACD柱状大于0红色,小于0绿色。
        data = indexDayMovingAverage(data);
        double ema12 = 0;
        double ema26 = 0;
        double oldEma12 = 0;
        double oldEma26 = 0;
        double diff = 0;
        double dea = 0;
        double oldDea = 0;
        double macd = 0;
        double sum = 0;
        double sumDif = 0;
        for (int i = 0; i < data.size(); i++) {
            sum += data.get(i).getClose();
            if (i == 11) {
                ema12 = sum / 12;
                oldEma12 = ema12;
            } else if (i > 11) {
                ema12 = (2 * data.get(i).getClose() + 11 * oldEma12) / 13;
                oldEma12 = ema12;
            }
            if (i == 25) {
                ema26 = sum / 26;
                oldEma26 = ema26;
            } else if (i > 25) {
                ema26 = (2 * data.get(i).getClose() + 25 * oldEma26) / 27;
                oldEma26 = ema26;
            }
            if (i >= 25) {
                diff = ema12 - ema26;
                sumDif += diff;
                if (i == 33) {
                    dea = sumDif / 9;
                    macd = (diff - dea) * 2;
                    oldDea = dea;
                } else if (i > 33) {
                    dea = (2 * diff + 8 * oldDea) / 10;
                    oldDea = dea;
                    macd = (diff - dea) * 2;
                }
            }

            MACD mMacd = new MACD(diff, dea, macd);
            data.get(i).setMacd(mMacd);
        }
        return data;
    }

    /**
     * 计算BOLL指标
     * 日BOLL指标的计算公式
     中轨线=N日的移动平均线
     上轨线=中轨线+两倍的标准差
     下轨线=中轨线-两倍的标准差
     日BOLL指标的计算过程

     1)计算MA,N取为26
     MA=N日内的收盘价之和÷N
     2)计算标准差MD
     两倍的标准差 = 平方根N日的(收盘价- MA)两次方之和除以N
     3)计算MB、上轨线、下轨线
     中轨线=(N-1)日的MA
     上轨线 = 中轨线+2×两倍的标准差
     下轨线 = 中轨线-2×两倍的标准差
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationBOLL(Vector<KLineData> data) {
        double closes26 = 0;// MA
        double MA = 0;// 中轨线
        double MD = 0;// 标准差
        double UP = 0;// 上轨线
        double DN = 0;// 下轨线
        for (int i = 0; i < data.size(); i++) {
            closes26 += data.get(i).getClose();
            if (i >= 25) {
                MA = closes26 / 26;
                List<KLineData> subList =  data.subList(i - 25, i + 1);
                MD = getBollMD(data.subList(i - 25, i + 1), MA);
                UP = MA + 2 * MD;
                DN = MA - 2 * MD;
                closes26 -= data.get(i - 25).getClose();
            }
            BOLL boll = new BOLL(UP, MA, DN);
            data.get(i).setBoll(boll);
        }
        return data;
    }

    /**
     * 计算KDJ
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationKDJ(Vector<KLineData> data) {
        data = indexDayMovingAverage(data);
        double K = 0;
        double D = 0;
        double J = 0;
        for (int i = 0; i < data.size(); i++) {
            if (i >= 8) {
                double Cn = data.get(i).getClose();
                double Ln = getLow(data.subList(i - 8, i + 1));
                double Hn = getHigh(data.subList(i - 8, i + 1));
                double RSV = (Cn - Ln) / (Hn - Ln == 0 ? 1 : Hn - Ln) * 100;
                Log.w("KDJ", "i= "+ i + " Ln=" + Ln + " Hn=" + Hn + " RSV=" + RSV);
                // 当日K值=2/3×前一日K值+1/3×当日RSV
                // 当日D值=2/3×前一日D值+1/3×当日K值
                // 若无前一日K 值与D值,则可分别用50来代替。
                // J值=3*当日K值-2*当日D值
                K = 2.0 / 3.0
                    * (i == 8 ? 50.0 : data.get(i - 1).getKdj().getK())
                    + 1.0 / 3.0 * RSV;
                D = 2.0 / 3.0
                    * (i == 8 ? 50.0 : data.get(i - 1).getKdj().getD())
                    + 1.0 / 3.0 * K;
                J = 3.0 * K - 2.0 * D;

               Log.w("KDJ", "K=" + K + " D=" + D + " J=" + J);

            }
            KDJ kdj = new KDJ(K, D, J);
            data.get(i).setKdj(kdj);

        }

        return data;
    }

    /**
     * 计算RSI
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationRSI(Vector<KLineData> data) {
        // N日RSI =
        // N日内收盘涨幅的平均值/(N日内收盘涨幅均值+N日内收盘跌幅均值) ×100%

        data = indexDayMovingAverage(data);
        double RSI1 = 0;// 参数6
        double RSI2 = 0;// 参数12
        double RSI3 = 0;// 参数24

        double sumCloseA = 0;
        double sumCloseB = 0;

        double a1 = 0;
        double b1 = 0;
        double oldA1 = 0;
        double oldB1 = 0;

        double a2 = 0;
        double b2 = 0;
        double oldA2 = 0;
        double oldB2 = 0;

        double a3 = 0;
        double b3 = 0;
        double oldA3 = 0;
        double oldB3 = 0;
        if(data != null && data.size() > 0){
        data.get(0).setRsi(new RSI(0, 0, 0));
        if (data.size() < 2)
            return data;
        for (int i = 1; i < data.size(); i++) {
            double tmp = data.get(i).getClose() - data.get(i - 1).getClose();
            if (tmp > 0) {
                sumCloseA += tmp;
            } else {
                sumCloseB += tmp;
            }
            double AA = tmp > 0 ? tmp : 0;
            double BB = Math.abs(tmp);

            if (i >= 6) {
                if (i == 6) {
                    a1 = sumCloseA / 6;
                    b1 = (Math.abs(sumCloseB) + sumCloseA) / 6;
                    oldA1 = a1;
                    oldB1 = b1;
                } else {
                    a1 = (AA + 5 * oldA1) / 6;
                    b1 = (BB + 5 * oldB1) / 6;
                    oldA1 = a1;
                    oldB1 = b1;
                }
                RSI1 = a1 / b1 * 100;
                if (i >= 12) {
                    if (i == 12) {
                        a2 = sumCloseA / 12;
                        b2 = (Math.abs(sumCloseB) + sumCloseA) / 12;
                        oldA2 = a2;
                        oldB2 = b2;
                    } else {
                        a2 = (AA + 11 * oldA2) / 12;
                        b2 = (BB + 11 * oldB2) / 12;
                        oldA2 = a2;
                        oldB2 = b2;
                    }
                    RSI2 = a2 / b2 * 100;
                    if (i >= 24) {
                        if (i == 24) {
                            a3 = sumCloseA / 24;
                            b3 = (Math.abs(sumCloseB) + sumCloseA) / 24;
                            oldA3 = a3;
                            oldB3 = b3;
                        } else {
                            a3 = (AA + 23 * oldA3) / 24;
                            b3 = (BB + 23 * oldB3) / 24;
                            oldA3 = a3;
                            oldB3 = b3;
                        }
                        RSI3 = a3 / b3 * 100;
                    }
                }
            }
            RSI rsi = new RSI(RSI1, RSI2, RSI3);
            data.get(i).setRsi(rsi);
        }
        }
        return data;
    }

    /**
     * 计算BIAS指标
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationBIAS(Vector<KLineData> data) {
        // 乖离率=[(当日收盘价-N日平均价)/N日平均价]*100%
        // 参数:6,12、24
        data = indexDayMovingAverage(data);
        double bias1 = 0;
        double bias2 = 0;
        double bias3 = 0;
        double closes1 = 0;
        double closes2 = 0;
        double closes3 = 0;
        for (int i = 0; i < data.size(); i++) {
            closes1 += data.get(i).getClose();
            closes2 += data.get(i).getClose();
            closes3 += data.get(i).getClose();
            if (i >= 5) {
                double mean6 = closes1 / 6;
                closes1 -= data.get(i - 5).getClose();
                bias1 = ((data.get(i).getClose() - mean6) / mean6) * 100;
                if (i >= 11) {
                    double mean12 = closes2 / 12;
                    closes2 -= data.get(i - 11).getClose();
                    bias2 = ((data.get(i).getClose() - mean12) / mean12) * 100;
                    if (i >= 23) {
                        double mean24 = closes3 / 24;
                        closes3 -= data.get(i - 23).getClose();
                        bias3 = ((data.get(i).getClose() - mean24) / mean24) * 100;
                    }
                }
            }
            BIAS bias = new BIAS(bias1, bias2, bias3);
            data.get(i).setBias(bias);
        }
        return data;
    }

    /**
     * 计算BRAR指标
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationBRAR(Vector<KLineData> data) {
        // 参数是26。
        // 公式N日BR=N日内(H-CY)之和除以N日内(CY-L)之和*100,
        // 其中,H为当日最高价,L为当日最低价,CY为前一交易日的收盘价,N为设定的时间参数。
        // N日AR=(N日内(H-O)之和除以N日内(O-L)之和)*100,
        // 其中,H为当日最高价,L为当日最低价,O为当日开盘价,N为设定的时间参数
        data = indexDayMovingAverage(data);
        double BR = 0;
        double AR = 0;
        double HCY = 0;
        double CYL = 0;
        double HO = 0;
        double OL = 0;
        for (int i = 0; i < data.size(); i++) {
            HO += (data.get(i).getHighPrice() - data.get(i).getOpen());
            OL += (data.get(i).getOpen() - data.get(i).getLowPrice());
            if (i > 0) {
                double CY = data.get(i - 1).getClose();
                HCY += (data.get(i).getHighPrice() - CY) > 0 ? (data.get(i)
                                                                        .getHighPrice() - CY) : 0;
                CYL += (CY - data.get(i).getLowPrice()) > 0 ? (CY - data.get(i)
                        .getLowPrice()) : 0;
                if (i >= 25) {
                    AR = HO / OL * 100;
                    HO -= data.get(i - 25).getHighPrice()
                          - data.get(i - 25).getOpen();
                    OL -= data.get(i - 25).getOpen()
                          - data.get(i - 25).getLowPrice();
                    if (i >= 26) {
                        BR = HCY / CYL * 100;
                        double CY1 = data.get(i - 26).getClose();
                        HCY -= (data.get(i - 25).getHighPrice() - CY1) > 0 ? (data
                                                                                      .get(i -
                                                                                           25).getHighPrice() -
                                                                              CY1) : 0;
                        CYL -= (CY1 - data.get(i - 25).getLowPrice()) > 0 ? (CY1 - data
                                .get(i - 25).getLowPrice()) : 0;
                    }
                }
            }
            BRAR brar = new BRAR(BR, AR);
            data.get(i).setBrar(brar);
        }
        return data;
    }

    /**
     * 计算CCI指标
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationCCI(Vector<KLineData> data) {
        // 中价与 中价的N日内移动平均 的差 除以 N日内中价的平均绝对偏差
        // 其中,中价等于最高价、最低价和收盘价之和除以3
        // ={【79-(79+62+45+90+25)/5)】
        // +【62-(79+62+45+90+25)/5)】
        // +【45-(79+62+45+90+25)/5)】
        // +【90-(79+62+45+90+25)/5)】
        // +【25-(79+62+45+90+25)/5)】}/5
        data = indexDayMovingAverage(data);
        double TYPEs = 0;
        double cci = 0;
        for (int i = 0; i < data.size(); i++) {
            double TYP = (data.get(i).getHighPrice()
                          + data.get(i).getLowPrice() + data.get(i).getClose()) / 3;
            TYPEs += TYP;
            if (i >= 13) {
                double TYPEsMean = TYPEs / 14;
                TYPEs -= (data.get(i - 13).getHighPrice()
                          + data.get(i - 13).getLowPrice() + data.get(i - 13)
                                  .getClose()) / 3;

                double types = 0;
                for (int j = i - 13; j < i + 1; j++) {
                    double typ = (data.get(j).getHighPrice()
                                  + data.get(j).getLowPrice() + data.get(j)
                                          .getClose()) / 3;
                    types += Math.abs(typ - TYPEsMean);
                }
                double MD = types / 14;
                if (MD == 0) {
                    cci = 0;
                } else {
                    cci = 200 * (TYP - TYPEsMean) / 3 / MD;
                }
            }
            CCI CCi = new CCI(cci);
            data.get(i).setCci(CCi);
        }
        return data;
    }

    /**
     * 计算DMI
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationDMI(Vector<KLineData> data) {
        // 参数 14,6
        // MTR:=EXPMEMA(MAX(MAX(HIGH-LOW,ABS(HIGH-REF(CLOSE,1))),ABS(REF(CLOSE,1)-LOW)),N)
        // HD :=HIGH-REF(HIGH,1);
        // LD :=REF(LOW,1)-LOW;
        // DMP:=EXPMEMA(IF(HD>0&&HD>LD,HD,0),N);
        // DMM:=EXPMEMA(IF(LD>0&&LD>HD,LD,0),N);
        //
        // PDI: DMP*100/MTR;
        // MDI: DMM*100/MTR;
        // ADX: EXPMEMA(ABS(MDI-PDI)/(MDI+PDI)*100,MM);
        // ADXR:EXPMEMA(ADX,MM);
        // 公式含义:
        // MTR赋值:最高价-最低价和最高价-昨收的绝对值的较大值和昨收-最低价的绝对值的较大值的N日指数平滑移动平均 
        // HD赋值:最高价-昨日最高价 
        // LD赋值:昨日最低价-最低价 
        // DMP赋值:如果HD>0并且HD>LD,返回HD,否则返回0的N日指数平滑移动平均 
        // DMM赋值:如果LD>0并且LD>HD,返回LD,否则返回0的N日指数平滑移动平均 
        // 输出PDI: DMP*100/MTR 
        // 输出MDI: DMM*100/MTR 
        // 输出ADX: MDI-PDI的绝对值/(MDI+PDI)*100的MM日指数平滑移动平均 
        // 输出ADXR:ADX的MM日指数平滑移动平均
        data = indexDayMovingAverage(data);
        double pdi = 0;
        double mdi = 0;
        double adx = 0;
        double adxr = 0;

        double HD = 0;
        double LD = 0;
        double refClose = 0;
        List<Double> sumMax = new Vector<Double>();
        List<Double> sumMaxDmp = new Vector<Double>();
        List<Double> sumMaxDmm = new Vector<Double>();
        List<Double> sumAdx = new Vector<Double>();
        List<Double> sumAdxr = new Vector<Double>();
        for (int i = 0; i < data.size(); i++) {
            if (i > 0) {
                refClose = data.get(i - 1).getClose();
                HD = data.get(i).getHighPrice()
                     - data.get(i - 1).getHighPrice();
                LD = data.get(i - 1).getLowPrice() - data.get(i).getLowPrice();

                double max1 = data.get(i).getHighPrice()
                              - data.get(i).getLowPrice() > Math.abs(data.get(i)
                                                                             .getHighPrice() -
                                                                     refClose) ? data.get(i)
                                                                                         .getHighPrice() -
                                                                                 data.get(i).getLowPrice()
                                                                               : Math
                                      .abs(data.get(i).getHighPrice() - refClose);
                double max2 = max1 > Math.abs(refClose)
                                     - data.get(i).getLowPrice() ? max1 : Math.abs(refClose)
                                                                          -
                                                                          data.get(i).getLowPrice();
                sumMax.add(max2);

                double H;
                if (HD > 0 && HD > LD)
                    H = HD;
                else
                    H = 0;
                sumMaxDmp.add(H);

                double L;
                if (LD > 0 && LD > HD)
                    L = LD;
                else
                    L = 0;
                sumMaxDmm.add(L);

                if (i >= 14) {
                    double sumMax1 = 0;
                    double sumMaxDmp1 = 0;
                    double sumMaxDmm1 = 0;
                    for (int j = 0; j < sumMax.size(); j++) {
                        sumMax1 += sumMax.get(j);
                        sumMaxDmp1 += sumMaxDmp.get(j);
                        sumMaxDmm1 += sumMaxDmm.get(j);
                    }
                    sumMax.remove(0);
                    sumMaxDmp.remove(0);
                    sumMaxDmm.remove(0);
                    double mtr = sumMax1;
                    double dmp = sumMaxDmp1;
                    double dmm = sumMaxDmm1;

                    pdi = dmp * 100 / mtr;
                    mdi = dmm * 100 / mtr;
                    double adxN1 = Math.abs((mdi - pdi)) / (mdi + pdi) * 100;
                    sumAdx.add(adxN1);
                    if (i >= 19) {
                        double sum = 0;
                        for (int j = 0; j < sumAdx.size(); j++) {
                            sum += sumAdx.get(j);
                        }
                        adx = sum / 6;
                        sumAdx.remove(0);
                        sumAdxr.add(adx);
                        if (i >= 25) {
                            double sum1 = 0;
                            sum1 += sumAdxr.get(0);
                            sum1 += sumAdxr.get(sumAdxr.size() - 1);
                            adxr = sum1 / 2;
                            sumAdxr.remove(0);
                        }
                    }
                }
            }
            DMI dmi = new DMI(pdi, mdi, adx, adxr);
            data.get(i).setDmi(dmi);
        }
        return data;
    }

    /**
     * 计算CR
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationCR(Vector<KLineData> data) {
        // 参数26、5、10、20
        // MID:=REF(HIGH+LOW,1)/2;
        // CR:SUM(MAX(0,HIGH-MID),N)/SUM(MAX(0,MID-LOW),N)*100;
        // MA1:REF(MA(CR,M1),M1/2.5+1);
        // MA2:REF(MA(CR,M2),M2/2.5+1);
        // MA3:REF(MA(CR,M3),M3/2.5+1);
        // MID赋值:(昨日最高价+昨日最低价)/2
        // 输出带状能量线:0和最高价-MID的较大值的N日累和/0和MID-最低价的较大值的N日累和*100
        // 输出MA1:M1(5)/2.5+1日前的CR的M1(5)日简单移动平均
        // 输出MA2:M2(10)/2.5+1日前的CR的M2(10)日简单移动平均
        // 输出MA3:M3(20)/2.5+1日前的CR的M3(20)日简单移动平均
        // 输出MA4:M4/2.5+1日前的CR的M4日简单移动平均

        data = indexDayMovingAverage(data);
        double cr = 0;
        double ma1 = 0;
        double ma2 = 0;
        double ma3 = 0;
        double P1 = 0;
        double P2 = 0;
        double ma1Index = 0;
        double ma2Index = 0;
        double ma3Index = 0;
        for (int i = 0; i < data.size(); i++) {
            if (i > 0) {
                double YM = (data.get(i - 1).getHighPrice()
                             + data.get(i - 1).getLowPrice() + data.get(i - 1)
                                     .getClose()) / 3;
                P1 += (0 >= data.get(i).getHighPrice() - YM ? 0 : data.get(i)
                                                                          .getHighPrice() - YM);
                P2 += (0 >= YM - data.get(i).getLowPrice() ? 0 : YM
                                                                 - data.get(i).getLowPrice());
                if (i >= 26) {
                    cr = P1 / P2 * 100;
                    ma1Index += cr;
                    ma2Index += cr;
                    ma3Index += cr;
                    double YM1 = (data.get(i - 26).getHighPrice()
                                  + data.get(i - 26).getLowPrice() + data.get(i - 26)
                                          .getClose()) / 3;
                    P1 -= 0 >= data.get(i - 25).getHighPrice() - YM1 ? 0 : data
                                                                                   .get(i -
                                                                                        25).getHighPrice() -
                                                                           YM1;
                    P2 -= 0 >= YM1 - data.get(i - 25).getLowPrice() ? 0 : YM1
                                                                          - data.get(
                            i - 25).getLowPrice();
                    if (i >= 33) {
                        double ma1Index1 = ma1Index
                                           - (data.get(i - 2).getCr().getCr()
                                              + data.get(i - 1).getCr().getCr() + cr);
                        ma1 = ma1Index1 / 5;
                        ma1Index -= data.get(i - 7).getCr().getCr();
                        if (i >= 40) {
                            double ma2Index2 = ma2Index
                                               - (data.get(i - 4).getCr().getCr()
                                                  + data.get(i - 3).getCr().getCr()
                                                  + data.get(i - 2).getCr().getCr()
                                                  + data.get(i - 1).getCr().getCr() + cr);
                            ma2 = ma2Index2 / 10;
                            ma2Index -= data.get(i - 14).getCr().getCr();
                            if (i >= 54) {
                                double ma3Index3 = ma3Index
                                                   - (data.get(i - 8).getCr().getCr()
                                                      + data.get(i - 7).getCr()
                                                              .getCr()
                                                      + data.get(i - 6).getCr()
                                                              .getCr()
                                                      + data.get(i - 5).getCr()
                                                              .getCr()
                                                      + data.get(i - 4).getCr()
                                                              .getCr()
                                                      + data.get(i - 3).getCr()
                                                              .getCr()
                                                      + data.get(i - 2).getCr()
                                                              .getCr()
                                                      + data.get(i - 1).getCr()
                                                              .getCr() + cr);
                                ma3 = ma3Index3 / 20;
                                ma3Index -= data.get(i - 28).getCr().getCr();
                            }
                        }
                    }
                }
            }
            CR Cr = new CR(cr, ma1, ma2, ma3);
            data.get(i).setCr(Cr);
        }
        return data;
    }

    /**
     * 计算PSY
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationPSY(Vector<KLineData> data) {
        // PSY:参数是12。公式:PSY=N日内的上涨天数/N×100%。
        data = indexDayMovingAverage(data);
        double psy = 0;
        double upDay = 0;
        for (int i = 0; i < data.size(); i++) {
            if (i > 0) {
                upDay += (data.get(i).getClose() - data.get(i - 1).getClose() > 0 ? 1
                                                                                  : 0);
                if (i >= 12) {
                    psy = upDay / 12 * 100;
                    upDay -= (data.get(i - 11).getClose()
                              - data.get(i - 12).getClose() > 0 ? 1 : 0);

                }
            }
            PSY Psy = new PSY(psy);
            data.get(i).setPsy(Psy);
        }
        return data;
    }

    /**
     * 计算DMA
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationDMA(Vector<KLineData> data) {
        // 参数是10、50、10。公式:DIF:MA(CLOSE,N1)-MA(CLOSE,N2);DIFMA:MA(DIF,M)
        data = indexDayMovingAverage(data);
        double Dma = 0;
        double Ama = 0;
        double ma10Index = 0;
        double ma50Index = 0;
        double Dma10Index = 0;
        for (int i = 0; i < data.size(); i++) {
            ma10Index += data.get(i).getClose();
            ma50Index += data.get(i).getClose();

            if (i >= 49) {
                Dma = ma10Index / 10 - ma50Index / 50;
                Dma10Index += Dma;
                if (i >= 58) {
                    Ama = Dma10Index / 10;
                    Dma10Index -= data.get(i - 9).getDma().getDif();
                }
                ma50Index -= data.get(i - 49).getClose();
            }
            if (i >= 9) {
                ma10Index -= data.get(i - 9).getClose();
            }
            DMA DMa = new DMA(Dma, Ama);
            data.get(i).setDma(DMa);
        }
        return data;
    }

    /**
     * 计算TRIX
     *
     * @param data
     * @return
     */
    public static Vector<KLineData> calculationTRIX(Vector<KLineData> data) {
        // TR=收盘价的N日指数移动平均的N日指数移动平均的N日指数移动平均;
        // TRIX=(TR-昨日TR)/昨日TR*100;
        // MATRIX=TRIX的M日简单移动平均;
        // 参数N设为12,参数M设为20;
        // 参数12、20
        // 公式:MTR:=EMA(EMA(EMA(CLOSE,N),N),N)
        // TRIX:(MTR-REF(MTR,1))/REF(MTR,1)*100;
        // TRMA:MA(TRIX,M)
        data = indexDayMovingAverage(data);
        double trix = 0;
        double maTrix = 0;
        double sumTrix = 0;

        double sumClose = 0;
        double emaClose = 0;
        double oldEmaClose = 0;
        double sumEmaClose = 0;
        double ema2 = 0;
        double oldEma2 = 0;
        double sumEma2 = 0;
        double ema3 = 0;
        double oldEma3 = 0;
        for (int i = 0; i < data.size(); i++) {
            sumClose += data.get(i).getClose();
            if (i == 11) {
                emaClose = sumClose / 12;
                oldEmaClose = emaClose;
            } else if (i > 11) {
                emaClose = (2 * data.get(i).getClose() + 11 * oldEmaClose) / 13;
                oldEmaClose = emaClose;
            }
            sumEmaClose += emaClose;
            if (i == 22) {
                ema2 = sumEmaClose / 12;
                oldEma2 = ema2;
            } else if (i > 22) {
                ema2 = (2 * emaClose + 11 * oldEma2) / 13;
                oldEma2 = ema2;
            }
            sumEma2 += ema2;
            if (i == 33) {
                ema3 = sumEma2 / 12;
                oldEma3 = ema3;
            } else if (i > 33) {
                ema3 = (2 * ema2 + 11 * oldEma3) / 13;
                // 公式:MTR:=EMA(EMA(EMA(CLOSE,N),N),N)
                // TRIX:(MTR-REF(MTR,1))/REF(MTR,1)*100;
                // TRMA:MA(TRIX,M)
                trix = (ema3 - oldEma3) / oldEma3 * 100;
                sumTrix += trix;
                if (i >= 52) {
                    maTrix = sumTrix / 20;
                    sumTrix -= data.get(i - 19).getTrix().getTrix();
                }
                oldEma3 = ema3;
            }

            TRIX Trix = new TRIX(trix, maTrix);
            data.get(i).setTrix(Trix);
        }
        return data;
    }

    /**
     * 计算均线数据
     *
     * @param data
     * @return
     */
    private static Vector<KLineData> indexDayMovingAverage(Vector<KLineData> data) {
        double ma5Num = 0.0;
        double ma10Num = 0.0;
        double ma20Num = 0.0;

        double ma5 = 0;
        double ma10 = 0;
        double ma20 = 0;
        for (int i = 0; i < data.size(); i++) {
            double close = data.get(i).getClose();
            ma5Num += close;
            ma10Num += close;
            ma20Num += close;
            if (i >= 4) {
                ma5 = ma5Num / 5;
                ma5Num -= Parse.getInstance().parseDouble(
                        data.get(i - 4).getClose());
                if (i >= 9) {
                    ma10 = ma10Num / 10;
                    ma10Num -= Parse.getInstance().parseDouble(
                            data.get(i - 9).getClose());
                    if (i >= 19) {
                        ma20 = ma20Num / 20;
                        ma20Num -= Parse.getInstance().parseDouble(
                                data.get(i - 19).getClose());
                    }
                }
            }
         //   Log.w("IndexCalculation", "i=" + i + ",dMA1:" + ma5 + ",dMA2:" + ma10 + ",dMA3:" + ma20 );
            KLineData.DayMovingAverage dma = new KLineData.DayMovingAverage(ma5, ma10, ma20);
            data.get(i).setDayMovingAverage(dma);
        }
        return data;
    }

    /**
     * 计算布林指标中的标准差
     *
     * @param list
     * @param MA
     * @return
     */
    private static double getBollMD(List<KLineData> list, double MA) {
        double sum = 0;
        for (int i = 0; i < list.size(); i++) {
            sum += (list.get(i).getClose() - MA)
                   * (list.get(i).getClose() - MA);
        }
        boolean b = sum > 0;
        sum = Math.abs(sum);
        double MD = Math.sqrt(sum / 26);
        return b ? MD : -1 * MD;
    }

    /**
     * 获取list中的最大的最高价
     *
     * @param list
     * @return
     */
    private static double getHigh(List<KLineData> list) {
        double high = 0;
        if (list != null && list.size() > 0) {
            int size = list.size();
            high = list.get(0).getHighPrice();
            for (int i = 1; i < size; i++) {
                high = high < list.get(i).getHighPrice() ? list.get(i)
                        .getHighPrice() : high;
            }
        }
        return high;
    }

    /**
     * 获取list中的最小的最低价
     *
     * @param list
     * @return
     */
    private static double getLow(List<KLineData> list) {
        double low = 0;
        if (list != null && list.size() > 0) {
            int size = list.size();
            low = list.get(0).getLowPrice();
            for (int i = 1; i < size; i++) {
                low = low > list.get(i).getLowPrice() ? list.get(i)
                        .getLowPrice() : low;
            }
        }
        return low;
    }

    /**
     * 获取N日内的涨和
     *
     * @param list
     * @return
     */
    private static double getUpHe(List<KLineData> list) {
        double up = 0;
        if (list != null && list.size() > 0) {
            int size = list.size();
            for (int i = 1; i < size; i++) {
                double z = list.get(i).getClose() - list.get(i - 1).getClose();
                up += z > 0 ? z : 0;
            }
        }
        return up;
    }

    /**
     * 获取N日内跌和
     *
     * @param list
     * @return
     */
    private static double getDownHe(List<KLineData> list) {
        double down = 0;
        if (list != null && list.size() > 0) {
            int size = list.size();
            for (int i = 1; i < size; i++) {
                double d = list.get(i).getClose() - list.get(i - 1).getClose();
                down += d < 0 ? Math.abs(d) : 0;
            }
        }
        return down;
    }

    /**
     * 比较较大值并返回
     *
     * @param d1
     * @param d2
     * @return
     */
    private static double getMax(double d1, double d2) {
        if (d1 > d2)
            return d1;
        else
            return d2;
    }

}

关注公众号“大模型全栈程序员”回复“小程序”获取1000个小程序打包源码。更多免费资源在http://www.gitweixin.com/?p=2627

发表评论

邮箱地址不会被公开。 必填项已用*标注