需求背景
最近在处理数据,横坐标是时间,纵坐标是价格,需要判断一段时间内,由这些点绘制成的曲线的走势,比如趋势朝上,趋势朝下,水平调整这三种趋势。尝试了不少方法,下面这个效果还可以。废话不多说,直接上Demo
引入pom依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId>
<version>3.6.1</version>
</dependency>
实现方法
/**
* 判断曲线的走势
*
* @param data 带计算的数据,这里表示价格的集合,取出来的数据,默认按时间维度
* @return 判断结果
*/
public TrendEnum coxStuart(double[] data) {
int n = data.length;
//这里的判断,作用是确保输入数据的长度为偶数。如果输入数据的长度为奇数,则将其减1,以便在后续计算中使用。这是因为Cox-Stuart检验需要将数据分成两个相等的部分,因此输入数据的长度必须是偶数
if (n % 2 == 1) {
n--;
}
int c = n / 2;
double[] diff = new double[c];
int pos = 0, neg = 0;
for (int i = 0; i < c; i++) {
diff[i] = data[i + c] - data[i];
if (diff[i] > 0) {
pos++;
} else if (diff[i] < 0) {
neg++;
}
}
int num = pos + neg;
int k = Math.min(pos, neg);
//核心代码
BinomialDistribution binomial = new BinomialDistribution(num, 0.5);
double pValue = binomial.probability(k);
if (pos > neg && pValue < 0.05) {
return TrendEnum.TREND_UP;
} else if (neg > pos && pValue < 0.05) {
return TrendEnum.TREND_DOWN;
} else {
return TrendEnum.TREND_LEVEL_ADJUSTMENT;
}
}
源码查看参数的意义
TrendEnum是一个枚举类
@Getter
public enum TrendEnum {
TREND_UP(0, "趋势朝上"),
TREND_LEVEL_ADJUSTMENT(1, "水平调整"),
TREND_DOWN(2, "趋势朝下");
private final Integer code;
private final String des;
TrendEnum(Integer code, String des) {
this.code = code;
this.des = des;
}
写在最后
测试的话,开发的铁子们应该看的明白,这里不再赘述,可以用股票的K线数据去验证,好了,今天的干货就分享到这里。欢迎一键三连,持续关注 “安前码后” ,一个只输出干货而不是随大流的技术号。另外,赚钱的号 “韭盾” ,也在持续开发中,有投资兴趣的铁子们可以先关注,绝对是好物。 加油,铁子们。