# 整理算法 ## 简称和命名 ### Quotes * 最原始的Quote对象包含五个字段:t,o,c,l,h * t 时间,该报价单元生成的时间戳 * o 开盘价,该报价单元的开始报价 * c 闭盘价,该报价单元的结束报价 * l 最低价,该报价单元的最低价 * h 最高价,该报价单元的最高价 ## 算法和示例代码 ### MA > 移动平均线,Moving Average,简称MA,MA是用统计分析的方法,将一定时期内的证券价格(指数)加以平均,并把不同时间的平均值连接起来,形成一根MA,用以观察证券价格变动趋势的一种技术指标。[[百度百科:移动平均线](https://baike.baidu.com/item/%E7%A7%BB%E5%8A%A8%E5%B9%B3%E5%9D%87%E7%BA%BF/217887?fr=aladdin&fromid=1511750&fromtitle=MA)] #### MA算法 * MA5,指的是5单位的移动平均线,其它同理。MA(5,10,20)指的是5单位、10单位、20单位三条移动平均线。 * 很多资料都把MAn,称为n天的移动平均线,感觉这样是不合理的,因为折线图有很多类型,比如1分钟的、1小时的、1周的等等。所以,这里"n"不应该称为“天”,而是应该是对应的类型,所以这里直接称为“单位”。 * 计算公式:MA =(C1+C2+C3+C4+C5+...+Cn)/n,其中C为收盘价n为移动平均周期数。例如现货黄金的5日移动平均价格计算方法为:MA5=(前四天收盘价+前三天收盘价+前天收盘价+昨天收盘价+今天收盘价)/5。 * 指定点的MAn值的计算,就是从该点开始(包括该点)起向历史数据取n个数据单元的收盘价之和,然后取均值。 * 特殊的,假如数据集合中最开始的n个数据,是没法计算MAn的。这里的处理方式有两种 1. 对于最开始的n个点,直接用当日的收盘价当作对应MA值即可。 2. 不计算,绘制时直接不绘制对应MA即可。本项目采用这种方式。 #### MA示例代码 * 本项目中处理MA只计算MA5,MA10,MA20。并且直接在Quotes中定义该三个字段,计算好之后直接赋值。 * 示例代码 ```java /** * 计算公式:MA =(C1+C2+C3+C4+C5+...+Cn)/n,其中C为收盘价n为移动平均周期数。 * 例如现货黄金的5日移动平均价格计算方法为:MA5=(前四天收盘价+前三天收盘价+前天收盘价+昨天收盘价+今天收盘价)/5。 * 特殊的,假如数据集合中最开始的n个数据,是没法计算MAn的。这里的处理方式是不计算,绘制时直接不绘制对应MA即可。 * @param quotesList 数据集合 * @param period MAn中的n */ public static void calculateMA(List quotesList, int period) { if (quotesList == null || quotesList.isEmpty()) return; if (period < 0 || period > quotesList.size() - 1) return; double sum = 0; for (int i = 0; i < quotesList.size(); i++) { //计算和 Quotes quotes = quotesList.get(i); sum += quotes.c; if (i > period - 1) { sum -= quotesList.get(i - period).c; } //边界 if (i < period - 1) { continue; } if (period == 5) { quotes.ma5 = sum / period; } else if (period == 10) { quotes.ma10 = sum / period; } else if (period == 20) { quotes.ma20 = sum / period; } else { Log.e(TAG, "calculateMA: 没有该种period,TODO:完善Quotes"); return; } } } ``` ### BOLL > 布林线,Boll,是股市技术分析的常用工具之一,通过计算股价的“标准差”,再求股价的“信赖区间”。该指标在图形上画出三条线,其中上下两条线可以分别看成是股价的压力线和支撑线,而在两条线之间还有一条股价平均线,布林线指标的参数最好设为20。一般来说,股价会运行在压力线和支撑线所形成的通道中。[[百度百科:布林线](https://baike.baidu.com/item/%E5%B8%83%E6%9E%97%E7%BA%BF/3424486?fr=aladdin)] #### BOLL算法 * BOLL(n),指的是n单位的BOLL线。 * BOLL(n)包含三条线,中轨线(MB)、上轨线(UP)和下轨线(DN)。 * BOLL(n)计算公式: * MA=n日内的收盘价之和÷n。 * MD=(n-1)日的平方根(C-MA)的两次方之和除以n * MB=(n-1)日的MA * UP=MB+k×MD * DN=MB-k×MD * K为参数,可根据股票的特性来做相应的调整,一般默认为2 * 特殊的,假如数据集合中最开始的n个数据,是没法计算BOLL(n)的。这里的处理方式有两种 1. 对于最开始的n个点,直接用当日的收盘价当作当日的MA值即可。 2. 不计算,绘制时直接不绘制对应BOLL即可。本项目采用这种方式。 #### BOLL示例代码 * 本项目中处理MA只计算BOLL(26),k=2。并且直接在Quotes中定义mb、up、dn,计算好之后直接赋值。 * 示例代码 ```java /** * BOLL(n)计算公式: * MA=n日内的收盘价之和÷n。 * MD=(n-1)日的平方根(C-MA)的两次方之和除以n * MB=(n-1)日的MA * UP=MB+k×MD * DN=MB-k×MD * K为参数,可根据股票的特性来做相应的调整,一般默认为2 * * @param quotesList 数据集合 * @param period 周期,一般为26 * @param k 参数,可根据股票的特性来做相应的调整,一般默认为2 */ public static void calculateBOLL(List quotesList, int period, int k) { if (quotesList == null || quotesList.isEmpty()) return; if (period < 0 || period > quotesList.size() - 1) return; double mb;//上轨线 double up;//中轨线 double dn;//下轨线 //n日 double sum = 0; //n-1日 double sum2=0; for (int i = 0; i < quotesList.size(); i++) { Quotes quotes = quotesList.get(i); sum += quotes.c; sum2+=quotes.c; if (i > period - 1) sum -= quotesList.get(i - period).c; if(i>period-2) sum2 -= quotesList.get(i - period+1).c; //这个范围不计算,在View上的反应就是不显示这个范围的boll线 if (i < period - 1) continue; //n日MA double ma = sum / period; //n-1日MA double ma2=sum2/(period-1); double md = 0; for (int j = i + 1 - period; j <= i; j++) { //n-1日 md += Math.pow(quotesList.get(j).c - ma, 2); } md = Math.sqrt(md / period); //(n-1)日的MA mb = ma2; up = mb + k * md; dn = mb - k * md; quotes.mb = mb; quotes.up = up; quotes.dn = dn; } } ```