| | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.List; |
| | | |
| | | /** |
| | |
| | | private BigDecimal prevFastEMA = null; |
| | | private BigDecimal prevSlowEMA = null; |
| | | private BigDecimal prevDea = null; |
| | | // 用于保存历史DIF值,用于计算DEA |
| | | private List<BigDecimal> difHistory = new ArrayList<>(); |
| | | // 最大保存的DIF历史值数量,至少为signalPeriod |
| | | private static final int MAX_DIF_HISTORY = 30; |
| | | |
| | | // 构造函数使用默认周期 |
| | | public MACD() { |
| | |
| | | // 计算DIF |
| | | dif = prevFastEMA.subtract(prevSlowEMA).setScale(8, RoundingMode.HALF_UP); |
| | | |
| | | // 计算DEA |
| | | List<BigDecimal> difList = new ArrayList<>(); |
| | | difList.add(dif); |
| | | prevDea = calculateEMA(difList, signalPeriod, prevDea); |
| | | // 将新的DIF值添加到历史记录 |
| | | difHistory.add(dif); |
| | | // 保持历史记录在合理范围内 |
| | | if (difHistory.size() > MAX_DIF_HISTORY) { |
| | | difHistory.remove(0); |
| | | } |
| | | |
| | | // 计算DEA:使用足够数量的历史DIF值 |
| | | // 如果历史DIF值不足,使用当前可用的所有值 |
| | | int difCount = difHistory.size(); |
| | | List<BigDecimal> deaCalculationList; |
| | | if (difCount >= signalPeriod) { |
| | | // 使用最近的signalPeriod个DIF值 |
| | | deaCalculationList = difHistory.subList(difCount - signalPeriod, difCount); |
| | | } else if (difCount > 0) { |
| | | // 使用所有可用的DIF值 |
| | | deaCalculationList = new ArrayList<>(difHistory); |
| | | } else { |
| | | // 没有DIF历史值,使用当前DIF |
| | | deaCalculationList = Collections.singletonList(dif); |
| | | } |
| | | |
| | | prevDea = calculateEMA(deaCalculationList, signalPeriod, prevDea); |
| | | dea = prevDea.setScale(8, RoundingMode.HALF_UP); |
| | | |
| | | // 计算MACD柱状图 |