package com.yami.trading.huobi.hobi.internal; import cn.hutool.core.util.ObjectUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.google.common.base.Splitter; import com.google.common.collect.Lists; import com.yami.trading.bean.data.domain.*; import com.yami.trading.bean.ipo.XueQiuNewStocks; import com.yami.trading.bean.syspara.domain.Syspara; import com.yami.trading.huobi.data.DataCache; import com.yami.trading.huobi.data.internal.DepthTimeObject; import com.yami.trading.huobi.data.internal.TradeTimeObject; import com.yami.trading.huobi.hobi.constant.TraderMadeOptions; import com.yami.trading.huobi.hobi.http.HttpHelper; import com.yami.trading.huobi.hobi.http.HttpMethodType; import com.yami.trading.service.item.ItemService; import com.yami.trading.service.syspara.SysparaService; import lombok.extern.slf4j.Slf4j; import org.checkerframework.checker.units.qual.A; import org.redisson.api.RMap; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.stream.Collectors; @Slf4j @Component public class SpiderService { /** * 实时行情 */ public static final String REALTIME_HASH = "realtime_hash"; public static final String REALTIME_HASH_BAK = "realtime_hash_bak"; /** * 时区状态hash */ public static final String MARKET_HASH = "market_hash"; /** * 交易明细,A股和美股有 */ public static final String TRADER_HASH = "trader_hash"; public static final String PANKOU_HASH = "pankou_hash"; public static final String KLINE_SYMBOL = "kline_"; public static final String XUEQIU_NEW_STOCKS = "xueqiu_new_stocks"; public static final String XUEQIU_NEW_STOCKS_NOT_LISTED = "xueqiu_new_stocks_not_listed"; public static final String SPIDER_SWITCH_CRYPTOS_KEY = "spider_switch_cryptos_key"; public static final String HUOBI = "huobi"; public static final String MEXC = "mexc"; @Qualifier("redissonClientSpider") @Autowired private RedissonClient redissonClientSpider; @Autowired private SysparaService sysparaService; @Autowired private ItemService itemService; /** * * 如果全局是抹茶,直接返回false * * 如果本地是抹茶返回false * * 其他返回true * * @return */ public boolean isHuobi(){ Object o = redissonClientSpider.getBucket(SPIDER_SWITCH_CRYPTOS_KEY).get(); if(o != null){ if(ObjectUtil.equals(MEXC, o.toString())){ return false; } } Syspara superSecret = sysparaService.find("cryptos_use_huobi"); // 配置了是抹茶数据源 if(superSecret != null && "0".equalsIgnoreCase(superSecret.getSvalue())){ return false; } return true; } public List fetchNewStocks() { Object o = redissonClientSpider.getBucket(XUEQIU_NEW_STOCKS).get(); if(o == null){ return Lists.newArrayList(); } return JSONArray.parseArray(o.toString(), XueQiuNewStocks.class); } public List fetchNewStocksNotList() { Object o = redissonClientSpider.getBucket(XUEQIU_NEW_STOCKS_NOT_LISTED).get(); if(o == null){ return Lists.newArrayList(); } return JSONArray.parseArray(o.toString(), XueQiuNewStocks.class); } public List fetchRealtimeList(String remarks, String key) { List list = new ArrayList<>(); RMap map = redissonClientSpider.getMap(key); Set keys = Splitter.on(",").trimResults().splitToStream(remarks).collect(Collectors.toSet()); Map values = map.getAll(keys); for (String symbol : values.keySet()) { JSONObject realtimeJson = JSONObject.parseObject(values.get(symbol).trim()); realtimeJson.put("mid", realtimeJson.get("current")); realtimeJson.put("currency", realtimeJson.get("symbol")); realtimeJson.put("timestamp", realtimeJson.get("time")); realtimeJson.put("marketCapital", realtimeJson.get("market_capital")); realtimeJson.put("floatMarketCapital", realtimeJson.get("float_market_capital")); realtimeJson.put("peForecast", realtimeJson.get("pe_forecast")); realtimeJson.put("volumeRatio", realtimeJson.get("volume_ratio")); realtimeJson.put("turnoverRate", realtimeJson.get("turnover_rate")); Realtime realtime = new Realtime(); // realtime.setUuid(ApplicationUtil.getCurrentTimeUUID()); String currency = realtimeJson.getString("currency"); int decimal = itemService.getDecimal(currency); String symbolByRemarks = itemService.getSymbolByRemarks(currency); realtime.setSymbol(symbolByRemarks); realtime.setName(symbolByRemarks); Long timestamp = realtimeJson.getLong("timestamp"); if (timestamp.toString().length() > 13) { timestamp = timestamp / 1000; } realtime.setTs(timestamp); realtime.setOpen(realtimeJson.getBigDecimal("open").setScale(decimal, RoundingMode.HALF_UP).doubleValue()); if (realtimeJson.getBigDecimal("mid").compareTo(BigDecimal.ZERO) != 0) { realtime.setClose(realtimeJson.getBigDecimal("mid").setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } else { realtime.setClose(realtimeJson.getBigDecimal("close").setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } realtime.setHigh(realtimeJson.getBigDecimal("high").setScale(decimal, RoundingMode.HALF_UP).doubleValue()); realtime.setLow(realtimeJson.getBigDecimal("low").setScale(decimal, RoundingMode.HALF_UP).doubleValue()); realtime.setMarketCapital(realtimeJson.getLong("marketCapital")); realtime.setFloatMarketCapital(realtimeJson.getLong("floatMarketCapital")); BigDecimal peForecast = realtimeJson.getBigDecimal("peForecast"); if (peForecast != null) { realtime.setPeForecast(peForecast.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal volumeRatio = realtimeJson.getBigDecimal("volumeRatio"); if (volumeRatio != null) { realtime.setVolumeRatio(volumeRatio.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal turnoverRate = realtimeJson.getBigDecimal("turnoverRate"); if (turnoverRate != null) { realtime.setTurnoverRate(turnoverRate.setScale(2, RoundingMode.HALF_UP).doubleValue()); } BigDecimal navps = realtimeJson.getBigDecimal("navps"); if (navps != null) { realtime.setNavps(navps.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal pb = realtimeJson.getBigDecimal("pb"); if (pb != null) { realtime.setPb(pb.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal amplitude = realtimeJson.getBigDecimal("amplitude"); if (amplitude != null) { realtime.setAmplitude(amplitude.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal eps = realtimeJson.getBigDecimal("eps"); if (eps != null) { realtime.setEps(eps.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal chg = realtimeJson.getBigDecimal("chg"); if (chg != null) { realtime.setChg(chg.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal percent = realtimeJson.getBigDecimal("percent"); if (percent != null) { realtime.setPercent(percent.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal amount = realtimeJson.getBigDecimal("amount"); if (amount == null) { amount = BigDecimal.ZERO; } realtime.setAmount(amount.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); BigDecimal volume = realtimeJson.getBigDecimal("volume"); if (volume == null) { volume = BigDecimal.ZERO; } BigDecimal averagePrice = realtimeJson.getBigDecimal("averagePrice"); if (averagePrice != null) { realtime.setAveragePrice(averagePrice.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal earningsRatio = realtimeJson.getBigDecimal("earningsRatio"); if (earningsRatio != null) { realtime.setEarningsRatio(earningsRatio.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } Long issuedShares = realtimeJson.getLong("issuedShares"); if (issuedShares != null) { realtime.setIssuedShares(issuedShares); } BigDecimal dailyLimit = realtimeJson.getBigDecimal("dailyLimit"); if (dailyLimit != null) { realtime.setDailyLimit(dailyLimit.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal limitDown = realtimeJson.getBigDecimal("limitDown"); if (limitDown != null) { realtime.setLimitDown(limitDown.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal w52High = realtimeJson.getBigDecimal("w52High"); if (w52High != null) { realtime.setW52High(w52High.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal w52Low = realtimeJson.getBigDecimal("w52Low"); if (w52Low != null) { realtime.setW52Low(w52Low.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal internalVolume = realtimeJson.getBigDecimal("internalVolume"); if (internalVolume != null) { realtime.setInternalVolume(internalVolume.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal externalVolume = realtimeJson.getBigDecimal("externalVolume"); if (externalVolume != null) { realtime.setExternalVolume(externalVolume.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal epsYear = realtimeJson.getBigDecimal("epsYear"); if (epsYear != null) { realtime.setEpsYear(epsYear.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal epsQuarter = realtimeJson.getBigDecimal("epsQuarter"); if (epsQuarter != null) { realtime.setEpsQuarter(epsQuarter.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal grossProfitMargin = realtimeJson.getBigDecimal("grossProfitMargin"); if (grossProfitMargin != null) { realtime.setGrossProfitMargin(grossProfitMargin.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal netValuePerShare = realtimeJson.getBigDecimal("netValuePerShare"); if (netValuePerShare != null) { realtime.setNetValuePerShare(netValuePerShare.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal priceToNetRatio = realtimeJson.getBigDecimal("priceToNetRatio"); if (priceToNetRatio != null) { realtime.setPriceToNetRatio(priceToNetRatio.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal profitMargin = realtimeJson.getBigDecimal("profitMargin"); if (profitMargin != null) { realtime.setProfitMargin(profitMargin.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal annualDividend = realtimeJson.getBigDecimal("annualDividend"); if (annualDividend != null) { realtime.setAnnualDividend(annualDividend.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal yield = realtimeJson.getBigDecimal("yield"); if (yield != null) { realtime.setYield(yield.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } BigDecimal netProfitMargin = realtimeJson.getBigDecimal("netProfitMargin"); if (netProfitMargin != null) { realtime.setNetProfitMargin(netProfitMargin.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); } realtime.setVolume(volume.setScale(decimal, RoundingMode.HALF_UP).doubleValue()); realtime.setAsk(realtimeJson.getBigDecimal("ask").setScale(decimal, RoundingMode.HALF_UP).doubleValue()); realtime.setBid(realtimeJson.getBigDecimal("bid").setScale(decimal, RoundingMode.HALF_UP).doubleValue()); list.add(realtime); } return list; } public List fetchRealtimeList(String remarks) { return fetchRealtimeList(remarks, REALTIME_HASH); } public List getMarkets(String remaks) { List list = new ArrayList<>(); RMap map = redissonClientSpider.getMap(MARKET_HASH); Set keys = Splitter.on(",").trimResults().splitToStream(remaks).collect(Collectors.toSet()); Map values = map.getAll(keys); for (String symbol : values.keySet()) { list.add(JSONObject.parseObject(values.get(symbol), StockMarket.class)); } return list; } public List pankous(String remaks) { List list = new ArrayList<>(); RMap map = redissonClientSpider.getMap(PANKOU_HASH); Set keys = Splitter.on(",").trimResults().splitToStream(remaks).collect(Collectors.toSet()); Map values = map.getAll(keys); for (String symbol : values.keySet()) { list.add(JSONObject.parseObject(values.get(symbol), Depth.class)); } return list; } public void tradeList(String remarks, boolean isUSStock) { RMap map = redissonClientSpider.getMap(TRADER_HASH); Set keys = Splitter.on(",").trimResults().splitToStream(remarks).collect(Collectors.toSet()); Map values = map.getAll(keys); for (String s : values.keySet()) { List tradeDetails = JSONObject.parseArray(values.get(s), TradeDetails.class); if (!tradeDetails.isEmpty()) { String symbol = itemService.getSymbolByRemarks(tradeDetails.get(0).getSymbol()); DataCache.putStockTradeList(symbol, tradeDetails); tradeListToTrade(symbol, tradeDetails); if (isUSStock) { setTradeListToDepth(symbol, tradeDetails); } } } } public static void setTradeListToDepth(String symbol, List tradeDetails) { Depth depth = new Depth(); depth.setTs(tradeDetails.get(0).getTimestamp() / 1000); depth.setSymbol(symbol); List asks = tradeDetails.stream().filter(t -> t.getSide() == -1).map(t -> { DepthEntry depthEntry = new DepthEntry(); depthEntry.setAmount((double) t.getTrade_volume()); depthEntry.setPrice(t.getCurrent()); return depthEntry; }).collect(Collectors.toList()); List bids = tradeDetails.stream().filter(t -> t.getSide() == 1).map(t -> { DepthEntry depthEntry = new DepthEntry(); depthEntry.setAmount((double) t.getTrade_volume()); depthEntry.setPrice(t.getCurrent()); return depthEntry; }).collect(Collectors.toList()); depth.setAsks(asks); depth.setBids(bids); DepthTimeObject timeObject = new DepthTimeObject(); timeObject.setDepth(depth); DataCache.putDepth(depth.getSymbol(), timeObject); } public static void tradeListToTrade(String symbol, List tradeDetails) { TradeTimeObject timeObject = DataCache.getTrade(symbol); if (timeObject == null) { timeObject = new TradeTimeObject(); } List data = tradeDetails.stream().map(a -> { TradeEntry tradeEntry = new TradeEntry(); tradeEntry.setDirection(a.getSide() == 1 ? "sell" : "buy"); tradeEntry.setAmount((double) a.getTrade_volume()); tradeEntry.setPrice(a.getCurrent()); tradeEntry.setTs(a.getTimestamp() / 1000); return tradeEntry; }).collect(Collectors.toList()); timeObject.put(symbol, data); DataCache.putTrade(symbol, timeObject); } public List>> getKlines(String symbols) { List remarksList = Splitter.on(",").omitEmptyStrings().splitToList(symbols).stream().map(s -> itemService.findBySymbol(s).getRemarks()).collect(Collectors.toList()); String remarks = remarksList.stream().collect(Collectors.joining(",")); List>> list = new ArrayList<>(); List dataList = new ArrayList<>(); for (String symbol : remarksList) { RMap map = redissonClientSpider.getMap(KLINE_SYMBOL + symbol); JSONObject data = new JSONObject(); JSONObject jsonObject = new JSONObject(); map.keySet().forEach(k -> { jsonObject.put(k, JSONObject.parseArray(map.get(k))); }); data.put(symbol, jsonObject); dataList.add(data); } try { for (int i = 0; i < dataList.size(); i++) { Map> map = new HashMap<>(); JSONObject klineJson = dataList.get(i); for (String s : remarksList) { if (klineJson.containsKey(s)) { JSONObject jsonObject = klineJson.getJSONObject(s); Set periods = jsonObject.keySet(); for (String period : periods) { JSONArray jsonArray = jsonObject.getJSONArray(period); if(jsonArray != null){ List javaList = jsonArray.toJavaList(Kline.class); javaList.forEach(k -> k.setSymbol(itemService.getSymbolByRemarks(s))); map.put(period, javaList); } } list.add(map); } } } }catch (Exception e) { log.error("getKlines error", e); } return list; } }