From 4884ebffeed775d63dbf7bb7d0ece8182f10c344 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Fri, 26 Dec 2025 18:19:46 +0800
Subject: [PATCH] fix(okxNewPrice): 解决交易订单为空时的空指针异常
---
src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/BullishSignalDetector.java | 87 +++++++++++++++++++++++++++++++++++++++++++
1 files changed, 87 insertions(+), 0 deletions(-)
diff --git a/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/BullishSignalDetector.java b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/BullishSignalDetector.java
new file mode 100644
index 0000000..b6265e6
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/okxNewPrice/indicator/macdAndMatrategy/BullishSignalDetector.java
@@ -0,0 +1,87 @@
+package com.xcong.excoin.modules.okxNewPrice.indicator.macdAndMatrategy;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 示例用法
+ * // 计算MACD结果(包含起始索引)
+ * MACDCalculator.MACDResult macdResult = MACDCalculator.calculateMACD(closePrices, 12, 26, 9);
+ *
+ * // 检测做多信号
+ * boolean bullishSignal = BullishSignalDetector.isBullishSignalFormed(macdResult, closePrices);
+ */
+public class BullishSignalDetector {
+ public static boolean isBullishSignalFormed(MACDResult macdResult, List<BigDecimal> closePrices) {
+ List<PriceData> macdData = macdResult.getMacdData();
+ int startIdx = macdResult.getStartIndex();
+
+ // 校验MACD数据和收盘价长度合法性
+ if (closePrices.size() < 34 || macdData.size() < 2 || startIdx + macdData.size() > closePrices.size()) {
+ return false;
+ }
+
+ int currentMacdIndex = macdData.size() - 1;
+ int currentCloseIndex = startIdx + currentMacdIndex;
+
+ // 1. 金叉判断
+ boolean isGoldenCross = isGoldenCross(macdData, currentMacdIndex);
+
+ // 2. MACD柱动量增强
+ boolean isMacdHistExpanding = isMacdHistExpanding(macdData, currentMacdIndex);
+
+ // 3. 价格突破前15周期高点
+ boolean isPriceBreakout = isPriceBreakout(closePrices, currentCloseIndex, 15);
+
+ return isGoldenCross && isMacdHistExpanding && isPriceBreakout;
+ }
+
+ private static boolean isGoldenCross(List<PriceData> macdData, int currentMacdIndex) {
+ if (currentMacdIndex < 1 || currentMacdIndex >= macdData.size()) {
+ return false;
+ }
+
+ PriceData current = macdData.get(currentMacdIndex);
+ PriceData previous = macdData.get(currentMacdIndex - 1);
+
+ return previous.getDif().compareTo(previous.getDea()) <= 0 &&
+ current.getDif().compareTo(current.getDea()) > 0;
+ }
+
+ private static boolean isMacdHistExpanding(List<PriceData> macdData, int currentMacdIndex) {
+ if (currentMacdIndex < 2 || currentMacdIndex >= macdData.size()) {
+ return false;
+ }
+
+ BigDecimal currentHist = macdData.get(currentMacdIndex).getMacdHist();
+ BigDecimal prevHist = macdData.get(currentMacdIndex - 1).getMacdHist();
+ BigDecimal prevPrevHist = macdData.get(currentMacdIndex - 2).getMacdHist();
+
+ boolean isPositive = currentHist.compareTo(BigDecimal.ZERO) > 0;
+ boolean isExpanding = prevPrevHist.compareTo(prevHist) <= 0 &&
+ prevHist.compareTo(currentHist) < 0;
+
+ return isPositive && isExpanding;
+ }
+
+ private static boolean isPriceBreakout(List<BigDecimal> closePrices, int currentCloseIndex, int period) {
+ if (currentCloseIndex < period || period <= 0) {
+ return false;
+ }
+
+ int startSearchIdx = Math.max(currentCloseIndex - period, 0);
+ BigDecimal maxPreviousPrice = closePrices.get(startSearchIdx);
+
+ for (int i = startSearchIdx + 1; i < currentCloseIndex; i++) {
+ if (i >= closePrices.size()) {
+ break;
+ }
+ BigDecimal price = closePrices.get(i);
+ if (price.compareTo(maxPreviousPrice) > 0) {
+ maxPreviousPrice = price;
+ }
+ }
+
+ return closePrices.get(currentCloseIndex).compareTo(maxPreviousPrice) > 0;
+ }
+}
\ No newline at end of file
--
Gitblit v1.9.1