From a9402bbb84f6a521822fc8beb32056d0b2d4201f Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Fri, 26 Dec 2025 18:08:07 +0800
Subject: [PATCH] refactor(indicator): 重构MACD策略实现并优化交易逻辑
---
src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/IndicatorBase.java | 109 ++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 88 insertions(+), 21 deletions(-)
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/IndicatorBase.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/IndicatorBase.java
index 6872bfd..a3b80b7 100644
--- a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/IndicatorBase.java
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/IndicatorBase.java
@@ -6,15 +6,31 @@
import java.util.List;
/**
- * 技术指标基础类,提供通用计算方法
+ * Technical indicators base class, provides common calculation methods
+ *
+ * Indicator combination strategy:
+ * 1. Trend judgment (MA/AdvancedMA/MACD): Determine the overall trend direction of prices
+ * 2. Momentum confirmation (RSI/KDJ): Confirm the strength and sustainability of the current trend
+ * 3. Volatility reference (BOLL): Determine reasonable price volatility range and breakthrough timing
+ *
+ * Long/Short direction selection logic:
+ * - Long signal: MA bullish arrangement + MACD golden cross + RSI(30-70) + BOLL price between upper and middle band
+ * - Short signal: MA bearish arrangement + MACD death cross + RSI(30-70) + BOLL price between lower and middle band
+ * - Consolidation signal: AdvancedMA three-line convergence + RSI(40-60) + BOLL bandwidth narrowing
+ *
+ * Open and close position strategies:
+ * - Open long: MA golden cross + MACD golden cross + KDJ golden cross + RSI(30-70) + price breaks through BOLL middle band
+ * - Open short: MA death cross + MACD death cross + KDJ death cross + RSI(30-70) + price breaks below BOLL middle band
+ * - Close long: MA death cross + MACD death cross + RSI overbought(>70) + price breaks below BOLL middle band
+ * - Close short: MA golden cross + MACD golden cross + RSI oversold(<30) + price breaks through BOLL middle band
*/
public abstract class IndicatorBase {
/**
- * 计算移动平均值
- * @param prices 价格列表
- * @param period 周期
- * @return 移动平均值
+ * Calculate moving average
+ * @param prices Price list
+ * @param period Period
+ * @return Moving average value
*/
protected BigDecimal calculateMA(List<BigDecimal> prices, int period) {
if (prices == null || prices.size() < period) {
@@ -28,11 +44,11 @@
}
/**
- * 计算指数移动平均值
- * @param prices 价格列表
- * @param period 周期
- * @param prevEMA 前一个EMA值
- * @return 指数移动平均值
+ * Calculate exponential moving average
+ * @param prices Price list
+ * @param period Period
+ * @param prevEMA Previous EMA value
+ * @return Exponential moving average value
*/
protected BigDecimal calculateEMA(List<BigDecimal> prices, int period, BigDecimal prevEMA) {
if (prices == null || prices.size() == 0) {
@@ -47,10 +63,10 @@
}
/**
- * 计算标准差
- * @param prices 价格列表
- * @param period 周期
- * @return 标准差
+ * Calculate standard deviation
+ * @param prices Price list
+ * @param period Period
+ * @return Standard deviation
*/
protected BigDecimal calculateStdDev(List<BigDecimal> prices, int period) {
if (prices == null || prices.size() < period) {
@@ -67,9 +83,9 @@
}
/**
- * 计算平方根(简化实现)
- * @param value 输入值
- * @return 平方根
+ * Calculate square root (simplified implementation)
+ * @param value Input value
+ * @return Square root
*/
protected BigDecimal sqrt(BigDecimal value) {
if (value.compareTo(BigDecimal.ZERO) < 0) {
@@ -79,10 +95,10 @@
}
/**
- * 获取最近的价格数据
- * @param prices 所有价格数据
- * @param period 周期
- * @return 最近period个价格数据
+ * Get recent price data
+ * @param prices All price data
+ * @param period Period
+ * @return Recent period price data
*/
protected List<BigDecimal> getRecentPrices(List<BigDecimal> prices, int period) {
if (prices == null || prices.size() == 0) {
@@ -91,4 +107,55 @@
int startIndex = Math.max(0, prices.size() - period);
return prices.subList(startIndex, prices.size());
}
+
+ /**
+ * Calculate ATR (Average True Range)
+ * @param high High price list
+ * @param low Low price list
+ * @param close Close price list
+ * @param period Period
+ * @return ATR value
+ */
+ protected BigDecimal calculateATR(List<BigDecimal> high, List<BigDecimal> low, List<BigDecimal> close, int period) {
+ if (high == null || low == null || close == null ||
+ high.size() < period || low.size() < period || close.size() < period) {
+ return BigDecimal.ZERO;
+ }
+
+ List<BigDecimal> trList = new ArrayList<>();
+ for (int i = 1; i < high.size(); i++) {
+ BigDecimal trueRange = calculateTrueRange(high.get(i), low.get(i), close.get(i - 1));
+ trList.add(trueRange);
+ }
+
+ // Use simple moving average to calculate ATR
+ return calculateMA(trList, Math.min(period, trList.size()));
+ }
+
+ /**
+ * Calculate True Range
+ * @param high Current high price
+ * @param low Current low price
+ * @param prevClose Previous close price
+ * @return True range
+ */
+ protected BigDecimal calculateTrueRange(BigDecimal high, BigDecimal low, BigDecimal prevClose) {
+ BigDecimal h1 = high.subtract(low);
+ BigDecimal h2 = high.subtract(prevClose).abs();
+ BigDecimal h3 = low.subtract(prevClose).abs();
+ return h1.max(h2).max(h3);
+ }
+
+ /**
+ * Calculate normalized volatility (based on ATR)
+ * @param close Close price list
+ * @param atr ATR value
+ * @return Normalized volatility (percentage)
+ */
+ protected BigDecimal normalizeVolatility(List<BigDecimal> close, BigDecimal atr) {
+ if (close == null || close.size() == 0 || atr.compareTo(BigDecimal.ZERO) == 0) {
+ return BigDecimal.ZERO;
+ }
+ return atr.divide(close.get(close.size() - 1), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
+ }
}
--
Gitblit v1.9.1