package com.xcong.excoin.modules.okxNewPrice.indicator;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.util.ArrayList;
|
import java.util.List;
|
|
/**
|
* 技术指标基础类,提供通用计算方法
|
*/
|
public abstract class IndicatorBase {
|
|
/**
|
* 计算移动平均值
|
* @param prices 价格列表
|
* @param period 周期
|
* @return 移动平均值
|
*/
|
protected BigDecimal calculateMA(List<BigDecimal> prices, int period) {
|
if (prices == null || prices.size() < period) {
|
return BigDecimal.ZERO;
|
}
|
BigDecimal sum = BigDecimal.ZERO;
|
for (int i = prices.size() - period; i < prices.size(); i++) {
|
sum = sum.add(prices.get(i));
|
}
|
return sum.divide(new BigDecimal(period), 8, RoundingMode.HALF_UP);
|
}
|
|
/**
|
* 计算指数移动平均值
|
* @param prices 价格列表
|
* @param period 周期
|
* @param prevEMA 前一个EMA值
|
* @return 指数移动平均值
|
*/
|
protected BigDecimal calculateEMA(List<BigDecimal> prices, int period, BigDecimal prevEMA) {
|
if (prices == null || prices.size() == 0) {
|
return BigDecimal.ZERO;
|
}
|
if (prevEMA == null || prevEMA.compareTo(BigDecimal.ZERO) == 0) {
|
return calculateMA(prices, Math.min(period, prices.size()));
|
}
|
BigDecimal k = new BigDecimal(2).divide(new BigDecimal(period + 1), 8, RoundingMode.HALF_UP);
|
BigDecimal currentPrice = prices.get(prices.size() - 1);
|
return currentPrice.multiply(k).add(prevEMA.multiply(BigDecimal.ONE.subtract(k)));
|
}
|
|
/**
|
* 计算标准差
|
* @param prices 价格列表
|
* @param period 周期
|
* @return 标准差
|
*/
|
protected BigDecimal calculateStdDev(List<BigDecimal> prices, int period) {
|
if (prices == null || prices.size() < period) {
|
return BigDecimal.ZERO;
|
}
|
BigDecimal ma = calculateMA(prices, period);
|
BigDecimal sumSquares = BigDecimal.ZERO;
|
for (int i = prices.size() - period; i < prices.size(); i++) {
|
BigDecimal diff = prices.get(i).subtract(ma);
|
sumSquares = sumSquares.add(diff.multiply(diff));
|
}
|
BigDecimal variance = sumSquares.divide(new BigDecimal(period), 8, RoundingMode.HALF_UP);
|
return sqrt(variance);
|
}
|
|
/**
|
* 计算平方根(简化实现)
|
* @param value 输入值
|
* @return 平方根
|
*/
|
protected BigDecimal sqrt(BigDecimal value) {
|
if (value.compareTo(BigDecimal.ZERO) < 0) {
|
return BigDecimal.ZERO;
|
}
|
return new BigDecimal(Math.sqrt(value.doubleValue())).setScale(8, RoundingMode.HALF_UP);
|
}
|
|
/**
|
* 获取最近的价格数据
|
* @param prices 所有价格数据
|
* @param period 周期
|
* @return 最近period个价格数据
|
*/
|
protected List<BigDecimal> getRecentPrices(List<BigDecimal> prices, int period) {
|
if (prices == null || prices.size() == 0) {
|
return new ArrayList<>();
|
}
|
int startIndex = Math.max(0, prices.size() - period);
|
return prices.subList(startIndex, prices.size());
|
}
|
}
|