From de704d4f87680600aa03782bcd905487e3e81e5f Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Tue, 06 Jan 2026 14:20:50 +0800
Subject: [PATCH] refactor(okxNewPrice): 优化MACD策略日志输出和交易逻辑

---
 src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MA.java |  133 +++++++++++++++++++++++++++++++++++--------
 1 files changed, 107 insertions(+), 26 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MA.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MA.java
index 25cba55..0da46e6 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MA.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/MA.java
@@ -10,18 +10,50 @@
 /**
  * MA (Moving Average) 指标实现
  * 支持不同周期的简单移动平均线(SMA)和指数移动平均线(EMA)
+ * 
+ * 作用:
+ * 1. 平滑价格波动,识别趋势方向
+ * 2. 短周期MA上穿长周期MA形成金叉,提示买入信号
+ * 3. 短周期MA下穿长周期MA形成死叉,提示卖出信号
+ * 4. 价格上穿/下穿MA线,也可作为买卖参考
+ * 
+ * 价格参数类型:
+ * - 参数名称:prices
+ * - 参数类型:List<BigDecimal>
+ * - 参数说明:需要至少1个价格数据点用于计算,根据不同周期需求更多数据点
+ * 
+ * 推荐时间粒度及优缺点:
+ * 1. 1分钟(1m):
+ *    - 优点:反应迅速,适合超短线交易
+ *    - 缺点:噪音多,容易产生虚假信号
+ * 2. 5分钟(5m):
+ *    - 优点:平衡了反应速度和噪音过滤
+ *    - 缺点:仍有一定噪音
+ * 3. 15分钟(15m):
+ *    - 优点:适合日内交易,信号相对可靠
+ *    - 缺点:反应速度较慢
+ * 4. 1小时(1h)及以上:
+ *    - 优点:趋势信号明确,虚假信号少
+ *    - 缺点:反应滞后,不适合短线交易
  */
 @Slf4j
 @Getter
 @Setter
 public class MA extends IndicatorBase {
 
-    // 常用周期
-    public static final int MA5 = 5;
-    public static final int MA10 = 10;
-    public static final int MA20 = 20;
-    public static final int MA30 = 30;
-    public static final int MA60 = 60;
+    // 默认周期
+    public static final int DEFAULT_MA5 = 5;
+    public static final int DEFAULT_MA10 = 10;
+    public static final int DEFAULT_MA20 = 20;
+    public static final int DEFAULT_MA30 = 30;
+    public static final int DEFAULT_MA60 = 60;
+
+    // 动态周期参数
+    private int ma5Period;
+    private int ma10Period;
+    private int ma20Period;
+    private int ma30Period;
+    private int ma60Period;
 
     private BigDecimal ma5 = BigDecimal.ZERO;
     private BigDecimal ma10 = BigDecimal.ZERO;
@@ -41,52 +73,101 @@
     private BigDecimal prevEma30 = null;
     private BigDecimal prevEma60 = null;
 
+    // 构造函数使用默认周期
+    public MA() {
+        this.ma5Period = DEFAULT_MA5;
+        this.ma10Period = DEFAULT_MA10;
+        this.ma20Period = DEFAULT_MA20;
+        this.ma30Period = DEFAULT_MA30;
+        this.ma60Period = DEFAULT_MA60;
+    }
+
     /**
-     * 计算所有周期的MA指标
+     * 计算所有周期的MA指标(使用当前周期设置)
      * @param prices 价格列表
      */
     public void calculate(List<BigDecimal> prices) {
+        calculate(prices, null);
+    }
+
+    /**
+     * 计算所有周期的MA指标,并支持动态周期调整
+     * @param prices 价格列表
+     * @param volatility 标准化波动率(ATR百分比),用于动态调整周期
+     */
+    public void calculate(List<BigDecimal> prices, BigDecimal volatility) {
         if (prices == null || prices.size() < 1) {
             return;
         }
 
+        // 如果提供了波动率,则动态调整周期
+        if (volatility != null) {
+            adjustPeriodsByVolatility(volatility);
+        }
+
         // 计算SMA
-        if (prices.size() >= MA5) {
-            ma5 = calculateMA(prices, MA5);
+        if (prices.size() >= ma5Period) {
+            ma5 = calculateMA(prices, ma5Period);
         }
-        if (prices.size() >= MA10) {
-            ma10 = calculateMA(prices, MA10);
+        if (prices.size() >= ma10Period) {
+            ma10 = calculateMA(prices, ma10Period);
         }
-        if (prices.size() >= MA20) {
-            ma20 = calculateMA(prices, MA20);
+        if (prices.size() >= ma20Period) {
+            ma20 = calculateMA(prices, ma20Period);
         }
-        if (prices.size() >= MA30) {
-            ma30 = calculateMA(prices, MA30);
+        if (prices.size() >= ma30Period) {
+            ma30 = calculateMA(prices, ma30Period);
         }
-        if (prices.size() >= MA60) {
-            ma60 = calculateMA(prices, MA60);
+        if (prices.size() >= ma60Period) {
+            ma60 = calculateMA(prices, ma60Period);
         }
 
         // 计算EMA
-        prevEma5 = calculateEMA(prices, MA5, prevEma5);
+        prevEma5 = calculateEMA(prices, ma5Period, prevEma5);
         ema5 = prevEma5;
         
-        prevEma10 = calculateEMA(prices, MA10, prevEma10);
+        prevEma10 = calculateEMA(prices, ma10Period, prevEma10);
         ema10 = prevEma10;
         
-        prevEma20 = calculateEMA(prices, MA20, prevEma20);
+        prevEma20 = calculateEMA(prices, ma20Period, prevEma20);
         ema20 = prevEma20;
         
-        prevEma30 = calculateEMA(prices, MA30, prevEma30);
+        prevEma30 = calculateEMA(prices, ma30Period, prevEma30);
         ema30 = prevEma30;
         
-        prevEma60 = calculateEMA(prices, MA60, prevEma60);
+        prevEma60 = calculateEMA(prices, ma60Period, prevEma60);
         ema60 = prevEma60;
 
-        log.debug("MA计算结果 - MA5: {}, MA10: {}, MA20: {}, MA30: {}, MA60: {}", 
-                ma5, ma10, ma20, ma30, ma60);
-        log.debug("EMA计算结果 - EMA5: {}, EMA10: {}, EMA20: {}, EMA30: {}, EMA60: {}", 
-                ema5, ema10, ema20, ema30, ema60);
+        log.info("MA计算结果 - MA5({}): {}, MA10({}): {}, MA20({}): {}, MA30({}): {}, MA60({}): {}",
+                ma5Period, ma5, ma10Period, ma10, ma20Period, ma20, ma30Period, ma30, ma60Period, ma60);
+        log.info("EMA计算结果 - EMA5({}): {}, EMA10({}): {}, EMA20({}): {}, EMA30({}): {}, EMA60({}): {}",
+                ma5Period, ema5, ma10Period, ema10, ma20Period, ema20, ma30Period, ema30, ma60Period, ema60);
+    }
+
+    /**
+     * 根据波动率调整MA周期
+     * @param volatility 标准化波动率(ATR百分比)
+     */
+    private void adjustPeriodsByVolatility(BigDecimal volatility) {
+        // 根据波动率缩放均线周期
+        // 3%、5%、8%作为ATR阈值
+        BigDecimal lowVolatility = new BigDecimal(3);
+        BigDecimal midVolatility = new BigDecimal(5);
+        BigDecimal highVolatility = new BigDecimal(8);
+
+        // 快速MA周期 (ma5)
+        ma5Period = volatility.compareTo(lowVolatility) < 0 ? 10 : 6;
+        
+        // 中期MA周期 (ma10, ma20)
+        ma10Period = volatility.compareTo(midVolatility) < 0 ? 10 : 8;
+        ma20Period = volatility.compareTo(midVolatility) < 0 ? 21 : 13;
+        
+        // 长期MA周期 (ma30, ma60)
+        ma30Period = volatility.compareTo(highVolatility) < 0 ? 30 : 24;
+        ma60Period = volatility.compareTo(highVolatility) < 0 ? 50 : 34;
+
+        log.info("根据波动率{}调整MA周期: ma5={}, ma10={}, ma20={}, ma30={}, ma60={}",
+                volatility, ma5Period, ma10Period, ma20Period, ma30Period, ma60Period);
     }
 
     /**

--
Gitblit v1.9.1