Administrator
2025-12-25 68167e4454f0ab5143f2100554cf797804b98cfc
```
fix(indicator): 修复MACD指标计算逻辑和空指针异常

- 添加DIF历史值缓存机制,确保DEA计算使用足够的历史数据
- 实现DIF历史记录的滑动窗口,限制最大存储数量为30条
- 优化DEA计算逻辑,根据可用历史数据数量动态调整计算方式
- 修复k线WebSocket客户端中的posHold空指针异常问题
- 添加null值检查,避免BigDecimal比较时出现空指针异常
```
2 files modified
34 ■■■■ changed files
src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxKlineWebSocketClient.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MACD.java 32 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/okxNewPrice/OkxKlineWebSocketClient.java
@@ -370,7 +370,7 @@
                            String posSide = tradeRequestParam.getPosSide();
                            String side = tradeRequestParam.getSide();
                            BigDecimal posHold = PositionsWs.getAccountMap(PositionsWs.initAccountName(accountName, posSide)).get("pos");
                            if (posHold.compareTo(BigDecimal.ZERO) > 0){
                            if (posHold != null && posHold.compareTo(BigDecimal.ZERO) > 0){
                                tradeRequestParam = strategy.getOrderParamClose(tradeRequestParam);
                            }
                            String currentPrice = String.valueOf(closePx);
src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MACD.java
@@ -7,6 +7,7 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -63,6 +64,10 @@
    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() {
@@ -103,10 +108,29 @@
        // 计算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柱状图