trading-order-admin/src/main/java/com/yami/trading/admin/task/StockTask.java
@@ -2,6 +2,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.yami.trading.admin.util.us.HttpClientRequest; import com.yami.trading.admin.util.us.ReponseBase; import com.yami.trading.bean.data.domain.Realtime; @@ -19,6 +20,7 @@ import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Component; import java.lang.reflect.Type; import java.math.BigDecimal; import java.util.*; import java.util.concurrent.CompletableFuture; @@ -45,7 +47,7 @@ /** * 同步系统所需要的股票 */ @Scheduled(cron = "0 0/5 * * * ?") @Scheduled(cron = "0 0/30 * * * ?") public void syncINStockData() { if (syncINStockData.get()) { // 判断任务是否在处理中 @@ -131,6 +133,7 @@ if (item != null) { //已有不添加 continue; } item = new Item(); String name = StringUtils.trim(o.getName()); item.setEnName(name); @@ -160,7 +163,6 @@ item.setStockCode(o.getId()); updateStockList.add(item); Realtime realtime = new Realtime(); realtime.setUuid(o.getId()); @@ -192,51 +194,53 @@ } /** * 初始化所有股票数据 * 初始化更新价格 */ public void initAllStock(EStockType eStockType) { log.info("init US股票 数据 {}", eStockType.getCode()); List<StockRealTimeBean> list = new ArrayList<>(); int totleStock = 1; int page = 0; try { while (totleStock > list.size()) { try { String result = HttpClientRequest.doGet(eStockType.stockUrl + "list?country_id=" + eStockType.getContryId() + "&size=100000&page=" + page + "&key=" + eStockType.stockKey); ReponseBase reponseBase = new Gson().fromJson(result, ReponseBase.class); list.addAll(reponseBase.getData()); page++; totleStock = reponseBase.getTotal(); } catch (Exception e) { e.printStackTrace(); break; } } if (list.isEmpty()) { return; } /*list.forEach( x-> { if (x.getSymbol().equalsIgnoreCase("IONM")) { System.out.println(x); System.out.println(x); } });*/ Map<String, Object> paramMap = new HashMap<>(); List<Item> stockList = itemService.list(new QueryWrapper<Item>() .eq("type", Item.US_STOCKS)); int batchSize = 5000; // 每批5000条 int totalSize = stockList.size(); // 总条数 List<Item> indicesList = itemService.list(new QueryWrapper<Item>() .eq("type", Item.indices)); for (StockRealTimeBean o : list) { Item indices = indicesList.stream() .filter(x -> x.getSymbol().equals(o.getSymbol())) .findFirst() .orElse(null); if (indices != null) { //指数不添加 continue; } List<String> pids = new ArrayList<>(); // 循环分批处理 for (int i = 0; i < totalSize; i += batchSize) { // 计算当前批次的结束索引(避免最后一批不足5000条时越界) int endIndex = Math.min(i + batchSize, totalSize); // 截取当前批次的子列表([i, endIndex),左闭右开) List<Item> batchList = stockList.subList(i, endIndex); // 拼接当前批次的pid(逗号分隔的stockCode) String batchPid = batchList.stream() .map(item -> String.valueOf(item.getStockCode())) // 提取stockCode并转字符串 .collect(Collectors.joining(",")); // 拼接 pids.add(batchPid); } pids.forEach(pid -> { paramMap.put("pid", pid); String result = HttpClientRequest.doPost(eStockType.stockUrl + "stock?" + "key=" + eStockType.stockKey, paramMap); // 定义List<StockRealTimeBean>的类型(通过TypeToken保留泛型信息) Type type = new TypeToken<List<StockRealTimeBean>>() { }.getType(); // 解析为List<StockRealTimeBean> List<StockRealTimeBean> stockRealTimeBeanList = new Gson().fromJson(result, type); list.addAll(stockRealTimeBeanList); }); stockList.forEach(item -> { StockRealTimeBean o = list.stream().filter(x -> x.getId() != null && x.getId().equals(item.getStockCode())).findFirst().orElse(null); if (o != null) { Realtime realtime = new Realtime(); realtime.setUuid(o.getId()); realtime.setSymbol(o.getSymbol()); realtime.setName(o.getName()); realtime.setUuid(item.getStockCode()); realtime.setSymbol(item.getSymbol()); realtime.setName(item.getName()); realtime.setClose(new BigDecimal(o.getLast().trim()).doubleValue()); realtime.setLow(new BigDecimal(o.getLow().trim()).doubleValue()); realtime.setHigh(new BigDecimal(o.getHigh().trim()).doubleValue()); @@ -249,19 +253,15 @@ realtime.setType(o.getType()); realtime.setBid(new BigDecimal(o.getBid()).doubleValue()); realtime.setAsk(new BigDecimal(o.getAsk()).doubleValue()); DataCache.putRealtime(realtime.getSymbol(), realtime); } }); log.info("init US股票 数据 成功"); } catch ( Exception e) { log.error("同步出错", e); } catch (Exception e) { log.error(e.getMessage(), e); } } public static void main(String[] args) { StockTask task = new StockTask(); trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractOrderController.java
@@ -133,8 +133,7 @@ // 此处返回的 closeTime 是时间戳类型 data = this.contractOrderService.getPaged(page_no, 10, partyId, symbol, type, startTime, endTime, symbolType); } String symbolsStr = ""; String symbolsStr = null; Set<String> symbols = new HashSet<>(); for (int i = 0; i < data.size(); i++) { Map<String, Object> oneRow = data.get(i); @@ -172,14 +171,16 @@ } } Map<String, Realtime> realtimeMap = new HashMap<String, Realtime>(); if (symbolsStr != null && !symbolsStr.isEmpty()) { List<Realtime> realtime_all = this.dataService.realtime(symbolsStr); if (realtime_all.size() <= 0) { realtime_all = new ArrayList<>(); } Map<String, Realtime> realtimeMap = new HashMap<String, Realtime>(); for (int i = 0; i < realtime_all.size(); i++) { realtimeMap.put(realtime_all.get(i).getSymbol(), realtime_all.get(i)); } } for (int i = 0; i < data.size(); i++) { @@ -192,7 +193,7 @@ } else { String thisSymbol = realtime.getSymbol(); Item bySymbol = itemService.findBySymbol(thisSymbol); Item bySymbol = itemService.findCaCheBySymbol(thisSymbol); if(LangUtils.isEnItem()){ map.put("name", bySymbol.getName()); } trading-order-admin/src/main/java/com/yami/trading/api/controller/KlineController.java
@@ -72,6 +72,7 @@ if (bySymbol.getType().equalsIgnoreCase(Item.US_STOCKS)) { data = klineService.getKData(bySymbol, line); if (!data.isEmpty()) { System.out.println(data.size()); formatKlineTimestamps(data, line); return Result.succeed(this.build(data, line, symbol)); } else { @@ -185,8 +186,12 @@ case "1week": case "quarter": case "year": case "d": case "w": case "m": return "yyyy-MM-dd"; case "1min": case "1": return "HH:mm"; default: return "MM-dd HH:mm"; trading-order-admin/src/main/java/com/yami/trading/api/controller/RealtimeController.java
@@ -214,6 +214,7 @@ .chg(realtime.getChg()) .type(item.getType()) .category(item.getCategory()) .pid(item.getStockCode()) .build(); list.add(dto); } @@ -356,6 +357,7 @@ .chg(realtime.getChg()) .category(item.getCategory()) .type(item.getType()) .pid(item.getStockCode()) .build(); finalList.add(dto); } else { trading-order-admin/src/main/resources/application-dev.yml
@@ -9,21 +9,21 @@ max-request-size: 100MB datasource: # 东八区时区 url: jdbc:mysql://127.0.0.1:3306/all_trading_order?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&serverTimezone=Europe/Paris&useLegacyDatetimeCode=false url: jdbc:mysql://127.0.0.1:3306/all_trading_order?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=America/New_York&nullCatalogMeansCurrent=true username: all_trading_order password: yYkDr5JJndEZtGCe driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource druid: # 配置初始化大小/最小/最大 initial-size: 20 initial-size: 50 # 最小连接池数量 min-idle: 20 min-idle: 50 # 最大连接池数量 max-active: 50 max-active: 400 # 获取连接时最大等待时间,单位毫秒。 # 配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。 max-wait: 6000 max-wait: 10000 # 间隔多久进行一次检测,检测需要关闭的空闲连接 time-between-eviction-runs-millis: 60000 # 配置一个连接在连接池中的最小生存时间,单位毫秒。(连接保持空闲而不被驱逐的最小时间) trading-order-bean/src/main/java/com/yami/trading/bean/data/query/QueryRealtimeDTO.java
@@ -44,4 +44,6 @@ private String type; private String pid; } trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderService.java
@@ -238,6 +238,7 @@ //symbols.add("-1"); if (StringUtils.isNotEmpty(symbolType) && StringUtils.isEmptyString(symbol)) { //rose 多个币种外汇持仓 if (symbolType.contains(",")) { List<String> types = Splitter.on(",").splitToList(symbolType); List<String> symbols = types.stream() .flatMap(type -> itemService.findByType(type).stream().map(Item::getSymbol)) @@ -249,6 +250,7 @@ queryWrapper.in(StringUtils.isNotEmpty(symbolType), "symbol", symbols); } } queryWrapper.ge(StringUtils.isNotEmpty(startTime), "date_format(create_time,'%Y-%m-%d')", startTime); queryWrapper.le(StringUtils.isNotEmpty(endTime), "date_format(create_time,'%Y-%m-%d')", endTime);