| src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/BearishSignalDetector.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/BullishSignalDetector.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/IndicatorUtils.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/MACDCalculator.java | ●●●●● patch | view | raw | blame | history | |
| src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/MacdMaStrategy.java | ●●●●● patch | view | raw | blame | history |
src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/BearishSignalDetector.java
File was deleted src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/BullishSignalDetector.java
File was deleted src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/IndicatorUtils.java
New file @@ -0,0 +1,154 @@ /** * 指标计算工具类 * 封装MACD策略中常用的通用功能,如高低点查找等 */ package com.xcong.excoin.modules.okxNewPrice.indicator.macdAndMatrategy; import java.math.BigDecimal; import java.util.List; /** * 指标计算工具类,提供MACD策略中常用的通用功能 */ public class IndicatorUtils { /** * 找到最近的价格高点索引 * * @param prices 价格列表 * @param startIdx 起始索引 * @return 最近的价格高点索引 */ public static int findRecentHighIndex(List<BigDecimal> prices, int startIdx) { if (prices == null || startIdx < 0 || startIdx >= prices.size()) { return -1; } int highIdx = startIdx; BigDecimal highPrice = prices.get(startIdx); for (int i = startIdx + 1; i < prices.size(); i++) { BigDecimal currentPrice = prices.get(i); if (currentPrice.compareTo(highPrice) > 0) { highPrice = currentPrice; highIdx = i; } } return highIdx; } /** * 找到最近的价格低点索引 * * @param prices 价格列表 * @param startIdx 起始索引 * @return 最近的价格低点索引 */ public static int findRecentLowIndex(List<BigDecimal> prices, int startIdx) { if (prices == null || startIdx < 0 || startIdx >= prices.size()) { return -1; } int lowIdx = startIdx; BigDecimal lowPrice = prices.get(startIdx); for (int i = startIdx + 1; i < prices.size(); i++) { BigDecimal currentPrice = prices.get(i); if (currentPrice.compareTo(lowPrice) < 0) { lowPrice = currentPrice; lowIdx = i; } } return lowIdx; } /** * 找到最近价格高点之前的价格高点索引 * * @param prices 价格列表 * @param startIdx 起始索引 * @param recentHighIdx 最近的价格高点索引 * @return 之前的价格高点索引 */ public static int findPreviousHighIndex(List<BigDecimal> prices, int startIdx, int recentHighIdx) { if (prices == null || startIdx < 0 || recentHighIdx <= startIdx || recentHighIdx >= prices.size()) { return -1; } int highIdx = startIdx; BigDecimal highPrice = prices.get(startIdx); for (int i = startIdx + 1; i < recentHighIdx; i++) { BigDecimal currentPrice = prices.get(i); if (currentPrice.compareTo(highPrice) > 0) { highPrice = currentPrice; highIdx = i; } } return highIdx; } /** * 找到最近价格低点之前的价格低点索引 * * @param prices 价格列表 * @param startIdx 起始索引 * @param recentLowIdx 最近的价格低点索引 * @return 之前的价格低点索引 */ public static int findPreviousLowIndex(List<BigDecimal> prices, int startIdx, int recentLowIdx) { if (prices == null || startIdx < 0 || recentLowIdx <= startIdx || recentLowIdx >= prices.size()) { return -1; } int lowIdx = startIdx; BigDecimal lowPrice = prices.get(startIdx); for (int i = startIdx + 1; i < recentLowIdx; i++) { BigDecimal currentPrice = prices.get(i); if (currentPrice.compareTo(lowPrice) < 0) { lowPrice = currentPrice; lowIdx = i; } } return lowIdx; } /** * 寻找最近的价格高点(带有回调确认) * * @param prices 价格列表 * @param startIndex 起始索引 * @param endIndex 结束索引 * @return 符合条件的价格高点索引,未找到则返回-1 */ public static int findRecentHighWithRetrace(List<BigDecimal> prices, int startIndex, int endIndex) { if (prices == null || startIndex < 0 || endIndex >= prices.size() || startIndex >= endIndex) { return -1; } int highIndex = -1; BigDecimal highPrice = BigDecimal.ZERO; // 从右向左搜索,找到第一个有效高点 for (int i = endIndex; i >= startIndex; i--) { if (prices.get(i).compareTo(highPrice) > 0) { highPrice = prices.get(i); highIndex = i; } // 检查高点后是否有回调 if (highIndex != -1 && i < endIndex) { if (prices.get(i + 1).compareTo(highPrice) < 0) { return highIndex; // 找到确认回调的高点 } } } return highIndex; } } src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/MACDCalculator.java
@@ -85,7 +85,7 @@ result.add(data); } System.out.println(result.get(result.size() -1)); return new MACDResult(result, startIdx); } @@ -123,14 +123,14 @@ } // 找到最近的价格高点和对应的DIF值 int recentPriceHighIdx = findRecentHighIndex(closePrices, startIdx); if (recentPriceHighIdx < startIdx + 2) { int recentPriceHighIdx = IndicatorUtils.findRecentHighIndex(closePrices, startIdx); if (recentPriceHighIdx < startIdx + 2 || recentPriceHighIdx == -1) { return false; } // 找到之前的价格高点和对应的DIF值 int previousPriceHighIdx = findPreviousHighIndex(closePrices, startIdx, recentPriceHighIdx); if (previousPriceHighIdx < startIdx) { int previousPriceHighIdx = IndicatorUtils.findPreviousHighIndex(closePrices, startIdx, recentPriceHighIdx); if (previousPriceHighIdx < startIdx || previousPriceHighIdx == -1) { return false; } @@ -173,14 +173,14 @@ } // 找到最近的价格低点和对应的DIF值 int recentPriceLowIdx = findRecentLowIndex(closePrices, startIdx); if (recentPriceLowIdx < startIdx + 2) { int recentPriceLowIdx = IndicatorUtils.findRecentLowIndex(closePrices, startIdx); if (recentPriceLowIdx < startIdx + 2 || recentPriceLowIdx == -1) { return false; } // 找到之前的价格低点和对应的DIF值 int previousPriceLowIdx = findPreviousLowIndex(closePrices, startIdx, recentPriceLowIdx); if (previousPriceLowIdx < startIdx) { int previousPriceLowIdx = IndicatorUtils.findPreviousLowIndex(closePrices, startIdx, recentPriceLowIdx); if (previousPriceLowIdx < startIdx || previousPriceLowIdx == -1) { return false; } @@ -202,95 +202,4 @@ return recentPrice.compareTo(previousPrice) < 0 && recentDif.compareTo(previousDif) > 0; } /** * 找到最近的价格高点索引 * * @param prices 价格列表 * @param startIdx 起始索引 * @return 最近的价格高点索引 */ private static int findRecentHighIndex(List<BigDecimal> prices, int startIdx) { int highIdx = startIdx; BigDecimal highPrice = prices.get(startIdx); for (int i = startIdx + 1; i < prices.size(); i++) { BigDecimal currentPrice = prices.get(i); if (currentPrice.compareTo(highPrice) > 0) { highPrice = currentPrice; highIdx = i; } } return highIdx; } /** * 找到最近的价格低点索引 * * @param prices 价格列表 * @param startIdx 起始索引 * @return 最近的价格低点索引 */ private static int findRecentLowIndex(List<BigDecimal> prices, int startIdx) { int lowIdx = startIdx; BigDecimal lowPrice = prices.get(startIdx); for (int i = startIdx + 1; i < prices.size(); i++) { BigDecimal currentPrice = prices.get(i); if (currentPrice.compareTo(lowPrice) < 0) { lowPrice = currentPrice; lowIdx = i; } } return lowIdx; } /** * 找到最近价格高点之前的价格高点索引 * * @param prices 价格列表 * @param startIdx 起始索引 * @param recentHighIdx 最近的价格高点索引 * @return 之前的价格高点索引 */ private static int findPreviousHighIndex(List<BigDecimal> prices, int startIdx, int recentHighIdx) { int highIdx = startIdx; BigDecimal highPrice = prices.get(startIdx); for (int i = startIdx + 1; i < recentHighIdx; i++) { BigDecimal currentPrice = prices.get(i); if (currentPrice.compareTo(highPrice) > 0) { highPrice = currentPrice; highIdx = i; } } return highIdx; } /** * 找到最近价格低点之前的价格低点索引 * * @param prices 价格列表 * @param startIdx 起始索引 * @param recentLowIdx 最近的价格低点索引 * @return 之前的价格低点索引 */ private static int findPreviousLowIndex(List<BigDecimal> prices, int startIdx, int recentLowIdx) { int lowIdx = startIdx; BigDecimal lowPrice = prices.get(startIdx); for (int i = startIdx + 1; i < recentLowIdx; i++) { BigDecimal currentPrice = prices.get(i); if (currentPrice.compareTo(lowPrice) < 0) { lowPrice = currentPrice; lowIdx = i; } } return lowIdx; } } src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/MacdMaStrategy.java
@@ -357,15 +357,13 @@ boolean isGoldenCross = prevPrev.getDif().compareTo(prevPrev.getDea()) <= 0 && previous.getDif().compareTo(previous.getDea()) > 0; boolean isUp = latest.getDif().compareTo(BigDecimal.ZERO) > 0 && latest.getDea().compareTo(BigDecimal.ZERO) > 0; // 柱状线扩张判断:连续正值且绝对值增大 boolean isExpanding = latest.getMacdHist().compareTo(BigDecimal.ZERO) > 0 && previous.getMacdHist().compareTo(BigDecimal.ZERO) > 0 && previous.getMacdHist().abs().compareTo(latest.getMacdHist().abs()) < 0; // 金叉或柱状线扩张任一满足即可 return isGoldenCross && isExpanding && isUp; // 金叉柱状线扩张满足 return isGoldenCross && isExpanding; } /** @@ -390,14 +388,14 @@ } /** * MACD死叉且柱状线收缩检查 * MACD死叉且柱状线扩张检查 * <p> * 条件: * 1. DIF线从上往下穿过DEA线(死叉) * 2. MACD柱状线绝对值减小且为负值(动量减弱) * 2. MACD柱状线绝对值增大且为负值(动量增强) * * @param macdResult MACD计算结果 * @return 是否形成MACD死叉或柱状线收缩 * @return 是否形成MACD死叉且柱状线扩张 */ private boolean isMacdDeathCrossAndContracting(MACDResult macdResult) { List<PriceData> macdData = macdResult.getMacdData(); @@ -413,15 +411,13 @@ boolean isDeathCross = prevPrev.getDif().compareTo(prevPrev.getDea()) >= 0 && previous.getDif().compareTo(previous.getDea()) < 0; boolean isDown = latest.getDif().compareTo(BigDecimal.ZERO) < 0 && latest.getDea().compareTo(BigDecimal.ZERO) < 0; // 优化后的死叉柱状线条件:空头趋势中,死叉应伴随柱状线扩张(绝对值增大) boolean isExpanding = latest.getMacdHist().compareTo(BigDecimal.ZERO) < 0 && previous.getMacdHist().compareTo(BigDecimal.ZERO) < 0 && previous.getMacdHist().abs().compareTo(latest.getMacdHist().abs()) < 0; // 死叉或柱状线收缩任一满足即可 return isDeathCross && isExpanding && isDown; // 死叉且柱状线扩张 return isDeathCross && isExpanding; } /**