算法代码传到这github
demo:StockChart
三、BOLL:
BOLL指标,其英文全称是“Bollinger Bands”
在所有的指标计算中,BOLL指标的计算方法是最复杂的之一,其中引进了统计学中的标准差概念,涉及到中轨线(MB)、上轨线(UP)和下轨线(DN)的计算。另外,和其他指标的计算一样,由于选用的计算周期的不同,BOLL指标也包括日BOLL指标、周BOLL指标、月BOLL指标年BOLL指标以及分钟BOLL指标等各种类型
计算公式
中轨线=N日的移动平均线
上轨线=中轨线+两倍的标准差
下轨线=中轨线-两倍的标准差
/**
* 布林带BOLL(n, k) 一般n默认取20,k取2, mb为计算好的中轨线
* 中轨线MB: n日移动平均线 MA(n)
* 上轨线:MB + 2*MD
* 下轨线:MB - 2*MD
* MD:n日方差
*
* @param entries
* @param n
* @param k
* @return
*/
public static List<Entry>[] getMB(List<CandleEntry> entries, int n, int k) {
ArrayList<Entry> resultMB = new ArrayList<>(); // 中轨线
ArrayList<Entry> resultUp = new ArrayList<>(); // 上轨线
ArrayList<Entry> resultDn = new ArrayList<>(); // 下轨线
for (int i = 0, len = entries.size(); i < len; i++) {
if (i < n - 1) {
continue;
}
float sumMB = 0;
float sumMD = 0;
for (int j = n - 1; j >= 0; j--) {
float thisClose = entries.get(i - j).getClose();
sumMB += thisClose;
}
float mb = sumMB / n;
float x = entries.get(i).getX();
resultMB.add(new Entry(x, mb));
for (int j = n - 1; j >= 0; j--) {
float thisClose = entries.get(i - j).getClose();
float cma = thisClose - mb; // C-MB
sumMD += cma * cma;
}
float md = (float) Math.pow(sumMD / (n - 1), 1.0 / k); //MD=前n日C-MB的平方和来开根
resultUp.add(new Entry(x, mb + 2 * md)); // UP=MB+2*MD
resultDn.add(new Entry(x, mb - 2 * md)); // DN=MB+2*MD
}
return new ArrayList[]{resultMB, resultUp, resultDn};
}
四、MACD
异同移动平均线,是从双指数移动平均线发展而来的,由快的指数移动平均线(EMA12)减去慢的指数移动平均线(EMA26)得到快线DIF,再用2×(快线DIF-DIF的9日加权移动均线DEA)得到MACD柱。
/**
* MACD算法:
* DIF:EMA(short) - EMA(long) 一般short取12,long取26
* DEA: EMA(DIF, mid), mid一般取9
* MACD:(DIF-DEA)*2
*
* @param entries
* @param s short
* @param l long
* @param m mid
* @return
*/
public static List[] getMACD(List<CandleEntry> entries, int s, int l, int m) {
ArrayList<Entry> listDIF = new ArrayList<>();
ArrayList<Entry> listDEA = new ArrayList<>();
ArrayList<BarEntry> listMACD = new ArrayList<>();
float lastEmaS = entries.get(0).getClose();
float lastEmaL = lastEmaS;
float lastDIF = 0;
listDIF.add(new Entry(0, 0));
listDEA.add(new Entry(0, 0));
listMACD.add(new BarEntry(0, 0));
float[] factorShort = getEMAFactor(s);
float[] factorLong = getEMAFactor(l);
float[] factorMid = getEMAFactor(m);
for (int i = 1; i < entries.size(); i++) {
float x = entries.get(i).getX();
// 短线EMA
float valueS = factorShort[0] * entries.get(i).getClose() + factorShort[1] * lastEmaS;
lastEmaS = valueS;
// 长线EMA
float valueL = factorLong[0] * entries.get(i).getClose() + factorLong[1] * lastEmaL;
lastEmaL = valueL;
// DIF:EMA(short) - EMA(long)
float valueDIF = valueS - valueL;
listDIF.add(new Entry(x, valueDIF));
// EMA(DIF, mid)
float valueDEA = factorMid[0] * valueDIF + factorMid[1] * lastDIF;
listDEA.add(new Entry(x, valueDEA));
lastDIF = valueDEA;
// MACD:(DIF-DEA)*2
listMACD.add(new BarEntry(x, (valueDIF - valueDEA) * 2));
}
return new ArrayList[]{listDIF, listDEA, listMACD};
}
/**
* 获取EMA计算时的相关系数
* @param n
* @return
*/
private static float[] getEMAFactor(int n) {
return new float[]{2f / (n + 1), (n - 1) * 1.0f / (n + 1)};
}