CoinService2Impl.java 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package top.lvzhiqiang.service.impl;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.apache.commons.codec.binary.Hex;
  6. import org.apache.commons.lang3.StringUtils;
  7. import org.jsoup.Connection;
  8. import org.springframework.stereotype.Service;
  9. import org.springframework.transaction.annotation.Propagation;
  10. import org.springframework.transaction.annotation.Transactional;
  11. import top.lvzhiqiang.entity.CoinBinanceOrderHistory;
  12. import top.lvzhiqiang.entity.CoinBinanceSymbol;
  13. import top.lvzhiqiang.mapper.CoinMapper;
  14. import top.lvzhiqiang.util.JsoupUtil;
  15. import javax.annotation.Resource;
  16. import javax.crypto.Mac;
  17. import javax.crypto.spec.SecretKeySpec;
  18. import javax.management.RuntimeErrorException;
  19. import java.math.BigDecimal;
  20. import java.math.RoundingMode;
  21. import java.net.Proxy;
  22. import java.nio.charset.StandardCharsets;
  23. import java.security.InvalidKeyException;
  24. import java.security.NoSuchAlgorithmException;
  25. import java.util.*;
  26. import java.util.stream.Collectors;
  27. /**
  28. * Coin ServiceImpl
  29. *
  30. * @author lvzhiqiang
  31. * 2023/9/5 15:23
  32. */
  33. @Service
  34. @Slf4j
  35. public class CoinService2Impl implements CoinService2 {
  36. private static final String secretKey = "Do5YDooH9OFimHXsF6nhi7rTZfxIZWWxaP35zsBEktGvCbogtbzBHpJs5cdVmple";
  37. private static final String apiKey = "1qY3LgxmNcW1dku8NiL8NWX8KZG4SBevXHtqLFgzWZbAuJ207CUuf0FSNzIAONh5";
  38. @Resource
  39. private CoinMapper coinMapper;
  40. private static Mac MAC;
  41. static {
  42. try {
  43. CoinService2Impl.MAC = Mac.getInstance("HmacSHA256");
  44. } catch (NoSuchAlgorithmException var1) {
  45. throw new RuntimeErrorException(new Error("Can't get Mac's instance."));
  46. }
  47. }
  48. @Override
  49. @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
  50. public void syncData4Binance(String startTime, String endTime, String pageSize) {
  51. String baseUrl = "https://fapi.binance.com";
  52. String businessUrl;
  53. String businessUrl2;
  54. Connection.Response response = null;
  55. Proxy proxy = Proxy.NO_PROXY;
  56. Map<String, String> paramMap = new LinkedHashMap<>();
  57. Map<String, String> headerMap = new HashMap<>();
  58. // 1同步合约交易对
  59. /*try {
  60. businessUrl = "/fapi/v1/exchangeInfo";
  61. response = JsoupUtil.requestBody(baseUrl + businessUrl, "GET", proxy, headerMap, paramMap);
  62. JSONArray symbolList = JSONObject.parseObject(response.body()).getJSONArray("symbols");
  63. if (symbolList.size() > 0) {
  64. coinMapper.insertCoinBinanceSymbolList(JSONArray.parseArray(symbolList.toJSONString(), CoinBinanceSymbol.class));
  65. log.warn("syncData4Binance->exchangeInfo,startTime={},endTime={},size={}", startTime, endTime, symbolList.size());
  66. }
  67. } catch (Exception e) {
  68. log.error("syncData4Binance->exchangeInfo error,response={}", response, e);
  69. }*/
  70. // 2同步订单历史
  71. // 2.1获取合约交易对
  72. Map<String, Object> queryParamMap = new HashMap<>();
  73. queryParamMap.put("status", "TRADING");
  74. queryParamMap.put("marginAsset", "USDT");
  75. queryParamMap.put("contractType", "PERPETUAL");
  76. queryParamMap.put("sortField", "onboardDate");
  77. queryParamMap.put("sort", "desc");
  78. List<CoinBinanceSymbol> coinBinanceSymbolList = coinMapper.findCoinBinanceSymbolListByParams(queryParamMap);
  79. // 2.2获取历史订单号集合
  80. List<String> orderIdList = coinMapper.findAllCoinBinanceOrderIdList();
  81. // 2.3循环调取查询所有订单(包括历史订单)接口
  82. headerMap.put("X-MBX-APIKEY", apiKey);
  83. try {
  84. businessUrl = "/fapi/v1/allOrders";
  85. businessUrl2 = "/fapi/v1/userTrades";
  86. for (CoinBinanceSymbol coinBinanceSymbol : coinBinanceSymbolList) {
  87. List<CoinBinanceOrderHistory> coinBinanceOrderHistoryListAll = new ArrayList<>();
  88. //权重: 5;每12秒调1次
  89. Thread.sleep(12000L);
  90. paramMap.clear();
  91. String timestamp = String.valueOf(System.currentTimeMillis());
  92. paramMap.put("symbol", coinBinanceSymbol.getSymbol());
  93. paramMap.put("startTime", startTime);
  94. paramMap.put("endTime", endTime);
  95. paramMap.put("timestamp", timestamp);
  96. String queryString = paramMap.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining("&"));
  97. String sign = generate("", "", "", queryString, null, secretKey);
  98. paramMap.put("signature", sign);
  99. try {
  100. response = JsoupUtil.requestBody(baseUrl + businessUrl, "GET", proxy, headerMap, paramMap);
  101. JSONArray orderList = JSONArray.parseArray(response.body());
  102. if (orderList != null && orderList.size() > 0) {
  103. List<CoinBinanceOrderHistory> coinBinanceOrderHistoryList = JSONArray.parseArray(orderList.toJSONString(), CoinBinanceOrderHistory.class);
  104. for (CoinBinanceOrderHistory coinBinanceOrderHistory : coinBinanceOrderHistoryList) {
  105. if (orderIdList.contains(coinBinanceOrderHistory.getOrderId())) {
  106. continue;
  107. }
  108. paramMap.clear();
  109. timestamp = String.valueOf(System.currentTimeMillis());
  110. paramMap.put("symbol", coinBinanceSymbol.getSymbol());
  111. paramMap.put("orderId", coinBinanceOrderHistory.getOrderId());
  112. paramMap.put("startTime", startTime);
  113. paramMap.put("endTime", endTime);
  114. paramMap.put("timestamp", timestamp);
  115. queryString = paramMap.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(Collectors.joining("&"));
  116. sign = generate("", "", "", queryString, null, secretKey);
  117. paramMap.put("signature", sign);
  118. response = JsoupUtil.requestBody(baseUrl + businessUrl2, "GET", proxy, headerMap, paramMap);
  119. JSONArray userTradeList = JSONArray.parseArray(response.body());
  120. BigDecimal commission = BigDecimal.ZERO;
  121. BigDecimal realizedPnl = BigDecimal.ZERO;
  122. if (userTradeList != null && userTradeList.size() > 0) {
  123. for (int i = 0; i < userTradeList.size(); i++) {
  124. JSONObject userTradeJO = userTradeList.getJSONObject(i);
  125. commission = commission.add(new BigDecimal(userTradeJO.getString("commission")));
  126. realizedPnl = realizedPnl.add(new BigDecimal(userTradeJO.getString("realizedPnl")));
  127. }
  128. coinBinanceOrderHistory.setCommission(commission.setScale(4, RoundingMode.HALF_UP));
  129. coinBinanceOrderHistory.setRealizedPnl(realizedPnl.setScale(4, RoundingMode.HALF_UP));
  130. }
  131. coinBinanceOrderHistoryListAll.add(coinBinanceOrderHistory);
  132. System.out.println(coinBinanceOrderHistory);
  133. }
  134. }
  135. if (coinBinanceOrderHistoryListAll.size() > 0) {
  136. coinMapper.insertOrUpdateBinanceOrderHistoryList(coinBinanceOrderHistoryListAll);
  137. log.warn("syncData4Binance->allOrders sub,startTime={},endTime={},size={}", startTime, endTime, coinBinanceOrderHistoryListAll.size());
  138. }
  139. } catch (Exception ee) {
  140. log.error("syncData4Binance->allOrders sub error,response={}", response, ee);
  141. }
  142. }
  143. } catch (Exception e) {
  144. log.error("syncData4Binance->allOrders error,response={}", response, e);
  145. }
  146. }
  147. private static String generate(String timestamp, String method, String requestPath,
  148. String queryString, String body, String secretKey)
  149. throws CloneNotSupportedException, InvalidKeyException {
  150. method = StringUtils.defaultIfBlank(method.toUpperCase(), StringUtils.EMPTY);
  151. body = StringUtils.defaultIfBlank(body, StringUtils.EMPTY);
  152. queryString = StringUtils.isBlank(queryString) ? StringUtils.EMPTY : (StringUtils.isEmpty(method) ? "" : "?") + queryString;
  153. String preHash = timestamp + method + requestPath + queryString + body;
  154. //log.info("preHash:{}", preHash);
  155. byte[] secretKeyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
  156. SecretKeySpec secretKeySpec = new SecretKeySpec(secretKeyBytes, "HmacSHA256");
  157. Mac mac = (Mac) CoinService2Impl.MAC.clone();
  158. mac.init(secretKeySpec);
  159. return new String(new Hex().encode(mac.doFinal(preHash.getBytes(StandardCharsets.UTF_8))), StandardCharsets.UTF_8);
  160. }
  161. }