zainali5120
2020-09-20 3ffaa6bf323862a3770897d4e934baf98d324c47
撮合交易代码提交
26 files modified
4 files added
617 ■■■■■ changed files
pom.xml 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/enumerates/CoinTypeEnum.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/common/enumerates/SymbolEnum.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/blackchain/model/RocCreateAcoountModel.java 10 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/blackchain/service/Impl/BlockSeriveImpl.java 11 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/blackchain/service/RocService.java 33 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/controller/OrderCoinController.java 7 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/parameter/vo/OrderWalletCoinVo.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java 2 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/service/impl/BlockCoinServiceImpl.java 6 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/coin/service/impl/OrderCoinServiceImpl.java 335 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/symbols/constants/SymbolsConstats.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/symbols/controller/SymbolsController.java 1 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/modules/symbols/service/impl/SymbolsServiceImpl.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/processor/DefaultCoinProcessor.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/BlockCoinUpdateJob.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/CoinTradeInitJob.java 7 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/KLineGeneratorJob.java 49 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/NewestPriceUpdateJob.java 4 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/NotionalPoolingJob.java 6 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/quartz/job/UsdtCnyExchangePriceUpdateJob.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/rabbit/consumer/ExchangeConsumer.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/rabbit/consumer/OperateOrderPriceConsumer.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/rabbit/init/OrderProducerInit.java 2 ●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/trade/CoinTrader.java 13 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/utils/CoinTypeConvert.java 12 ●●●● patch | view | raw | blame | history
src/main/java/com/xcong/excoin/websocket/TradePlateSendWebSocket.java 8 ●●●●● patch | view | raw | blame | history
src/main/resources/application-test.yml 18 ●●●● patch | view | raw | blame | history
src/main/resources/mapper/member/MemberWalletCoinDao.xml 12 ●●●● patch | view | raw | blame | history
src/test/java/com/xcong/excoin/TradeTest.java 34 ●●●●● patch | view | raw | blame | history
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>
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
}
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;
src/main/java/com/xcong/excoin/modules/blackchain/model/RocCreateAcoountModel.java
New file
@@ -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;
}
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;
                }
src/main/java/com/xcong/excoin/modules/blackchain/service/RocService.java
New file
@@ -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;
    }
}
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();
    }
}
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;
    /**
     * 成交量
     */
src/main/java/com/xcong/excoin/modules/coin/service/BlockCoinService.java
@@ -16,4 +16,6 @@
    public void updateTrc20();
    public void updateRoc();
}
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();
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);
    }
}
src/main/java/com/xcong/excoin/modules/symbols/constants/SymbolsConstats.java
New file
@@ -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");
    }
}
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;
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线的开盘价
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);
        }
    }
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();
    }
}
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")){
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);
                }
            }
        });
    }
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);
            }
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();
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();
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);
    }
    /**
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 {
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
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) {
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;
        }
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<>();
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:
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}
src/test/java/com/xcong/excoin/TradeTest.java
New file
@@ -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"));
    }
}