package com.xcong.excoin.modules.okxNewPrice.indicator; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; /** * MACD (Moving Average Convergence Divergence) 指标实现 * 计算逻辑: * 1. DIF = EMA(12) - EMA(26) * 2. DEA = EMA(DIF, 9) * 3. MACD柱状图 = (DIF - DEA) * 2 */ @Slf4j @Getter @Setter public class MACD extends IndicatorBase { private static final int FAST_PERIOD = 12; private static final int SLOW_PERIOD = 26; private static final int SIGNAL_PERIOD = 9; private BigDecimal dif = BigDecimal.ZERO; private BigDecimal dea = BigDecimal.ZERO; private BigDecimal macdBar = BigDecimal.ZERO; private BigDecimal prevFastEMA = null; private BigDecimal prevSlowEMA = null; private BigDecimal prevDea = null; /** * 计算MACD指标 * @param prices 价格列表 */ public void calculate(List prices) { if (prices == null || prices.size() < 2) { return; } // 计算快速EMA prevFastEMA = calculateEMA(prices, FAST_PERIOD, prevFastEMA); // 计算慢速EMA prevSlowEMA = calculateEMA(prices, SLOW_PERIOD, prevSlowEMA); // 计算DIF dif = prevFastEMA.subtract(prevSlowEMA).setScale(8, RoundingMode.HALF_UP); // 计算DEA List difList = new ArrayList<>(); difList.add(dif); prevDea = calculateEMA(difList, SIGNAL_PERIOD, prevDea); dea = prevDea.setScale(8, RoundingMode.HALF_UP); // 计算MACD柱状图 macdBar = dif.subtract(dea).multiply(new BigDecimal(2)).setScale(8, RoundingMode.HALF_UP); log.debug("MACD计算结果 - DIF: {}, DEA: {}, MACD柱状图: {}", dif, dea, macdBar); } /** * 判断金叉信号(DIF上穿DEA) * @return 是否形成金叉 */ public boolean isGoldenCross(BigDecimal previousDIF, BigDecimal previousDEA) { return previousDIF.compareTo(previousDEA) < 0 && dif.compareTo(dea) > 0; } /** * 判断死叉信号(DIF下穿DEA) * @return 是否形成死叉 */ public boolean isDeathCross(BigDecimal previousDIF, BigDecimal previousDEA) { return previousDIF.compareTo(previousDEA) > 0 && dif.compareTo(dea) < 0; } }