Administrator
4 days ago e0aac76f043820b9ee36f182000e40858bc68ab8
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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.List;
 
/**
 * Advanced MA (Moving Average) 指标实现
 * 支持扩展周期的指数移动平均线(EMA),用于三重EMA交叉系统
 */
@Slf4j
@Getter
@Setter
public class AdvancedMA extends IndicatorBase {
 
    // 扩展周期 - 三重EMA交叉系统
    public static final int EMA9 = 9;
    public static final int EMA21 = 21;
    public static final int EMA55 = 55;
 
    private BigDecimal ema9 = BigDecimal.ZERO;
    private BigDecimal ema21 = BigDecimal.ZERO;
    private BigDecimal ema55 = BigDecimal.ZERO;
 
    private BigDecimal prevEma9 = null;
    private BigDecimal prevEma21 = null;
    private BigDecimal prevEma55 = null;
 
    /**
     * 计算三重EMA交叉系统的指标
     * @param prices 价格列表
     */
    public void calculateTripleEMA(List<BigDecimal> prices) {
        if (prices == null || prices.isEmpty()) {
            return;
        }
 
        // 计算三重EMA
        prevEma9 = calculateEMA(prices, EMA9, prevEma9);
        ema9 = prevEma9;
        
        prevEma21 = calculateEMA(prices, EMA21, prevEma21);
        ema21 = prevEma21;
        
        prevEma55 = calculateEMA(prices, EMA55, prevEma55);
        ema55 = prevEma55;
 
        log.debug("三重EMA计算结果 - EMA9: {}, EMA21: {}, EMA55: {}", 
                ema9, ema21, ema55);
    }
 
    /**
     * 判断三重EMA多头排列
     * 当9EMA > 21EMA > 55EMA时触发多头条件
     * @return 是否形成多头排列
     */
    public boolean isBullish() {
        return ema9.compareTo(ema21) > 0 && ema21.compareTo(ema55) > 0;
    }
 
    /**
     * 判断三重EMA空头排列
     * 当9EMA < 21EMA < 55EMA时触发空头条件
     * @return 是否形成空头排列
     */
    public boolean isBearish() {
        return ema9.compareTo(ema21) < 0 && ema21.compareTo(ema55) < 0;
    }
 
    /**
     * 计算三线粘合度
     * 用于自动过滤震荡行情
     * @return 粘合度百分比,值越小表示越粘合
     */
    public BigDecimal calculatePercent() {
        // 计算最大值和最小值
        BigDecimal max = ema9.max(ema21).max(ema55);
        BigDecimal min = ema9.min(ema21).min(ema55);
        
        // 计算平均价
        BigDecimal avg = ema9.add(ema21).add(ema55).divide(new BigDecimal(3), 8, RoundingMode.HALF_UP);
        
        // 计算粘合度: (最大值 - 最小值) / 平均值 * 100%
        if (avg.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        
        return max.subtract(min).divide(avg, 8, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
    }
 
    /**
     * 检查是否处于震荡行情(三线粘合)
     * 当三线粘合度 < 2% 时判定为震荡行情
     * @return 是否处于震荡行情
     */
    public boolean isUpAndDown() {
        BigDecimal bigDecimal = calculatePercent();
        return bigDecimal.compareTo(new BigDecimal(2)) < 0;
    }
}