package com.xcong.excoin.modules.symbols.service.impl; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONObject; import com.huobi.client.model.Candlestick; import com.xcong.excoin.common.contants.AppContants; import com.xcong.excoin.common.enumerates.SymbolEnum; import com.xcong.excoin.common.response.Result; import com.xcong.excoin.common.system.mapper.CandlestickMapper; import com.xcong.excoin.modules.platform.dao.PlatformCnyUsdtExchangeDao; import com.xcong.excoin.modules.platform.entity.PlatformCnyUsdtExchangeEntity; import com.xcong.excoin.modules.symbols.parameter.dto.KlineDetailDto; import com.xcong.excoin.modules.symbols.parameter.vo.HomeSymbolsVo; import com.xcong.excoin.modules.symbols.parameter.vo.KlineDataVo; import com.xcong.excoin.modules.symbols.service.SymbolsService; import com.xcong.excoin.utils.CoinTypeConvert; import com.xcong.excoin.utils.RedisUtils; import com.xcong.excoin.utils.api.ApiClient; import com.xcong.excoin.utils.api.response.Kline; import com.xcong.excoin.utils.api.response.KlineResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; /** * @author wzy * @date 2020-05-26 **/ @Slf4j @Service public class SymbolsServiceImpl implements SymbolsService { @Resource private RedisUtils redisUtils; @Resource private PlatformCnyUsdtExchangeDao platformCnyUsdtExchangeDao; private static final String API_KEY = "3938f004-bfe31905-f7581c1a-6abe0"; private static final String API_SECRET = "a0f7a154-ghxertfvbf-6ce2d90c-a0bab"; private static volatile ApiClient client; private static ApiClient getClient() { if (client == null) { synchronized (ApiClient.class) { if (client == null) { client = new ApiClient(API_KEY, API_SECRET); } } } return client; } @Override public void updateSymbolsKine(String time) { synchronized (this) { //更新币币交易K线历史数据 for (SymbolEnum symbol : SymbolEnum.values()) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } String[] symbols = symbol.getValue().toLowerCase().split("/"); ApiClient client = getClient(); KlineResponse kline = client.kline(symbols[0] + symbols[1], time, 1000 + ""); if (kline != null) { if ("ok".equalsIgnoreCase(kline.getStatus())) { List klines = (List) kline.data; List list = new ArrayList(); Candlestick candlestick = null; for (Kline kline1 : klines) { candlestick = new Candlestick(); candlestick.setAmount(BigDecimal.valueOf(kline1.getAmount())); candlestick.setClose(BigDecimal.valueOf(kline1.getClose())); candlestick.setCount(kline1.getCount()); candlestick.setHigh(BigDecimal.valueOf(kline1.getHigh())); candlestick.setLow(BigDecimal.valueOf(kline1.getLow())); candlestick.setVolume(BigDecimal.valueOf(kline1.getVol())); candlestick.setTimestamp(kline1.getId() * 1000); candlestick.setOpen(BigDecimal.valueOf(kline1.getOpen())); list.add(candlestick); } if (klines.size() > 0) { redisUtils.set("KINE_" + symbol.getValue() + "_" + time, list); } } } } } } @Override public Result homeSymbols(Integer type) { List list = new ArrayList<>(); // 币币行情 if (AppContants.HOME_SYMBOLS_COIN == type) { for (SymbolEnum symbolEnum : SymbolEnum.values()) { list.add(getSymbolReturnData(symbolEnum.getValue())); } // 合约行情 } else if (AppContants.HOME_SYMBOLS_CONTRACT == type) { for (SymbolEnum symbolEnum : SymbolEnum.values()) { list.add(getSymbolReturnData(symbolEnum.getValue())); } // 自选行情 } else { } return Result.ok(list); } @Override public Result findSymbolData(String symbol) { HomeSymbolsVo homeSymbolsVo = getSymbolReturnData(symbol); return Result.ok(homeSymbolsVo); } public HomeSymbolsVo getSymbolReturnData(String symbol) { PlatformCnyUsdtExchangeEntity cnyUsdtExchange = platformCnyUsdtExchangeDao.getCNYAndUSDTOne(); // 获取当日k线数据 Candlestick symbolObject = (Candlestick) redisUtils.get(symbol); // 获取当前币种最新价 BigDecimal newestPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol))); // 获取当日k线的开盘价 BigDecimal openPrice = symbolObject.getOpen(); BigDecimal upOrDown = newestPrice.subtract(openPrice).divide(openPrice, 8, BigDecimal.ROUND_HALF_UP); HomeSymbolsVo homeSymbolsVo = new HomeSymbolsVo(); homeSymbolsVo.setSymbol(symbol); homeSymbolsVo.setCurrentPrice(newestPrice); homeSymbolsVo.setUpOrDown(upOrDown); homeSymbolsVo.setVolume(symbolObject.getAmount()); if (cnyUsdtExchange != null) { BigDecimal cnyPrice = newestPrice.multiply(cnyUsdtExchange.getValue()).setScale(2, BigDecimal.ROUND_HALF_UP); homeSymbolsVo.setCnyPrice(cnyPrice); } return homeSymbolsVo; } @Override public Result findKlineDetails(KlineDetailDto klineDetailDto) { String key = "KINE_{}_{}"; // 币币k线数据 if (AppContants.HOME_SYMBOLS_COIN == klineDetailDto.getType()) { key = StrUtil.format(key, klineDetailDto.getSymbol(), klineDetailDto.getPeriod()); // 合约k线数据 } else { key = StrUtil.format(key, klineDetailDto.getSymbol(), klineDetailDto.getPeriod()); } Object data = redisUtils.get(key); if (data != null) { List list = (List) data; int length = 0; // 默认获取k线900个柱状(超出会报错) int size = 900; if (list.size() > size) { length = size - 1; } else { length = list.size() - 1; } List result = new ArrayList<>(length); for (int i = length; i > 0; i--) { Candlestick object = (Candlestick) list.get(i); KlineDataVo klineDataVo = CandlestickMapper.INSTANCE.toKlineDataVo(object); result.add(klineDataVo); } return Result.ok(result); } return Result.fail("获取数据失败"); } }