From 3ffaa6bf323862a3770897d4e934baf98d324c47 Mon Sep 17 00:00:00 2001 From: zainali5120 <512061637@qq.com> Date: Sun, 20 Sep 2020 23:39:55 +0800 Subject: [PATCH] 撮合交易代码提交 --- src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java | 7 src/test/java/com/xcong/excoin/TradeTest.java | 34 +++ src/main/java/com/xcong/excoin/utils/CoinTypeConvert.java | 12 src/main/java/com/xcong/excoin/websocket/TradePlateSendWebSocket.java | 8 src/main/java/com/xcong/excoin/common/enumerates/CoinTypeEnum.java | 2 src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java | 2 src/main/java/com/xcong/excoin/rabbit/init/OrderProducerInit.java | 2 src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java | 6 src/main/java/com/xcong/excoin/modules/coin/parameter/vo/OrderWalletCoinVo.java | 6 pom.xml | 2 src/main/java/com/xcong/excoin/modules/blackchain/service/RocService.java | 33 +++ src/main/java/com/xcong/excoin/modules/symbols/controller/SymbolsController.java | 1 src/main/java/com/xcong/excoin/modules/blackchain/model/RocCreateAcoountModel.java | 10 src/main/java/com/xcong/excoin/modules/symbols/constants/SymbolsConstats.java | 12 + src/main/java/com/xcong/excoin/quartz/job/NewestPriceUpdateJob.java | 4 src/main/java/com/xcong/excoin/quartz/job/CoinTradeInitJob.java | 7 src/main/java/com/xcong/excoin/rabbit/consumer/ExchangeConsumer.java | 2 src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java | 335 ++++++++++++++++++------------ src/main/resources/mapper/member/MemberWalletCoinDao.xml | 12 src/main/java/com/xcong/excoin/modules/blackchain/service/Impl/BlockSeriveImpl.java | 11 src/main/java/com/xcong/excoin/common/enumerates/SymbolEnum.java | 2 src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java | 2 src/main/resources/application-test.yml | 18 src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java | 6 src/main/java/com/xcong/excoin/rabbit/consumer/OperateOrderPriceConsumer.java | 2 src/main/java/com/xcong/excoin/modules/coin/controller/OrderCoinController.java | 7 src/main/java/com/xcong/excoin/modules/symbols/service/impl/SymbolsServiceImpl.java | 5 src/main/java/com/xcong/excoin/quartz/job/UsdtCnyExchangePriceUpdateJob.java | 5 src/main/java/com/xcong/excoin/quartz/job/KLineGeneratorJob.java | 49 +--- src/main/java/com/xcong/excoin/trade/CoinTrader.java | 13 + 30 files changed, 399 insertions(+), 218 deletions(-) diff --git a/pom.xml b/pom.xml index c77623f..c565c51 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ </parent> <groupId>com.xcong</groupId> <artifactId>excoin</artifactId> - <version>0.0.1-SNAPSHOT</version> + <version>roc</version> <name>excoin</name> <description>Demo project for Spring Boot</description> diff --git a/src/main/java/com/xcong/excoin/common/enumerates/CoinTypeEnum.java b/src/main/java/com/xcong/excoin/common/enumerates/CoinTypeEnum.java index 720342a..f50807c 100644 --- a/src/main/java/com/xcong/excoin/common/enumerates/CoinTypeEnum.java +++ b/src/main/java/com/xcong/excoin/common/enumerates/CoinTypeEnum.java @@ -6,5 +6,5 @@ * @author wzy */ public enum CoinTypeEnum { - USDT, BTC, ETH, LTC, EOS, XRP, BCH, ETC + USDT, BTC, ETH, LTC, EOS, XRP, BCH, ETC,ROC } diff --git a/src/main/java/com/xcong/excoin/common/enumerates/SymbolEnum.java b/src/main/java/com/xcong/excoin/common/enumerates/SymbolEnum.java index 70888bd..17a811f 100644 --- a/src/main/java/com/xcong/excoin/common/enumerates/SymbolEnum.java +++ b/src/main/java/com/xcong/excoin/common/enumerates/SymbolEnum.java @@ -15,7 +15,7 @@ ,EOS("EOS", "EOS/USDT") ,XRP("XRP", "XRP/USDT") ,ETC("ETC", "ETC/USDT") - ,NEKK("NEKK", "NEKK/USDT"); + ,ROC("ROC", "ROC/USDT"); private String name; diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/model/RocCreateAcoountModel.java b/src/main/java/com/xcong/excoin/modules/blackchain/model/RocCreateAcoountModel.java new file mode 100644 index 0000000..d0d7d04 --- /dev/null +++ b/src/main/java/com/xcong/excoin/modules/blackchain/model/RocCreateAcoountModel.java @@ -0,0 +1,10 @@ +package com.xcong.excoin.modules.blackchain.model; + +import lombok.Data; + +@Data +public class RocCreateAcoountModel { + private String password; + private String walletName; + private String terminalId; +} diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/service/Impl/BlockSeriveImpl.java b/src/main/java/com/xcong/excoin/modules/blackchain/service/Impl/BlockSeriveImpl.java index 87d9239..cd653c2 100644 --- a/src/main/java/com/xcong/excoin/modules/blackchain/service/Impl/BlockSeriveImpl.java +++ b/src/main/java/com/xcong/excoin/modules/blackchain/service/Impl/BlockSeriveImpl.java @@ -5,18 +5,13 @@ import javax.annotation.Resource; +import com.xcong.excoin.modules.blackchain.service.*; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSONObject; import com.xcong.excoin.common.LoginUserUtils; import com.xcong.excoin.common.response.Result; -import com.xcong.excoin.modules.blackchain.service.BlockSerive; -import com.xcong.excoin.modules.blackchain.service.BtcService; -import com.xcong.excoin.modules.blackchain.service.EthService; -import com.xcong.excoin.modules.blackchain.service.LtcService; -import com.xcong.excoin.modules.blackchain.service.UsdtService; -import com.xcong.excoin.modules.blackchain.service.XrpService; import com.xcong.excoin.modules.member.dao.MemberCoinAddressDao; import com.xcong.excoin.modules.member.dao.MemberDao; import com.xcong.excoin.modules.member.entity.MemberCoinAddressEntity; @@ -185,6 +180,10 @@ } } break; + case "ROC": + address = RocService.createWallet(); + map.put("address", address); + break; default: break; } diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/service/RocService.java b/src/main/java/com/xcong/excoin/modules/blackchain/service/RocService.java new file mode 100644 index 0000000..37465f0 --- /dev/null +++ b/src/main/java/com/xcong/excoin/modules/blackchain/service/RocService.java @@ -0,0 +1,33 @@ +package com.xcong.excoin.modules.blackchain.service; + +import com.alibaba.fastjson.JSONObject; +import com.xcong.excoin.modules.blackchain.model.RocCreateAcoountModel; +import org.apache.commons.lang3.StringUtils; + +/** + * ROC币种接入 + */ +public class RocService { + + private final static String URL = "http://api.rocwallet.cc"; + + private final static String CREATE_WALLET= "/init/createaccount"; + public static String createWallet(){ + RocCreateAcoountModel createAcoountModel = new RocCreateAcoountModel(); + createAcoountModel.setPassword("123456"); + createAcoountModel.setTerminalId("rocexcoin"); + createAcoountModel.setWalletName("coin"); + String post = HttpUtil.jsonPost(URL+CREATE_WALLET, JSONObject.toJSONString(createAcoountModel)); + if(StringUtils.isBlank(post)){ + return null; + } + JSONObject jsonObject = JSONObject.parseObject(post); + Object code = jsonObject.get("code"); + if("0".equals(code.toString())){ + Object o = jsonObject.getJSONObject("data").get("address"); + return o.toString(); + } + return null; + } + +} diff --git a/src/main/java/com/xcong/excoin/modules/coin/controller/OrderCoinController.java b/src/main/java/com/xcong/excoin/modules/coin/controller/OrderCoinController.java index f630d34..bea2599 100644 --- a/src/main/java/com/xcong/excoin/modules/coin/controller/OrderCoinController.java +++ b/src/main/java/com/xcong/excoin/modules/coin/controller/OrderCoinController.java @@ -5,7 +5,9 @@ import javax.annotation.Resource; import javax.validation.Valid; +import com.alibaba.fastjson.JSONObject; import com.xcong.excoin.modules.coin.entity.OrderCoinsEntity; +import com.xcong.excoin.modules.symbols.constants.SymbolsConstats; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -63,12 +65,13 @@ @ApiOperation(value = "提交买卖订单", notes = "提交买卖订单") @PostMapping(value="/submitSalesWalletCoinOrder") public Result submitSalesWalletCoinOrder(@RequestBody @Valid SubmitSalesWalletCoinOrderDto submitSalesWalletCoinOrderDto) { + log.info("买卖单参数[{}]", JSONObject.toJSONString(submitSalesWalletCoinOrderDto)); String symbol = submitSalesWalletCoinOrderDto.getSymbol(); Integer type = submitSalesWalletCoinOrderDto.getType(); Integer tradeType = submitSalesWalletCoinOrderDto.getTradeType(); BigDecimal price = submitSalesWalletCoinOrderDto.getPrice(); BigDecimal amount = submitSalesWalletCoinOrderDto.getAmount(); - if("NEKK".equals(symbol)){ + if(SymbolsConstats.EXCHANGE_SYMBOLS.contains(symbol)){ return orderCoinService.submitSalesWalletCoinOrderWithMatch(symbol,type,tradeType,price,amount,submitSalesWalletCoinOrderDto.getEntrustAmount()); }else{ @@ -174,5 +177,5 @@ public Result searchSymbolResultList() { return orderCoinService.searchSymbolResultList(); } - + } diff --git a/src/main/java/com/xcong/excoin/modules/coin/parameter/vo/OrderWalletCoinVo.java b/src/main/java/com/xcong/excoin/modules/coin/parameter/vo/OrderWalletCoinVo.java index 8a6f509..9583bad 100644 --- a/src/main/java/com/xcong/excoin/modules/coin/parameter/vo/OrderWalletCoinVo.java +++ b/src/main/java/com/xcong/excoin/modules/coin/parameter/vo/OrderWalletCoinVo.java @@ -48,6 +48,12 @@ */ @ApiModelProperty(value = "委托价") private BigDecimal entrustPrice; + + /** + * 委托价 + */ + @ApiModelProperty(value = "委托价") + private BigDecimal entrustAmount; /** * 成交量 */ diff --git a/src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java b/src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java index 0c51f47..ce314cd 100644 --- a/src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java +++ b/src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java @@ -16,4 +16,6 @@ public void updateTrc20(); + public void updateRoc(); + } diff --git a/src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java b/src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java index e611d45..9e50fb4 100644 --- a/src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java +++ b/src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java @@ -481,6 +481,12 @@ } + @Override + public void updateRoc() { + // 更新ROC + + } + private String generateNo() { // 生成订单号 Long timestamp = System.currentTimeMillis(); diff --git a/src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java b/src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java index 37caea9..37490b2 100644 --- a/src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java +++ b/src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java @@ -7,14 +7,18 @@ import javax.annotation.Resource; +import com.alibaba.fastjson.JSONObject; +import com.xcong.excoin.modules.blackchain.service.RocService; import com.xcong.excoin.modules.coin.mapper.OrderCoinsDealMapper; import com.xcong.excoin.modules.platform.entity.PlatformCnyUsdtExchangeEntity; import com.xcong.excoin.modules.platform.entity.PlatformSymbolsCoinEntity; +import com.xcong.excoin.modules.symbols.constants.SymbolsConstats; import com.xcong.excoin.trade.CoinTrader; import com.xcong.excoin.trade.CoinTraderFactory; import com.xcong.excoin.trade.ExchangeTrade; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -161,7 +165,7 @@ @Override @Transactional - public Result submitSalesWalletCoinOrder(String symbol, Integer type, Integer tradeType, BigDecimal price, BigDecimal amount,BigDecimal entrustAmount) { + public Result submitSalesWalletCoinOrder(String symbol, Integer type, Integer tradeType, BigDecimal price, BigDecimal amount, BigDecimal entrustAmount) { //获取用户ID @@ -169,8 +173,10 @@ BigDecimal nowPriceinBigDecimal = price; //查询当前价 BigDecimal nowPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol + "/USDT"))); - if(OrderCoinsEntity.ORDERTYPE_BUY.equals(type) && OrderCoinsEntity.TRADETYPE_MARKETPRICE.equals(tradeType)){ - amount = entrustAmount.divide(nowPrice,BigDecimal.ROUND_DOWN); + System.out.println(symbol + "当前价:" + nowPrice); + if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type) && OrderCoinsEntity.TRADETYPE_MARKETPRICE.equals(tradeType)) { + amount = entrustAmount.divide(nowPrice, 8, BigDecimal.ROUND_DOWN); + System.out.println(symbol + "市价量:" + amount); } // 处理市价 // 获取交易管理的杠杠倍率,手续费率等信息,由平台进行设置 @@ -209,7 +215,7 @@ // 创建订单 OrderCoinsEntity order = new OrderCoinsEntity(); if ((OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType) && type.equals(1) && price.compareTo(nowPrice) < 0) - || (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType) && type.equals(2) && price.compareTo(nowPrice) > 0)) { + || (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType) && type.equals(2) && price.compareTo(nowPrice) > 0)) { // 如果是限价交易直接插入主表数据 order.setMemberId(memberId); order.setOrderNo(generateSimpleSerialno(memberId.toString())); @@ -253,9 +259,10 @@ order.setEntrustCnt(amount); order.setEntrustPrice(price); order.setDealCnt(amount); + order.setEntrustAmount(entrustAmount); if ((OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType) && type.equals(1) && price.compareTo(nowPrice) >= 0) - || (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType) && type.equals(2) && price.compareTo(nowPrice) <= 0)) { - // 手续费用(手续费=建仓价X数量X手续费率) + || (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType) && type.equals(2) && price.compareTo(nowPrice) <= 0)) { + // 手续费用(手续费=建仓价X数量X手续费率) closingPrice = nowPrice.multiply(amount).multiply(tradeSetting.getCoinFeeRatio()); //总费用 = 成交价*数量+手续费 totalPayPrice = nowPrice.multiply(amount).add(closingPrice); @@ -333,7 +340,15 @@ symbol = symbol.toUpperCase(); MemberWalletCoinEntity walletCoin = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, symbol); if (ObjectUtil.isEmpty(walletCoin)) { - return Result.fail(MessageSourceUtils.getString("order_service_0003")); + // 创建这个钱包 + walletCoin = new MemberWalletCoinEntity(); + walletCoin.setAvailableBalance(BigDecimal.ZERO); + walletCoin.setFrozenBalance(BigDecimal.ZERO); + walletCoin.setTotalBalance(BigDecimal.ZERO); + walletCoin.setBorrowedFund(BigDecimal.ZERO); + walletCoin.setMemberId(memberId); + walletCoin.setWalletCode(symbol); + memberWalletCoinDao.insert(walletCoin); } // 查询交易设置 PlatformTradeSettingEntity tradeSetting = platformTradeSettingDao.findTradeSetting(); @@ -341,20 +356,23 @@ return Result.fail(MessageSourceUtils.getString("order_service_0009")); } // 手续费用(手续费=建仓价X数量X手续费率) - BigDecimal closingPrice ; + BigDecimal closingPrice = BigDecimal.ZERO; // 总费用分两种 1,限价交易 是价格*数量+手续费 2,市价交易 用户输入的金额+手续费 //总费用 = 成交价*数量+手续费 - BigDecimal totalPayPrice ; - if(OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType) ){ + BigDecimal totalPayPrice = BigDecimal.ZERO; + if (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType)) { // 限价 closingPrice = price.multiply(amount).multiply(tradeSetting.getCoinFeeRatio()); totalPayPrice = price.multiply(amount).add(closingPrice); - }else{ + entrustAmount = price.multiply(amount); + } else { // 市价 - closingPrice = entrustAmount.multiply(tradeSetting.getCoinFeeRatio()); - totalPayPrice = entrustAmount.add(closingPrice); + if(OrderCoinsEntity.ORDERTYPE_BUY==type){ + closingPrice = entrustAmount.multiply(tradeSetting.getCoinFeeRatio()); + totalPayPrice = entrustAmount.add(closingPrice); + } } - // BigDecimal totalPayPricCoin = nowPrice.multiply(amount).add(closingPrice); + // BigDecimal totalPayPricCoin = nowPrice.multiply(amount).add(closingPrice); String walletCode = MemberWalletCoinEnum.WALLETCOINCODE.getValue(); MemberWalletCoinEntity walletCoinUsdt = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, walletCode); @@ -385,6 +403,8 @@ // 成交量 先设置为0 order.setDealCnt(BigDecimal.ZERO); + order.setEntrustCnt(BigDecimal.ZERO); + order.setEntrustPrice(BigDecimal.ZERO); // 成交价 //order.setDealPrice(price); // 成交金额 @@ -393,28 +413,25 @@ order.setTradeType(tradeType); // 手续费 order.setFeeAmount(closingPrice); - if(OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType)){ - - // 限价 是需要价格和数量 可以得到成交金额 - // 下单量 - order.setEntrustCnt(amount); - // 下单价格 - order.setEntrustPrice(price); - order.setEntrustAmount(amount.multiply(price)); - - - }else{ - if(OrderCoinsEntity.ORDERTYPE_BUY.equals(type)){ + if (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType)) { + // 限价 是需要价格和数量 可以得到成交金额 + // 下单量 + order.setEntrustCnt(amount); + // 下单价格 + order.setEntrustPrice(price); + order.setEntrustAmount(amount.multiply(price)); + } else { + if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) { // 市价 只有金额 order.setEntrustAmount(entrustAmount); - }else{ + } else { + // 市价卖单 // 下单量 order.setEntrustCnt(amount); // 下单价格 - order.setEntrustPrice(price); - order.setEntrustAmount(amount.multiply(price)); + order.setEntrustPrice(BigDecimal.ZERO); + order.setEntrustAmount(BigDecimal.ZERO); } - } orderCoinsDao.insert(order); @@ -422,40 +439,24 @@ //冻结相应的资产 if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) { //如果是买入,所对应的币种增加,USDT账户减少金额 - BigDecimal availableBalance = walletCoinUsdt.getAvailableBalance().subtract(totalPayPrice); - BigDecimal frozenBalance = walletCoinUsdt.getFrozenBalance().add(totalPayPrice); - walletCoinUsdt.setAvailableBalance(availableBalance); - walletCoinUsdt.setFrozenBalance(frozenBalance); - memberWalletCoinDao.updateById(walletCoinUsdt); +// BigDecimal availableBalance = walletCoinUsdt.getAvailableBalance().subtract(totalPayPrice); +// BigDecimal frozenBalance = walletCoinUsdt.getFrozenBalance().add(totalPayPrice); +// walletCoinUsdt.setAvailableBalance(availableBalance); +// walletCoinUsdt.setFrozenBalance(frozenBalance); +// memberWalletCoinDao.updateById(walletCoinUsdt); + memberWalletCoinDao.updateWalletBalance(walletCoinUsdt.getId(),totalPayPrice.negate(),totalPayPrice.negate(),entrustAmount); } else { //如果是卖出,币种减少,USDT增加 - BigDecimal availableBalance = walletCoin.getAvailableBalance().subtract(amount); - BigDecimal frozenBalance = walletCoin.getFrozenBalance().add(amount); - walletCoin.setAvailableBalance(availableBalance); - walletCoin.setFrozenBalance(frozenBalance); - memberWalletCoinDao.updateById(walletCoin); +// BigDecimal availableBalance = walletCoin.getAvailableBalance().subtract(amount); +// BigDecimal frozenBalance = walletCoin.getFrozenBalance().add(amount); +// walletCoin.setAvailableBalance(availableBalance); +// walletCoin.setFrozenBalance(frozenBalance); +// memberWalletCoinDao.updateById(walletCoin); + memberWalletCoinDao.updateWalletBalance(walletCoin.getId(),amount.negate(),amount.negate(),amount); } // 加入到撮合 CoinTrader trader = factory.getTrader(symbol); trader.trade(order); - -// // 流水记录 TODO -// MemberAccountFlowEntity record = new MemberAccountFlowEntity(); -// record.setMemberId(memberId); -// if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) { -// record.setPrice(totalPayPrice.setScale(4, BigDecimal.ROUND_DOWN)); -// record.setSource(MemberAccountFlowEntity.SOURCE_BUY + symbol); -// record.setRemark(MemberAccountFlowEntity.REMARK_BUY + symbol + ":" + amount); -// } else { -// record.setPrice(totalPayPrice.negate().setScale(4, BigDecimal.ROUND_DOWN)); -// record.setSource(MemberAccountFlowEntity.SOURCE_SALE + symbol); -// record.setRemark(MemberAccountFlowEntity.REMARK_SALE + symbol + ":" + amount); -// } -// record.setSymbol(symbol); -// record.setBalance(walletCoinUsdt.getAvailableBalance()); -// -// memberAccountFlowEntityDao.insert(record); - return Result.ok(MessageSourceUtils.getString("order_service_0011")); } @@ -470,20 +471,20 @@ if (CollUtil.isNotEmpty(findCoinOrderListByMemberIdAndSysmbol)) { for (OrderCoinsEntity orderCoinsEntity : findCoinOrderListByMemberIdAndSysmbol) { OrderWalletCoinVo entityToVo = OrderWalletCoinMapper.INSTANCE.entityToVo(orderCoinsEntity); - entityToVo.setFeeAmount(entityToVo.getFeeAmount()== null - ? BigDecimal.ZERO : entityToVo.getFeeAmount().setScale(4, BigDecimal.ROUND_DOWN)); - entityToVo.setMarkPrice(entityToVo.getMarkPrice()== null - ? BigDecimal.ZERO : entityToVo.getMarkPrice().setScale(4, BigDecimal.ROUND_DOWN)); - entityToVo.setEntrustCnt(entityToVo.getEntrustCnt()== null - ? BigDecimal.ZERO : entityToVo.getEntrustCnt().setScale(4, BigDecimal.ROUND_DOWN)); - entityToVo.setEntrustPrice(entityToVo.getEntrustPrice()== null - ? BigDecimal.ZERO : entityToVo.getEntrustPrice().setScale(4, BigDecimal.ROUND_DOWN)); - entityToVo.setDealCnt(entityToVo.getDealCnt()== null - ? BigDecimal.ZERO : entityToVo.getDealCnt().setScale(4, BigDecimal.ROUND_DOWN)); - entityToVo.setDealPrice(entityToVo.getDealPrice()== null - ? BigDecimal.ZERO : entityToVo.getDealPrice().setScale(4, BigDecimal.ROUND_DOWN)); - entityToVo.setDealAmount(entityToVo.getDealAmount()== null - ? BigDecimal.ZERO : entityToVo.getDealAmount().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setFeeAmount(entityToVo.getFeeAmount() == null + ? BigDecimal.ZERO : entityToVo.getFeeAmount().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setMarkPrice(entityToVo.getMarkPrice() == null + ? BigDecimal.ZERO : entityToVo.getMarkPrice().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setEntrustCnt(entityToVo.getEntrustCnt() == null + ? BigDecimal.ZERO : entityToVo.getEntrustCnt().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setEntrustPrice(entityToVo.getEntrustPrice() == null + ? BigDecimal.ZERO : entityToVo.getEntrustPrice().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setDealCnt(entityToVo.getDealCnt() == null + ? BigDecimal.ZERO : entityToVo.getDealCnt().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setDealPrice(entityToVo.getDealPrice() == null + ? BigDecimal.ZERO : entityToVo.getDealPrice().setScale(4, BigDecimal.ROUND_DOWN)); + entityToVo.setDealAmount(entityToVo.getDealAmount() == null + ? BigDecimal.ZERO : entityToVo.getDealAmount().setScale(4, BigDecimal.ROUND_DOWN)); arrayList.add(entityToVo); } } @@ -498,7 +499,11 @@ Long memberId = LoginUserUtils.getAppLoginUser().getId(); OrderCoinsEntity orderCoinsEntity = orderCoinsDao.selectById(orderId); if (ObjectUtil.isNotEmpty(orderCoinsEntity) && orderCoinsEntity.getMemberId() == memberId) { - if (orderCoinsEntity.getOrderStatus() == OrderCoinsEntity.ORDERSTATUS_CANCEL) { + // 如果是撮合交易单 + if (SymbolsConstats.EXCHANGE_SYMBOLS.contains(orderCoinsEntity.getSymbol())) { + return this.cancelEntrustWalletCoinOrderForMatch(orderId); + } + if (orderCoinsEntity.getOrderStatus() == OrderCoinsEntity.ORDERSTATUS_CANCEL || orderCoinsEntity.getOrderStatus()==OrderCoinsEntity.ORDERSTATUS_DONE) { return Result.fail(MessageSourceUtils.getString("order_service_0012")); } orderCoinsEntity.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_CANCEL); @@ -580,7 +585,7 @@ CoinTrader trader = factory.getTrader(orderCoinsEntity.getSymbol()); trader.cancelOrder(orderCoinsEntity); if (ObjectUtil.isNotEmpty(orderCoinsEntity) && orderCoinsEntity.getMemberId() == memberId) { - if (orderCoinsEntity.getOrderStatus() == OrderCoinsEntity.ORDERSTATUS_CANCEL) { + if (orderCoinsEntity.getOrderStatus() == OrderCoinsEntity.ORDERSTATUS_CANCEL || orderCoinsEntity.getOrderStatus()==OrderCoinsEntity.ORDERSTATUS_DONE) { return Result.fail(MessageSourceUtils.getString("order_service_0012")); } orderCoinsEntity.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_CANCEL); @@ -611,15 +616,23 @@ if (ObjectUtil.isNotEmpty(walletCoin)) { //手续费 = 开仓价*数量*手续费率 //返还金额=开仓价*未成交数量+手续费 - BigDecimal returnBalance = orderCoinsEntity.getDealAmount(); - - walletCoin.setAvailableBalance(walletCoin.getAvailableBalance().add(returnBalance)); + BigDecimal returnBalance = orderCoinsEntity.getEntrustAmount().subtract(orderCoinsEntity.getDealAmount()); + // 需要退回的手续费 + BigDecimal returnFee = BigDecimal.ZERO; + if (returnBalance.compareTo(orderCoinsEntity.getEntrustAmount()) == 0) { + returnFee = orderCoinsEntity.getFeeAmount(); + } else { + // 按比例退回 + BigDecimal needFee = orderCoinsEntity.getDealAmount().divide(orderCoinsEntity.getEntrustAmount(), 8, BigDecimal.ROUND_DOWN).multiply(orderCoinsEntity.getFeeAmount()); + returnFee = orderCoinsEntity.getFeeAmount().subtract(needFee); + } + walletCoin.setAvailableBalance(walletCoin.getAvailableBalance().add(returnBalance).add(returnFee)); walletCoin.setFrozenBalance(walletCoin.getFrozenBalance().subtract(returnBalance)); memberWalletCoinDao.updateById(walletCoin); // 流水记录 MemberAccountFlowEntity record = new MemberAccountFlowEntity(); record.setSource(MemberAccountFlowEntity.SOURCE_CANCEL); - record.setRemark(MemberAccountFlowEntity.REMARK_CANCEL + symbol + MemberAccountFlowEntity.REMARK_RETURNBALANCE + returnBalance); + record.setRemark(MemberAccountFlowEntity.REMARK_CANCEL + symbol + MemberAccountFlowEntity.REMARK_RETURNBALANCE + returnBalance.add(returnFee)); record.setBalance(walletCoin.getAvailableBalance()); record.setMemberId(memberId); record.setSymbol(symbol); @@ -631,8 +644,8 @@ //如果是限价卖出,撤单将对应的钱包冻结金额返回 MemberWalletCoinEntity walletCoin = memberWalletCoinDao.selectWalletCoinBymIdAndCode(memberId, symbol); if (ObjectUtil.isNotEmpty(walletCoin)) { - - BigDecimal returnBalance = orderCoinsEntity.getEntrustCnt(); + // 卖出按卖出的数量计算手续费 + BigDecimal returnBalance = orderCoinsEntity.getEntrustCnt().subtract(orderCoinsEntity.getDealCnt()); walletCoin.setAvailableBalance(walletCoin.getAvailableBalance().add(returnBalance)); walletCoin.setFrozenBalance(walletCoin.getFrozenBalance().subtract(returnBalance)); memberWalletCoinDao.updateById(walletCoin); @@ -664,25 +677,25 @@ IPage<OrderCoinsDealEntity> list = orderCoinDealDao.findAllWalletCoinOrderInPage(page, orderCoinsDealEntity); Page<OrderWalletCoinDealVo> pageEntityToPageVo = OrderWalletCoinDealMapper.INSTANCE.pageEntityToPageVo(list); List<OrderWalletCoinDealVo> records = pageEntityToPageVo.getRecords(); - if(CollUtil.isNotEmpty(records)) { - for(OrderWalletCoinDealVo orderWalletCoinDealVo : records) { - orderWalletCoinDealVo.setFeeAmount(orderWalletCoinDealVo.getFeeAmount() == null - ? BigDecimal.ZERO : orderWalletCoinDealVo.getFeeAmount().setScale(4, BigDecimal.ROUND_DOWN)); - - orderWalletCoinDealVo.setDealAmount(orderWalletCoinDealVo.getDealAmount() == null - ? BigDecimal.ZERO : orderWalletCoinDealVo.getDealAmount().setScale(4, BigDecimal.ROUND_DOWN)); - - orderWalletCoinDealVo.setSymbolCnt(orderWalletCoinDealVo.getSymbolCnt() == null - ? BigDecimal.ZERO : orderWalletCoinDealVo.getSymbolCnt().setScale(4, BigDecimal.ROUND_DOWN)); - - orderWalletCoinDealVo.setEntrustPrice(orderWalletCoinDealVo.getEntrustPrice() == null - ? BigDecimal.ZERO : orderWalletCoinDealVo.getEntrustPrice().setScale(4, BigDecimal.ROUND_DOWN)); - - orderWalletCoinDealVo.setDealPrice(orderWalletCoinDealVo.getDealPrice() == null - ? BigDecimal.ZERO : orderWalletCoinDealVo.getDealPrice().setScale(4, BigDecimal.ROUND_DOWN)); - } + if (CollUtil.isNotEmpty(records)) { + for (OrderWalletCoinDealVo orderWalletCoinDealVo : records) { + orderWalletCoinDealVo.setFeeAmount(orderWalletCoinDealVo.getFeeAmount() == null + ? BigDecimal.ZERO : orderWalletCoinDealVo.getFeeAmount().setScale(4, BigDecimal.ROUND_DOWN)); + + orderWalletCoinDealVo.setDealAmount(orderWalletCoinDealVo.getDealAmount() == null + ? BigDecimal.ZERO : orderWalletCoinDealVo.getDealAmount().setScale(4, BigDecimal.ROUND_DOWN)); + + orderWalletCoinDealVo.setSymbolCnt(orderWalletCoinDealVo.getSymbolCnt() == null + ? BigDecimal.ZERO : orderWalletCoinDealVo.getSymbolCnt().setScale(4, BigDecimal.ROUND_DOWN)); + + orderWalletCoinDealVo.setEntrustPrice(orderWalletCoinDealVo.getEntrustPrice() == null + ? BigDecimal.ZERO : orderWalletCoinDealVo.getEntrustPrice().setScale(4, BigDecimal.ROUND_DOWN)); + + orderWalletCoinDealVo.setDealPrice(orderWalletCoinDealVo.getDealPrice() == null + ? BigDecimal.ZERO : orderWalletCoinDealVo.getDealPrice().setScale(4, BigDecimal.ROUND_DOWN)); + } } - + return Result.ok(pageEntityToPageVo); } @@ -693,21 +706,21 @@ Long memberId = LoginUserUtils.getAppLoginUser().getId(); OrderCoinsDealEntity selectWalletCoinOrder = orderCoinDealDao.selectWalletCoinOrder(orderId, memberId); OrderWalletCoinDealVo entityToVo = OrderWalletCoinDealMapper.INSTANCE.entityToVoOrder(selectWalletCoinOrder); - if(ObjectUtil.isNotEmpty(entityToVo)) { - entityToVo.setFeeAmount(entityToVo.getFeeAmount() == null - ? BigDecimal.ZERO : entityToVo.getFeeAmount().setScale(4, BigDecimal.ROUND_DOWN)); - - entityToVo.setDealAmount(entityToVo.getDealAmount() == null - ? BigDecimal.ZERO : entityToVo.getDealAmount().setScale(4, BigDecimal.ROUND_DOWN)); - - entityToVo.setSymbolCnt(entityToVo.getSymbolCnt() == null - ? BigDecimal.ZERO : entityToVo.getSymbolCnt().setScale(4, BigDecimal.ROUND_DOWN)); - - entityToVo.setEntrustPrice(entityToVo.getEntrustPrice() == null - ? BigDecimal.ZERO : entityToVo.getEntrustPrice().setScale(4, BigDecimal.ROUND_DOWN)); - - entityToVo.setDealPrice(entityToVo.getDealPrice() == null - ? BigDecimal.ZERO : entityToVo.getDealPrice().setScale(4, BigDecimal.ROUND_DOWN)); + if (ObjectUtil.isNotEmpty(entityToVo)) { + entityToVo.setFeeAmount(entityToVo.getFeeAmount() == null + ? BigDecimal.ZERO : entityToVo.getFeeAmount().setScale(4, BigDecimal.ROUND_DOWN)); + + entityToVo.setDealAmount(entityToVo.getDealAmount() == null + ? BigDecimal.ZERO : entityToVo.getDealAmount().setScale(4, BigDecimal.ROUND_DOWN)); + + entityToVo.setSymbolCnt(entityToVo.getSymbolCnt() == null + ? BigDecimal.ZERO : entityToVo.getSymbolCnt().setScale(4, BigDecimal.ROUND_DOWN)); + + entityToVo.setEntrustPrice(entityToVo.getEntrustPrice() == null + ? BigDecimal.ZERO : entityToVo.getEntrustPrice().setScale(4, BigDecimal.ROUND_DOWN)); + + entityToVo.setDealPrice(entityToVo.getDealPrice() == null + ? BigDecimal.ZERO : entityToVo.getDealPrice().setScale(4, BigDecimal.ROUND_DOWN)); } return Result.ok(entityToVo); } @@ -802,7 +815,7 @@ @Transactional(rollbackFor = Exception.class) public void dealEntrustCoinOrder() { List<String> ignoreTypes = new ArrayList<>(); - ignoreTypes.add("NEKK"); + ignoreTypes.add(SymbolsConstats.ROC); List<OrderCoinsEntity> list = orderCoinsDao.selectAllEntrustingCoinOrderList(ignoreTypes); if (CollUtil.isNotEmpty(list)) { for (OrderCoinsEntity orderCoinsEntity : list) { @@ -869,10 +882,12 @@ } } - public void handleOrder(List<ExchangeTrade> trades){ + @Transactional + public void handleOrder(List<ExchangeTrade> trades) { + // 处理撮合交易的订单 - for(ExchangeTrade exchangeTrade : trades){ - if(exchangeTrade==null){ + for (ExchangeTrade exchangeTrade : trades) { + if (exchangeTrade == null) { continue; } // 量 @@ -889,16 +904,28 @@ // 买卖单都需要处理 // 买单 OrderCoinsEntity buyOrderCoinsEntity = orderCoinsDao.selectById(buyOrderId); - if(buyOrderCoinsEntity!=null){ + if(buyOrderCoinsEntity==null){ + return; + } + BigDecimal buyEntrustCnt = buyOrderCoinsEntity.getEntrustCnt(); + if(buyEntrustCnt==null){ + buyEntrustCnt = BigDecimal.ZERO; + } + Long memberId = buyOrderCoinsEntity.getMemberId(); + if (buyOrderCoinsEntity != null) { // 比较剩余的量 BigDecimal dealAmount = buyOrderCoinsEntity.getDealAmount(); // 单的总金额 BigDecimal entrustAmount = buyOrderCoinsEntity.getEntrustAmount(); BigDecimal add = dealAmount.add(buyTurnover); + BigDecimal closingPrice = buyTurnover.multiply(new BigDecimal("0.002")); + + //成交量 + BigDecimal dealCnt = buyOrderCoinsEntity.getDealCnt().add(amount); // 创建一个完成的单 OrderCoinsDealEntity detail = new OrderCoinsDealEntity(); detail.setMemberId(buyOrderCoinsEntity.getMemberId()); - //detail.setOrderId(order.getId()); + detail.setOrderId(buyOrderCoinsEntity.getId()); detail.setOrderNo(buyOrderCoinsEntity.getOrderNo()); detail.setOrderType(buyOrderCoinsEntity.getOrderType()); detail.setTradeType(buyOrderCoinsEntity.getTradeType()); @@ -907,11 +934,11 @@ detail.setEntrustPrice(buyOrderCoinsEntity.getEntrustPrice()); detail.setDealPrice(price); detail.setDealAmount(buyTurnover); - //detail.setFeeAmount(closingPrice); + detail.setFeeAmount(closingPrice); detail.setOrderStatus(OrderCoinsDealEntity.ORDERSTATUS_DONE); orderCoinDealDao.insert(detail); // 如果这个单成交完 更改状态 - if(add.compareTo(entrustAmount)>=0){ + if (add.compareTo(entrustAmount) >= 0 ||(buyEntrustCnt.compareTo(BigDecimal.ZERO)>0 &&dealCnt.compareTo(buyEntrustCnt)>=0) ) { OrderCoinsEntity update = new OrderCoinsEntity(); update.setId(buyOrderId); update.setDealAmount(entrustAmount); @@ -919,7 +946,7 @@ update.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_DONE); update.setUpdateTime(new Date()); orderCoinsDao.updateById(update); - }else{ + } else { OrderCoinsEntity update = new OrderCoinsEntity(); update.setId(buyOrderId); update.setDealAmount(add); @@ -930,7 +957,7 @@ } // 卖单 OrderCoinsEntity sellOrderCoinsEntity = orderCoinsDao.selectById(sellOrderId); - if(sellOrderCoinsEntity!=null){ + if (sellOrderCoinsEntity != null) { // 比较剩余的量 BigDecimal dealAmount = sellOrderCoinsEntity.getDealCnt(); // 单的总数量 @@ -939,7 +966,7 @@ // 创建一个完成的单 OrderCoinsDealEntity detail = new OrderCoinsDealEntity(); detail.setMemberId(sellOrderCoinsEntity.getMemberId()); - //detail.setOrderId(order.getId()); + detail.setOrderId(sellOrderCoinsEntity.getId()); detail.setOrderNo(sellOrderCoinsEntity.getOrderNo()); detail.setOrderType(sellOrderCoinsEntity.getOrderType()); detail.setTradeType(sellOrderCoinsEntity.getTradeType()); @@ -952,7 +979,7 @@ detail.setOrderStatus(OrderCoinsDealEntity.ORDERSTATUS_DONE); orderCoinDealDao.insert(detail); // 如果这个单成交完 更改状态 - if(add.compareTo(entrustCnt)>=0){ + if (add.compareTo(entrustCnt) >= 0) { OrderCoinsEntity update = new OrderCoinsEntity(); update.setId(sellOrderId); // 总成交额 @@ -961,7 +988,7 @@ update.setDealCnt(entrustCnt); update.setUpdateTime(new Date()); orderCoinsDao.updateById(update); - }else{ + } else { // 未完成 OrderCoinsEntity update = new OrderCoinsEntity(); update.setId(sellOrderId); @@ -971,19 +998,54 @@ update.setUpdateTime(new Date()); orderCoinsDao.updateById(update); } - // 卖币得到的usdt - MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(sellOrderCoinsEntity.getMemberId(), sellOrderCoinsEntity.getSymbol()); - if(memberWalletCoinEntity!=null){ - memberWalletCoinDao.updateWalletBalance(memberWalletCoinEntity.getId(),buyTurnover,buyTurnover,null); + // 买币扣除冻结usdt 增加币种的可用 + MemberWalletCoinEntity usdtWallet = memberWalletCoinDao.selectWalletCoinBymIdAndCode(buyOrderCoinsEntity.getMemberId(), MemberWalletCoinEnum.WALLETCOINCODE.getValue()); + if (usdtWallet != null) { + // 减少usdt冻结 + memberWalletCoinDao.updateWalletBalance(usdtWallet.getId(), null, null, buyTurnover.negate()); } + // 增加买的币 + MemberWalletCoinEntity buySymbolWallet = memberWalletCoinDao.selectWalletCoinBymIdAndCode(buyOrderCoinsEntity.getMemberId(), buyOrderCoinsEntity.getSymbol()); + if (buySymbolWallet != null) { + memberWalletCoinDao.updateWalletBalance(buySymbolWallet.getId(), amount, amount, null); + } + // 流水记录 + MemberAccountFlowEntity record = new MemberAccountFlowEntity(); + record.setMemberId(buyOrderCoinsEntity.getMemberId()); + record.setPrice(buyTurnover.setScale(4, BigDecimal.ROUND_DOWN).negate()); + record.setSource(MemberAccountFlowEntity.SOURCE_BUY + buyOrderCoinsEntity.getSymbol()); + record.setRemark(MemberAccountFlowEntity.REMARK_BUY + buyOrderCoinsEntity.getSymbol() + ":" + amount); + record.setSymbol(buyOrderCoinsEntity.getSymbol()); + record.setBalance(usdtWallet.getAvailableBalance().subtract(buyTurnover)); + memberAccountFlowEntityDao.insert(record); + // 卖家需要减少冻结的币种 增加usdt + MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(sellOrderCoinsEntity.getMemberId(), sellOrderCoinsEntity.getSymbol()); + if (memberWalletCoinEntity != null) { + // 更新卖币减少的币种 + memberWalletCoinDao.updateWalletBalance(memberWalletCoinEntity.getId(), null, null, amount.negate()); + } + // 更新卖币得到的usdt + MemberWalletCoinEntity sellWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(sellOrderCoinsEntity.getMemberId(), MemberWalletCoinEnum.WALLETCOINCODE.getValue()); + if (sellOrderCoinsEntity != null) { + memberWalletCoinDao.updateWalletBalance(sellWalletCoinEntity.getId(), buyTurnover, buyTurnover, null); + } + // 流水记录 + MemberAccountFlowEntity recordSell = new MemberAccountFlowEntity(); + recordSell.setMemberId(sellOrderCoinsEntity.getMemberId()); + recordSell.setPrice(buyTurnover.setScale(4, BigDecimal.ROUND_DOWN)); + recordSell.setSource(MemberAccountFlowEntity.SOURCE_SALE + buyOrderCoinsEntity.getSymbol()); + recordSell.setRemark(MemberAccountFlowEntity.REMARK_SALE + buyOrderCoinsEntity.getSymbol() + ":" + amount.toPlainString()); + recordSell.setSymbol(buyOrderCoinsEntity.getSymbol()); + recordSell.setBalance(sellWalletCoinEntity.getAvailableBalance().add(buyTurnover)); + memberAccountFlowEntityDao.insert(recordSell); } } } @Override public void initOrders(String symbol, Integer type, Integer tradeType, BigDecimal price, - BigDecimal amount,BigDecimal entrustAmount) { + BigDecimal amount, BigDecimal entrustAmount) { //获取用户ID Long memberId = 10L; BigDecimal nowPriceinBigDecimal = price; @@ -994,7 +1056,7 @@ symbol = symbol.toUpperCase(); // 手续费用(手续费=建仓价X数量X手续费率) - BigDecimal closingPrice = BigDecimal.ZERO ; + BigDecimal closingPrice = BigDecimal.ZERO; // BigDecimal totalPayPricCoin = nowPrice.multiply(amount).add(closingPrice); // 首先将单插入到数据库主表(委托表) @@ -1018,18 +1080,18 @@ order.setTradeType(tradeType); // 手续费 order.setFeeAmount(closingPrice); - if(OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType)){ + if (OrderCoinsEntity.TRADETYPE_FIXEDPRICE.equals(tradeType)) { // 限价 是需要价格和数量 可以得到成交金额 // 下单量 order.setEntrustCnt(amount); // 下单价格 order.setEntrustPrice(price); order.setEntrustAmount(amount.multiply(price)); - }else{ - if(OrderCoinsEntity.ORDERTYPE_BUY.equals(type)){ + } else { + if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) { // 市价 只有金额 order.setEntrustAmount(entrustAmount); - }else{ + } else { // 下单量 order.setEntrustCnt(amount); // 下单价格 @@ -1043,4 +1105,5 @@ CoinTrader trader = factory.getTrader(symbol); trader.trade(order); } + } diff --git a/src/main/java/com/xcong/excoin/modules/symbols/constants/SymbolsConstats.java b/src/main/java/com/xcong/excoin/modules/symbols/constants/SymbolsConstats.java new file mode 100644 index 0000000..2ae5ded --- /dev/null +++ b/src/main/java/com/xcong/excoin/modules/symbols/constants/SymbolsConstats.java @@ -0,0 +1,12 @@ +package com.xcong.excoin.modules.symbols.constants; + +import java.util.ArrayList; +import java.util.List; + +public class SymbolsConstats { + public final static List<String> EXCHANGE_SYMBOLS = new ArrayList<>(); + public final static String ROC = "ROC"; + static { + EXCHANGE_SYMBOLS.add("ROC"); + } +} diff --git a/src/main/java/com/xcong/excoin/modules/symbols/controller/SymbolsController.java b/src/main/java/com/xcong/excoin/modules/symbols/controller/SymbolsController.java index 64fe133..afae70f 100644 --- a/src/main/java/com/xcong/excoin/modules/symbols/controller/SymbolsController.java +++ b/src/main/java/com/xcong/excoin/modules/symbols/controller/SymbolsController.java @@ -1,5 +1,6 @@ package com.xcong.excoin.modules.symbols.controller; +import com.alibaba.fastjson.JSON; import com.huobi.client.model.Candlestick; import com.xcong.excoin.common.response.Result; import com.xcong.excoin.modules.symbols.parameter.dto.KlineDetailDto; diff --git a/src/main/java/com/xcong/excoin/modules/symbols/service/impl/SymbolsServiceImpl.java b/src/main/java/com/xcong/excoin/modules/symbols/service/impl/SymbolsServiceImpl.java index 95d294a..11dc131 100644 --- a/src/main/java/com/xcong/excoin/modules/symbols/service/impl/SymbolsServiceImpl.java +++ b/src/main/java/com/xcong/excoin/modules/symbols/service/impl/SymbolsServiceImpl.java @@ -128,6 +128,11 @@ PlatformCnyUsdtExchangeEntity cnyUsdtExchange = platformCnyUsdtExchangeDao.getCNYAndUSDTOne(); // 获取当日k线数据 Candlestick symbolObject = (Candlestick) redisUtils.get(symbol); + if(symbolObject==null){ + symbolObject = new Candlestick(); + symbolObject.setOpen(new BigDecimal(1)); + symbolObject.setAmount(new BigDecimal(1)); + } // 获取当前币种最新价 BigDecimal newestPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol))); // 获取当日k线的开盘价 diff --git a/src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java b/src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java index 8e1423f..3953174 100644 --- a/src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java +++ b/src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java @@ -362,7 +362,7 @@ // 存储昨日K线 if("day".equals(rangeUnit)){ - redisUtils.set("NEKK/USDT",kLine); + redisUtils.set("ROC/USDT",kLine); } } diff --git a/src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java b/src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java index 4138bee..65e8c1e 100644 --- a/src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java +++ b/src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java @@ -60,4 +60,11 @@ blockCoinService.updateXrp(); } + /** + * ETH_USDT 同步 + */ + @Scheduled(cron = "0 0/5 * * * ? ") + public void rocUpdate() { + blockCoinService.updateEthUsdt(); + } } diff --git a/src/main/java/com/xcong/excoin/quartz/job/CoinTradeInitJob.java b/src/main/java/com/xcong/excoin/quartz/job/CoinTradeInitJob.java index 9d4215c..6f114b0 100644 --- a/src/main/java/com/xcong/excoin/quartz/job/CoinTradeInitJob.java +++ b/src/main/java/com/xcong/excoin/quartz/job/CoinTradeInitJob.java @@ -10,6 +10,7 @@ import com.xcong.excoin.modules.coin.dao.OrderCoinsDao; import com.xcong.excoin.modules.coin.entity.OrderCoinsEntity; import com.xcong.excoin.modules.coin.service.OrderCoinService; +import com.xcong.excoin.modules.symbols.constants.SymbolsConstats; import com.xcong.excoin.modules.symbols.service.SymbolsService; import com.xcong.excoin.processor.CoinProcessor; import com.xcong.excoin.processor.CoinProcessorFactory; @@ -43,7 +44,7 @@ **/ @Slf4j @Component -//@ConditionalOnProperty(prefix = "app", name = "trade", havingValue = "true") +@ConditionalOnProperty(prefix = "app", name = "trade", havingValue = "true") public class CoinTradeInitJob { @Resource @@ -69,7 +70,7 @@ @PostConstruct public void initCoinTrade() { log.info("#=======撮合交易器开启=======#"); - String symbol = "NEKK"; + String symbol = SymbolsConstats.ROC; CoinTrader newTrader = new CoinTrader(symbol); newTrader.setExchangeProducer(exchangeProducer); //newTrader.setKafkaTemplate(kafkaTemplate); @@ -104,7 +105,7 @@ processor.initializeThumb(); //processor.initializeUsdRate(); processor.setIsHalt(false); - List<ExchangeTrade> nekk = orderCoinDealDao.selectOrderCoinDealByTime("NEKK", null, null); + List<ExchangeTrade> nekk = orderCoinDealDao.selectOrderCoinDealByTime(SymbolsConstats.ROC, null, null); processor.process(nekk); String symbolUsdt = symbol; if(!symbol.contains("USDT")){ diff --git a/src/main/java/com/xcong/excoin/quartz/job/KLineGeneratorJob.java b/src/main/java/com/xcong/excoin/quartz/job/KLineGeneratorJob.java index 5972de9..8fb4f5c 100644 --- a/src/main/java/com/xcong/excoin/quartz/job/KLineGeneratorJob.java +++ b/src/main/java/com/xcong/excoin/quartz/job/KLineGeneratorJob.java @@ -1,28 +1,16 @@ package com.xcong.excoin.quartz.job; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.huobi.client.model.Candlestick; -import com.xcong.excoin.modules.coin.dao.OrderCoinDealDao; import com.xcong.excoin.modules.coin.entity.OrderCoinsDealEntity; import com.xcong.excoin.modules.coin.service.OrderCoinService; import com.xcong.excoin.processor.CoinProcessorFactory; -import com.xcong.excoin.trade.TradePlateModel; -import com.xcong.excoin.utils.RedisUtils; -import com.xcong.excoin.websocket.CandlestickModel; -import com.xcong.excoin.websocket.NewCandlestick; -import com.xcong.excoin.websocket.TradePlateSendWebSocket; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.ArrayList; import java.util.Calendar; -import java.util.List; import java.util.Random; /** @@ -40,35 +28,19 @@ - @Scheduled(cron = "0/1 * * * * *") + //@Scheduled(cron = "0/40 * * * * *") public void test(){ -// for(int i=1;i<=2;i++){ -// OrderCoinsDealEntity detail = new OrderCoinsDealEntity(); -// detail.setMemberId(13L); -// //detail.setOrderId(111); -// detail.setOrderNo("tete"); -// detail.setOrderType(1); -// detail.setTradeType(1); -// detail.setSymbol("NEKK"); -// detail.setSymbolCnt(new BigDecimal(10)); -// detail.setEntrustPrice(new BigDecimal(10)); -// detail.setDealPrice(new BigDecimal(i*10*Math.random())); -// detail.setDealAmount(new BigDecimal(50)); -// detail.setFeeAmount(new BigDecimal(1)); -// detail.setOrderStatus(OrderCoinsDealEntity.ORDERSTATUS_DONE); -// orderCoinDealDao.insert(detail); -// } Random random = new Random(); Integer type = OrderCoinsDealEntity.ORDERTYPE_BUY; Integer tradeType = OrderCoinsDealEntity.TRADETYPE_FIXEDPRICE; - int i = random.nextInt(100); - if(i==0){ - i=10; + double random1 = Math.random(); + BigDecimal price = new BigDecimal(random1).setScale(4, RoundingMode.HALF_UP).multiply(new BigDecimal("2")); + if(price.compareTo(BigDecimal.ZERO)==0){ + price = BigDecimal.ONE; } - BigDecimal price = new BigDecimal(i); - orderCoinService.initOrders("NEKK",type,tradeType,price,new BigDecimal(2),null); - orderCoinService.initOrders("NEKK",OrderCoinsDealEntity.ORDERTYPE_SELL,tradeType,price,new BigDecimal(2),null); - + System.out.println(price); + orderCoinService.initOrders("ROC",type,tradeType,price,new BigDecimal(2),null); + orderCoinService.initOrders("ROC",OrderCoinsDealEntity.ORDERTYPE_SELL,tradeType,price,new BigDecimal(2),null); } @@ -130,6 +102,11 @@ long time = calendar.getTimeInMillis(); processor.generateKLine(1, Calendar.HOUR_OF_DAY, time); + // 四小时K线 + int hour = calendar.get(Calendar.HOUR_OF_DAY); + if(hour%4==0){ + processor.generateKLine(4, Calendar.HOUR_OF_DAY, time); + } } }); } diff --git a/src/main/java/com/xcong/excoin/quartz/job/NewestPriceUpdateJob.java b/src/main/java/com/xcong/excoin/quartz/job/NewestPriceUpdateJob.java index 0ac98f7..b849903 100644 --- a/src/main/java/com/xcong/excoin/quartz/job/NewestPriceUpdateJob.java +++ b/src/main/java/com/xcong/excoin/quartz/job/NewestPriceUpdateJob.java @@ -52,8 +52,8 @@ // TODO 测试环境关闭这个插入redis redisUtils.set(CoinTypeConvert.convertToKey(symbol), price); // 比较 - websocketPriceService.comparePriceAsc(symbol, price); - websocketPriceService.comparePriceDesc(symbol, price); + //websocketPriceService.comparePriceAsc(symbol, price); + //websocketPriceService.comparePriceDesc(symbol, price); //System.out.println("比较完毕:"+symbol+"-"+price); } diff --git a/src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java b/src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java index 75f36ad..6914b58 100644 --- a/src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java +++ b/src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java @@ -27,7 +27,7 @@ /** * usdt 归集 */ - @Scheduled(cron = "0 5/30 * * * ? ") + // @Scheduled(cron = "0 5/30 * * * ? ") public void poolUsdtEth() { try { log.info("USDT归集开始"); @@ -38,13 +38,13 @@ } } - @Scheduled(cron = "0 2/8 * * * ? ") + //@Scheduled(cron = "0 2/8 * * * ? ") public void usdtEthPoolCheck() { log.info("USDTETH归集结果扫描开始"); usdtEthService.usdtEthPoolCheck(); } - @Scheduled(cron = "0 2/30 * * * ? ") + //@Scheduled(cron = "0 2/30 * * * ? ") public void poolEth() { try { usdtEthService.ethPool(); diff --git a/src/main/java/com/xcong/excoin/quartz/job/UsdtCnyExchangePriceUpdateJob.java b/src/main/java/com/xcong/excoin/quartz/job/UsdtCnyExchangePriceUpdateJob.java index 96dc366..596ffe6 100644 --- a/src/main/java/com/xcong/excoin/quartz/job/UsdtCnyExchangePriceUpdateJob.java +++ b/src/main/java/com/xcong/excoin/quartz/job/UsdtCnyExchangePriceUpdateJob.java @@ -2,6 +2,7 @@ import com.alibaba.fastjson.JSONObject; import com.xcong.excoin.modules.platform.dao.PlatformCnyUsdtExchangeDao; +import com.xcong.excoin.utils.RedisUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; @@ -28,6 +29,9 @@ @Resource private PlatformCnyUsdtExchangeDao cnyUsdtExchangeDao; + + @Resource + private RedisUtils redisUtils; @Scheduled(cron = "0 */5 * * * ? ") public void updateUsdtCnyExchange() { @@ -59,6 +63,7 @@ if ("200".equals(code)) { JSONObject jsonData = (JSONObject) jsonObject.get("data"); cnyUsdtExchangeDao.updateUsdt(BigDecimal.valueOf(jsonData.getDouble("price"))); + redisUtils.set("platform_cny_usdt_exchange",BigDecimal.valueOf(jsonData.getDouble("price"))); } } catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/com/xcong/excoin/rabbit/consumer/ExchangeConsumer.java b/src/main/java/com/xcong/excoin/rabbit/consumer/ExchangeConsumer.java index cf45f32..a124d69 100644 --- a/src/main/java/com/xcong/excoin/rabbit/consumer/ExchangeConsumer.java +++ b/src/main/java/com/xcong/excoin/rabbit/consumer/ExchangeConsumer.java @@ -49,7 +49,7 @@ */ @RabbitListener(queues = RabbitMqConfig.QUEUE_TRADE_PLATE) public void tradePlate(String content) { - tradePlateSendWebSocket.sendMessagePlate("NEKK/USDT",content,null); + tradePlateSendWebSocket.sendMessagePlate("ROC/USDT",content,null); } /** diff --git a/src/main/java/com/xcong/excoin/rabbit/consumer/OperateOrderPriceConsumer.java b/src/main/java/com/xcong/excoin/rabbit/consumer/OperateOrderPriceConsumer.java index 45ff0f7..bfb2d92 100644 --- a/src/main/java/com/xcong/excoin/rabbit/consumer/OperateOrderPriceConsumer.java +++ b/src/main/java/com/xcong/excoin/rabbit/consumer/OperateOrderPriceConsumer.java @@ -17,7 +17,7 @@ * @author helius */ @Component -@ConditionalOnProperty(prefix = "app", name = "newest-price-update-job", havingValue = "true") +@ConditionalOnProperty(prefix = "app", name = "newest-price-update-job-contract", havingValue = "true") public class OperateOrderPriceConsumer { diff --git a/src/main/java/com/xcong/excoin/rabbit/init/OrderProducerInit.java b/src/main/java/com/xcong/excoin/rabbit/init/OrderProducerInit.java index 25638d8..9fb3756 100644 --- a/src/main/java/com/xcong/excoin/rabbit/init/OrderProducerInit.java +++ b/src/main/java/com/xcong/excoin/rabbit/init/OrderProducerInit.java @@ -27,7 +27,7 @@ */ @Slf4j @Component -@ConditionalOnProperty(prefix = "app", name = "newest-price-update-job", havingValue = "true") +@ConditionalOnProperty(prefix = "app", name = "newest-price-update-job-contract", havingValue = "true") public class OrderProducerInit { @Resource diff --git a/src/main/java/com/xcong/excoin/trade/CoinTrader.java b/src/main/java/com/xcong/excoin/trade/CoinTrader.java index e4d34f0..6c4f979 100644 --- a/src/main/java/com/xcong/excoin/trade/CoinTrader.java +++ b/src/main/java/com/xcong/excoin/trade/CoinTrader.java @@ -2,6 +2,7 @@ import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; import com.xcong.excoin.modules.coin.entity.OrderCoinsEntity; import com.xcong.excoin.modules.coin.service.OrderCoinService; import com.xcong.excoin.rabbit.producer.ExchangeProducer; @@ -139,9 +140,16 @@ return; } // 如果 - if (exchangeOrder.getEntrustAmount().compareTo(BigDecimal.ZERO) <= 0 || exchangeOrder.getEntrustAmount().subtract(exchangeOrder.getDealAmount()).compareTo(BigDecimal.ZERO) <= 0) { - return; + if(OrderCoinsEntity.ORDERTYPE_BUY==exchangeOrder.getOrderType()){ + if (exchangeOrder.getEntrustAmount().compareTo(BigDecimal.ZERO) <= 0 || exchangeOrder.getEntrustAmount().subtract(exchangeOrder.getDealAmount()).compareTo(BigDecimal.ZERO) <= 0) { + return; + } + }else{ + if (exchangeOrder.getEntrustCnt().compareTo(BigDecimal.ZERO) <= 0 || exchangeOrder.getEntrustCnt().subtract(exchangeOrder.getDealCnt()).compareTo(BigDecimal.ZERO) <= 0) { + return; + } } + TreeMap<BigDecimal, MergeOrder> limitPriceOrderList; LinkedList<OrderCoinsEntity> marketPriceOrderList; @@ -402,6 +410,7 @@ availAmount = calculateTradedAmount(matchOrder, dealPrice); //计算成交量 取少的 BigDecimal tradedAmount = (availAmount.compareTo(needAmount) >= 0 ? needAmount : availAmount); + System.out.println("成交量:"+tradedAmount); //logger.info("dealPrice={},amount={}", dealPrice, tradedAmount); //如果成交额为0说明剩余额度无法成交,退出 if (tradedAmount.compareTo(BigDecimal.ZERO) == 0) { diff --git a/src/main/java/com/xcong/excoin/utils/CoinTypeConvert.java b/src/main/java/com/xcong/excoin/utils/CoinTypeConvert.java index a32f0f9..d0d5c68 100644 --- a/src/main/java/com/xcong/excoin/utils/CoinTypeConvert.java +++ b/src/main/java/com/xcong/excoin/utils/CoinTypeConvert.java @@ -22,8 +22,8 @@ return "EOS/USDT"; case "etcusdt": return "ETC/USDT"; - case "nekkusdt": - return "NEKK/USDT"; + case "rocusdt": + return "ROC/USDT"; default: return null; } @@ -33,8 +33,8 @@ switch (symbol) { case "BTC/USDT": return "btcusdt"; - case "NEKK/USDT": - return "nekkusdt"; + case "ROC/USDT": + return "rocusdt"; default: return null; } @@ -56,8 +56,8 @@ return "EOS_NEW_PRICE"; case "ETC/USDT": return "ETC_NEW_PRICE"; - case "NEKK/USDT": - return "NEKK_NEW_PRICE"; + case "ROC/USDT": + return "ROC_NEW_PRICE"; default: return null; } diff --git a/src/main/java/com/xcong/excoin/websocket/TradePlateSendWebSocket.java b/src/main/java/com/xcong/excoin/websocket/TradePlateSendWebSocket.java index fc1ccab..5eedf8e 100644 --- a/src/main/java/com/xcong/excoin/websocket/TradePlateSendWebSocket.java +++ b/src/main/java/com/xcong/excoin/websocket/TradePlateSendWebSocket.java @@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSONObject; import com.huobi.client.model.Candlestick; import com.xcong.excoin.common.contants.AppContants; +import com.xcong.excoin.modules.symbols.constants.SymbolsConstats; import com.xcong.excoin.trade.CoinTraderFactory; import com.xcong.excoin.utils.CoinTypeConvert; import com.xcong.excoin.utils.RedisUtils; @@ -82,6 +83,7 @@ JSONObject jsonObject = JSON.parseObject(message); // 盘口的判断 if (jsonObject.containsKey("sub") && jsonObject.get("sub").toString().contains("depth")) { + String sub = jsonObject.get("sub").toString(); String symbol = sub.split("\\.")[1]; symbol = CoinTypeConvert.convert(symbol); @@ -95,9 +97,9 @@ // 发送一次盘口 CoinTraderFactory factory = SpringContextHolder.getBean(CoinTraderFactory.class); // 发送订阅消息 - String nekk = factory.getTrader("NEKK").sendTradePlateMessage(); + String nekk = factory.getTrader(SymbolsConstats.ROC).sendTradePlateMessage(); SubResultModel subResultModel = new SubResultModel(); - subResultModel.setId("nekkusdt"); + subResultModel.setId("rocusdt"); subResultModel.setSubbed(sub); synchronized (session){ try { @@ -188,7 +190,7 @@ String key = "KINE_{}_{}"; // 币币k线数据 //key = StrUtil.format(key, symbol, period); - key = StrUtil.format(key, "NEKK/USDT", period); + key = StrUtil.format(key, "ROC/USDT", period); RedisUtils bean = SpringContextHolder.getBean(RedisUtils.class); Object o = bean.get(key); List<CandlestickModel> candlestickModels = new ArrayList<>(); diff --git a/src/main/resources/application-test.yml b/src/main/resources/application-test.yml index a21709a..732bfb1 100644 --- a/src/main/resources/application-test.yml +++ b/src/main/resources/application-test.yml @@ -7,9 +7,9 @@ profiles: active: dev datasource: - url: jdbc:mysql://120.27.238.55:3306/kss_framework?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8 - username: ct_test - password: 123456 + url: jdbc:mysql://47.114.114.219:3306/db_roc?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8 + username: roc_user + password: roc123pasd!@ driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource druid: @@ -91,17 +91,17 @@ app: - debug: true + debug: false redis_expire: 3000 kline-update-job: false - newest-price-update-job: false + newest-price-update-job: true #日线 该任务不能与最新价处于同一个服务器 - trade: false + trade: true day-line: false - other-job: false - loop-job: false + other-job: true + loop-job: true rabbit-consumer: true - block-job: false + block-job: true aliyun: oss: diff --git a/src/main/resources/mapper/member/MemberWalletCoinDao.xml b/src/main/resources/mapper/member/MemberWalletCoinDao.xml index e7fd894..ff0d8b4 100644 --- a/src/main/resources/mapper/member/MemberWalletCoinDao.xml +++ b/src/main/resources/mapper/member/MemberWalletCoinDao.xml @@ -43,13 +43,19 @@ update member_wallet_coin <set> <if test="availableBalance != null"> - available_balance = IFNULL(available_balance, 0) + #{availableBalance}, + available_balance = ( + case when IFNULL(available_balance, 0) + #{availableBalance}>0 then IFNULL(available_balance, 0) + #{availableBalance} else 0 end + ), </if> <if test="totalBalance != null"> - total_balance = IFNULL(total_balance, 0) + #{totalBalance}, + total_balance = ( + case when IFNULL(total_balance, 0) + #{totalBalance}>0 then IFNULL(total_balance, 0) + #{totalBalance} else 0 end + ), </if> <if test="frozenBalance != null"> - frozen_balance = IFNULL(frozen_balance, 0) + #{frozenBalance}, + frozen_balance = ( + case when IFNULL(frozen_balance, 0) + #{frozenBalance}>0 then IFNULL(frozen_balance, 0) + #{frozenBalance} else 0 end + ), </if> </set> where id=#{id} diff --git a/src/test/java/com/xcong/excoin/TradeTest.java b/src/test/java/com/xcong/excoin/TradeTest.java new file mode 100644 index 0000000..b517349 --- /dev/null +++ b/src/test/java/com/xcong/excoin/TradeTest.java @@ -0,0 +1,34 @@ +package com.xcong.excoin; + +import com.xcong.excoin.modules.coin.dao.OrderCoinsDao; +import com.xcong.excoin.modules.coin.entity.OrderCoinsEntity; +import com.xcong.excoin.modules.coin.service.OrderCoinService; +import com.xcong.excoin.trade.CoinTrader; +import com.xcong.excoin.utils.RedisUtils; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@SpringBootTest +public class TradeTest { + + @Resource + private OrderCoinService orderCoinService; + + @Resource + OrderCoinsDao orderCoinsDao; + @Resource + RedisUtils redisUtils; + + @Test + public void buy(){ + redisUtils.set("ROC_NEW_PRICE",new BigDecimal("12.33")); + } +} -- Gitblit v1.9.1