Administrator
7 days ago 4dbaa914142b578be0756608d3cd23c328c3e4cd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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<BigDecimal> 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<BigDecimal> 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;
    }
}