From 030e1d50c1f643137220f1ecf1d90ce39174204a Mon Sep 17 00:00:00 2001
From: dd <gitluke@outlook.com>
Date: Sat, 30 May 2026 01:58:54 +0800
Subject: [PATCH] 1

---
 trading-order-huobi/src/main/java/com.yami.trading.huobi/data/internal/RemoteDataServiceImpl.java |  162 +++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 112 insertions(+), 50 deletions(-)

diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/internal/RemoteDataServiceImpl.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/internal/RemoteDataServiceImpl.java
index c97d876..0bca53d 100644
--- a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/internal/RemoteDataServiceImpl.java
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/internal/RemoteDataServiceImpl.java
@@ -11,6 +11,7 @@
 import com.yami.trading.bean.data.domain.Depth;
 import com.yami.trading.bean.data.domain.Trade;
 import com.yami.trading.bean.data.domain.Trend;
+import com.yami.trading.huobi.hobi.HobiDataService;
 import com.yami.trading.service.data.DataService;
 import com.yami.trading.service.item.ItemService;
 import com.yami.trading.service.syspara.SysparaService;
@@ -22,6 +23,7 @@
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 
 @Service("remoteDataService")
 public class RemoteDataServiceImpl implements DataService {
@@ -32,6 +34,8 @@
     private SysparaService sysparaService;
     @Autowired
     private KlineService klineService;
+    @Autowired
+    private HobiDataService hobiDataService;
 
     @Override
     public List<Realtime> realtime(String symbols) {
@@ -73,6 +77,10 @@
 
     @Override
     public List<Kline> kline(String symbol, String line) {
+        Item bySymbol = itemService.findBySymbol(symbol);
+        if(Item.cryptos.equals(bySymbol.getType())){
+            return klineCryptos(symbol, line);
+        }
         KlineTimeObject timeObject = DataCache.getKline(symbol, line);
         List<Kline> list = new ArrayList<Kline>();
         if (timeObject != null) {
@@ -81,7 +89,7 @@
         List<Kline> list_clone = new ArrayList<Kline>();
         try {
             for (int i = 0; i < list.size(); i++) {
-                if (list.get(i) == null) {
+                if(list.get(i) == null){
                     continue;
                 }
                 Kline kline = (Kline) list.get(i).clone();
@@ -91,62 +99,116 @@
             e.printStackTrace();
         }
 
+        appendInProgressKline(list_clone, symbol, line);
+        // 按时间升序
+        Collections.sort(list_clone);
+        return list_clone;
+
+    }
+
+    public List<Kline> klineCryptos(String symbol, String line) {
+        KlineTimeObject timeObject = DataCache.getKline(symbol, line);
+        List<Kline> list = new ArrayList<Kline>();
+        if (timeObject != null) {
+            list = timeObject.getKline();
+        }
+        List<Kline> list_clone = new ArrayList<Kline>();
+        try {
+            for (int i = 0; i < list.size(); i++) {
+                Kline kline = (Kline) list.get(i).clone();
+                list_clone.add(kline);
+            }
+        } catch (CloneNotSupportedException e) {
+            e.printStackTrace();
+        }
+        // 火币 K 线倒序返回,缓存仅含已收盘 K 线;补拉最新一根未收盘 K 线
+        boolean mergedFromHobi = false;
+        Item item = itemService.findBySymbol(symbol);
+        if (item != null) {
+            List<Kline> latestKlines = hobiDataService.kline(item.getSymbol(), line, 1);
+            if (!latestKlines.isEmpty()) {
+                try {
+                    Kline latest = (Kline) latestKlines.get(0).clone();
+                    latest.setSymbol(symbol);
+                    latest.setPeriod(line);
+                    mergeLatestKline(list_clone, latest);
+                    mergedFromHobi = true;
+                } catch (CloneNotSupportedException e) {
+                    Kline latest = latestKlines.get(0);
+                    latest.setSymbol(symbol);
+                    latest.setPeriod(line);
+                    mergeLatestKline(list_clone, latest);
+                    mergedFromHobi = true;
+                }
+            }
+        }
+        if (!mergedFromHobi) {
+            appendInProgressKline(list_clone, symbol, line);
+        }
+        Collections.sort(list_clone); // 按时间升序
+        return list_clone;
+
+    }
+
+    /**
+     * 合并最新 K 线:同时间戳则更新(未收盘 K 线持续变化),否则追加。
+     */
+    private void mergeLatestKline(List<Kline> list, Kline latest) {
+        if (latest == null || latest.getTs() == null) {
+            return;
+        }
+        if (list.isEmpty()) {
+            list.add(latest);
+            return;
+        }
+        Kline last = list.get(list.size() - 1);
+        if (Objects.equals(last.getTs(), latest.getTs())) {
+            list.set(list.size() - 1, latest);
+        } else if (last.getTs() < latest.getTs()) {
+            list.add(latest);
+        }
+    }
+
+    /**
+     * 基于实时行情聚合当前周期未收盘 K 线(非加密货币等场景兜底)。
+     */
+    private void appendInProgressKline(List<Kline> list, String symbol, String line) {
         Realtime realtime = DataCache.getLatestRealTime(symbol);
         if (realtime == null) {
             realtime = DataCache.getRealtime(symbol);
         }
-        if (realtime != null) {
-            appendOrReplaceKline(list_clone, buildCurrentKline(realtime, line));
-        }
-        Collections.sort(list_clone);
-        return list_clone;
-    }
-
-    private Kline buildCurrentKline(Realtime realtime, String line) {
-        if (KlineConstant.PERIOD_1MIN.equals(line)) {
-            return klineService.bulidKline1Minute(realtime, KlineConstant.PERIOD_1MIN);
-        } else if (KlineConstant.PERIOD_5MIN.equals(line)) {
-            return klineService.bulidKline5Minute(realtime, KlineConstant.PERIOD_5MIN);
-        } else if (KlineConstant.PERIOD_15MIN.equals(line)) {
-            return klineService.bulidKline15Minute(realtime, KlineConstant.PERIOD_15MIN);
-        } else if (KlineConstant.PERIOD_30MIN.equals(line)) {
-            return klineService.bulidKline30Minute(realtime, KlineConstant.PERIOD_30MIN);
-        } else if (KlineConstant.PERIOD_60MIN.equals(line)) {
-            return klineService.bulidKline60Minute(realtime, KlineConstant.PERIOD_60MIN);
-        } else if (KlineConstant.PERIOD_4HOUR.equals(line)) {
-            return klineService.bulidKline4Hour(realtime, KlineConstant.PERIOD_4HOUR);
-        } else if (KlineConstant.PERIOD_1DAY.equals(line)) {
-            return klineService.bulidKline1Day(realtime, KlineConstant.PERIOD_1DAY);
-        } else if (KlineConstant.PERIOD_5DAY.equals(line)) {
-            return klineService.bulidKline5Day(realtime, KlineConstant.PERIOD_5DAY);
-        } else if (KlineConstant.PERIOD_1WEEK.equals(line)) {
-            return klineService.bulidKline1Week(realtime, KlineConstant.PERIOD_1WEEK);
-        } else if (KlineConstant.PERIOD_1MON.equals(line)) {
-            return klineService.bulidKline1Mon(realtime, KlineConstant.PERIOD_1MON);
-        } else if (KlineConstant.PERIOD_QUARTER.equals(line)) {
-            return klineService.bulidKlineQuarter(realtime, KlineConstant.PERIOD_QUARTER);
-        } else if (KlineConstant.PERIOD_YEAR.equals(line)) {
-            return klineService.bulidKlineYear(realtime, KlineConstant.PERIOD_YEAR);
-        }
-        return null;
-    }
-
-    public List<Kline> klineCryptos(String symbol, String line) {
-        return kline(symbol, line);
-    }
-
-    private void appendOrReplaceKline(List<Kline> list, Kline kline) {
-        if (kline == null) {
+        if (realtime == null) {
             return;
         }
-        for (int i = list.size() - 1; i >= 0; i--) {
-            Kline existing = list.get(i);
-            if (existing.getTs() != null && existing.getTs().equals(kline.getTs())) {
-                list.set(i, kline);
-                return;
-            }
+        Kline kline = null;
+        if (KlineConstant.PERIOD_1MIN.equals(line)) {
+            kline = klineService.bulidKline1Minute(realtime, KlineConstant.PERIOD_1MIN);
+        } else if (KlineConstant.PERIOD_5MIN.equals(line)) {
+            kline = klineService.bulidKline5Minute(realtime, KlineConstant.PERIOD_5MIN);
+        } else if (KlineConstant.PERIOD_15MIN.equals(line)) {
+            kline = klineService.bulidKline15Minute(realtime, KlineConstant.PERIOD_15MIN);
+        } else if (KlineConstant.PERIOD_30MIN.equals(line)) {
+            kline = klineService.bulidKline30Minute(realtime, KlineConstant.PERIOD_30MIN);
+        } else if (KlineConstant.PERIOD_60MIN.equals(line)) {
+            kline = klineService.bulidKline60Minute(realtime, KlineConstant.PERIOD_60MIN);
+        } else if (KlineConstant.PERIOD_4HOUR.equals(line)) {
+            kline = klineService.bulidKline4Hour(realtime, KlineConstant.PERIOD_4HOUR);
+        } else if (KlineConstant.PERIOD_1DAY.equals(line)) {
+            kline = klineService.bulidKline1Day(realtime, KlineConstant.PERIOD_1DAY);
+        } else if (KlineConstant.PERIOD_5DAY.equals(line)) {
+            kline = klineService.bulidKline5Day(realtime, KlineConstant.PERIOD_5DAY);
+        } else if (KlineConstant.PERIOD_1WEEK.equals(line)) {
+            kline = klineService.bulidKline1Week(realtime, KlineConstant.PERIOD_1WEEK);
+        } else if (KlineConstant.PERIOD_1MON.equals(line)) {
+            kline = klineService.bulidKline1Mon(realtime, KlineConstant.PERIOD_1MON);
+        } else if (KlineConstant.PERIOD_QUARTER.equals(line)) {
+            kline = klineService.bulidKline1Mon(realtime, KlineConstant.PERIOD_QUARTER);
+        } else if (KlineConstant.PERIOD_YEAR.equals(line)) {
+            kline = klineService.bulidKline1Mon(realtime, KlineConstant.PERIOD_YEAR);
         }
-        list.add(kline);
+        if (kline != null) {
+            mergeLatestKline(list, kline);
+        }
     }
 
     @Override

--
Gitblit v1.9.3