package org.example.server.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.reflect.TypeToken; import com.google.gson.Gson; import lombok.Data; import org.apache.commons.lang.StringUtils; import org.example.dao.CurrencyMapper; import org.example.pojo.Currency; import org.example.pojo.Market; import org.example.pojo.bo.AsksBo; import org.example.pojo.bo.BidsBo; import org.example.pojo.bo.MarketBo; import org.example.server.CurrencySerivce; import org.example.util.RedisUtil; import org.springframework.stereotype.Service; import org.yaml.snakeyaml.error.Mark; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; import java.util.ArrayList; import java.util.stream.Collectors; /** * @program: demo * @description: * @create: 2024-07-16 15:23 **/ @Service public class CurrencySerivceImpl extends ServiceImpl implements CurrencySerivce { private HashMap hashMap = new HashMap(); private static final Gson gson = new Gson(); private ArrayList keys; List mexcList = new ArrayList<>(); List gateList = new ArrayList<>(); List bitgetList = new ArrayList<>(); List kucoinList = new ArrayList<>(); @Override public void start() throws JsonProcessingException { Set mexcSet = RedisUtil.keys("mexc"); Set gateSet = RedisUtil.keys("gate"); Set bitgetSet = RedisUtil.keys("bitget"); Set kucoinSet = RedisUtil.keys("kucoin"); //这里做一个定时器,每10分钟更新一次 Set setKeys = RedisUtil.keys("*"); keys = new ArrayList<>(setKeys); for (String key : mexcSet) { MarketBo marketBo = new MarketBo(); String v = RedisUtil.get(key); Map redisValueMap = gson.fromJson(v, new TypeToken>() {}.getType()); String asks = redisValueMap.get("asks").toString(); String bids = redisValueMap.get("bids").toString(); if(!asks.equals("[]") && !StringUtils.isEmpty(asks)){ Gson gson = new Gson(); AsksBo asksBo = new AsksBo(); Market[] asksDataArray = gson.fromJson(asks, Market[].class); Market asksElement = asksDataArray[0]; asksBo.setP(asksElement.getP()); asksBo.setV(asksElement.getV()); marketBo.setAsks(asksBo); } if(!bids.equals("[]") && !StringUtils.isEmpty(bids)){ BidsBo bidsBo = new BidsBo(); Market[] bidsDataArray = gson.fromJson(bids, Market[].class); Market bidsElement = bidsDataArray[bidsDataArray.length-1]; bidsBo.setP(bidsElement.getP()); bidsBo.setV(bidsElement.getV()); marketBo.setBids(bidsBo); } marketBo.setKey(key.replaceAll("mexc","")); marketBo.setExchange("mexc"); mexcList.add(marketBo); } for (String key : gateSet) { String v = RedisUtil.get(key); Map redisValueMap = gson.fromJson(v, new TypeToken>() {}.getType()); String asks = redisValueMap.get("asks").toString(); String bids = redisValueMap.get("bids").toString(); MarketBo marketBo = new MarketBo(); if(!asks.equals("[]") && !StringUtils.isEmpty(asks)){ String[][] dataArray = gson.fromJson(asks, String[][].class); String[] asksData = dataArray[0]; AsksBo asksBo = new AsksBo(); asksBo.setP(new BigDecimal(asksData[0])); asksBo.setV(new BigDecimal(asksData[1])); marketBo.setAsks(asksBo); } if(!bids.equals("[]") && !StringUtils.isEmpty(bids)){ String[][] dataArray = gson.fromJson(bids, String[][].class); String[] bidsData = dataArray[dataArray.length-1]; BidsBo bidsBo = new BidsBo(); bidsBo.setP(new BigDecimal(bidsData[0])); bidsBo.setV(new BigDecimal(bidsData[1])); marketBo.setBids(bidsBo); } marketBo.setKey(key.replaceAll("gate","")); marketBo.setExchange("gate"); gateList.add(marketBo); } for (String key : bitgetSet) { String v = RedisUtil.get(key); Map redisValueMap = gson.fromJson(v, new TypeToken>() {}.getType()); String asks = redisValueMap.get("asks").toString(); String bids = redisValueMap.get("bids").toString(); MarketBo marketBo = new MarketBo(); if(!asks.equals("[]") && !StringUtils.isEmpty(asks)){ String[][] dataArray = gson.fromJson(asks, String[][].class); String[] asksData = dataArray[0]; AsksBo asksBo = new AsksBo(); asksBo.setP(new BigDecimal(asksData[0])); asksBo.setV(new BigDecimal(asksData[1])); marketBo.setAsks(asksBo); } if(!bids.equals("[]") && !StringUtils.isEmpty(bids)){ String[][] dataArray = gson.fromJson(bids, String[][].class); String[] bidsData = dataArray[dataArray.length-1]; BidsBo bidsBo = new BidsBo(); bidsBo.setP(new BigDecimal(bidsData[0])); bidsBo.setV(new BigDecimal(bidsData[1])); marketBo.setBids(bidsBo); } marketBo.setKey(key.replaceAll("bitget","")); marketBo.setExchange("bitget"); bitgetList.add(marketBo); } for (String key : kucoinSet) { String v = RedisUtil.get(key); Map redisValueMap = gson.fromJson(v, new TypeToken>() {}.getType()); String asks = redisValueMap.get("asks").toString(); String bids = redisValueMap.get("bids").toString(); MarketBo marketBo = new MarketBo(); if(!asks.equals("[]") && !StringUtils.isEmpty(asks)){ String[][] dataArray = gson.fromJson(asks, String[][].class); String[] asksData = dataArray[0]; AsksBo asksBo = new AsksBo(); asksBo.setP(new BigDecimal(asksData[0])); asksBo.setV(new BigDecimal(asksData[1])); marketBo.setAsks(asksBo); } if(!bids.equals("[]") && !StringUtils.isEmpty(bids)){ String[][] dataArray = gson.fromJson(bids, String[][].class); String[] bidsData = dataArray[dataArray.length-1]; BidsBo bidsBo = new BidsBo(); bidsBo.setP(new BigDecimal(bidsData[0])); bidsBo.setV(new BigDecimal(bidsData[1])); marketBo.setBids(bidsBo); } marketBo.setKey(key.replaceAll("kucoin","")); marketBo.setExchange("kucoin"); kucoinList.add(marketBo); } testDemo(); } // 计算利润百分比 private static BigDecimal calculateProfitPercentage(BigDecimal buyPrice, BigDecimal sellPrice) { BigDecimal profit = sellPrice.subtract(buyPrice); if (buyPrice.compareTo(BigDecimal.ZERO) == 0) { return BigDecimal.ZERO; // 防止除以零 } BigDecimal profitPercentage = profit.divide(buyPrice, 12, RoundingMode.DOWN).multiply(new BigDecimal(100)); return profitPercentage; } private static List findProfitablePairs(List... exchangeLists) { List result = new ArrayList<>(); Map> marketMap = new HashMap<>(); // 按币种名称和交易所分组市场数据 for (List exchangeList : exchangeLists) { for (MarketBo market : exchangeList) { String coinName = market.getKey(); String exchangeName = market.getExchange(); // 假设有获取交易所名称的方法 getExchange() // 如果该币种在该交易所不存在,则创建新的列表 if (!marketMap.containsKey(coinName)) { marketMap.put(coinName, new HashMap<>()); } if (!marketMap.get(coinName).containsKey(exchangeName)) { marketMap.get(coinName).put(exchangeName, new MarketBo()); } // 将市场数据添加到对应的交易所列表中 marketMap.get(coinName).put(exchangeName,market); } } marketMap = marketMap.entrySet().stream() .filter(entry -> entry.getValue().size() != 1) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); // 遍历每个币种 for (String coinName : marketMap.keySet()) { Map exchangeMap = marketMap.get(coinName); // 遍历每个交易所 for (String exchangeName : exchangeMap.keySet()) { MarketBo markets1 = exchangeMap.get(exchangeName); // 在同一交易所中寻找有差价的交易对 for (String exchangeName2 : exchangeMap.keySet()) { MarketBo markets2 = exchangeMap.get(exchangeName2); if(markets1.getExchange().equals(markets2.getExchange())){ continue; } if(null != markets1.getBids() && null != markets2.getAsks()){ BigDecimal buyPrice = markets1.getBids().getP(); BigDecimal sellPrice = markets2.getAsks().getP(); // 计算利润百分比 BigDecimal profitPercentage = calculateProfitPercentage(buyPrice, sellPrice); // 如果利润大于零,则添加到结果列表 if (profitPercentage.compareTo(BigDecimal.ZERO) > 0) { // 准备输出字符串 String pair = String.format("%s: 在 %s 以 %s 买入,在 %s 以 %s 卖出,利润为 %.4f%%", coinName, markets1.getExchange(), buyPrice, markets2.getExchange(), sellPrice, profitPercentage); result.add(pair); } } } } } return result; } public void testDemo(){ List profitablePairs = findProfitablePairs(mexcList, gateList, bitgetList, kucoinList); // 输出结果 for (String pair : profitablePairs) { System.out.println(pair); } } }