本章上接 股市K线图指标算法的代码实现(一)
6.KDJ
以KDJ(9,3,3)为例,括号内为传入的参数
(1)计算周期的RSV值
RSV = (C(9)-L(9))/(H(9)-L(9))×100
公式中,C(9)为第9日收盘价;L(9)为9日内的最低价;(H(9)为9日内的最高价。
(2)计算K值,D值,J值
当日K值=2/3×前一日K值+1/3×当日RSV
当日D值=2/3×前一日D值+1/3×当日K值
J值=3*当日K值-2*当日D值
(注:第一天的K值我取的是33.33,D值我取的是11.11,J值我取的是77.78,当然它们要取50也可以)
(注:KDJ的值均须在0~100内)
代码如下:
public void setKDJ(int n, int m1, int m2,List<Entry> firstData, List<Entry> secondData, List<Entry> thirdData) {
firstData.clear();
secondData.clear();
thirdData.clear();
if (mChartData==null){
return;
}
double[] mK = new double[mChartData.close.length]; //K值
double[] mD = new double[mChartData.close.length]; //D值
double jValue; //J值
double highValue =mChartData.high[0];
double lowValue = mChartData.low[0];
int highPosition = 0; //记录最高价的位置
int lowPosition = 0; //记录最低价位置
double rSV = 0.0;
for (int i = 0; i < mChartData.close.length; i++) {
if (i == 0) {
mK[0] = 33.33;
mD[0] = 11.11;
jValue = 77.78;
} else {
//对最高价和最低价赋值
if (highValue <= mChartData.high[i]) {
highValue = mChartData.high[i];
highPosition = i;
}
if (lowValue >= mChartData.low[i]) {
lowValue = mChartData.low[i];
lowPosition = i;
}
if (i > (n - 1)) {
//判断存储的最高价是否高于当前最高价
if (highValue > mChartData.high[i]) {
//判断最高价是不是在最近n天内,若不在最近n天内,则从最近n天找出最高价并赋值
if (highPosition < (i - (n - 1))) {
highValue = mChartData.high[i - (n - 1)];
for (int j = (i - (n - 2)); j <= i; j++) {
if (highValue <= mChartData.high[j]) {
highValue = mChartData.high[j];
highPosition = j;
}
}
}
}
if ((lowValue < mChartData.low[i])) {
if (lowPosition < i - (n - 1)) {
lowValue = mChartData.low[i - (n - 1)];
for (int k = i - (n - 2); k <= i; k++) {
if (lowValue >= mChartData.low[k]) {
lowValue = mChartData.low[k];
lowPosition = k;
}
}
}
}
}
if (highValue != lowValue) {
rSV = (mChartData.close[i] - lowValue) / (highValue - lowValue) * 100;
}
mK[i] = (mK[i - 1] * (m1 - 1) + rSV) / m1;
mD[i] = (mD[i - 1] * (m2 - 1) + mK[i]) / m2;
jValue = 3 * mK[i] - 2 * mD[i];
}
addLimitEntry(i, mK[i], firstData);
addLimitEntry(i, mD[i], secondData);
addLimitEntry(i, jValue, thirdData);
}
}
private void addLimitEntry(int position, double value, List<Entry> data) {
if (value > 100) {
value = 100;
} else if (value < 0) {
value = 0;
}
Entry entry = new Entry(position, (float) value);
data.add(entry);
}
以PBX(6)为例,括号内为传入的参数
PBX = (MA(close,6)+MA(close,12))
代码如下:
public void setPBX(int period,List<Entry> firstList){
firstList.clear();
if (mChartData==null){
return;
}
float[] arr1 = new float[mChartData.close.length];
float[] arr2 = new float[mChartData.close.length];
float[] arr3 = new float[mChartData.close.length];
float pbxValue;
closeMA(period,arr1);
closeMA(period*2,arr2);
closeMA(period*4,arr3);
for (int i = period*4-1;i<mChartData.close.length;i++){
pbxValue = arr1[i]+arr2[i]+arr3[i];
firstList.add(new Entry(i,pbxValue/3));
}
}
private void closeMA(int optInTimePeriod, float[] arr) {
if (mChartData==null){
return;
}
double closeSum = 0;
int period;
for (int i = 0; i < mChartData.close.length; i++) {
closeSum += mChartData.close[i];
if (i >= (optInTimePeriod - 1)) {
period = i - optInTimePeriod;
if (period >= 0) {
closeSum -= mChartData.close[period];
}
arr[i] = (float) closeSum / optInTimePeriod;
}
}
}
8.CCI
以CCI(14)为例,括号内为传入的参数
(1)TYP=(HIGH+LOW+CLOSE)/3
(2)AVEDEV(TYP,N) =( | 第N天的TYP - MA(TYP,N) | + | 第N-1天的TYP - MA(TYP,N) | + ...... + | 第1天的TYP - MA(TYP,N | ) /N
(MA(TYP,N)表示TYP的N日移动平均,我在股市K线图指标算法的代码实现(一)有解释)
(3)CCI = (TYP-MA(TYP,N))/(0.015*AVEDEV(TYP,N));
代码如下:
public void setCCI(int n){
if (mChartData==null){
return;
}
double typSum = 0;
double cciValue;
double typMa;
double typDiff;
double typDiffSum;
double typDEV;
double []typ = new double[mChartData.close.length];
int period;
for (int i = 0;i<mChartData.close.length;i++){
typ[i] = (mChartData.close[i]+mChartData.high[i]+mChartData.low[i])/3;
typSum += typ[i];
if (i >= (n - 1)) {
period = i - n;
if (period >= 0) {
typSum -= typ[period];
}
typMa = typSum/n;
typDiffSum = 0;
for (int j = period+1;j<=i;j++){
typDiff = Math.abs(typ[j]-typMa);
typDiffSum+=typDiff;
}
typDEV = typDiffSum/n;
cciValue = (typ[i]-typMa)/(typDEV*0.015);
}
}
}
以CCI(26)为例,括号内为传入的参数
(1)TR(真实波动幅度)
a = 当天最高点和最低点间的差的绝对值
b = 前一天收盘价和当天最高价间的差的绝对值
c = 前天收盘价和当天最低价间的差的绝对值
TR = MAX(a,b,c)
(2)ATR = MA(TR,26)
代码如下:
public void setATR(int n,List<Entry> firstList,List<Entry> secondList){
firstList.clear();
secondList.clear();
if (mChartData==null){
return;
}
double a; //最高-最低
double b; //最高-昨收
double c; //昨收-最低
double tr[] = new double[mChartData.close.length];
double trSum = 0;
double atrValue;
int period;
for (int i = 0;i<mChartData.close.length;i++){
if (i == 0){
tr[i] = Math.abs(mChartData.high[i] - mChartData.low[i]);
}else {
a = Math.abs(mChartData.high[i] - mChartData.low[i]);
b = Math.abs(mChartData.high[i] - mChartData.close[i - 1]);
c = Math.abs(mChartData.close[i - 1] - mChartData.low[i]);
tr[i] = Math.max(Math.max(a, b), c);
}
trSum += tr[i];
firstList.add(new Entry(i, (float) tr[i]));
if (i>=n-1){
period = i-n;
if (period >= 0) {
trSum -= tr[period];
}
atrValue = trSum/n;
secondList.add(new Entry(i, (float) atrValue));
}
}
}
BIAS=(CLOSE - MA(CLOSE,N))/(MA(CLOSE,N))*100
代码如下:
public void setBIAS(int optInTimePeriod){
if (mChartData==null){
return;
}
double closeSum = 0;
double ma;
double biasValue;
int period;
for (int i = 0; i < mChartData.close.length; i++) {
closeSum += mChartData.close[i];
if (i >= (optInTimePeriod - 1)) {
period = i - optInTimePeriod;
if (period >= 0) {
closeSum -= mChartData.close[period];
}
ma = (float) closeSum / optInTimePeriod;
biasValue = (mChartData.close[i]-ma)/ma*100;
}
}
}
使用方法如下,以RSI算法举例:
public void RSI( int optInTimePeriod, List<Entry> tempData) {
tempData.clear();
if (mChartData==null){
return;
}
Core lib = new Core();
MInteger outBegIdx = new MInteger();
MInteger outNbElement = new MInteger();
double[] rsi = new double[mChartData.close.length];
double[] close = new double[mChartData.close.length];
System.arraycopy(mChartData.close, 0, close, 0, mChartData.close.length);
lib.rsi(0,close.length - 1, close, optInTimePeriod, outBegIdx, outNbElement, rsi);
for (int i = 0; i < rsi.length - optInTimePeriod; i++) {
tempData.add(new Entry(i + optInTimePeriod, (float) rsi[i]));
}
}