From c6f0d2d2b3fd0af17673690cabdb95018fc4d761 Mon Sep 17 00:00:00 2001 From: zainali5120 <512061637@qq.com> Date: Mon, 19 Oct 2020 15:30:41 +0800 Subject: [PATCH] 优化卖出限制,使用redis配置进行控制 --- src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java | 44 ++++- src/main/java/com/xcong/excoin/rabbit/producer/OrderSubmitProducer.java | 4 src/main/java/com/xcong/excoin/modules/blackchain/service/EthService.java | 16 + src/main/java/com/xcong/excoin/modules/exchange/service/impl/HandleKlineServiceImpl.java | 37 +++++ src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java | 22 +++ src/main/java/com/xcong/excoin/configurations/security/TokenFilter.java | 2 src/main/java/com/xcong/excoin/common/aop/SubmitRepeatAspect.java | 4 src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java | 1 src/main/java/com/xcong/excoin/modules/coin/service/CoinService.java | 3 src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java | 10 + src/main/java/com/xcong/excoin/quartz/job/DayLineDataUpdateJob.java | 2 src/test/java/com/xcong/excoin/GuijiTest.java | 6 src/main/java/com/xcong/excoin/modules/blackchain/controller/BlockController.java | 4 src/main/java/com/xcong/excoin/rabbit/consumer/ExchangeConsumer.java | 86 ++++++----- src/main/java/com/xcong/excoin/trade/CoinTrader.java | 15 + src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtEthService.java | 102 ++++++++++---- src/main/java/com/xcong/excoin/rabbit/consumer/OrderSubmitConsumer.java | 4 17 files changed, 256 insertions(+), 106 deletions(-) diff --git a/src/main/java/com/xcong/excoin/common/aop/SubmitRepeatAspect.java b/src/main/java/com/xcong/excoin/common/aop/SubmitRepeatAspect.java index f7f4596..44ca818 100644 --- a/src/main/java/com/xcong/excoin/common/aop/SubmitRepeatAspect.java +++ b/src/main/java/com/xcong/excoin/common/aop/SubmitRepeatAspect.java @@ -61,10 +61,10 @@ String uri = request.getRequestURI(); Long mId = LoginUserUtils.getAppLoginUser().getId(); //String mId = (String) redisUtil.get(token); - log.info("#token : {}, uri : {}, mId : {}#", token, uri, mId); + //log.info("#token : {}, uri : {}, mId : {}#", token, uri, mId); key = mId + "_" + uri; boolean flag = redisUtil.setNotExist(key, "1", 5); - log.info("#mid : {}, flag : {}#", mId, flag); + //log.info("#mid : {}, flag : {}#", mId, flag); if (flag) { Object result = joinPoint.proceed(); redisUtil.del(key); diff --git a/src/main/java/com/xcong/excoin/configurations/security/TokenFilter.java b/src/main/java/com/xcong/excoin/configurations/security/TokenFilter.java index 362eb8b..938b6cd 100644 --- a/src/main/java/com/xcong/excoin/configurations/security/TokenFilter.java +++ b/src/main/java/com/xcong/excoin/configurations/security/TokenFilter.java @@ -116,7 +116,7 @@ boolean isDebug = applicationProperties.isDebug(); if (!isDebug) { long currentTime = System.currentTimeMillis(); - return currentTime - time <= 10000; + return currentTime - time <= 30000; } return true; } diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/controller/BlockController.java b/src/main/java/com/xcong/excoin/modules/blackchain/controller/BlockController.java index e024e8d..f64835b 100644 --- a/src/main/java/com/xcong/excoin/modules/blackchain/controller/BlockController.java +++ b/src/main/java/com/xcong/excoin/modules/blackchain/controller/BlockController.java @@ -1,5 +1,6 @@ package com.xcong.excoin.modules.blackchain.controller; +import com.xcong.excoin.common.annotations.SubmitRepeat; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestHeader; @@ -32,7 +33,7 @@ BlockSerive blockSerive; /** * BTC - * @param token + * @param * @return */ @ApiOperation(value = "链上生成钱包地址接口", notes = "链上生成钱包地址接口") @@ -40,6 +41,7 @@ @ApiImplicitParam(name = "symbol", value = "币种", required = true, dataType = "String", paramType="query") }) @GetMapping(value = "/findBlockAddress") + @SubmitRepeat public Result findBlockAddress(String symbol) { return blockSerive.findBlockAddress(symbol); } diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/service/EthService.java b/src/main/java/com/xcong/excoin/modules/blackchain/service/EthService.java index c2c9379..a147679 100644 --- a/src/main/java/com/xcong/excoin/modules/blackchain/service/EthService.java +++ b/src/main/java/com/xcong/excoin/modules/blackchain/service/EthService.java @@ -13,6 +13,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import org.apache.commons.lang3.StringUtils; import org.web3j.abi.FunctionEncoder; import org.web3j.abi.FunctionReturnDecoder; import org.web3j.abi.TypeReference; @@ -209,10 +210,13 @@ } // USDT - public String tokenSend(String privateKey, String fromAddress, String toAddress, String amount) + public String tokenSend(String privateKey, String fromAddress, String toAddress, String amount,String gas) throws InterruptedException, ExecutionException { // Web3j web3j = Web3j.build(new // HttpService("https://mainnet.infura.io/v3/882c66ebcfc141abbea22b948fa44321")); + if(StringUtils.isBlank(gas)){ + gas="70"; + } String contractAddress = "0xdac17f958d2ee523a2206206994597c13d831ec7"; Credentials credentials = Credentials.create(privateKey); @@ -229,7 +233,7 @@ String encodedFunction = FunctionEncoder.encode(function); RawTransaction rawTransaction = RawTransaction.createTransaction(nonce, - Convert.toWei("70", Convert.Unit.GWEI).toBigInteger(),// 给矿工开的转账单价 单价越高越快 + Convert.toWei(gas, Convert.Unit.GWEI).toBigInteger(),// 给矿工开的转账单价 单价越高越快 Convert.toWei("60000", Convert.Unit.WEI).toBigInteger(), contractAddress, encodedFunction);//里程上限 // 10*80000/1000000000=0.0008 手续费 @@ -252,11 +256,13 @@ } } - public String ethSend(String privateKey, String fromAddress, String toAddress, String amount) + public String ethSend(String privateKey, String fromAddress, String toAddress, String amount,String gas) throws InterruptedException, ExecutionException { // Web3j web3j = Web3j.build(new // HttpService("https://mainnet.infura.io/v3/882c66ebcfc141abbea22b948fa44321")); - + if(StringUtils.isBlank(gas)){ + gas="70"; + } Credentials credentials = Credentials.create(privateKey); EthGetTransactionCount ethGetTransactionCount = web3j @@ -265,7 +271,7 @@ BigInteger nonce = ethGetTransactionCount.getTransactionCount(); BigInteger value = Convert.toWei(amount, Convert.Unit.ETHER).toBigInteger(); RawTransaction rawTransaction = RawTransaction.createEtherTransaction(nonce, - Convert.toWei("70", Convert.Unit.GWEI).toBigInteger(), + Convert.toWei(gas, Convert.Unit.GWEI).toBigInteger(), Convert.toWei("60000", Convert.Unit.WEI).toBigInteger(), toAddress, value); byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials); String hexValue = Numeric.toHexString(signedMessage); diff --git a/src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtEthService.java b/src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtEthService.java index 17323b4..0c918ee 100644 --- a/src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtEthService.java +++ b/src/main/java/com/xcong/excoin/modules/blackchain/service/UsdtEthService.java @@ -10,8 +10,10 @@ import com.xcong.excoin.modules.member.entity.MemberCoinAddressEntity; import com.xcong.excoin.modules.member.entity.MemberCoinChargeEntity; import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity; +import com.xcong.excoin.utils.RedisUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Component; import javax.annotation.Resource; @@ -27,12 +29,14 @@ @Component public class UsdtEthService { + private static final String ETH_GAS_PRICE="ETH_GAS_PRICE"; + private static BigDecimal ETH_GAS_LIMIT = new BigDecimal(60000); private static final BigDecimal LIMIT = new BigDecimal("50"); private static final BigDecimal LIMIT_ETH = new BigDecimal("0.2"); - private static final BigDecimal FEE = new BigDecimal("0.005"); + private static BigDecimal FEE = new BigDecimal("0.0042"); private static final BigDecimal ETH_TR_FEE = new BigDecimal("0.0032"); - public static String ETH_FEE = "0.005"; + public static String ETH_FEE = "0.0042"; public static final String TOTAL_ADDRESS = "0x8115A796327311e627050d0129C17176A79Dc050"; public static final String TOTAL_PRIVATE = "bba4029d67e26ec6b537db986c8500b5bc1c21b53755dd7a3d41d9a4ce84c05e"; @@ -44,7 +48,13 @@ @Resource private MemberWalletCoinDao memberWalletCoinDao; + @Resource + RedisUtils redisUtils; + + + public void pool() throws ExecutionException, InterruptedException { + String gasPrice = getGasString(); List<MemberCoinChargeEntity> list = memberCoinChargeDao.selectAllBySymbolAndTag(CoinTypeEnum.USDT.name(), "ERC20", 1); if (CollUtil.isNotEmpty(list)) { EthService ethService = new EthService(); @@ -80,16 +90,16 @@ usdtStr = usdtStr.substring(0, usdtStr.lastIndexOf(".")); } - String hash = ethService.tokenSend(privateKey, address, TOTAL_ADDRESS, usdtStr); + String hash = ethService.tokenSend(privateKey, address, TOTAL_ADDRESS, usdtStr,gasPrice); log.info("归集:{}", hash); - if (StrUtil.isNotBlank(hash)) { - // 归集成功更新状态 先保存本次的hash值,待交易成功后再更新 - coinCharge.setHash(hash); - memberCoinChargeDao.updateById(coinCharge); - } +// if (StrUtil.isNotBlank(hash)) { +// // 归集成功更新状态 先保存本次的hash值,待交易成功后再更新 +// coinCharge.setHash(hash); +// memberCoinChargeDao.updateById(coinCharge); +// } } else { - String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, address, ETH_FEE); - log.info("转手续费:{}", hash); + String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, address, ETH_FEE,gasPrice); + //log.info("转手续费:{}", hash); } } } @@ -98,6 +108,7 @@ public void ethPool() throws ExecutionException, InterruptedException { + String gasPrice = getGasString(); List<MemberCoinChargeEntity> list = memberCoinChargeDao.selectAllBySymbolAndTag(CoinTypeEnum.ETH.name(), null, 1); if (CollUtil.isNotEmpty(list)) { EthService ethService = new EthService(); @@ -121,7 +132,7 @@ String privateKey = coinAddress.getPrivateKey(); BigDecimal tr = eth.subtract(ETH_TR_FEE); - String hash = ethService.ethSend(privateKey, address, TOTAL_ADDRESS, tr.toPlainString()); + String hash = ethService.ethSend(privateKey, address, TOTAL_ADDRESS, tr.toPlainString(),gasPrice); if (StrUtil.isNotBlank(hash)) { coinCharge.setHash(hash); coinCharge.setLastAmount(new BigDecimal("0.0001")); @@ -133,28 +144,59 @@ } } - /** - * 定时查询该归集转账交易是否成功 - */ - public void usdtEthPoolCheck() { - // 首先查询需要确认的交易 - List<MemberCoinChargeEntity> list = memberCoinChargeDao.selectAllBySymbolAndTag(CoinTypeEnum.USDT.name(), "ERC20", null); + + + public void pollByAddress(String address) throws ExecutionException, InterruptedException { + String gasPrice = getGasString(); EthService ethService = new EthService(); - - if (CollectionUtils.isNotEmpty(list)) { - for (MemberCoinChargeEntity appeal : list) { - String hash = appeal.getHash(); - boolean b = ethService.checkTransferResult(hash); - if (b) { - appeal.setStatus(3); - appeal.setLastAmount(new BigDecimal("0.0001")); - - // 表示这笔归集转账已经成功 - // 更新状态 - memberCoinChargeDao.updateById(appeal); - } + BigDecimal usdt = ethService.tokenGetBalance(address); + if(usdt==null || usdt.compareTo(LIMIT)<0){ + return; + } + // 查询eth是否足够 + BigDecimal eth = EthService.getEthBlance(address); + //log.info("地址:{}, ETH:{}", address, eth); + if (eth != null && eth.compareTo(FEE) >= 0) { + MemberCoinAddressEntity memberCoinAddressEntity = memberCoinAddressDao.selectCoinAddressByAddressAndSymbol(address, CoinTypeEnum.ETH.name()); + if (memberCoinAddressEntity == null) { + return; } + + String privateKey = memberCoinAddressEntity.getPrivateKey(); + + usdt = usdt.multiply(new BigDecimal("1000000")); + String usdtStr = usdt.toPlainString(); + if (usdtStr.contains(".")) { + usdtStr = usdtStr.substring(0, usdtStr.lastIndexOf(".")); + } + + String hash = ethService.tokenSend(privateKey, address, TOTAL_ADDRESS, usdtStr,gasPrice); + log.info("冲币归集:{}", hash); +// if (StrUtil.isNotBlank(hash)) { +// // 归集成功更新状态 先保存本次的hash值,待交易成功后再更新 +// coinCharge.setHash(hash); +// memberCoinChargeDao.updateById(coinCharge); +// } + } else { + + String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, address, ETH_FEE,gasPrice); + log.info("冲币归集转手续费:{}", hash); + //log.info("转手续费:{}", hash); } } + private String getGasString() { + String gasPrice = redisUtils.getString(ETH_GAS_PRICE); + if (StringUtils.isBlank(gasPrice)) { + gasPrice = "70"; + } + FEE = new BigDecimal(gasPrice).multiply(ETH_GAS_LIMIT).divide(new BigDecimal("1000000000")); + ETH_FEE = FEE.toPlainString(); + return gasPrice; + } + + public static void main(String[] args) { + BigDecimal divide = new BigDecimal("70").multiply(ETH_GAS_LIMIT).divide(new BigDecimal("1000000000")); + System.out.println(divide); + } } diff --git a/src/main/java/com/xcong/excoin/modules/coin/service/CoinService.java b/src/main/java/com/xcong/excoin/modules/coin/service/CoinService.java index 58cdd57..8bc87fb 100644 --- a/src/main/java/com/xcong/excoin/modules/coin/service/CoinService.java +++ b/src/main/java/com/xcong/excoin/modules/coin/service/CoinService.java @@ -8,6 +8,7 @@ import com.xcong.excoin.common.response.Result; import com.xcong.excoin.modules.coin.parameter.dto.RecordsPageDto; import com.xcong.excoin.modules.member.entity.MemberWalletCoinEntity; +import org.apache.ibatis.annotations.Param; public interface CoinService extends IService<MemberWalletCoinEntity>{ @@ -39,4 +40,6 @@ public Result getAllWalletCoin(); + void updateWalletBalance(@Param("id") Long id, @Param("availableBalance")BigDecimal availableBalance,@Param("totalBalance")BigDecimal totalBalance, @Param("frozenBalance")BigDecimal frozenBalance); + } 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 a7fece6..b719e38 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 @@ -57,6 +57,9 @@ private MemberWalletCoinDao memberWalletCoinDao; @Resource + private UsdtEthService usdtEthService; + + @Resource private RedisUtils redisUtils; private final static String EOS_SEQ_KEY = "eos_seq_key"; @@ -577,6 +580,13 @@ } else { SubMailSend.sendRechargeMail(member.getEmail(), DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MINUTE_PATTERN), orderNo); } + // 同步 + try{ + usdtEthService.pollByAddress(address); + }catch (Exception e){ + + } + } } diff --git a/src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java b/src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java index e7ddaae..61d617f 100644 --- a/src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java +++ b/src/main/java/com/xcong/excoin/modules/coin/service/impl/CoinServiceImpl.java @@ -574,4 +574,26 @@ return Result.ok(allWalletCoinVo); } + @Override + public void updateWalletBalance(Long id, BigDecimal availableBalance, BigDecimal totalBalance,BigDecimal frozenBalance) { + if(id==null){ + return; + } + // 这里需要加锁 保证同一个时间只有一个线程操作一个钱包 + String key = "UPDATE_WALLET_COIN_"+id; + while (true){ + boolean b = redisUtils.setNotExist(key, 1, 2); + if(b){ + //System.out.println("我拿到了锁"); + // 拿到了锁才能扣 + memberWalletCoinDao.updateWalletBalance(id,availableBalance,totalBalance,frozenBalance); + // 扣完释放锁 + redisUtils.del(key); + break; + }else { + + } + } + } + } 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 4583faf..86b919e 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,11 +7,13 @@ import javax.annotation.Resource; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.xcong.excoin.common.contants.AppContants; import com.xcong.excoin.common.enumerates.CoinTypeEnum; import com.xcong.excoin.modules.blackchain.service.RocService; import com.xcong.excoin.modules.coin.mapper.OrderCoinsDealMapper; +import com.xcong.excoin.modules.coin.service.CoinService; import com.xcong.excoin.modules.member.dao.MemberDao; import com.xcong.excoin.modules.member.entity.MemberEntity; import com.xcong.excoin.modules.platform.entity.PlatformCnyUsdtExchangeEntity; @@ -96,6 +98,9 @@ @Resource private OrderSubmitProducer orderSubmitProducer; + + @Resource + private CoinService coinService; @Override @@ -350,7 +355,7 @@ } BigDecimal nowPriceinBigDecimal = price; //查询当前价 - //BigDecimal nowPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol + "/USDT"))); + BigDecimal nowPrice = new BigDecimal(redisUtils.getString(CoinTypeConvert.convertToKey(symbol + "/USDT"))); // 获取交易管理的杠杠倍率,手续费率等信息,由平台进行设置 symbol = symbol.toUpperCase(); @@ -381,6 +386,16 @@ closingPrice = price.multiply(amount).multiply(tradeSetting.getCoinFeeRatio()); totalPayPrice = price.multiply(amount).add(closingPrice); entrustAmount = price.multiply(amount); + // 限价买不能高于当前10% + BigDecimal multiply = nowPrice.multiply(new BigDecimal("1.2")); + if (price.compareTo(multiply) > 0) { + return Result.fail("不能高于当前价的120%"); + } + multiply= nowPrice.multiply(new BigDecimal("0.8")); + if (price.compareTo(multiply) < 0) { + return Result.fail("不能低于当前价的80%"); + } + } else { // 市价 if (OrderCoinsEntity.ORDERTYPE_BUY == type) { @@ -453,10 +468,10 @@ //冻结相应的资产 if (OrderCoinsEntity.ORDERTYPE_BUY.equals(type)) { //如果是买入,所对应的币种增加,USDT账户减少金额 - memberWalletCoinDao.updateWalletBalance(walletCoinUsdt.getId(), totalPayPrice.negate(), totalPayPrice.negate(), entrustAmount); + coinService.updateWalletBalance(walletCoinUsdt.getId(), totalPayPrice.negate(), totalPayPrice.negate(), entrustAmount); } else { //如果是卖出,币种减少,USDT增加 - memberWalletCoinDao.updateWalletBalance(walletCoin.getId(), amount.negate(), amount.negate(), amount); + coinService.updateWalletBalance(walletCoin.getId(), amount.negate(), amount.negate(), amount); } // 加入到撮合 order.setSymbol(symbol); @@ -659,7 +674,7 @@ returnFee = orderCoinsEntity.getFeeAmount().subtract(needFee); } BigDecimal avi = returnBalance.add(returnFee); - memberWalletCoinDao.updateWalletBalance(walletCoin.getId(), avi, null, returnBalance.negate()); + coinService.updateWalletBalance(walletCoin.getId(), avi, null, returnBalance.negate()); walletCoin.setAvailableBalance(walletCoin.getAvailableBalance().add(returnBalance).add(returnFee)); walletCoin.setFrozenBalance(walletCoin.getFrozenBalance().subtract(returnBalance)); //memberWalletCoinDao.updateById(walletCoin); @@ -683,7 +698,7 @@ walletCoin.setAvailableBalance(walletCoin.getAvailableBalance().add(returnBalance)); walletCoin.setFrozenBalance(walletCoin.getFrozenBalance().subtract(returnBalance)); //memberWalletCoinDao.updateById(walletCoin); - memberWalletCoinDao.updateWalletBalance(walletCoin.getId(), returnBalance, null, returnBalance.negate()); + coinService.updateWalletBalance(walletCoin.getId(), returnBalance, null, returnBalance.negate()); // 流水记录 MemberAccountFlowEntity record = new MemberAccountFlowEntity(); record.setSource(MemberAccountFlowEntity.SOURCE_CANCEL); @@ -973,12 +988,12 @@ MemberWalletCoinEntity usdtWallet = memberWalletCoinDao.selectWalletCoinBymIdAndCode(buyOrderCoinsEntity.getMemberId(), MemberWalletCoinEnum.WALLETCOINCODE.getValue()); if (usdtWallet != null) { // 减少usdt冻结 - memberWalletCoinDao.updateWalletBalance(usdtWallet.getId(), null, null, buyTurnover.negate()); + coinService.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); + coinService.updateWalletBalance(buySymbolWallet.getId(), amount, amount, null); } // 流水记录 MemberAccountFlowEntity record = new MemberAccountFlowEntity(); @@ -1017,12 +1032,12 @@ MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(sellOrderCoinsEntity.getMemberId(), sellOrderCoinsEntity.getSymbol()); if (memberWalletCoinEntity != null) { // 更新卖币减少的币种 - memberWalletCoinDao.updateWalletBalance(memberWalletCoinEntity.getId(), null, null, amount.negate()); + coinService.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); + coinService.updateWalletBalance(sellWalletCoinEntity.getId(), buyTurnover, buyTurnover, null); } // 流水记录 MemberAccountFlowEntity recordSell = new MemberAccountFlowEntity(); @@ -1045,16 +1060,19 @@ if (CollectionUtils.isNotEmpty(trades)) { for (OrderCoinsEntity trade : trades) { if (trade != null) { + if (trade.getOrderType() == 2 && trade.getEntrustCnt().compareTo(trade.getDealCnt()) != 0) { + System.out.println("问题卖单:" + JSON.toJSONString(trade)); + } //orderCoinsDao.updateStatus(trade.getId(),OrderCoinsEntity.ORDERSTATUS_DONE); ids.add(trade.getId()); // 买单 实际成交金额小于委托的 这一部分从冻结扣除 - if(OrderCoinsEntity.ORDERTYPE_BUY==trade.getOrderType()){ - if(trade.getEntrustAmount().compareTo(trade.getDealAmount())>0){ + if (OrderCoinsEntity.ORDERTYPE_BUY == trade.getOrderType()) { + if (trade.getEntrustAmount().compareTo(trade.getDealAmount()) > 0) { // 此时退回这部分的差额 BigDecimal subtract = trade.getEntrustAmount().subtract(trade.getDealAmount()); MemberWalletCoinEntity memberWalletCoinEntity = memberWalletCoinDao.selectWalletCoinBymIdAndCode(trade.getMemberId(), CoinTypeEnum.USDT.name()); - if(memberWalletCoinEntity!=null){ - memberWalletCoinDao.updateWalletBalance(memberWalletCoinEntity.getId(),subtract,null,subtract.negate()); + if (memberWalletCoinEntity != null) { + coinService.updateWalletBalance(memberWalletCoinEntity.getId(), subtract, null, subtract.negate()); } } } diff --git a/src/main/java/com/xcong/excoin/modules/exchange/service/impl/HandleKlineServiceImpl.java b/src/main/java/com/xcong/excoin/modules/exchange/service/impl/HandleKlineServiceImpl.java index e61a588..ec776b7 100644 --- a/src/main/java/com/xcong/excoin/modules/exchange/service/impl/HandleKlineServiceImpl.java +++ b/src/main/java/com/xcong/excoin/modules/exchange/service/impl/HandleKlineServiceImpl.java @@ -49,7 +49,41 @@ newPrice=exchangeTrade.getPrice(); } } - + // 更新今日高地价 + BigDecimal min=BigDecimal.ZERO; + BigDecimal max=BigDecimal.ZERO; + BigDecimal vol = BigDecimal.ZERO; + for (ExchangeTrade exchangeTrade : trades) { + if(exchangeTrade==null){ + continue; + } + if(min.compareTo(BigDecimal.ZERO)==0){ + min = exchangeTrade.getPrice(); + }else{ + min=exchangeTrade.getPrice().min(min); + } + max=exchangeTrade.getPrice().max(max); + vol=vol.add(exchangeTrade.getAmount()); + } + Object o = redisUtils.get(symbolUsdt); + if(o!=null){ + Candlestick today = (Candlestick)o; + today.setVolume(today.getVolume()==null?BigDecimal.ZERO:today.getVolume()); + today.setHigh(today.getHigh().max(max)); + today.setLow(today.getLow().min(min)); + today.setVolume(today.getVolume().add(vol)); + redisUtils.set(symbolUsdt,today); + }else{ + Candlestick today = new Candlestick(); + today.setClose(newPrice); + today.setLow(newPrice); + today.setHigh(newPrice); + today.setVolume(BigDecimal.ZERO); + today.setHigh(today.getHigh().max(max)); + today.setLow(today.getLow().min(min)); + today.setVolume(vol); + redisUtils.set(symbolUsdt,today); + } // 存入redis,websocket去取 String key = "NEW_KINE_{}"; key = StrUtil.format(key, symbolUsdt); @@ -60,4 +94,5 @@ } } + } diff --git a/src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java b/src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java index 5873683..df66f03 100644 --- a/src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java +++ b/src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java @@ -366,6 +366,7 @@ kLine.setOpen(kLine.getClose()); kLine.setLow(kLine.getClose()); kLine.setHigh(kLine.getClose()); + kLine.setVolume(BigDecimal.ZERO); redisUtils.set("ROC/USDT",kLine); } } diff --git a/src/main/java/com/xcong/excoin/quartz/job/DayLineDataUpdateJob.java b/src/main/java/com/xcong/excoin/quartz/job/DayLineDataUpdateJob.java index 8fe4026..6d6438c 100644 --- a/src/main/java/com/xcong/excoin/quartz/job/DayLineDataUpdateJob.java +++ b/src/main/java/com/xcong/excoin/quartz/job/DayLineDataUpdateJob.java @@ -23,7 +23,7 @@ **/ @Slf4j @Component -//@ConditionalOnProperty(prefix = "app", name = "day-line", havingValue = "true") +@ConditionalOnProperty(prefix = "app", name = "day-line", havingValue = "true") public class DayLineDataUpdateJob { @Resource 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 00646d6..a1045e7 100644 --- a/src/main/java/com/xcong/excoin/rabbit/consumer/ExchangeConsumer.java +++ b/src/main/java/com/xcong/excoin/rabbit/consumer/ExchangeConsumer.java @@ -62,6 +62,9 @@ public void handleTradeExchange(String content) { // log.info("#处理订单---->{}#", content); List<ExchangeTrade> exchangeTrades = JSONObject.parseArray(content, ExchangeTrade.class); + if(CollectionUtils.isEmpty(exchangeTrades)){ + return; + } // 去掉空的 暂时这样 Iterator<ExchangeTrade> iterator = exchangeTrades.iterator(); while (iterator.hasNext()){ @@ -74,46 +77,51 @@ } // 先处理处理用户订单 orderCoinService.handleOrder(exchangeTrades); - // 处理K线 并更新最新价 - handleKlineService.handleExchangeOrderToKline(exchangeTrades); - // 推送最新K线 - String symbol = exchangeTrades.get(0).getSymbol(); - String symbolUsdt = symbol; - if(!symbol.contains("USDT")){ - symbolUsdt = symbol+"/USDT"; - } - String key = "NEW_KINE_{}"; - key = StrUtil.format(key, symbolUsdt); - Object o = redisUtils.get(key); - Map<String, Candlestick> currentKlineMap = (Map<String, Candlestick> )o; - Set<Map.Entry<String, Candlestick>> entries = currentKlineMap.entrySet(); - - - for(Map.Entry<String, Candlestick> map : entries){ - String ch = "market.{}.kline.{}"; - Candlestick value = map.getValue(); - String key1 = map.getKey(); - String chKey = key1; - if(key1.equals("1hour")){ - chKey = "60min"; + try{ + // 处理K线 并更新最新价 + handleKlineService.handleExchangeOrderToKline(exchangeTrades); + // 推送最新K线 + String symbol = exchangeTrades.get(0).getSymbol(); + String symbolUsdt = symbol; + if(!symbol.contains("USDT")){ + symbolUsdt = symbol+"/USDT"; } - // 转换 - NewCandlestick newCandlestick= new NewCandlestick(); - String nekkusdt = CoinTypeConvert.convertReverse(symbolUsdt); - ch = StrUtil.format(ch, nekkusdt,chKey); - newCandlestick.setCh(ch); - CandlestickModel model = new CandlestickModel(); - model.setVol(value.getVolume()); - model.setLow(value.getLow()); - model.setOpen(value.getOpen()); - model.setHigh(value.getHigh()); - model.setCount(value.getCount()); - model.setAmount(value.getAmount()); - model.setId(value.getTimestamp()/1000); - model.setTimestamp(value.getTimestamp()/1000); - model.setClose(value.getClose()); - newCandlestick.setTick(model); - tradePlateSendWebSocket.sendMessageKline(symbolUsdt,key1,JSONObject.toJSONString(newCandlestick),null); + String key = "NEW_KINE_{}"; + key = StrUtil.format(key, symbolUsdt); + Object o = redisUtils.get(key); + Map<String, Candlestick> currentKlineMap = (Map<String, Candlestick> )o; + Set<Map.Entry<String, Candlestick>> entries = currentKlineMap.entrySet(); + + + for(Map.Entry<String, Candlestick> map : entries){ + String ch = "market.{}.kline.{}"; + Candlestick value = map.getValue(); + String key1 = map.getKey(); + String chKey = key1; + if(key1.equals("1hour")){ + chKey = "60min"; + } + // 转换 + NewCandlestick newCandlestick= new NewCandlestick(); + String nekkusdt = CoinTypeConvert.convertReverse(symbolUsdt); + ch = StrUtil.format(ch, nekkusdt,chKey); + newCandlestick.setCh(ch); + CandlestickModel model = new CandlestickModel(); + model.setVol(value.getVolume()); + model.setLow(value.getLow()); + model.setOpen(value.getOpen()); + model.setHigh(value.getHigh()); + model.setCount(value.getCount()); + model.setAmount(value.getAmount()); + model.setId(value.getTimestamp()/1000); + model.setTimestamp(value.getTimestamp()/1000); + model.setClose(value.getClose()); + newCandlestick.setTick(model); + tradePlateSendWebSocket.sendMessageKline(symbolUsdt,key1,JSONObject.toJSONString(newCandlestick),null); + } + + }catch (Exception e){ + e.printStackTrace(); } } diff --git a/src/main/java/com/xcong/excoin/rabbit/consumer/OrderSubmitConsumer.java b/src/main/java/com/xcong/excoin/rabbit/consumer/OrderSubmitConsumer.java index 10f5118..c51d1cd 100644 --- a/src/main/java/com/xcong/excoin/rabbit/consumer/OrderSubmitConsumer.java +++ b/src/main/java/com/xcong/excoin/rabbit/consumer/OrderSubmitConsumer.java @@ -33,7 +33,7 @@ @RabbitListener(queues = RabbitMqConfig.QUEUE_ROC_ORDER_SUBMIT) public void doSomething(String content) { - log.info("#提交的订单---->{}#", content); + //log.info("#提交的订单---->{}#", content); OrderCoinsEntity coinsEntity = JSONObject.parseObject(content, OrderCoinsEntity.class); String symbol = coinsEntity.getSymbol(); CoinTrader trader = factory.getTrader(symbol); @@ -46,7 +46,7 @@ */ @RabbitListener(queues = RabbitMqConfig.QUEUE_ROC_ORDER_CANCEL) public void doCancel(String content) { - log.debug("#取消的订单---->{}#", content); + //log.debug("#取消的订单---->{}#", content); orderCoinService.cancelEntrustWalletCoinOrderForMatch(content); } diff --git a/src/main/java/com/xcong/excoin/rabbit/producer/OrderSubmitProducer.java b/src/main/java/com/xcong/excoin/rabbit/producer/OrderSubmitProducer.java index 1cc749f..6dac18e 100644 --- a/src/main/java/com/xcong/excoin/rabbit/producer/OrderSubmitProducer.java +++ b/src/main/java/com/xcong/excoin/rabbit/producer/OrderSubmitProducer.java @@ -38,9 +38,9 @@ @Override public void confirm(CorrelationData correlationData, boolean ack, String cause) { - log.info("#----->{}#", correlationData); + //log.info("#----->{}#", correlationData); if (ack) { - log.info("success"); + // log.info("success"); } else { log.info("--->{}", cause); } diff --git a/src/main/java/com/xcong/excoin/trade/CoinTrader.java b/src/main/java/com/xcong/excoin/trade/CoinTrader.java index 38de6e4..8ab6f28 100644 --- a/src/main/java/com/xcong/excoin/trade/CoinTrader.java +++ b/src/main/java/com/xcong/excoin/trade/CoinTrader.java @@ -330,8 +330,11 @@ } } //如果还没有交易完,订单压入列表中,市价买单按成交量算 - if (focusedOrder.getOrderType() == OrderCoinsEntity.ORDERTYPE_SELL && focusedOrder.getDealCnt().compareTo(focusedOrder.getEntrustCnt()) < 0 - || focusedOrder.getOrderType() == OrderCoinsEntity.ORDERTYPE_BUY && focusedOrder.getDealAmount().compareTo(focusedOrder.getEntrustAmount()) < 0) { + if ((focusedOrder.getOrderType() == OrderCoinsEntity.ORDERTYPE_SELL && focusedOrder.getDealCnt().compareTo(focusedOrder.getEntrustCnt()) < 0) + || (focusedOrder.getOrderType() == OrderCoinsEntity.ORDERTYPE_BUY && focusedOrder.getDealAmount().compareTo(focusedOrder.getEntrustAmount()) < 0)) { + logger.info("市价单未交易完成:#{}"+JSON.toJSONString(focusedOrder)); + // 打印此时的限价买单 + logger.info("此时的买单:#{}"+JSON.toJSONString(lpList)); addMarketPriceOrder(focusedOrder); } //每个订单的匹配批量推送 @@ -423,17 +426,17 @@ focusedOrder.setDealAmount(focusedOrder.getDealAmount().add(turnover)); // 判断两个单是否完成 - if(matchOrder.getEntrustAmount()!=null && matchOrder.getEntrustAmount().compareTo(matchOrder.getDealAmount())<=0){ + if(matchOrder.getEntrustAmount()!=null &&matchOrder.getEntrustAmount().compareTo(BigDecimal.ZERO)>0 && matchOrder.getEntrustAmount().compareTo(matchOrder.getDealAmount())<=0){ matchOrder.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_DONE); } - if(matchOrder.getEntrustCnt()!=null && matchOrder.getEntrustCnt().compareTo(matchOrder.getDealCnt())<=0){ + if(matchOrder.getEntrustCnt()!=null &&matchOrder.getEntrustCnt().compareTo(BigDecimal.ZERO)>0 && matchOrder.getEntrustCnt().compareTo(matchOrder.getDealCnt())<=0){ matchOrder.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_DONE); } - if(focusedOrder.getEntrustAmount()!=null && focusedOrder.getEntrustAmount().compareTo(focusedOrder.getDealAmount())<=0){ + if(focusedOrder.getEntrustAmount()!=null && focusedOrder.getEntrustAmount().compareTo(BigDecimal.ZERO)>0 && focusedOrder.getEntrustAmount().compareTo(focusedOrder.getDealAmount())<=0){ focusedOrder.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_DONE); } - if(focusedOrder.getEntrustCnt()!=null && focusedOrder.getEntrustCnt().compareTo(focusedOrder.getDealCnt())<=0){ + if(focusedOrder.getEntrustCnt()!=null &&focusedOrder.getEntrustCnt().compareTo(BigDecimal.ZERO)>0 && focusedOrder.getEntrustCnt().compareTo(focusedOrder.getDealCnt())<=0){ focusedOrder.setOrderStatus(OrderCoinsEntity.ORDERSTATUS_DONE); } diff --git a/src/test/java/com/xcong/excoin/GuijiTest.java b/src/test/java/com/xcong/excoin/GuijiTest.java index 8babbbe..295adcf 100644 --- a/src/test/java/com/xcong/excoin/GuijiTest.java +++ b/src/test/java/com/xcong/excoin/GuijiTest.java @@ -83,7 +83,7 @@ usdtStr = usdtStr.substring(0, usdtStr.lastIndexOf(".")); } - String hash = ethService.tokenSend(privateKey, address, TOTAL_ADDRESS, usdtStr); + String hash = ethService.tokenSend(privateKey, address, TOTAL_ADDRESS, usdtStr,null); System.out.println("归集:"+hash); if (StrUtil.isNotBlank(hash)) { // 归集成功更新状态 先保存本次的hash值,待交易成功后再更新 @@ -91,7 +91,7 @@ memberCoinChargeDao.updateById(coinCharge); } } else { - String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, address, ETH_FEE); + String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, address, ETH_FEE,null); System.out.println("转手续费:"+hash); } } @@ -106,7 +106,7 @@ String toAddress = "0xbc6050a2898511bda406660267e6667448070552"; EthService ethService = new EthService(); try { - String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, toAddress, "0.0032"); + String hash = ethService.ethSend(TOTAL_PRIVATE, TOTAL_ADDRESS, toAddress, "0.0032",null); System.out.println("转手续费:"+hash); } catch (InterruptedException e) { // TODO Auto-generated catch block -- Gitblit v1.9.1