From d4be4cc69f18b01cc39bd3f9dc9497a828848ca8 Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Tue, 30 Sep 2025 11:18:44 +0800
Subject: [PATCH] 1

---
 trading-order-service/src/main/java/com/yami/trading/service/impl/WithdrawServiceImpl.java                      |   38 +
 trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/ETFResponse.java                            |   19 +
 trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/RealTimeData.java                           |   35 ++
 trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWalletController.java                      |    8 
 trading-order-admin/src/main/resources/application-prod.yml                                                     |    2 
 trading-order-admin/src/main/resources/redisson/redisson-dev.yml                                                |    2 
 trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java |   19 
 trading-order-bean/src/main/java/com/yami/trading/bean/item/domain/Item.java                                    |    2 
 trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/RealTimeResponse.java                       |   19 +
 trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/StockGetMarketJob.java                        |    6 
 trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/XinLangDataServiceImpl.java              |   20 
 trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/XueQiuDataServiceImpl.java               |  371 +++++++++++++++++-----
 trading-order-admin/src/main/java/com/yami/trading/admin/task/InitHandle.java                                   |    5 
 trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiCapitaltWalletWalletController.java        |    8 
 trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWithdrawController.java                    |   15 
 trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/ETFData.java                                |   30 +
 trading-order-service/src/main/java/com/yami/trading/service/user/impl/UserStatisticsServiceImpl.java           |    6 
 trading-order-service/src/main/java/com/yami/trading/service/item/ItemService.java                              |    2 
 trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/ETFDataSynchronizationJob.java                |  272 +++++++++++++++++
 trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/StockGetDataJob.java                          |   25 
 trading-order-service/src/main/java/com/yami/trading/service/impl/RechargeBlockchainOrderServiceImpl.java       |   13 
 trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java   |   20 
 22 files changed, 764 insertions(+), 173 deletions(-)

diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/task/InitHandle.java b/trading-order-admin/src/main/java/com/yami/trading/admin/task/InitHandle.java
index 33444ae..65c5759 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/admin/task/InitHandle.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/task/InitHandle.java
@@ -112,6 +112,7 @@
         // todo 先注释观察报错
 //		futuresRecomConsumeServer.start();
         log.info("开始Data初始化........");
+        stockGetDataJob.start();
         List<Item> items = itemService.list();
         for (Item item : items) {
             AdjustmentValueCache.getCurrentValue().put(item.getSymbol(), item.getAdjustmentValue());
@@ -135,9 +136,9 @@
          klineInitService.klineInit(symbols);
         // 高低修正
         highLowHandleJob.start();
-        stockGetMarketJob.start();
+//        stockGetMarketJob.start();
 //        // 获取realtime实时数据
-        stockGetDataJob.start();
+
 //        forexGetDataJob.start(); 外汇
         cryptosGetDataJob.start();
         fakeSymbolGetDataJob.start();
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiCapitaltWalletWalletController.java b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiCapitaltWalletWalletController.java
index e0811c2..fd404e5 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiCapitaltWalletWalletController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiCapitaltWalletWalletController.java
@@ -92,8 +92,8 @@
         // 获取合约账户(contract)
         Wallet wallet = walletService.saveWalletByPartyId(partyId);
         // 获取资金账户(capital)
-        CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
-                .eq(CapitaltWallet::getUserId, partyId).last(" limit 1 "));
+//        CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
+//                .eq(CapitaltWallet::getUserId, partyId).last(" limit 1 "));
         List<WalletExtend> walletExtends = walletExtendService.findByUserId(partyId);
         AtomicReference<BigDecimal> walletExtendMoneyRef = new AtomicReference<>(BigDecimal.ZERO);
         walletExtends.forEach(f -> {
@@ -107,8 +107,8 @@
         Map<String, BigDecimal> assets =  new HashMap<>();
 
         assets.put("contract",wallet.getMoney().setScale(2,RoundingMode.DOWN));
-        assets.put("capital",capitaltWallet.getMoney().add(walletExtendMoney).setScale(2,RoundingMode.DOWN));
-        assets.put("capitalUSDT",capitaltWallet.getMoney());//划转专用
+//        assets.put("capital",capitaltWallet.getMoney().add(walletExtendMoney).setScale(2,RoundingMode.DOWN));
+//        assets.put("capitalUSDT",capitaltWallet.getMoney());//划转专用
         return Result.succeed(assets);
     }
 }
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWalletController.java b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWalletController.java
index 75bb105..b90503b 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWalletController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWalletController.java
@@ -215,13 +215,13 @@
         df2.setRoundingMode(RoundingMode.FLOOR);
         // String partyId ="dcc0dd35a49c383dadabc4dc030afe70";
         String partyId = SecurityUtils.getCurrentUserId();
-        CapitaltWallet usdt = null;
+        Wallet usdt = null;
         if (StringUtils.isNotEmpty(partyId)) {
-//            usdt = this.walletService.saveWalletByPartyId(partyId);
-            usdt = capitaltWalletService.getUserIdWallet(partyId);
+            usdt = this.walletService.saveWalletByPartyId(partyId);
+//            usdt = capitaltWalletService.getUserIdWallet(partyId);
         }
         if (null == usdt) {
-            usdt = new CapitaltWallet();
+            usdt = new Wallet();
             usdt.setMoney(new BigDecimal(0));
             usdt.setLockMoney(new BigDecimal(0));
             usdt.setFreezeMoney(new BigDecimal(0));
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWithdrawController.java b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWithdrawController.java
index 9b16eb1..15074a2 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWithdrawController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWithdrawController.java
@@ -3,6 +3,7 @@
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.yami.trading.bean.model.CapitaltWallet;
 import com.yami.trading.bean.model.User;
+import com.yami.trading.bean.model.Wallet;
 import com.yami.trading.bean.model.Withdraw;
 import com.yami.trading.common.constants.Constants;
 import com.yami.trading.common.domain.Result;
@@ -13,6 +14,7 @@
 import com.yami.trading.security.common.util.SecurityUtils;
 import com.yami.trading.service.CapitaltWalletService;
 import com.yami.trading.service.SessionTokenService;
+import com.yami.trading.service.WalletService;
 import com.yami.trading.service.WithdrawService;
 import com.yami.trading.service.syspara.SysparaService;
 import com.yami.trading.service.user.UserService;
@@ -50,6 +52,8 @@
     protected WalletLogService walletLogService;
     @Autowired
     CapitaltWalletService capitaltWalletService;
+    @Autowired
+    WalletService walletService;
 
     /**
      * 首次进入页面,传递session_token
@@ -111,9 +115,14 @@
 
         // 获取资金账户(capital)
         if(channel.contains("USDT")){
-            CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
-                    .eq(CapitaltWallet::getUserId, partyId).last(" limit 1 "));
-            if(capitaltWallet.getMoney().compareTo(new BigDecimal(amount)) < 0){
+//            CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
+//                    .eq(CapitaltWallet::getUserId, partyId).last(" limit 1 "));
+//            if(capitaltWallet.getMoney().compareTo(new BigDecimal(amount)) < 0){
+//                throw new YamiShopBindException("Insufficient available balance for withdrawal!");
+//            }
+            Wallet wallet = walletService.getOne(new LambdaQueryWrapper<>(Wallet.class)
+                    .eq(Wallet::getUserId, partyId).last(" limit 1 "));
+            if(wallet.getMoney().compareTo(new BigDecimal(amount)) < 0){
                 throw new YamiShopBindException("Insufficient available balance for withdrawal!");
             }
         }
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java b/trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java
index bd8f0ac..1e1bcfb 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java
@@ -109,13 +109,14 @@
         Map<String, Object> parities = parities(symbol, symbol_to, volume_temp);
         Object getVolume = parities.get("get_volume");
         if(symbol.equals("usdt")){
-            CapitaltWallet userIdWallet = capitaltWalletService.getUserIdWallet(partyId);
+            Wallet userIdWallet = walletService.saveWalletByPartyId(partyId);
+//            CapitaltWallet userIdWallet = capitaltWalletService.getUserIdWallet(partyId);
             if(userIdWallet.getMoney().compareTo(new BigDecimal(volume_temp)) < 0){
                 throw new YamiShopBindException("not sufficient funds");
             }
             Double value = Double.valueOf(volume_temp);
-            capitaltWalletService.update(userIdWallet,  -value);
-
+//            capitaltWalletService.update(userIdWallet,  -value);
+            walletService.update(userIdWallet.getUserId(),  -value);
             WalletExtend walletExtend = walletExtendService.getOne(new LambdaQueryWrapper<>(WalletExtend.class)
                     .eq(WalletExtend::getWallettype, symbol_to)
                             .eq(WalletExtend::getPartyId,partyId)
@@ -147,8 +148,10 @@
             walletExtendService.update(walletExtend,new LambdaUpdateWrapper<WalletExtend>().eq(UUIDEntity::getUuid,walletExtend.getUuid()));
 
 
-            CapitaltWallet userIdWallet = capitaltWalletService.getUserIdWallet(partyId);
-            capitaltWalletService.update(userIdWallet,Double.valueOf(getVolume.toString()));
+//            CapitaltWallet userIdWallet = capitaltWalletService.getUserIdWallet(partyId);
+//            capitaltWalletService.update(userIdWallet,Double.valueOf(getVolume.toString()));
+            Wallet userIdWallet = walletService.saveWalletByPartyId(partyId);
+            walletService.update(userIdWallet.getUserId(),Double.valueOf(getVolume.toString()));
         }else{
             WalletExtend walletExtend = walletExtendService.getOne(new LambdaQueryWrapper<>(WalletExtend.class)
                     .eq(WalletExtend::getWallettype, symbol)
@@ -374,12 +377,12 @@
     public Result openview() {
         Map<String, Object> data = new HashMap<String, Object>();
         String partyId = SecurityUtils.getUser().getUserId();
-//        Wallet wallet = walletService.saveWalletByPartyId(partyId);
-        CapitaltWallet userIdWallet = capitaltWalletService.getUserIdWallet(partyId);
+        Wallet wallet = walletService.saveWalletByPartyId(partyId);
+//        CapitaltWallet userIdWallet = capitaltWalletService.getUserIdWallet(partyId);
         // 账户剩余资金
         DecimalFormat df = new DecimalFormat("#.##");
         df.setRoundingMode(RoundingMode.FLOOR);// 向下取整
-        data.put("volume", df.format(userIdWallet.getMoney()));
+        data.put("volume", df.format(wallet.getMoney()));
         String session_token = sessionTokenService.savePut(partyId);
         data.put("session_token", session_token);
         data.put("fee", sysparaService.find("exchange_apply_order_buy_fee").getSvalue());
diff --git a/trading-order-admin/src/main/resources/application-prod.yml b/trading-order-admin/src/main/resources/application-prod.yml
index c292727..783234e 100644
--- a/trading-order-admin/src/main/resources/application-prod.yml
+++ b/trading-order-admin/src/main/resources/application-prod.yml
@@ -49,4 +49,4 @@
         maxIdle: 20
         maxTotal: 50
       host: 127.0.0.1
-      port: 6379
+      port: 6380
diff --git a/trading-order-admin/src/main/resources/redisson/redisson-dev.yml b/trading-order-admin/src/main/resources/redisson/redisson-dev.yml
index c76245f..603a29c 100644
--- a/trading-order-admin/src/main/resources/redisson/redisson-dev.yml
+++ b/trading-order-admin/src/main/resources/redisson/redisson-dev.yml
@@ -1,6 +1,6 @@
 # 单节点设置
 singleServerConfig:
-  address: redis://127.0.0.1:6379
+  address: redis://127.0.0.1:6380
   database: 0
   password:
   idleConnectionTimeout: 10000
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/item/domain/Item.java b/trading-order-bean/src/main/java/com/yami/trading/bean/item/domain/Item.java
index b916445..91d75af 100644
--- a/trading-order-bean/src/main/java/com/yami/trading/bean/item/domain/Item.java
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/item/domain/Item.java
@@ -30,7 +30,7 @@
      */
     public final static String forex = "forex";
     /**
-     * 指数
+     * etf
      */
     public final static String indices = "indices";
 
diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/ETFDataSynchronizationJob.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/ETFDataSynchronizationJob.java
new file mode 100644
index 0000000..ee40771
--- /dev/null
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/ETFDataSynchronizationJob.java
@@ -0,0 +1,272 @@
+package com.yami.trading.huobi.data.job;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.yami.trading.bean.item.domain.Item;
+import com.yami.trading.huobi.data.model.ETFData;
+import com.yami.trading.huobi.data.model.ETFResponse;
+import com.yami.trading.huobi.data.model.RealTimeData;
+import com.yami.trading.huobi.data.model.RealTimeResponse;
+import com.yami.trading.service.item.ItemService;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.checkerframework.checker.units.qual.A;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.*;
+
+/**
+ * @program: trading-order-master
+ * @description:
+ * @create: 2025-09-28 11:20
+ **/
+@Slf4j
+@Component
+public class ETFDataSynchronizationJob {
+
+    @Autowired
+    private ItemService itemService;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    private static final String LIST_API_URL = "https://www.tsanghi.com/api/fin/etf/XNAS/list?token=9668db3503214cd19a831a9f866923b9";
+    private static final String REALTIME_API_URL = "https://www.tsanghi.com/api/fin/etf/XNAS/realtime?token=9668db3503214cd19a831a9f866923b9&ticker=";
+
+    /**
+     * 同步ETF数据定时任务
+     */
+//    @Scheduled(cron = "0 * * * * ?")
+    public void syncETFData() {
+        try {
+            log.info("开始同步ETF数据...");
+
+            // 获取ETF列表
+            List<ETFData> etfList = getETFList();
+            if (etfList == null || etfList.isEmpty()) {
+                log.warn("未获取到ETF列表数据");
+                return;
+            }
+
+            log.info("共获取到{}个ETF数据", etfList.size());
+
+            int successCount = 0;
+            int errorCount = 0;
+
+            // 处理每个ETF
+            for (ETFData etf : etfList) {
+                try {
+                    if (processETFItem(etf)) {
+                        successCount++;
+                    } else {
+                        errorCount++;
+                    }
+                } catch (Exception e) {
+                    log.error("处理ETF {} 时发生错误: {}", etf.getTicker(), e.getMessage());
+                    errorCount++;
+                }
+            }
+
+            log.info("ETF数据同步完成: 成功 {}, 失败 {}", successCount, errorCount);
+
+        } catch (Exception e) {
+            log.error("同步ETF数据时发生错误: {}", e.getMessage(), e);
+        }
+    }
+
+    /**
+     * 获取ETF列表
+     */
+    private List<ETFData> getETFList() {
+        try {
+            ResponseEntity<ETFResponse> response = restTemplate.exchange(
+                    LIST_API_URL,
+                    HttpMethod.GET,
+                    null,
+                    ETFResponse.class
+            );
+
+            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
+                ETFResponse apiResponse = response.getBody();
+                if (apiResponse.getCode() == 200) {
+                    return apiResponse.getData();
+                } else {
+                    log.error("API返回错误: {} - {}", apiResponse.getCode(), apiResponse.getMsg());
+                }
+            }
+        } catch (Exception e) {
+            log.error("获取ETF列表失败: {}", e.getMessage(), e);
+        }
+        return null;
+    }
+
+    /**
+     * 处理单个ETF项目
+     */
+    private boolean processETFItem(ETFData etf) {
+        // 只处理活跃的ETF
+        if (etf.getIsActive() == null || etf.getIsActive() != 1) {
+            log.info("跳过非活跃ETF: {}", etf.getTicker());
+            return false;
+        }
+
+        // 检查是否已存在
+        Item existingItem = itemService.getOne(new LambdaQueryWrapper<Item>()
+                .eq(Item::getSymbol,etf.getTicker())
+        );
+        if (existingItem != null) {
+            log.info("ETF {} 已存在,跳过", etf.getTicker());
+            return true;
+        }
+
+        // 获取实时数据计算小数位
+        RealTimeData realtimeData = getRealtimeData(etf.getTicker());
+        if (realtimeData == null) {
+            log.warn("无法获取ETF {} 的实时数据", etf.getTicker());
+            return false;
+        }
+
+        // 创建Item对象
+        Item item = createItemFromETFData(etf, realtimeData);
+
+        // 保存到数据库
+            return itemService.save(item);
+    }
+
+    /**
+     * 获取实时数据
+     */
+    private RealTimeData getRealtimeData(String ticker) {
+        try {
+            String url = REALTIME_API_URL + ticker;
+            ResponseEntity<RealTimeResponse> response = restTemplate.exchange(
+                    url,
+                    HttpMethod.GET,
+                    null,
+                    RealTimeResponse.class
+            );
+
+            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
+                RealTimeResponse apiResponse = response.getBody();
+                if (apiResponse.getCode() == 200) {
+                    return apiResponse.getData().get(0);
+                }
+            }
+        } catch (Exception e) {
+            log.error("获取ETF {} 实时数据失败: {}", ticker, e.getMessage());
+        }
+        return null;
+    }
+
+    /**
+     * 根据收盘价计算小数位数和PIPS
+     */
+    private ETFDecimalInfo calculateDecimalInfo(BigDecimal closePrice) {
+        ETFDecimalInfo info = new ETFDecimalInfo();
+
+        if (closePrice == null) {
+            // 默认值
+            info.setDecimals(2);
+            info.setPips(new BigDecimal("0.01"));
+            info.setPipsAmount(new BigDecimal("0.01"));
+            return info;
+        }
+
+        try {
+            String priceStr = closePrice.stripTrailingZeros().toPlainString();
+            int decimalPlaces = 0;
+
+            // 查找小数点位置
+            int dotIndex = priceStr.indexOf('.');
+            if (dotIndex != -1) {
+                // 计算实际的小数位数(去除末尾的0)
+                decimalPlaces = priceStr.length() - dotIndex - 1;
+            }
+
+            // 设置小数位数,至少为2位
+            int decimals = Math.max(decimalPlaces, 2);
+            info.setDecimals(decimals);
+
+            // 计算PIPS(最小价格单位)
+            BigDecimal pips = BigDecimal.ONE.divide(
+                    BigDecimal.TEN.pow(decimals),
+                    decimals,
+                    RoundingMode.HALF_UP
+            );
+
+            info.setPips(pips);
+            info.setPipsAmount(pips);
+
+        } catch (Exception e) {
+            log.error("计算小数位信息失败,使用默认值", e);
+            info.setDecimals(2);
+            info.setPips(new BigDecimal("0.01"));
+            info.setPipsAmount(new BigDecimal("0.01"));
+        }
+
+        return info;
+    }
+
+    /**
+     * 创建Item对象
+     */
+    private Item createItemFromETFData(ETFData etf, RealTimeData realtimeData) {
+        Item item = new Item();
+
+        // 生成UUID
+        String uuid = UUID.randomUUID().toString().replace("-", "");
+        item.setUuid(uuid);
+
+        // 基础信息
+        item.setName(etf.getName());
+        item.setEnName(etf.getName());
+        item.setSymbol(etf.getTicker());
+        item.setSymbolData(etf.getTicker());
+        item.setSymbolFullName(etf.getName());
+
+        // 计算小数位信息
+        item.setDecimals(2);
+        item.setPips(new BigDecimal("0.01"));
+        item.setPipsAmount(new BigDecimal("0.01"));
+
+        // 固定值设置
+        item.setAdjustmentValue(BigDecimal.ZERO);
+        item.setUnitAmount(new BigDecimal("1000"));
+        item.setUnitFee(new BigDecimal("30"));
+        item.setMarket("indices");
+        item.setMultiple(BigDecimal.ZERO);
+        item.setBorrowingRate(BigDecimal.ZERO);
+        item.setType("indices");
+        item.setCategory("Miscellaneous");
+        item.setSorted("100");
+        item.setOpenCloseType("indices");
+        item.setFake("0");
+        item.setShowStatus("1");
+        item.setTradeStatus("1");
+        item.setQuoteCurrency("USDT");
+        item.setFaceValue(0.01);
+
+        // 创建时间和更新时间
+        item.setCreateTime(new Date());
+        item.setUpdateTime(new Date());
+
+        return item;
+    }
+
+    /**
+     * 小数位信息辅助类
+     */
+    @Data
+    private static class ETFDecimalInfo {
+        private Integer decimals;
+        private BigDecimal pips;
+        private BigDecimal pipsAmount;
+    }
+}
diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/StockGetDataJob.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/StockGetDataJob.java
index 5bd7517..8a715f5 100644
--- a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/StockGetDataJob.java
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/StockGetDataJob.java
@@ -2,9 +2,11 @@
 
 
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.yami.trading.bean.data.domain.Realtime;
 import com.yami.trading.bean.data.domain.StockMarket;
 import com.yami.trading.bean.item.domain.Item;
+import com.yami.trading.common.domain.BaseEntity;
 import com.yami.trading.common.util.*;
 import com.yami.trading.huobi.data.AdjustmentValueCache;
 import com.yami.trading.huobi.data.DataCache;
@@ -64,23 +66,24 @@
         }
         while (true) {
             try {
-                List<Item> list = itemService.list().stream().filter(i->"0".equalsIgnoreCase(i.getFake())).collect(Collectors.toList());
+                List<Item> list = itemService.list(new LambdaQueryWrapper<>(Item.class).eq(BaseEntity::getDelFlag,0)).stream().filter(i->"0".equalsIgnoreCase(i.getFake())).collect(Collectors.toList());
                 // etf 和A股开盘时间是一样的
-                String aStocSymbols = list.stream().filter(item ->item.getOpenCloseType() != null &&  item.getOpenCloseType().equalsIgnoreCase(Item.A_STOCKS))
-                        .map(Item::getSymbol).collect(Collectors.joining(","));
-                String hkStocSymbols = list.stream().filter(item -> item.getOpenCloseType() != null &&item.getOpenCloseType().equalsIgnoreCase(Item.HK_STOCKS)).map(Item::getSymbol).collect(Collectors.joining(","));
+//                String aStocSymbols = list.stream().filter(item ->item.getOpenCloseType() != null &&  item.getOpenCloseType().equalsIgnoreCase(Item.A_STOCKS))
+//                        .map(Item::getSymbol).collect(Collectors.joining(","));
+//                String hkStocSymbols = list.stream().filter(item -> item.getOpenCloseType() != null &&item.getOpenCloseType().equalsIgnoreCase(Item.HK_STOCKS)).map(Item::getSymbol).collect(Collectors.joining(","));
                 String usStocSymbols = list.stream().filter(item -> item.getOpenCloseType() != null &&item.getOpenCloseType().equalsIgnoreCase(Item.US_STOCKS)).map(Item::getSymbol).collect(Collectors.joining(","));
+                String indicesymbols = list.stream().filter(item -> item.getOpenCloseType() != null &&item.getOpenCloseType().equalsIgnoreCase(Item.indices)).map(Item::getSymbol).collect(Collectors.joining(","));
                 if(stockFirstFetch){
-                    this.realtimeHandle(aStocSymbols);
-                    this.realtimeHandle(hkStocSymbols);
+//                    this.realtimeHandle(aStocSymbols);
+                    this.realtimeHandle(indicesymbols);
                     this.realtimeHandle(usStocSymbols);
                     stockFirstFetch = false;
                 }
-                if(MarketOpenChecker.isMarketOpen(Item.A_STOCKS)){
-                    this.realtimeHandle(aStocSymbols);
-                }
-                if(MarketOpenChecker.isMarketOpen(Item.HK_STOCKS)){
-                    this.realtimeHandle(hkStocSymbols);
+//                if(MarketOpenChecker.isMarketOpen(Item.A_STOCKS)){
+//                    this.realtimeHandle(aStocSymbols);
+//                }
+                if(MarketOpenChecker.isMarketOpen(Item.indices)){
+                    this.realtimeHandle(indicesymbols);
                 }
                 if(MarketOpenChecker.isMarketOpen(Item.US_STOCKS)){
                     this.realtimeHandle(usStocSymbols);
diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/StockGetMarketJob.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/StockGetMarketJob.java
index 5976886..47b198d 100644
--- a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/StockGetMarketJob.java
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/job/StockGetMarketJob.java
@@ -58,10 +58,10 @@
             try {
                 List<Item> list = itemService.list().stream().filter(i -> "0".equalsIgnoreCase(i.getFake())).collect(Collectors.toList());
                 // etf 和A股开盘时间是一样的
-                String aStocSymbols = list.stream().filter(item -> item.getOpenCloseType() != null && item.getOpenCloseType().equalsIgnoreCase(Item.A_STOCKS)).map(Item::getSymbol).collect(Collectors.joining(","));
-                String hkStocSymbols = list.stream().filter(item -> item.getOpenCloseType() != null && item.getOpenCloseType().equalsIgnoreCase(Item.HK_STOCKS)).map(Item::getSymbol).collect(Collectors.joining(","));
+//                String aStocSymbols = list.stream().filter(item -> item.getOpenCloseType() != null && item.getOpenCloseType().equalsIgnoreCase(Item.A_STOCKS)).map(Item::getSymbol).collect(Collectors.joining(","));
+//                String hkStocSymbols = list.stream().filter(item -> item.getOpenCloseType() != null && item.getOpenCloseType().equalsIgnoreCase(Item.HK_STOCKS)).map(Item::getSymbol).collect(Collectors.joining(","));
                 String usStocSymbols = list.stream().filter(item -> item.getOpenCloseType() != null && item.getOpenCloseType().equalsIgnoreCase(Item.US_STOCKS)).map(Item::getSymbol).collect(Collectors.joining(","));
-                String symbols = aStocSymbols + "," + hkStocSymbols + "," + usStocSymbols;
+                String symbols = usStocSymbols;
                 List<StockMarket> markets = xueQiuDataService.getMarkets(symbols);
                 markets.forEach(m -> DataCache.putMarket(m.getSymbol(), m));
 
diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/ETFData.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/ETFData.java
new file mode 100644
index 0000000..57c88a3
--- /dev/null
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/ETFData.java
@@ -0,0 +1,30 @@
+package com.yami.trading.huobi.data.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @program: trading-order-master
+ * @description:
+ * @create: 2025-09-28 14:16
+ **/
+@Data
+public class ETFData {
+    @JsonProperty("ticker")
+    private String ticker;
+
+    @JsonProperty("name")
+    private String name;
+
+    @JsonProperty("is_active")
+    private Integer isActive;
+
+    @JsonProperty("exchange_code")
+    private String exchangeCode;
+
+    @JsonProperty("country_code")
+    private String countryCode;
+
+    @JsonProperty("currency_code")
+    private String currencyCode;
+}
diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/ETFResponse.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/ETFResponse.java
new file mode 100644
index 0000000..66ca9b1
--- /dev/null
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/ETFResponse.java
@@ -0,0 +1,19 @@
+package com.yami.trading.huobi.data.model;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @program: trading-order-master
+ * @description:
+ * @create: 2025-09-28 14:18
+ **/
+@Data
+public class ETFResponse {
+
+    private String msg;
+    private Integer code;
+    private List<ETFData> data;
+
+}
diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/RealTimeData.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/RealTimeData.java
new file mode 100644
index 0000000..8efe937
--- /dev/null
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/RealTimeData.java
@@ -0,0 +1,35 @@
+package com.yami.trading.huobi.data.model;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * @program: trading-order-master
+ * @description:
+ * @create: 2025-09-28 14:18
+ **/
+@Data
+public class RealTimeData {
+
+    @JsonProperty("ticker")
+    private String ticker;
+
+    @JsonProperty("close")
+    private Double close;
+
+    @JsonProperty("date")
+    private String date;
+
+    @JsonProperty("open")
+    private Double open;
+
+    @JsonProperty("high")
+    private Double high;
+
+    @JsonProperty("low")
+    private Double low;
+
+    @JsonProperty("volume")
+    private Double volume;
+
+}
diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/RealTimeResponse.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/RealTimeResponse.java
new file mode 100644
index 0000000..4689111
--- /dev/null
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/model/RealTimeResponse.java
@@ -0,0 +1,19 @@
+package com.yami.trading.huobi.data.model;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @program: trading-order-master
+ * @description:
+ * @create: 2025-09-28 14:19
+ **/
+@Data
+public class RealTimeResponse {
+
+    private String msg;
+    private Integer code;
+    private List<RealTimeData> data;
+
+}
diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/XinLangDataServiceImpl.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/XinLangDataServiceImpl.java
index e71ab96..649d4c1 100644
--- a/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/XinLangDataServiceImpl.java
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/XinLangDataServiceImpl.java
@@ -65,17 +65,7 @@
     private ItemService itemService;
 
 
-    public static void main(String[] args) {
-        XinLangDataServiceImpl service = new XinLangDataServiceImpl();
-        List<Realtime> usdsgd = service.realtimeSingle("USDSGD");
-        for (Realtime re : usdsgd) {
-            System.out.println(JSONObject.toJSONString(re));
-        }
-//        List<Kline> sz300750 = service.buildOneYearPeriod("AAPL");
-//        System.out.println(sz300750.size());
-//        List<Kline> eurusd = service.getTimeseriesByPeriodOneDay("EURUSD");
-//        System.out.println(JSONObject.toJSONString(eurusd));
-    }
+
 
 
     /**
@@ -142,10 +132,10 @@
         return list;
     }
 
-    public List<Realtime> realtime(String symbols) {
-        List<Realtime> realtimeList = realtimeSingle(symbols);
-        return realtimeList;
-    }
+//    public List<Realtime> realtime(String symbols) {
+//        List<Realtime> realtimeList = realtimeSingle(symbols);
+//        return realtimeList;
+//    }
 
     /**
      * 1day       历史数据  : 周期 1年
diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/XueQiuDataServiceImpl.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/XueQiuDataServiceImpl.java
index aed4a9c..029c123 100644
--- a/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/XueQiuDataServiceImpl.java
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/XueQiuDataServiceImpl.java
@@ -7,6 +7,7 @@
 import com.google.common.collect.Lists;
 import com.yami.trading.bean.cms.Infomation;
 import com.yami.trading.bean.data.domain.*;
+import com.yami.trading.bean.item.domain.Item;
 import com.yami.trading.common.util.RedisUtil;
 import com.yami.trading.huobi.data.DataCache;
 import com.yami.trading.huobi.data.internal.DepthTimeObject;
@@ -16,6 +17,7 @@
 import com.yami.trading.huobi.hobi.http.HttpMethodType;
 import com.yami.trading.service.cms.InfomationService;
 import com.yami.trading.service.item.ItemService;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.NameValuePair;
 import org.apache.http.client.utils.URLEncodedUtils;
@@ -27,6 +29,7 @@
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -36,6 +39,7 @@
  * 完成需求k线图采集
  */
 @Component
+@Slf4j
 public class XueQiuDataServiceImpl {
     //   https://stock.xueqiu.com/v5/stock/chart/kline.json?symbol=TSLA&begin=1682695800000&period=120m&type=before&count=-500&indicator=kline";
     public final static String klineUrl = "https://stock.xueqiu.com/v5/stock/chart/kline.json?symbol={}&begin={}&period={}&type=before&count=-500&indicator=kline";
@@ -45,7 +49,7 @@
     /**
      * live
      */
-    public final static String live = "https://stock.xueqiu.com/v5/stock/quote.json";
+    public final static String live = "https://www.tsanghi.com/api/fin/";
     public final static String markets = "https://stock.xueqiu.com/v5/stock/quote.json";
 
     public final static String pankou = "https://stock.xueqiu.com/v5/stock/realtime/pankou.json";
@@ -322,55 +326,164 @@
     }
 
     public List<Realtime> realtimeSingle(String symbols) {
-        List<Realtime> list = new ArrayList<Realtime>();
+        List<Realtime> list = new ArrayList<>();
         try {
-            List<String> strings = Arrays.asList(symbols.split(","));
-            String cookie = HttpHelper.getCookie("https://xueqiu.com/");
-            for (String symbol: strings) {
-                String result = HttpHelper.sendGetHttp(live, "symbol=" + symbol, cookie);
-                JSONObject resultJson = JSON.parseObject(result);
-                String code = resultJson.getString("error_code");
-                if ("0".equals(code)) {
-                    JSONObject jsonObject = resultJson.getJSONObject("data").getJSONObject("quote");
-                    Realtime realtime = new Realtime();
-                    String currency;
-                    currency = symbol;
-                    int decimal = itemService.getDecimal(currency);
-                    realtime.setSymbol(currency);
-                    realtime.setName(currency);
-                    Long timestamp = jsonObject.getLong("timestamp");
-                    if (timestamp.toString().length() > 13) {
-                        timestamp = timestamp / 1000;
+            List<String> symbolList = Arrays.asList(symbols.split(","));
+
+            for (String symbol : symbolList) {
+                try {
+                    Item item = itemService.findBySymbol(symbol);
+                    if (item == null) {
+                        log.warn("未找到对应的item: {}", symbol);
+                        continue;
                     }
-                    realtime.setTs(timestamp);
-                    realtime.setOpen(jsonObject.getBigDecimal("open").setScale(decimal, RoundingMode.HALF_UP));
-                    realtime.setClose(jsonObject.getBigDecimal("current").setScale(decimal, RoundingMode.HALF_UP));
-                    realtime.setHigh(jsonObject.getBigDecimal("high").setScale(decimal, RoundingMode.HALF_UP));
-                    realtime.setLow(jsonObject.getBigDecimal("low").setScale(decimal, RoundingMode.HALF_UP));
-                    realtime.setMarketCapital(jsonObject.getLong("market_capital"));
-                    realtime.setFloatMarketCapital(jsonObject.getLong("float_market_capital"));
-                    realtime.setPeForecast(jsonObject.getBigDecimal("pe_forecast"));
-                    realtime.setVolumeRatio(jsonObject.getBigDecimal("volume_ratio"));
-                    realtime.setTurnoverRate(jsonObject.getBigDecimal("turnover_rate"));
-                    BigDecimal amount = jsonObject.getBigDecimal("amount");
-                    if (amount == null) {
-                        amount = BigDecimal.ZERO;
+
+                    String type = "";
+                    String exchange = "";
+
+                    // 根据类型确定API路径和交易所
+                    if ("US-stocks".equals(item.getType())) {
+                        type = "stock";
+                        exchange = "XNAS";  // 美股纳斯达克
+                    } else if ("indices".equals(item.getType()) || "ETF".equals(item.getType())) {
+                        type = "etf";
+                        exchange = "XNAS";  // ETF也在纳斯达克
+                    } else {
+                        // 其他类型,默认为股票和上交所
+                        type = "stock";
+                        exchange = "XSHG";
                     }
-                    realtime.setAmount(amount.setScale(decimal, RoundingMode.HALF_UP));
-                    BigDecimal volume = jsonObject.getBigDecimal("volume");
-                    if (volume == null) {
-                        volume = BigDecimal.ZERO;
+
+                    // 构建API URL
+                    String url = String.format("https://www.tsanghi.com/api/fin/%s/%s/realtime?token=9668db3503214cd19a831a9f866923b9&ticker=%s",
+                            type, exchange, symbol);
+
+                    String result = HttpHelper.sendGetHttp(url, null, null);
+                    JSONObject resultJson = JSON.parseObject(result);
+
+                    String code = resultJson.getString("code");
+                    if ("200".equals(code)) {
+                        JSONArray dataArray = resultJson.getJSONArray("data");
+
+                        // 检查数据是否为空
+                        if (dataArray == null || dataArray.isEmpty()) {
+                            log.warn("股票 {} 的实时数据为空", symbol);
+                            continue;
+                        }
+
+                        // 取第一个数据对象
+                        JSONObject dataObject = dataArray.getJSONObject(0);
+
+                        Realtime realtime = new Realtime();
+                        int decimal = itemService.getDecimal(symbol);
+
+                        realtime.setSymbol(symbol);
+                        realtime.setName(item.getName() != null ? item.getName() : symbol);
+
+                        // 处理时间戳
+                        String dateStr = dataObject.getString("date");
+                        long timestamp = parseDateTimeToTimestamp(dateStr);
+                        if (Long.toString(timestamp).length() > 13) {
+                            timestamp = timestamp / 1000;
+                        }
+                        realtime.setTs(timestamp);
+
+                        // 设置价格数据
+                        realtime.setOpen(getBigDecimalValue(dataObject, "open", decimal));
+                        realtime.setClose(getBigDecimalValue(dataObject, "close", decimal));
+                        realtime.setHigh(getBigDecimalValue(dataObject, "high", decimal));
+                        realtime.setLow(getBigDecimalValue(dataObject, "low", decimal));
+
+                        // 设置成交量和成交额
+                        realtime.setVolume(getBigDecimalValue(dataObject, "volume", decimal));
+                        realtime.setAmount(getBigDecimalValue(dataObject, "amount", decimal));
+
+                        // 设置昨收价
+                        BigDecimal preClose = getBigDecimalValue(dataObject, "pre_close", decimal);
+                        if (preClose != null) {
+                            // 如果Realtime类有preClose字段,取消注释
+                            // realtime.setPreClose(preClose);
+                        }
+
+                        // 处理盘口数据(如果存在)
+                        JSONArray buyPriceArray = dataObject.getJSONArray("buy_price");
+                        JSONArray sellPriceArray = dataObject.getJSONArray("sell_price");
+                        JSONArray buyVolumeArray = dataObject.getJSONArray("buy_volume");
+                        JSONArray sellVolumeArray = dataObject.getJSONArray("sell_volume");
+
+                        if (buyPriceArray != null && !buyPriceArray.isEmpty()) {
+                            realtime.setBid(getBigDecimalFromArray(buyPriceArray, 0, decimal));
+                        }
+                        if (sellPriceArray != null && !sellPriceArray.isEmpty()) {
+                            realtime.setAsk(getBigDecimalFromArray(sellPriceArray, 0, decimal));
+                        }
+
+                        list.add(realtime);
+                    } else {
+                        log.warn("API返回错误代码: {}, 股票: {}", code, symbol);
                     }
-                    realtime.setVolume(volume.setScale(decimal, RoundingMode.HALF_UP));
-//                    realtime.setAsk(realtimeJson.getBigDecimal("ask").setScale(decimal, RoundingMode.HALF_UP));
-//                    realtime.setBid(realtimeJson.getBigDecimal("pb").setScale(decimal, RoundingMode.HALF_UP));
-                    list.add(realtime);
+                } catch (Exception e) {
+                    log.error("处理股票 {} 时发生错误", symbol, e);
                 }
             }
         } catch (Exception e) {
-            logger.error("error", e);
+            log.error("获取实时数据失败", e);
         }
         return list;
+    }
+
+    /**
+     * 将日期时间字符串转换为时间戳
+     * 格式: "yyyy-mm-dd hh:mm:ss"
+     */
+    private long parseDateTimeToTimestamp(String dateTimeStr) {
+        try {
+            if (dateTimeStr == null || dateTimeStr.isEmpty()) {
+                return System.currentTimeMillis();
+            }
+
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            Date date = sdf.parse(dateTimeStr);
+            return date.getTime();
+        } catch (Exception e) {
+            log.error("日期时间解析失败: {}", dateTimeStr, e);
+            return System.currentTimeMillis();
+        }
+    }
+
+    /**
+     * 安全获取BigDecimal值
+     */
+    private BigDecimal getBigDecimalValue(JSONObject jsonObject, String key, int decimal) {
+        try {
+            BigDecimal value = jsonObject.getBigDecimal(key);
+            if (value == null) {
+                return BigDecimal.ZERO;
+            }
+            return value.setScale(decimal, RoundingMode.HALF_UP);
+        } catch (Exception e) {
+            log.warn("获取字段 {} 失败", key, e);
+            return BigDecimal.ZERO;
+        }
+    }
+
+    /**
+     * 从JSONArray中获取BigDecimal值
+     */
+    private BigDecimal getBigDecimalFromArray(JSONArray jsonArray, int index, int decimal) {
+        try {
+            if (jsonArray == null || jsonArray.size() <= index) {
+                return BigDecimal.ZERO;
+            }
+            BigDecimal value = jsonArray.getBigDecimal(index);
+            if (value == null) {
+                return BigDecimal.ZERO;
+            }
+            return value.setScale(decimal, RoundingMode.HALF_UP);
+        } catch (Exception e) {
+            log.warn("从数组获取数据失败", e);
+            return BigDecimal.ZERO;
+        }
     }
 
     public List<Realtime> realtime(String symbols) {
@@ -389,25 +502,25 @@
         map.put(Kline.PERIOD_1MON, buildOneMonthPeriod(symbol));
         map.put(Kline.PERIOD_1DAY, buildOneDayPeriod(symbol));
         map.put(Kline.PERIOD_5DAY, buildFiveDayPeriod(symbol));
-        map.put(Kline.PERIOD_QUARTER, buildOneQuarterPeriod(symbol));
+//        map.put(Kline.PERIOD_QUARTER, buildOneQuarterPeriod(symbol));
         map.put(Kline.PERIOD_YEAR, buildOneYearPeriod(symbol));
 
         return map;
     }
 
     public List<Kline> buildOneDayPeriod(String currency) {
-        return getTimeseriesByPeriod(currency, "day", Kline.PERIOD_1DAY, 365);
+        return getTimeseriesByPeriod(currency, "daily", Kline.PERIOD_1DAY, 365);
 
     }
 
 
     public List<Kline> buildOneWeekPeriod(String currency) {
-        return getTimeseriesByPeriod(currency, "week", Kline.PERIOD_1WEEK, 365 * 5);
+        return getTimeseriesByPeriod(currency, "weekly", Kline.PERIOD_1WEEK, 365 * 5);
 
     }
 
     public List<Kline> buildOneMonthPeriod(String currency) {
-        return getTimeseriesByPeriod(currency, "month", Kline.PERIOD_1MON, 365 * 5);
+        return getTimeseriesByPeriod(currency, "monthly", Kline.PERIOD_1MON, 365 * 5);
     }
 
     public List<Kline> buildOneQuarterPeriod(String currency) {
@@ -415,7 +528,7 @@
     }
 
     public List<Kline> buildOneYearPeriod(String currency) {
-        return getTimeseriesByPeriod(currency, "year", Kline.PERIOD_YEAR, 365 * 100);
+        return getTimeseriesByPeriod(currency, "yearly", Kline.PERIOD_YEAR, 365 * 100);
     }
 
     /**
@@ -588,64 +701,144 @@
 
     public List<Kline> getTimeseriesByPeriod(String currency, String periodXieQiu, String sysPeriod, long limitDays) {
         List<Kline> resList = new ArrayList<>();
-        long nowTs = System.currentTimeMillis();
-        long startTs = System.currentTimeMillis() - limitDays * 24 * 60 * 60 * 1000;
-        long begin = nowTs;
-        String cookie = HttpHelper.getCookie("https://xueqiu.com/");
 
-        Set<Long> tsSet = new HashSet<>();
-        while (begin > startTs) {
-            String url = StrUtil.format(klineUrl, currency, begin, periodXieQiu);
-            String json = HttpHelper.sendGetHttp(url, null, cookie);
+        try {
+            // 获取商品信息判断类型
+            Item itemData = itemService.findBySymbol(currency);
+            String type = "stock"; // 默认股票
+            String exchange = "XNAS"; // 默认纳斯达克
+
+            if (itemData != null) {
+                if ("ETF".equals(itemData.getType()) || "etf".equals(itemData.getType()) ||
+                        "indices".equals(itemData.getType()) || currency.startsWith("51") ||
+                        currency.startsWith("15") || currency.startsWith("16")) {
+                    type = "etf";
+                    // ETF可能在不同的交易所,根据实际情况调整
+                    exchange = "XNAS"; // 或者可能是XSHG等其他交易所
+                } else if ("US-stocks".equals(itemData.getType())) {
+                    type = "stock";
+                    exchange = "XNAS";
+                } else {
+                    // 其他类型默认为A股股票
+                    type = "stock";
+                    exchange = "XSHG";
+                }
+            } else {
+                // 如果没有找到item信息,根据symbol特征猜测类型
+                if (currency.startsWith("51") || currency.startsWith("15") || currency.startsWith("16")) {
+                    type = "etf";
+                    exchange = "XSHG"; // A股ETF
+                } else if (currency.matches("[A-Z]+")) {
+                    type = "stock";
+                    exchange = "XNAS"; // 美股
+                } else {
+                    type = "stock";
+                    exchange = "XSHG"; // 默认A股
+                }
+            }
+
+            log.debug("获取K线数据,symbol: {}, 类型: {}, 交易所: {}, 周期: {}",
+                    currency, type, exchange, periodXieQiu);
+
+            // 构建API URL
+            String url = StrUtil.format("https://www.tsanghi.com/api/fin/{}/{}/{}?token=9668db3503214cd19a831a9f866923b9&ticker={}&order=2",
+                    type, exchange, periodXieQiu, currency);
+
+            // 发送HTTP请求
+            String json = HttpHelper.sendGetHttp(url, null, null);
             JSONObject resultJson = JSON.parseObject(json);
-            JSONArray dataArray = resultJson.getJSONObject("data").getJSONArray("item");
-            List<List> lists = dataArray.toJavaList(List.class);
-            long minTS = begin;
-            for (List result : lists) {
+
+            // 检查API响应是否成功
+            if (resultJson == null || !resultJson.containsKey("data")) {
+                log.error("API响应数据格式异常: {}", json);
+                return resList;
+            }
+
+            JSONArray dataArray = resultJson.getJSONArray("data");
+            if (dataArray == null || dataArray.isEmpty()) {
+                log.warn("未获取到K线数据");
+                return resList;
+            }
+
+            // 计算时间范围
+            long endTime = System.currentTimeMillis();
+            long startTime = endTime - limitDays * 24 * 60 * 60 * 1000L;
+
+            Set<String> dateSet = new HashSet<>();
+
+            // 解析数据
+            for (int i = 0; i < dataArray.size(); i++) {
+                JSONObject item = dataArray.getJSONObject(i);
+
+                // 解析日期
+                String dateStr = item.getString("date");
+                if (dateSet.contains(dateStr)) {
+                    continue;
+                }
+                dateSet.add(dateStr);
+
+                // 将日期转换为时间戳
+                long ts = parseDateToTimestamp(dateStr);
+
+                // 检查时间范围
+                if (ts < startTime) {
+                    continue;
+                }
+
                 Kline kline = new Kline();
                 kline.setSymbol(currency);
                 kline.setPeriod(sysPeriod);
-                // 毫秒
-                long ts = Long.parseLong(result.get(0).toString());
-                if (Long.toString(ts).length() > 13) {
-                    ts = ts / 1000;
-                }
-                if (tsSet.contains(ts)) {
-                    continue;
-                } else {
-                    tsSet.add(ts);
-                }
                 kline.setTs(ts);
-                kline.setOpen(new BigDecimal(result.get(2).toString()));
-                kline.setClose(new BigDecimal(result.get(5).toString()));
-                kline.setHigh(new BigDecimal(result.get(3).toString()));
-                kline.setLow(new BigDecimal(result.get(4).toString()));
-                kline.setVolume(new BigDecimal(result.get(1).toString()));
-                kline.setAmount(new BigDecimal(result.get(9).toString()));
+                kline.setOpen(item.getBigDecimal("open"));
+                kline.setClose(item.getBigDecimal("close"));
+                kline.setHigh(item.getBigDecimal("high"));
+                kline.setLow(item.getBigDecimal("low"));
+                kline.setVolume(item.getBigDecimal("volume"));
+
+                // 如果有amount字段就设置,没有就设为0
+                if (item.containsKey("amount")) {
+                    kline.setAmount(item.getBigDecimal("amount"));
+                } else {
+                    kline.setAmount(BigDecimal.ZERO);
+                }
+
+                // 修复K线数据(如果有修复逻辑)
                 if (klineService != null) {
                     klineService.repairKline(kline);
                 }
+
                 resList.add(kline);
-                if (ts < minTS) {
-                    minTS = ts;
-                }
+            }
 
+            // 按时间戳升序排序
+            Collections.sort(resList);
+
+            // 如果需要设置开盘价为前一根的收盘价
+            int len = resList.size();
+            for (int i = 1; i < len; i++) {
+                resList.get(i).setOpen(resList.get(i - 1).getClose());
             }
-            if (minTS == begin) {
-                break;
-            }
-            begin = minTS;
-            if (begin < startTs) {
-                break;
-            }
+
+        } catch (Exception e) {
+            log.error("获取K线数据失败: {}", currency, e);
         }
-        Collections.sort(resList);
-        int len = resList.size();
-        for (int i = 1; i < len; i++) {
-            resList.get(i).setOpen(resList.get(i - 1).getClose());
-        }
+
         return resList;
+    }
 
+    /**
+     * 将日期字符串转换为时间戳
+     * 格式: "yyyy-mm-dd"
+     */
+    private long parseDateToTimestamp(String dateStr) {
+        try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+            Date date = sdf.parse(dateStr);
+            return date.getTime();
+        } catch (Exception e) {
+            log.error("日期解析失败: {}", dateStr, e);
+            return System.currentTimeMillis();
+        }
     }
 
     public List<Kline> getTimeseriesByMinute(String currency, int minute, long limitDays) {
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java
index 00ea947..635ba0d 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java
@@ -111,11 +111,11 @@
         double amount = Arith.mul(sub, realtime.getClose().doubleValue());
         order.setCloseTime(new Date());
         order.setClosePrice(realtime.getClose().doubleValue());
-//        Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId());
-        CapitaltWallet capitaltWallet = capitaltWalletService.getUserIdWallet(order.getPartyId());
-        double amount_before = capitaltWallet.getMoney().doubleValue();
-//        this.walletService.update(userIdWallet.getUserId().toString(), amount);
-        this.capitaltWalletService.update(capitaltWallet, amount);
+        Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId());
+//        CapitaltWallet capitaltWallet = capitaltWalletService.getUserIdWallet(order.getPartyId());
+        double amount_before = wallet.getMoney().doubleValue();
+        this.walletService.update(wallet.getUserId().toString(), amount);
+//        this.capitaltWalletService.update(capitaltWallet, amount);
 
         /*
          * 保存资金日志
@@ -124,7 +124,7 @@
         moneylog_deposit.setCategory(Constants.MONEYLOG_CATEGORY_EXCHANGE);
         moneylog_deposit.setAmountBefore(new BigDecimal(amount_before));
         moneylog_deposit.setAmount(new BigDecimal(amount));
-        moneylog_deposit.setAmountAfter(capitaltWallet.getMoney());
+        moneylog_deposit.setAmountAfter(wallet.getMoney());
         moneylog_deposit.setLog("委托单,订单号[" + order.getOrderNo() + "]");
         moneylog_deposit.setUserId(order.getPartyId());
         moneylog_deposit.setWalletType(Constants.WALLET);
@@ -615,8 +615,8 @@
         // 可以买的数量
         double amount = Arith.div(sub, order.getClosePrice(), 8);
         order.setSymbolValue(amount);
-//        Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId());
-        CapitaltWallet userIdWallet = capitaltWalletService.getUserIdWallet(order.getPartyId());
+        Wallet userIdWallet = this.walletService.saveWalletByPartyId(order.getPartyId());
+//        CapitaltWallet userIdWallet = capitaltWalletService.getUserIdWallet(order.getPartyId());
         double amount_before = userIdWallet.getMoney().doubleValue();
         // 如果是计划委托,则先不扣钱
         if (order.isTriggerOrder()) {
@@ -643,8 +643,8 @@
             if (userIdWallet.getMoney().doubleValue() < order.getVolume().doubleValue()) {
                 throw new YamiShopBindException("余额不足");
             }
-//            this.walletService.update(userIdWallet.getUserId().toString(), Arith.sub(0, order.getVolume()));
-            capitaltWalletService.update(userIdWallet, Arith.sub(0, order.getVolume()));
+            this.walletService.update(userIdWallet.getUserId().toString(), Arith.sub(0, order.getVolume()));
+//            capitaltWalletService.update(userIdWallet, Arith.sub(0, order.getVolume()));
             /*
              * 保存资金日志
              */
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/impl/RechargeBlockchainOrderServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/impl/RechargeBlockchainOrderServiceImpl.java
index ee52404..d6c6276 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/impl/RechargeBlockchainOrderServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/impl/RechargeBlockchainOrderServiceImpl.java
@@ -135,10 +135,15 @@
 //
 //            walletService.update(wallet.getUserId(), amount1);
 
-            CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
-                    .eq(CapitaltWallet::getUserId, recharge.getPartyId()).last(" limit 1 "));
-            double amount_before = capitaltWallet.getMoney().doubleValue();
-            capitaltWalletService.update(capitaltWallet,amount1);
+//            CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
+//                    .eq(CapitaltWallet::getUserId, recharge.getPartyId()).last(" limit 1 "));
+//            double amount_before = capitaltWallet.getMoney().doubleValue();
+//            capitaltWalletService.update(capitaltWallet,amount1);
+
+            Wallet wallet = walletService.getOne(new LambdaQueryWrapper<>(Wallet.class)
+                    .eq(Wallet::getUserId, recharge.getPartyId()).last(" limit 1 "));
+            double amount_before = wallet.getMoney().doubleValue();
+            walletService.update(wallet.getUserId(),amount1);
 
             // 保存资金日志
             MoneyLog moneyLog = new MoneyLog();
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/impl/WithdrawServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/impl/WithdrawServiceImpl.java
index b132fc4..a883d85 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/impl/WithdrawServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/impl/WithdrawServiceImpl.java
@@ -151,14 +151,24 @@
 //            walletService.update(wallet.getUserId().toString(),
 //                    Arith.add(withdraw.getAmount(), withdraw.getAmountFee()));
 
-            CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
-                    .eq(CapitaltWallet::getUserId, wallet.getUserId().toString()).last(" limit 1 "));
-            if(ObjectUtil.isEmpty(capitaltWallet)){
+//            CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
+//                    .eq(CapitaltWallet::getUserId, wallet.getUserId().toString()).last(" limit 1 "));
+//            if(ObjectUtil.isEmpty(capitaltWallet)){
+//                throw new YamiShopBindException("用户资金账户不存在!");
+//            }
+//            capitaltWalletService.update(new LambdaUpdateWrapper<CapitaltWallet>()
+//                    .set(CapitaltWallet::getMoney,new BigDecimal(Arith.add(capitaltWallet.getMoney(), withdraw.getVolume())))
+//                    .eq(CapitaltWallet::getUserId,wallet.getUserId()));
+
+            Wallet wallet1 = walletService.getOne(new LambdaQueryWrapper<>(Wallet.class)
+                    .eq(Wallet::getUserId, wallet.getUserId().toString()).last(" limit 1 "));
+            if(ObjectUtil.isEmpty(wallet1)){
                 throw new YamiShopBindException("用户资金账户不存在!");
             }
-            capitaltWalletService.update(new LambdaUpdateWrapper<CapitaltWallet>()
-                    .set(CapitaltWallet::getMoney,new BigDecimal(Arith.add(capitaltWallet.getMoney(), withdraw.getVolume())))
-                    .eq(CapitaltWallet::getUserId,wallet.getUserId()));
+            walletService.update(new LambdaUpdateWrapper<Wallet>()
+                    .set(Wallet::getMoney,new BigDecimal(Arith.add(wallet1.getMoney(), withdraw.getVolume())))
+                    .eq(Wallet::getUserId,wallet.getUserId()));
+
 
 
             /*
@@ -482,11 +492,11 @@
             throw new YamiShopBindException("Your account has been frozen");
         }
 
-//        Wallet wallet = walletService.saveWalletByPartyId(withdraw.getUserId());
+        Wallet wallet = walletService.saveWalletByPartyId(withdraw.getUserId());
 
-        CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
-                .eq(CapitaltWallet::getUserId, withdraw.getUserId()).last(" limit 1 "));
-        if (capitaltWallet.getMoney().doubleValue() < withdraw.getVolume().doubleValue()) {
+//        CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
+//                .eq(CapitaltWallet::getUserId, withdraw.getUserId()).last(" limit 1 "));
+        if (wallet.getMoney().doubleValue() < withdraw.getVolume().doubleValue()) {
             throw new YamiShopBindException("not sufficient funds");
         }
         // 手续费(USDT)
@@ -671,17 +681,17 @@
          */
         String withdraw_qr = qRGenerateService.generateWithdraw(withdraw.getOrderNo(), withdraw.getAddress());
         withdraw.setQdcode(withdraw_qr);
-        double amount_before = capitaltWallet.getMoney().doubleValue();
+        double amount_before = wallet.getMoney().doubleValue();
 
 
 
 //        walletService.update(wallet.getUserId().toString(), Arith.sub(0, withdraw.getVolume().doubleValue()));
 
 
-        if(ObjectUtil.isEmpty(capitaltWallet)){
+        if(ObjectUtil.isEmpty(wallet)){
             throw new YamiShopBindException("The user's funds account does not exist!");
         }
-        capitaltWalletService.update(capitaltWallet,-withdraw.getVolume().doubleValue());
+        walletService.update(wallet.getUserId(),-withdraw.getVolume().doubleValue());
 
         save(withdraw);
 
@@ -692,7 +702,7 @@
         moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
         moneyLog.setAmountBefore(new BigDecimal(amount_before));
         moneyLog.setAmount(new BigDecimal(Arith.sub(0, withdraw.getVolume().doubleValue())));
-        moneyLog.setAmountAfter(capitaltWallet.getMoney());
+        moneyLog.setAmountAfter(wallet.getMoney());
         moneyLog.setLog("提现订单[" + withdraw.getOrderNo() + "]");
         // moneyLog.setExtra(withdraw.getOrder_no());
         moneyLog.setUserId(withdraw.getUserId());
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/item/ItemService.java b/trading-order-service/src/main/java/com/yami/trading/service/item/ItemService.java
index 5c0e090..6735b3b 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/item/ItemService.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/item/ItemService.java
@@ -162,7 +162,7 @@
     @Cached(name = ITEM_CACHE, key = "'all'", expire = 3600)
     @Override
     public List<Item> list() {
-        List<Item> list = super.list(new LambdaQueryWrapper<>(Item.class).eq(Item::getType,Item.cryptos));
+        List<Item> list = super.list(new LambdaQueryWrapper<>(Item.class).eq(Item::getDelFlag,0));
         symbolDecimal = list.stream()
                 .collect(Collectors.toMap(Item::getSymbol, Item::getDecimals, (s1, s2) -> s2));
         return list;
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/user/impl/UserStatisticsServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/user/impl/UserStatisticsServiceImpl.java
index 2274407..cd5de8f 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/user/impl/UserStatisticsServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/user/impl/UserStatisticsServiceImpl.java
@@ -118,8 +118,10 @@
         result.add(0,data);
 
         Map<String,Object> capitaldata = new HashMap<String,Object>();
-        CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
-                .eq(CapitaltWallet::getUserId, targetPartyId).last(" limit 1 "));
+//        CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
+//                .eq(CapitaltWallet::getUserId, targetPartyId).last(" limit 1 "));
+        Wallet capitaltWallet = walletService.getOne(new LambdaQueryWrapper<>(Wallet.class)
+                .eq(Wallet::getUserId, targetPartyId).last(" limit 1 "));
         capitaldata.put("wallettype", "capitalusdt");
         capitaldata.put("amount",null==capitaltWallet?0:new BigDecimal(capitaltWallet.getMoney().doubleValue()).setScale(8, RoundingMode.FLOOR).toPlainString() );
         capitaldata.put("lock_amount",null==capitaltWallet?0:capitaltWallet.getLockMoney().setScale(8, RoundingMode.FLOOR).toPlainString() );

--
Gitblit v1.9.3