1
zj
2024-08-14 a949bf71283aeabbf4ac26adb7f183b67c02dfc7
1
6 files modified
489 ■■■■ changed files
.idea/inspectionProfiles/Project_Default.xml 42 ●●●●● patch | view | raw | blame | history
src/main/java/project/contract/internal/ContractOrderServiceImpl.java 198 ●●●● patch | view | raw | blame | history
src/main/java/project/contract/job/ContractOrderCalculationServiceImpl.java 54 ●●●●● patch | view | raw | blame | history
src/main/java/project/project/web/admin/AdminContractOrderController.java 135 ●●●● patch | view | raw | blame | history
src/main/java/project/project/web/api/ContractOrderController.java 52 ●●●●● patch | view | raw | blame | history
src/main/java/project/wallet/internal/WalletServiceImpl.java 8 ●●●●● patch | view | raw | blame | history
.idea/inspectionProfiles/Project_Default.xml
@@ -2,16 +2,58 @@
  <profile version="1.0">
    <option name="myName" value="Project Default" />
    <inspection_tool class="AlibabaAbstractClassShouldStartWithAbstractNaming" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAbstractMethodOrInterfaceMethodMustUseJavadoc" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidApacheBeanUtilsCopy" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidCallStaticSimpleDateFormat" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidCommentBehindStatement" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidComplexCondition" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidConcurrentCompetitionRandom" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidDoubleOrFloatEqualCompare" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidManuallyCreateThread" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidMissUseOfMathRandom" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidNegationOperator" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidNewDateGetTime" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidPatternCompileInMethod" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidReturnInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidStartWithDollarAndUnderLineNaming" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaAvoidUseTimer" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaBigDecimalAvoidDoubleConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaBooleanPropertyShouldNotStartWithIs" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaClassCastExceptionWithSubListToArrayList" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaClassCastExceptionWithToArray" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaClassMustHaveAuthor" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaClassNamingShouldBeCamel" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaCollectionInitShouldAssignCapacity" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaCommentsMustBeJavadocFormat" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaConcurrentExceptionWithModifyOriginSubList" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaConstantFieldShouldBeUpperCase" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaCountDownShouldInFinally" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaDontModifyInForeachCircle" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaEnumConstantsMustHaveComment" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaExceptionClassShouldEndWithException" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaIbatisMethodQueryForList" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaLockShouldWithTryFinally" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaLowerCamelCaseVariableNaming" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaMethodReturnWrapperType" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaMethodTooLong" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaPackageNaming" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaPojoMustOverrideToString" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaPojoMustUsePrimitiveField" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaPojoNoDefaultValue" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaRemoveCommentedCode" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaServiceOrDaoClassShouldEndWithImpl" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaSneakyThrowsWithoutExceptionType" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaStringConcat" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaSwitchExpression" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaSwitchStatement" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaTestClassShouldEndWithTestNaming" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaThreadLocalShouldRemove" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaThreadPoolCreation" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaThreadShouldSetName" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaTransactionMustHaveRollback" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaUndefineMagicConstant" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaUnsupportedExceptionWithModifyAsList" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaUseQuietReferenceNotation" enabled="true" level="WARNING" enabled_by_default="true" />
    <inspection_tool class="AlibabaUseRightCaseForDateFormat" enabled="true" level="WARNING" enabled_by_default="true" />
  </profile>
</component>
src/main/java/project/contract/internal/ContractOrderServiceImpl.java
@@ -14,6 +14,7 @@
import kernel.util.StringUtils;
import kernel.web.ApplicationUtil;
import kernel.web.Page;
import org.springframework.beans.factory.annotation.Autowired;
import project.Constants;
import project.contract.ContractApplyOrder;
import project.contract.ContractApplyOrderService;
@@ -75,25 +76,25 @@
        ApplicationUtil.executeInsert(order);
        redisHandler.setSync(ContractRedisKeys.CONTRACT_ORDERNO + order.getOrder_no(), order);
        Map<String, ContractOrder> map = (Map<String, ContractOrder>) redisHandler.get(ContractRedisKeys.CONTRACT_SUBMITTED_ORDER_PARTY_ID + order.getPartyId().toString());
        if (map == null) map = new ConcurrentHashMap<String, ContractOrder>();
        map.put(order.getOrder_no(), order);
        redisHandler.setSync(ContractRedisKeys.CONTRACT_SUBMITTED_ORDER_PARTY_ID + order.getPartyId().toString(), map);
        // 获取单个订单的合约总资产、总保证金、总未实现盈利
        Map<String, Double> contractAssetsOrder = this.assetService.getMoneyContractByOrder(order);
        Double contractAssets = (Double) this.redisHandler.get(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + order.getPartyId().toString());
        Double contractAssetsDeposit = (Double) this.redisHandler.get(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + order.getPartyId().toString());
        Double contractAssetsProfit = (Double) this.redisHandler.get(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString());
        this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + order.getPartyId().toString(),
        this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + order.getPartyId().toString(),
                Arith.add(null == contractAssets ? 0.000D : contractAssets, contractAssetsOrder.get("money_contract")));
        this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + order.getPartyId().toString(),
                Arith.add(null == contractAssetsDeposit ? 0.000D : contractAssetsDeposit, contractAssetsOrder.get("money_contract_deposit")));
        this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString(),
        this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + order.getPartyId().toString(),
                Arith.add(null == contractAssetsDeposit ? 0.000D : contractAssetsDeposit, contractAssetsOrder.get("money_contract_deposit")));
        this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString(),
                Arith.add(null == contractAssetsProfit ? 0.000D : contractAssetsProfit, contractAssetsOrder.get("money_contract_profit")));
        /**
         * 进入市场
         */
@@ -101,7 +102,7 @@
        applyOrder.setState(ContractApplyOrder.STATE_CREATED);
        this.contractApplyOrderService.update(applyOrder);
        Party party = this.partyService.cachePartyBy(order.getPartyId(), false);
        if (Constants.SECURITY_ROLE_MEMBER.equals(party.getRolename())) {
            tipService.saveTip(order.getId().toString(), TipConstants.CONTRACT_ORDER);
@@ -163,7 +164,7 @@
    /**
     * 根据用户批量赎回订单
     *
     *
     * @param partyId
     */
    public void saveCloseRemoveAllByPartyId(String partyId) {
@@ -175,9 +176,9 @@
                    saveClose(order.getPartyId().toString(), order.getOrder_no());
                }
                redisHandler.remove(ContractRedisKeys.CONTRACT_ORDERNO + order.getOrder_no());
            }
            }
            redisHandler.remove(ContractRedisKeys.CONTRACT_SUBMITTED_ORDER_PARTY_ID + partyId);
            this.redisHandler.remove(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + partyId);
            this.redisHandler.remove(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + partyId);
            this.redisHandler.remove(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + partyId);
@@ -192,7 +193,7 @@
        if (order == null || !ContractOrder.STATE_SUBMITTED.equals(order.getState()) || !partyId.equals(order.getPartyId().toString()) || order.getVolume() <= 0) {
            return null; //状态已改变,退出处理
        }
        /**
         * 收益
         */
@@ -244,30 +245,30 @@
        String id = null == order.getId() ? ApplicationUtil.getCurrentTimeUUID() : order.getId().toString();
        ApplicationUtil.executeInsertOrUpdate(order, "WHERE UUID=?", new Object[] {id});
        redisHandler.setSync(ContractRedisKeys.CONTRACT_ORDERNO + order.getOrder_no(), order);
        if (ContractOrder.STATE_SUBMITTED.equals(order.getState())) {
            Map<String, ContractOrder> map = (Map<String, ContractOrder>) redisHandler.get(ContractRedisKeys.CONTRACT_SUBMITTED_ORDER_PARTY_ID + order.getPartyId().toString());
            if (null == map) map = new ConcurrentHashMap<String, ContractOrder>();
            ContractOrder orderOld = map.get(order.getOrder_no());
            map.put(order.getOrder_no(), order);
            redisHandler.setSync(ContractRedisKeys.CONTRACT_SUBMITTED_ORDER_PARTY_ID + order.getPartyId().toString(), map);
            // 获取单个订单的合约总资产、总保证金、总未实现盈利
            Map<String, Double> contractAssetsOrder = this.assetService.getMoneyContractByOrder(order);
            Map<String, Double> contractAssetsOrderOld = this.assetService.getMoneyContractByOrder(orderOld);
            Double contractAssets = (Double) this.redisHandler.get(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + order.getPartyId().toString());
            Double contractAssetsDeposit = (Double) this.redisHandler.get(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + order.getPartyId().toString());
            Double contractAssetsProfit = (Double) this.redisHandler.get(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString());
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + order.getPartyId().toString(),
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + order.getPartyId().toString(),
                    Arith.add(null == contractAssets ? 0.000D : contractAssets, contractAssetsOrder.get("money_contract") - contractAssetsOrderOld.get("money_contract")));
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + order.getPartyId().toString(),
                    Arith.add(null == contractAssetsDeposit ? 0.000D : contractAssetsDeposit, contractAssetsOrder.get("money_contract_deposit") - contractAssetsOrderOld.get("money_contract_deposit")));
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString(),
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + order.getPartyId().toString(),
                    Arith.add(null == contractAssetsDeposit ? 0.000D : contractAssetsDeposit, contractAssetsOrder.get("money_contract_deposit") - contractAssetsOrderOld.get("money_contract_deposit")));
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString(),
                    Arith.add(null == contractAssetsProfit ? 0.000D : contractAssetsProfit, contractAssetsOrder.get("money_contract_profit") - contractAssetsOrderOld.get("money_contract_profit")));
        } else if (ContractOrder.STATE_CREATED.equals(order.getState())) { // 平仓后,移除持仓列表
            Map<String, ContractOrder> map = (Map<String, ContractOrder>) redisHandler.get(ContractRedisKeys.CONTRACT_SUBMITTED_ORDER_PARTY_ID + order.getPartyId().toString());
            ContractOrder orderOld = null;
@@ -276,21 +277,21 @@
                map.remove(order.getOrder_no());
            }
            redisHandler.setSync(ContractRedisKeys.CONTRACT_SUBMITTED_ORDER_PARTY_ID + order.getPartyId().toString(), map);
            // 获取单个订单的合约总资产、总保证金、总未实现盈利
            Map<String, Double> contractAssetsOrderOld = this.assetService.getMoneyContractByOrder(orderOld);
            Double contractAssets = (Double) this.redisHandler.get(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + order.getPartyId().toString());
            Double contractAssetsDeposit = (Double) this.redisHandler.get(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + order.getPartyId().toString());
            Double contractAssetsProfit = (Double) this.redisHandler.get(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString());
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + order.getPartyId().toString(),
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PARTY_ID + order.getPartyId().toString(),
                    Arith.add(null == contractAssets ? 0.000D : contractAssets, 0.000D - contractAssetsOrderOld.get("money_contract")));
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + order.getPartyId().toString(),
                    Arith.add(null == contractAssetsDeposit ? 0.000D : contractAssetsDeposit, 0.000D - contractAssetsOrderOld.get("money_contract_deposit")));
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString(),
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_DEPOSIT_PARTY_ID + order.getPartyId().toString(),
                    Arith.add(null == contractAssetsDeposit ? 0.000D : contractAssetsDeposit, 0.000D - contractAssetsOrderOld.get("money_contract_deposit")));
            this.redisHandler.setSync(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString(),
                    Arith.add(null == contractAssetsProfit ? 0.000D : contractAssetsProfit, 0.000D - contractAssetsOrderOld.get("money_contract_profit")));
            // 平仓则纪录数据(委托平仓,订单直接平仓)
            this.userDataService.saveClose(order);
            Party party = this.partyService.cachePartyBy(order.getPartyId(), false);
@@ -302,7 +303,7 @@
    /**
     * 收益结算,平仓时计算
     *
     *
     * @param closevolume 平仓的张数
     */
    public double settle(ContractOrder order, double volume) {
@@ -330,7 +331,7 @@
    public ContractOrder findByOrderNo(String order_no) {
        ContractOrder order = (ContractOrder) this.redisHandler.get(ContractRedisKeys.CONTRACT_ORDERNO + order_no);
        if (null != order) return order;
        List<ContractOrder> list = ApplicationUtil.executeSelect(ContractOrder.class,"WHERE ORDER_NO=?",new Object[] {order_no});
        return list.size()<=0?null:list.get(0);
    }
@@ -355,11 +356,11 @@
            }
            return list;
        }
        Page page = new Page(1,Integer.MAX_VALUE,Integer.MAX_VALUE);
        StringBuilder whereSql=new StringBuilder("WHERE 1=1 ");
        ArrayList<Object> params=new ArrayList<Object>();
        if (!StringUtils.isNullOrEmpty(partyId)) {
            whereSql.append("AND PARTY_ID=? ");
            params.add(partyId);
@@ -369,7 +370,7 @@
            whereSql.append("AND SYMBOL=? ");
            params.add(symbol);
        }
        if (!StringUtils.isNullOrEmpty(direction)) {
            whereSql.append("AND DIRECTION=? ");
            params.add(direction);
@@ -379,18 +380,18 @@
        params.add("submitted");
        params.add(page.getFirstElementNumber());
        params.add(page.getPageSize());
        return ApplicationUtil.executeSelect(ContractOrder.class,whereSql.toString(),params.toArray(new Object[params.size()]));
    }
    public List<Map<String, Object>> getPaged(int pageNo, int pageSize, String partyId, String symbol, String type,String startTime, String endTime) {
        if (pageNo <= 0) pageNo = 1;
        Page page = new Page(pageNo, pageSize, Integer.MAX_VALUE);
        StringBuilder whereSql=new StringBuilder("WHERE PARTY_ID=? ");
        ArrayList<Object> params=new ArrayList<Object>();
        params.add(partyId);
        if (!StringUtils.isNullOrEmpty(symbol)) {
            whereSql.append("AND SYMBOL=? ");
            params.add(symbol);
@@ -403,19 +404,19 @@
            whereSql.append("AND STATE=? ");
            params.add("created");
        }
        if (!StringUtils.isNullOrEmpty(startTime)) {
            whereSql.append("AND DATE(CREATE_TIME)>=DATE('"+startTime+" 00:00:00') ");
        }
        if (!StringUtils.isNullOrEmpty(endTime)) {
            whereSql.append("AND DATE(CREATE_TIME)<=DATE('"+endTime+" 23:59:59') ");
        }
        whereSql.append("ORDER BY CREATE_TIME DESC LIMIT ?,?");
        params.add(page.getFirstElementNumber());
        params.add(pageSize);
        return bulidData(ApplicationUtil.executeSelect(ContractOrder.class,whereSql.toString(),params.toArray(new Object[params.size()])));
    }
@@ -426,14 +427,14 @@
            for (Entry<String, ContractOrder> entry : ordersMap.entrySet()) {
                if (StringUtils.isNotEmpty(symbol)) {
                    if (symbol.equals(entry.getValue().getSymbol())) {
                        ordersList.add(entry.getValue());
                        ordersList.add(entry.getValue());
                    }
                } else {
                    ordersList.add(entry.getValue());
                }
            }
            // 创建时间 降序排列
            // 创建时间 降序排列
            if (ordersList.size() > 0) {
                Collections.sort(ordersList, new Comparator<ContractOrder>() {
                    @Override
@@ -501,12 +502,113 @@
        } else {
            map.put("profit", df.format(Arith.sub(Arith.add(order.getAmount_close(), order.getDeposit()), order.getDeposit_open())));
        }
//        double currentPrice = Double.parseDouble(map.get("trade_avg_price").toString());
//
//        double leve = Double.parseDouble(map.get("lever_rate").toString());
//        //得到强平价格
//        if(null != map.get("direction")){
//            double liquidationPrice;
//            if(map.get("direction").equals("sell")){
//                liquidationPrice = currentPrice * (1 + (1 / leve));
//            }else{
//                liquidationPrice = currentPrice * (1 - 1 / leve);
//            }
//            DecimalFormat dfs = new DecimalFormat("#.#####");
//            String formattedPrice = dfs.format(liquidationPrice);
//            map.put("qiangPing",formattedPrice);
//        }
        double depositOpen =  Double.parseDouble(map.get("deposit_open").toString());
        double leverRate = Double.parseDouble(map.get("lever_rate").toString());
        double tradeAvgPrice =  Double.parseDouble(map.get("trade_avg_price").toString());
        double mul = Arith.mul(depositOpen, leverRate);//仓位
        double div = Arith.div(mul, tradeAvgPrice);//持有币的数量
        /**
         * 计算全仓收益 保证金
         */
        double profit = 0;
        List<ContractOrder> list = findSubmitted(order.getPartyId().toString(), null, null);
        for (int f = 0; f < list.size(); f++) {
            ContractOrder close_line = list.get(f);
            if(close_line.getProfit() > 0){
                profit = Arith.add(profit, Arith.add(close_line.getProfit(), close_line.getDeposit()));
            }else{
                profit = Arith.add(profit, close_line.getDeposit());
            }
        }
        Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId().toString());
        double totleMoney = wallet.getMoney();
        profit = Arith.add(profit,totleMoney);
        if (map.get("direction") != null) {
            String direction = map.get("direction").toString();
            double liquidationPrice;
            double deposit = depositOpen + profit;
            if(leverRate == 1){
                liquidationPrice = 0;
            }else {
                if ("sell".equals(direction)) {
                    liquidationPrice = tradeAvgPrice + (deposit / div);
                } else {
                    liquidationPrice = (mul * tradeAvgPrice) / (deposit + mul);
                }
            }
            DecimalFormat dfs = new DecimalFormat("#.#####");
            String formattedPrice = dfs.format(liquidationPrice);
            map.put("qiangPing", formattedPrice);
        }
        map.put("volume", order.getVolume());
        map.put("volume_open", order.getVolume_open());
        return map;
    }
//
//
    public static void main(String[] args) {
        Map<String, Object> map = new HashMap<>();
        map.put("direction", "buy");  // "buy" 或 "sell"
        double currentPrice = 59649.7;  // 开仓价格
        double leve = 10;  // 杠杆倍数
        double bzj = 500; // 保证金
        double zjbzj = 500; // 资金账户
        double xj = 70781.28; // 现价
        double mul = Arith.mul(bzj, leve);//仓位
        double div = Arith.div(mul, currentPrice);//持有币的数量
        double amount = Arith.mul(div, Arith.sub(xj, currentPrice));
        System.out.println(amount);
        if (map.get("direction") != null) {
            String direction = map.get("direction").toString();
            double liquidationPrice;
            double bcbzj = bzj + zjbzj;
            if(leve == 1){
                liquidationPrice = 0;
            }else{
                if ("sell".equals(direction)) {
                    liquidationPrice = currentPrice + (bcbzj / div);
                } else {
                    liquidationPrice = (mul * currentPrice) / (bcbzj + mul);
                }
            }
            DecimalFormat dfs = new DecimalFormat("#.#####");
            String formattedPrice = dfs.format(liquidationPrice);
            map.put("qiangPing", formattedPrice);
        }
        // 打印结果以验证
        System.out.println("Calculated Liquidation Price: " + map.get("qiangPing"));
    }
//
    @Override
    public List<ContractOrder> findSubmitted() {
@@ -554,11 +656,11 @@
    public void setPartyService(PartyService partyService) {
        this.partyService = partyService;
    }
    public void setTipService(TipService tipService) {
        this.tipService = tipService;
    }
    public void setAssetService(AssetService assetService) {
        this.assetService = assetService;
    }
src/main/java/project/contract/job/ContractOrderCalculationServiceImpl.java
@@ -2,26 +2,37 @@
import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;
import kernel.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import kernel.util.Arith;
import kernel.util.ThreadUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import project.contract.ContractLock;
import project.contract.ContractOrder;
import project.contract.ContractOrderService;
import project.contract.ContractRedisKeys;
import project.data.DataService;
import project.data.model.Realtime;
import project.redis.RedisHandler;
import project.syspara.SysparaService;
import project.wallet.AssetService;
import project.wallet.Wallet;
import project.wallet.WalletRedisKeys;
import project.wallet.WalletService;
import project.wallet.consumer.WalletMessage;
public class ContractOrderCalculationServiceImpl implements ContractOrderCalculationService {
    private static final Logger logger = LoggerFactory.getLogger(ContractOrderCalculationServiceImpl.class);
    private ContractOrderService contractOrderService;
    private DataService dataService;
    private WalletService walletService;
    private RedisHandler redisHandler;
    private AssetService assetService;
    public final static String STATE_SUBMITTED = "submitted";
    public final static String STATE_CREATED = "created";
    /**
@@ -102,6 +113,33 @@
            order.setProfit(Arith.add(0.0D, Math.abs(amount)));
        } else if ("loss".equals(profit_loss)) {
            order.setProfit(Arith.sub(0.0D,Math.abs(amount) ));
            //定义一个 总浮动亏损的值
            logger.info("----------fffffffffffffff-------"+redisHandler);
            logger.info("----------ssssssssssss-------"+order.getPartyId().toString());
            Double contractAssetsProfit = (Double) this.redisHandler.get(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString());
            logger.info("----------bbbbbbbbbbbbbbbbbb-------"+contractAssetsProfit);
            double contractProfit = null == contractAssetsProfit ? 0.000D : contractAssetsProfit;
            logger.info("----------contractProfit-------"+contractProfit);
            if(contractProfit <= 0){
                redisHandler.setSync("MONEY_CONTRACT_PROFIT_"+order.getPartyId().toString(), contractProfit);
            }
            logger.info("----------1111111111111-------");
            //修改余额,每次修改取平仓前余额减去浮动亏损
            Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId().toString());
            logger.info("----------wallet-------"+wallet);
            Object money = redisHandler.get("PARTY_ID_MONEY_" + order.getPartyId().toString());
            Object profit = redisHandler.get("MONEY_CONTRACT_PROFIT_" + order.getPartyId().toString());
            logger.info("----------money-------"+money);
            logger.info("----------profit-------"+profit);
            if(!ObjectUtils.isEmpty(money) && !ObjectUtils.isEmpty(profit)){
                wallet.setMoney(Arith.sub(Double.parseDouble(money.toString()),Double.parseDouble(profit.toString())));
            }
            logger.info("----------2222222222222-------");
            redisHandler.setSync(WalletRedisKeys.WALLET_PARTY_ID + wallet.getPartyId().toString(), wallet);
            logger.info("----------3333333333333333------");
            redisHandler.pushAsyn(WalletRedisKeys.WALLET_QUEUE_UPDATE, new WalletMessage(order.getPartyId().toString(), amount));
            logger.info("----------4444444444444-------");
        }
        double changeRatio;
@@ -161,6 +199,7 @@
                return;
            }
        }
        logger.info("order_close_line_type:"+order_close_line_type);
        if (order_close_line_type == 1) {
            /**
             * 收益
@@ -210,15 +249,19 @@
            }
        } else {
            logger.info("---------进入单个持仓----------------");
            logger.info("---------order.getProfit()----------------"+order.getProfit());
            logger.info("---------order.getDeposit()----------------"+order.getDeposit());
            logger.info("---------order_close_line----------------"+order_close_line);
            if (order.getProfit() < 0 && (Arith.div(order.getDeposit(), Math.abs(order.getProfit())) <= Arith
                    .div(order_close_line, 100))) {
                logger.info("---------进入强平了----------------");
                /**
                 * 低于系统默认平仓线,进行强平
                 */
                this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrder_no());
                return;
            }
        }
    }
@@ -246,4 +289,13 @@
        this.order_close_line_type = order_close_line_type;
    }
    public void setRedisHandler(RedisHandler redisHandler) {
        this.redisHandler = redisHandler;
    }
    public void setAssetService(AssetService assetService) {
        this.assetService = assetService;
    }
}
src/main/java/project/project/web/admin/AdminContractOrderController.java
@@ -41,6 +41,8 @@
import project.log.LogService;
import project.syspara.Syspara;
import project.syspara.SysparaService;
import project.wallet.Wallet;
import project.wallet.WalletService;
import security.SecUser;
import security.internal.SecUserService;
@@ -70,6 +72,9 @@
    
    @Autowired
    private AdminContractOrderService adminContractOrderService;
    @Autowired
    private WalletService walletService;
    private final String action = "normal/adminContractOrderAction!";
    
@@ -110,19 +115,63 @@
                    String roleName = map.get("rolename").toString();
                    map.put("roleNameDesc", Constants.ROLE_MAP.containsKey(roleName) ? Constants.ROLE_MAP.get(roleName) : roleName);
                }
                double currentPrice = Double.parseDouble(map.get("trade_avg_price").toString());
                // 计算仓位总价
                double positionValue = Double.parseDouble(map.get("deposit_open").toString()) * Double.parseDouble(map.get("lever_rate").toString());
                double depositOpen =  Double.parseDouble(map.get("deposit_open").toString());
                double leverRate = Double.parseDouble(map.get("lever_rate").toString());
                double tradeAvgPrice =  Double.parseDouble(map.get("trade_avg_price").toString());
                // 计算数量
                double quantity = positionValue / currentPrice;
                double mul = Arith.mul(depositOpen, leverRate);//仓位
                double div = Arith.div(mul, tradeAvgPrice);//持有币的数量
                /**
                 * 计算全仓收益 保证金
                 */
                double profit = 0;
                List<ContractOrder> contractOrders = contractOrderService.findSubmitted(this.getLoginPartyId(), null, null);
                for (int f = 0; f < contractOrders.size(); f++) {
                    ContractOrder close_line = contractOrders.get(f);
                    if(close_line.getProfit() > 0){
                        profit = Arith.add(profit, Arith.add(close_line.getProfit(), close_line.getDeposit()));
                    }else{
                        profit = Arith.add(profit, close_line.getDeposit());
                    }                }
                Wallet wallet = this.walletService.saveWalletByPartyId(this.getLoginPartyId());
                double totleMoney = wallet.getMoney();
                profit = Arith.add(profit,totleMoney);
                // 得到强平价格
                double liquidationPrice = currentPrice + (110 / quantity);
                DecimalFormat df = new DecimalFormat("#.#####");
                String formattedPrice = df.format(liquidationPrice);
                map.put("qiangPing",formattedPrice);
                if (map.get("direction") != null) {
                    String direction = map.get("direction").toString();
                    double liquidationPrice;
                    double deposit = depositOpen + profit;
                    if(leverRate == 1){
                        liquidationPrice = 0;
                    }else {
                        if ("sell".equals(direction)) {
                            liquidationPrice = tradeAvgPrice + (deposit / div);
                        } else {
                            liquidationPrice = (mul * tradeAvgPrice) / (deposit + mul);
                        }
                    }
                    DecimalFormat dfs = new DecimalFormat("#.#####");
                    String formattedPrice = dfs.format(liquidationPrice);
                    map.put("qiangPing", formattedPrice);
                }
//                double currentPrice = Double.parseDouble(map.get("trade_avg_price").toString());
//
//                double leve = Double.parseDouble(map.get("lever_rate").toString());
//                //得到强平价格
//                if(null != map.get("direction")){
//                    double liquidationPrice;
//                    if(map.get("direction").equals("sell")){
//                        liquidationPrice = currentPrice * (1 + (1 / leve));
//                    }else{
//                        liquidationPrice = currentPrice * (1 - 1 / leve);
//                    }
//                    DecimalFormat df = new DecimalFormat("#.#####");
//                    String formattedPrice = df.format(liquidationPrice);
//                    map.put("qiangPing",formattedPrice);
//                }
            }
            List<Item> items = this.itemService.cacheGetAll();
@@ -214,19 +263,65 @@
                    String roleName = map.get("rolename").toString();
                    map.put("roleNameDesc", Constants.ROLE_MAP.containsKey(roleName) ? Constants.ROLE_MAP.get(roleName) : roleName);
                }
                double currentPrice = Double.parseDouble(map.get("trade_avg_price").toString());
//                double currentPrice = Double.parseDouble(map.get("trade_avg_price").toString());
//
//                double leve = Double.parseDouble(map.get("lever_rate").toString());
//                //得到强平价格
//                if(null != map.get("direction")){
//                    double liquidationPrice;
//                    if(map.get("direction").equals("sell")){
//                        liquidationPrice = currentPrice * (1 + (1 / leve));
//                    }else{
//                        liquidationPrice = currentPrice * (1 - 1 / leve);
//                    }
//                    DecimalFormat df = new DecimalFormat("#.#####");
//                    String formattedPrice = df.format(liquidationPrice);
//                    map.put("qiangPing",formattedPrice);
//                }
                // 计算仓位总价
                double positionValue = Double.parseDouble(map.get("deposit_open").toString()) * Double.parseDouble(map.get("lever_rate").toString());
                double depositOpen =  Double.parseDouble(map.get("deposit_open").toString());
                double leverRate = Double.parseDouble(map.get("lever_rate").toString());
                double tradeAvgPrice =  Double.parseDouble(map.get("trade_avg_price").toString());
                // 计算数量
                double quantity = positionValue / currentPrice;
                double mul = Arith.mul(depositOpen, leverRate);//仓位
                double div = Arith.div(mul, tradeAvgPrice);//持有币的数量
                /**
                 * 计算全仓收益 保证金
                 */
                double profit = 0;
                List<ContractOrder> contractOrders = contractOrderService.findSubmitted(this.getLoginPartyId(), null, null);
                for (int f = 0; f < contractOrders.size(); f++) {
                    ContractOrder close_line = contractOrders.get(f);
                    if(close_line.getProfit() > 0){
                        profit = Arith.add(profit, Arith.add(close_line.getProfit(), close_line.getDeposit()));
                    }else{
                        profit = Arith.add(profit, close_line.getDeposit());
                    }
                }
                Wallet wallet = this.walletService.saveWalletByPartyId(this.getLoginPartyId());
                double totleMoney = wallet.getMoney();
                profit = Arith.add(profit,totleMoney);
                // 得到强平价格
                double liquidationPrice = currentPrice + (110 / quantity);
                DecimalFormat df = new DecimalFormat("#.#####");
                String formattedPrice = df.format(liquidationPrice);
                map.put("qiangPing",formattedPrice);
                if (map.get("direction") != null) {
                    String direction = map.get("direction").toString();
                    double liquidationPrice;
                    double deposit = depositOpen + profit;
                    if(leverRate == 1){
                        liquidationPrice = 0;
                    }else {
                        if ("sell".equals(direction)) {
                            liquidationPrice = tradeAvgPrice + (deposit / div);
                        } else {
                            liquidationPrice = (mul * tradeAvgPrice) / (deposit + mul);
                        }
                    }
                    DecimalFormat dfs = new DecimalFormat("#.#####");
                    String formattedPrice = dfs.format(liquidationPrice);
                    map.put("qiangPing", formattedPrice);
                }
            }
        } catch (BusinessException e) {
src/main/java/project/project/web/api/ContractOrderController.java
@@ -1,6 +1,7 @@
package project.project.web.api;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -10,6 +11,7 @@
import javax.servlet.http.HttpServletRequest;
import kernel.util.Arith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -27,6 +29,8 @@
import project.contract.ContractOrderService;
import project.data.DataService;
import project.data.model.Realtime;
import project.wallet.Wallet;
import project.wallet.WalletService;
/**
 * 永续合约持仓单
@@ -43,6 +47,9 @@
    
    @Autowired
    private ContractOrderService contractOrderService;
    @Autowired
    private WalletService walletService;
    private final String action = "/api/contractOrder!";
    
@@ -183,6 +190,51 @@
            for (int i = 0; i < data.size(); i++) {
                Map<String, Object> map = data.get(i);
                double depositOpen =  Double.parseDouble(map.get("deposit_open").toString());
                double leverRate = Double.parseDouble(map.get("lever_rate").toString());
                double tradeAvgPrice =  Double.parseDouble(map.get("trade_avg_price").toString());
                double mul = Arith.mul(depositOpen, leverRate);//仓位
                double div = Arith.div(mul, tradeAvgPrice);//持有币的数量
                /**
                 * 计算全仓收益 保证金
                 */
                double profit = 0;
                List<ContractOrder> list = contractOrderService.findSubmitted(this.getLoginPartyId(), null, null);
                for (int f = 0; f < list.size(); f++) {
                    ContractOrder close_line = list.get(f);
                    if(close_line.getProfit() > 0){
                        profit = Arith.add(profit, Arith.add(close_line.getProfit(), close_line.getDeposit()));
                    }else{
                        profit = Arith.add(profit, close_line.getDeposit());
                    }                }
                Wallet wallet = this.walletService.saveWalletByPartyId(this.getLoginPartyId());
                double totleMoney = wallet.getMoney();
                profit = Arith.add(profit,totleMoney);
                if (map.get("direction") != null) {
                    String direction = map.get("direction").toString();
                    double liquidationPrice;
                    double deposit = depositOpen + profit;
                    if(leverRate == 1){
                        liquidationPrice = 0;
                    }else {
                        if ("sell".equals(direction)) {
                            liquidationPrice = tradeAvgPrice + (deposit / div);
                        } else {
                            liquidationPrice = (mul * tradeAvgPrice) / (deposit + mul);
                        }
                    }
                    DecimalFormat dfs = new DecimalFormat("#.#####");
                    String formattedPrice = dfs.format(liquidationPrice);
                    map.put("qiangPing", formattedPrice);
                }
                // 标记价格
                Realtime realtime = realtimeMap.get(map.get("symbol"));
                if (null == realtime) {
src/main/java/project/wallet/internal/WalletServiceImpl.java
@@ -21,6 +21,7 @@
import kernel.util.UUIDGenerator;
import kernel.web.ApplicationUtil;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import project.Constants;
import project.data.DataService;
import project.data.model.Realtime;
@@ -84,10 +85,17 @@
    @Override
    public void update(String partyId, double amount) {
        Object money = redisHandler.get("PARTY_ID_MONEY_" + partyId);
        Wallet wallet = (Wallet) redisHandler.get(WalletRedisKeys.WALLET_PARTY_ID + partyId.toString());
        if(!ObjectUtils.isEmpty(money)){
            wallet.setMoney(Double.parseDouble(money.toString()));
        }
        wallet.setMoney(Arith.add(wallet.getMoney(), amount));
        redisHandler.setSync(WalletRedisKeys.WALLET_PARTY_ID + wallet.getPartyId().toString(), wallet);
        redisHandler.pushAsyn(WalletRedisKeys.WALLET_QUEUE_UPDATE, new WalletMessage(partyId, amount));
        //用于计算合约亏损
        redisHandler.setSync("PARTY_ID_MONEY_"+partyId, wallet.getMoney());
    }
    @Override