trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractApplyOrderController.java
@@ -23,6 +23,7 @@ import com.yami.trading.common.util.ThreadUtils; import com.yami.trading.security.common.util.SecurityUtils; import com.yami.trading.service.SessionTokenService; import com.yami.trading.service.StrongLevelCalculationService; import com.yami.trading.service.WalletService; import com.yami.trading.service.contract.ContractApplyOrderService; import com.yami.trading.service.contract.ContractLockService; @@ -196,13 +197,23 @@ String partyId = SecurityUtils.getUser().getUserId(); RLock rLock = redissonClient.getLock("contract_open_" + partyId); boolean lockAcquired = false; double faceValue = 0.01;//面值 double minAmount = 0.01;//最低张数 try { // 尝试获取锁,最多等待5秒 lockAcquired = rLock.tryLock(5, TimeUnit.SECONDS); if (!lockAcquired) { log.warn("无法获取锁: contract_open_{}", partyId); throw new YamiShopBindException("请稍后再试"); } //判断下单金额是否符合最低金额 最低下单张数:0.01 //合约张数 张数=保证金*杠杆倍数/(面值*最新成交价) double v = openAction.getAmount().doubleValue() * openAction.getLever_rate().doubleValue() / (faceValue * openAction.getPrice().doubleValue()); BigDecimal amount = BigDecimal.valueOf(v).setScale(4, RoundingMode.DOWN); if (amount.compareTo(new BigDecimal(faceValue)) < 0) { double minimumAmount = minAmount * faceValue * openAction.getPrice().doubleValue() / openAction.getLever_rate().doubleValue(); double roundedAmount = Math.ceil(minimumAmount * 10000) / 10000; throw new YamiShopBindException("最低下单金额:"+roundedAmount); } // 校验当前用户订单状态 @@ -278,14 +289,15 @@ order.setSymbol(openAction.getSymbol()); order.setDirection(openAction.getDirection()); order.setOffset(ContractApplyOrder.OFFSET_OPEN); order.setVolume(openAction.getAmount()); order.setVolumeOpen(openAction.getAmount()); // order.setVolume(openAction.getAmount()); // order.setVolumeOpen(openAction.getAmount()); order.setLeverRate(openAction.getLever_rate()); order.setPrice(openAction.getPrice()); order.setStopPriceProfit(openAction.getStop_price_profit()); order.setStopPriceLoss(openAction.getStop_price_loss()); order.setOrderPriceType(openAction.getPrice_type()); order.setState(ContractApplyOrder.STATE_SUBMITTED); order.setMoney(openAction.getAmount()); contractApplyOrderService.saveCreate(order); } trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractOrderController.java
@@ -23,6 +23,8 @@ import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.*; /** @@ -153,10 +155,10 @@ bySymbol.transName(); map.put("name", bySymbol.getName()); } map.put("mark_price", realtime.getClose()); map.put("mark_price", realtime.getClose().setScale(4, RoundingMode.DOWN)); } if (ObjectUtils.isEmpty(data.get(i).get("close_avg_price"))) { data.get(i).put("close_avg_price", data.get(i).get("mark_price")); data.get(i).put("close_avg_price", new BigDecimal(data.get(i).get("mark_price").toString()).setScale(4, RoundingMode.DOWN)); } } return Result.ok(data); trading-order-bean/src/main/java/com/yami/trading/bean/contract/domain/ContractApplyOrder.java
@@ -113,5 +113,8 @@ */ private BigDecimal deposit; /** * 下单金额 */ private BigDecimal money; } trading-order-service/src/main/java/com/yami/trading/service/StrongLevelCalculationService.java
@@ -12,4 +12,6 @@ public double calculateEmptyLiquidationPrice ( double marginBalance, double faceValue, double contractQuantity, double openingPrice, double maintenanceMarginRate, double feeRate); public double countSheets(double earnestMoney,int level,double faceValue,double recentQuotation); } trading-order-service/src/main/java/com/yami/trading/service/contract/ContractApplyOrderService.java
@@ -23,6 +23,7 @@ import com.yami.trading.common.util.StringUtils; import com.yami.trading.dao.contract.ContractApplyOrderMapper; import com.yami.trading.service.MoneyLogService; import com.yami.trading.service.StrongLevelCalculationService; import com.yami.trading.service.data.DataService; import com.yami.trading.service.user.UserService; import com.yami.trading.service.WalletService; @@ -73,6 +74,8 @@ private WalletService walletService; @Autowired private ContractOrderService contractOrderService; @Autowired private StrongLevelCalculationService strongLevelCalculationService; public Page<Map<String, Object>> findList(Page<ContractApplyOrder> page, String partyId, String symbol, String type, String startTime, String endTime, String symbolType) { QueryWrapper<ContractApplyOrder> queryWrapper = new QueryWrapper<>(); @@ -163,12 +166,15 @@ public void saveCreate(ContractApplyOrder order) { if (order.getVolumeOpen().doubleValue() % 1 != 0) { throw new YamiShopBindException("Parameter Error1"); } if (order.getVolumeOpen().compareTo(BigDecimal.ZERO) <= 0) { throw new YamiShopBindException("Parameter Error2"); // if (order.getVolumeOpen().doubleValue() % 1 != 0) { // throw new YamiShopBindException("Parameter Error1"); // } // // if (order.getVolumeOpen().compareTo(BigDecimal.ZERO) <= 0) { // throw new YamiShopBindException("Parameter Error2"); // } if(order.getMoney().compareTo(BigDecimal.ZERO) <= 0){ throw new YamiShopBindException("Please enter the order amount"); } boolean orderOpen = this.sysparaService.find("order_open").getBoolean(); @@ -199,54 +205,28 @@ log.info("{} --- order --- {} --- {}", order.getSymbol(), item.getUuid(), levers.size()); checkLever(order, levers); List<ContractOrder> contractOrderSubmitted = contractOrderService.findSubmitted(order.getPartyId(), order.getSymbol(), order.getDirection()); for (int i = 0; i < contractOrderSubmitted.size(); i++) { BigDecimal sourceLeverRate = order.getLeverRate(); sourceLeverRate = sourceLeverRate == null ? BigDecimal.ZERO : sourceLeverRate; BigDecimal targetLeverRate = contractOrderSubmitted.get(i).getLeverRate(); targetLeverRate = targetLeverRate == null ? BigDecimal.ZERO : targetLeverRate; if (sourceLeverRate.compareTo(targetLeverRate) != 0) { throw new YamiShopBindException("存在不同杠杆的持仓单"); } } List<ContractApplyOrder> applyOrderSubmittedList = this.findSubmitted(order.getPartyId().toString(), order.getSymbol(), "open", order.getDirection()); for (int i = 0; i < applyOrderSubmittedList.size(); i++) { BigDecimal sourceLeverRate = order.getLeverRate(); sourceLeverRate = sourceLeverRate == null ? BigDecimal.ZERO : sourceLeverRate; BigDecimal targetLeverRate = applyOrderSubmittedList.get(i).getLeverRate(); targetLeverRate = targetLeverRate == null ? BigDecimal.ZERO : targetLeverRate; if (sourceLeverRate.compareTo(targetLeverRate) != 0) { throw new YamiShopBindException("存在不同杠杆的持仓单"); } } order.setOrderNo(DateUtil.getToday("yyMMddHHmmss") + RandomUtil.getRandomNum(8)); double number = strongLevelCalculationService.countSheets(order.getMoney().doubleValue(), order.getLeverRate().intValue(), 0.01, order.getPrice().doubleValue()); order.setVolumeOpen(new BigDecimal(number)); order.setVolume(new BigDecimal(number)); BigDecimal unitAmount = order.getPrice().multiply(BigDecimal.valueOf(item.getFaceValue())); unitAmount = unitAmount.setScale(4, RoundingMode.DOWN); BigDecimal deposit = unitAmount.multiply(order.getVolumeOpen()).divide(order.getLeverRate(), 4, RoundingMode.DOWN); order.setUnitAmount(unitAmount); order.setDeposit(deposit); order.setDeposit(order.getMoney()); if (order.getLeverRate() != null) { /** * 加上杠杆 */ // 设置订单数量 order.setVolume(order.getVolumeOpen()); BigDecimal fee = order.getDeposit().multiply(order.getLeverRate()).multiply(item.getUnitFee()); fee = fee.setScale(4, RoundingMode.DOWN); // 保留两位小数 order.setFee(fee); } order.setVolumeOpen(order.getVolumeOpen()); Wallet wallet = this.walletService.findByUserId(order.getPartyId()); BigDecimal amountBefore = wallet.getMoney(); @@ -291,7 +271,7 @@ volume = volume.subtract(applyOrderSubmittedList.get(i).getVolume()); } if (order.getVolume().compareTo(volume) > 0) { throw new YamiShopBindException("可平仓合约张数不足"); throw new YamiShopBindException("可平仓合约数量不足"); } save(order); trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java
@@ -263,17 +263,36 @@ this.contractOrderService.updateByIdBuffer(order); // if (profit.add(wallet.getMoney()).compareTo(BigDecimal.ZERO) <= 0) { if (currentPrice.toString().compareTo(order.getForceClosePrice()) <= 0) {//达到强平价 /** * 触发全仓强平 */ this.contractOrderService.allClose(order.getPartyId()); //判断买涨还是买跌"buy":买(多) "sell":卖(空) if(order.getDirection().equals("buy")){ if (currentPrice.toString().compareTo(order.getForceClosePrice()) <= 0) {//达到强平价 /** * 触发全仓强平 */ this.contractOrderService.allClose(order.getPartyId()); } }else{ if (currentPrice.toString().compareTo(order.getForceClosePrice())>= 0) {//达到强平价 /** * 触发全仓强平 */ this.contractOrderService.allClose(order.getPartyId()); } } } else { if (currentPrice.toString().compareTo(order.getForceClosePrice()) <= 0) {//达到强平价 this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo(),"强平"); if(order.getDirection().equals("buy")){ if (currentPrice.toString().compareTo(order.getForceClosePrice()) <= 0) {//达到强平价 this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo(),"强平"); } }else{ if (currentPrice.toString().compareTo(order.getForceClosePrice()) >= 0) {//达到强平价 this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo(),"强平"); } } } } trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderService.java
@@ -1,6 +1,7 @@ package com.yami.trading.service.contract; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -21,10 +22,7 @@ import com.yami.trading.common.constants.ContractRedisKeys; import com.yami.trading.common.constants.TipConstants; import com.yami.trading.common.exception.YamiShopBindException; import com.yami.trading.common.util.DateUtils; import com.yami.trading.common.util.RandomUtil; import com.yami.trading.common.util.RedisUtil; import com.yami.trading.common.util.StringUtils; import com.yami.trading.common.util.*; import com.yami.trading.service.StrongLevelCalculationService; import com.yami.trading.service.data.DataService; import com.yami.trading.service.system.TipService; @@ -32,8 +30,10 @@ import com.yami.trading.service.user.UserService; import com.yami.trading.service.WalletService; import com.yami.trading.service.item.ItemService; import com.yami.trading.util.ConverterUtil; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Lazy; @@ -45,6 +45,7 @@ import com.yami.trading.dao.contract.ContractOrderMapper; import org.springframework.web.bind.annotation.RequestParam; import java.lang.reflect.Type; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; @@ -506,6 +507,86 @@ public void saveOpen(ContractApplyOrder applyOrder, Realtime realtime) { Item item = this.itemService.findBySymbol(applyOrder.getSymbol()); ContractOrder f = getOne(new LambdaQueryWrapper<>(ContractOrder.class) .eq(ContractOrder::getPartyId, applyOrder.getPartyId()) .eq(ContractOrder::getSymbol, applyOrder.getSymbol()) .eq(ContractOrder::getDirection, applyOrder.getDirection()) .eq(ContractOrder::getState,"submitted") .last(" limit 1") ); //合并订单 if(ObjectUtils.isNotEmpty(f)){ //创建订单 if(applyOrder.getOrderPriceType().equals("opponent")){//市价单,创建订单在计算和扣款 BigDecimal price = ((realtime.getClose().add(f.getTradeAvgPrice())) .divide(new BigDecimal(2))).multiply(BigDecimal.valueOf(item.getFaceValue())); BigDecimal unitAmount = price.setScale(4, RoundingMode.DOWN); f.setUnitAmount(unitAmount); f.setDepositOpen(f.getDepositOpen().add(applyOrder.getMoney())); f.setDeposit(f.getDeposit().add(applyOrder.getMoney())); f.setTradeAvgPrice((f.getTradeAvgPrice().add(realtime.getClose())).divide(new BigDecimal(2))); BigDecimal fee = BigDecimal.ZERO; if (f.getLeverRate() != null) { fee = applyOrder.getDeposit().multiply(f.getLeverRate()).multiply(item.getUnitFee()); fee = fee.setScale(4, RoundingMode.DOWN); // 保留两位小数 f.setFee(f.getFee().add(fee)); } double number = strongLevelCalculationService.countSheets(f.getDepositOpen().doubleValue(), f.getLeverRate().intValue(), 0.01, realtime.getClose().doubleValue()); f.setVolumeOpen(new BigDecimal(number)); f.setVolume(new BigDecimal(number)); walletService.updateMoney(f.getSymbol(), f.getPartyId(), BigDecimal.ZERO.subtract(applyOrder.getDeposit()), BigDecimal.ZERO , Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT, Constants.MONEYLOG_CONTENT_CONTRACT_OPEN, "委托单,订单号[" + f.getOrderNo() + "]" ); walletService.updateMoney(f.getSymbol(), f.getPartyId(), BigDecimal.ZERO.subtract(fee), BigDecimal.ZERO , Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT, Constants.MONEYLOG_CONTENT_FEE, "委托单,订单号[" + f.getOrderNo() + "]" ); } //计算强平价格 getStrongPrice(f,item); update(f); refreshOrder(applyOrder, f); }else{ //创建订单 ContractOrder order = getContractOrder(applyOrder, item); if(applyOrder.getOrderPriceType().equals("opponent")) {//市价单,创建订单在计算和扣款 BigDecimal price = ((realtime.getClose().add(order.getTradeAvgPrice())) .divide(new BigDecimal(2))).multiply(BigDecimal.valueOf(item.getFaceValue())); BigDecimal unitAmount = price.setScale(4, RoundingMode.DOWN); order.setUnitAmount(unitAmount); order.setDepositOpen(applyOrder.getMoney()); order.setDeposit(applyOrder.getMoney()); if (order.getLeverRate() != null) { BigDecimal fee = order.getDeposit().multiply(order.getLeverRate()).multiply(item.getUnitFee()); fee = fee.setScale(4, RoundingMode.DOWN); // 保留两位小数 order.setFee(fee); } double number = strongLevelCalculationService.countSheets(order.getDepositOpen().doubleValue(), order.getLeverRate().intValue(), 0.01, applyOrder.getPrice().doubleValue()); order.setVolume(new BigDecimal(number)); order.setVolumeOpen(new BigDecimal(number)); walletService.updateMoney(order.getSymbol(), order.getPartyId(), BigDecimal.ZERO.subtract(order.getDeposit()), BigDecimal.ZERO , Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT, Constants.MONEYLOG_CONTENT_CONTRACT_OPEN, "委托单,订单号[" + order.getOrderNo() + "]" ); walletService.updateMoney(order.getSymbol(), order.getPartyId(), BigDecimal.ZERO.subtract(order.getFee()), BigDecimal.ZERO , Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT, Constants.MONEYLOG_CONTENT_FEE, "委托单,订单号[" + order.getOrderNo() + "]" ); } //计算强平价格 getStrongPrice(order,item); save(order); refreshOrder(applyOrder, order); } } @NotNull private static ContractOrder getContractOrder(ContractApplyOrder applyOrder, Item item) { ContractOrder order = new ContractOrder(); order.setPartyId(applyOrder.getPartyId()); order.setSymbol(applyOrder.getSymbol()); @@ -514,59 +595,15 @@ order.setDirection(applyOrder.getDirection()); order.setLeverRate(applyOrder.getLeverRate()); order.setOrderPriceType(applyOrder.getOrderPriceType()); order.setTradeAvgPrice(applyOrder.getPrice()); order.setStopPriceProfit(applyOrder.getStopPriceProfit()); order.setStopPriceLoss(applyOrder.getStopPriceLoss()); order.setPips(item.getPips()); order.setPipsAmount(item.getPipsAmount()); if(applyOrder.getOrderPriceType().equals("opponent")){//市价单,创建订单在计算和扣款 BigDecimal unitAmount = applyOrder.getPrice().multiply(BigDecimal.valueOf(item.getFaceValue())); unitAmount = unitAmount.setScale(4, RoundingMode.DOWN); return order; } BigDecimal deposit = unitAmount.multiply(applyOrder.getVolumeOpen()).divide(order.getLeverRate(), 4, RoundingMode.DOWN); order.setUnitAmount(unitAmount); order.setDepositOpen(deposit); order.setDeposit(deposit); if (order.getLeverRate() != null) { /** * 加上杠杆 */ // 设置订单数量 order.setVolume(applyOrder.getVolumeOpen()); BigDecimal fee = order.getDeposit().multiply(order.getLeverRate()).multiply(item.getUnitFee()); fee = fee.setScale(4, RoundingMode.DOWN); // 保留两位小数 order.setFee(fee); } order.setVolumeOpen(applyOrder.getVolumeOpen()); walletService.updateMoney(order.getSymbol(), order.getPartyId(), BigDecimal.ZERO.subtract(order.getDeposit()), BigDecimal.ZERO , Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT, Constants.MONEYLOG_CONTENT_CONTRACT_OPEN, "委托单,订单号[" + order.getOrderNo() + "]" ); walletService.updateMoney(order.getSymbol(), order.getPartyId(), BigDecimal.ZERO.subtract(order.getFee()), BigDecimal.ZERO , Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT, Constants.MONEYLOG_CONTENT_FEE, "委托单,订单号[" + order.getOrderNo() + "]" ); } double faceValue = 0.01; // 合约面值(固定面值不能调整) double maintenanceMarginRate = 0.004; // 维持保证金率(固定不变) //"buy":买(多) "sell":卖(空) if(order.getDirection().equals("buy")){ double forceClosePrice = strongLevelCalculationService.calculateLiquidationPrice(order.getDepositOpen().doubleValue(), faceValue, order.getVolumeOpen().doubleValue(), order.getTradeAvgPrice().doubleValue() , maintenanceMarginRate, item.getUnitFee().doubleValue()); order.setForceClosePrice(BigDecimal.valueOf(forceClosePrice).toString()); }else{ double forceClosePrice = strongLevelCalculationService.calculateEmptyLiquidationPrice(order.getDepositOpen().doubleValue(), faceValue, order.getVolumeOpen().doubleValue(), order.getTradeAvgPrice().doubleValue() , maintenanceMarginRate, item.getUnitFee().doubleValue()); order.setForceClosePrice(BigDecimal.valueOf(forceClosePrice).toString()); } save(order); private void refreshOrder(ContractApplyOrder applyOrder, ContractOrder order) { RedisUtil.set(ContractRedisKeys.CONTRACT_ORDERNO + order.getOrderNo(), order); Map<String, ContractOrder> map = RedisUtil @@ -614,6 +651,23 @@ } } private void getStrongPrice(ContractOrder order, Item item) { double faceValue = 0.01; // 合约面值(固定面值不能调整) double maintenanceMarginRate = 0.004; // 维持保证金率(固定不变) //"buy":买(多) "sell":卖(空) if(order.getDirection().equals("buy")){ double forceClosePrice = strongLevelCalculationService.calculateLiquidationPrice(order.getDepositOpen().doubleValue(), faceValue, order.getVolumeOpen().doubleValue(), order.getTradeAvgPrice().doubleValue() , maintenanceMarginRate, item.getUnitFee().doubleValue()); order.setForceClosePrice(BigDecimal.valueOf(forceClosePrice).toString()); }else{ double forceClosePrice = strongLevelCalculationService.calculateEmptyLiquidationPrice(order.getDepositOpen().doubleValue(), faceValue, order.getVolumeOpen().doubleValue(), order.getTradeAvgPrice().doubleValue() , maintenanceMarginRate, item.getUnitFee().doubleValue()); order.setForceClosePrice(BigDecimal.valueOf(forceClosePrice).toString()); } } public ContractApplyOrder saveClose(ContractApplyOrder applyOrder, Realtime realtime, String order_no) { ContractOrder order = this.findByOrderNo(order_no); if (order == null || !ContractOrder.STATE_SUBMITTED.equals(order.getState()) || order.getVolume().compareTo(BigDecimal.ZERO) <= 0) { trading-order-service/src/main/java/com/yami/trading/service/impl/StrongLevelCalculationServiceImpl.java
@@ -17,10 +17,10 @@ public static void main(String[] args) { // 给定参数 double marginBalance = 100; // 保证金余额 double marginBalance = 10; // 保证金余额 double faceValue = 0.01; // 合约面值(固定面值不能调整) double contractQuantity = 5; // 合约张数 张数=保证金/开仓均价*面值/杠杆 double openingPrice = 97016.44; // 开仓均价 double contractQuantity = 0.5; // 合约张数 张数=可用保证金*杠杆倍数/(面值*最新成交价) double openingPrice = 97016.4; // 开仓均价 double maintenanceMarginRate = 0.004; // 维持保证金率(固定不变) double feeRate = 0.0005; // 手续费率 根据实际设置 @@ -94,6 +94,25 @@ return new BigDecimal(result).setScale(2, RoundingMode.HALF_UP).doubleValue(); } /** * * @param earnestMoney 保证金 * @param level 杠杆 * @param faceValue 面值 * @param recentQuotation 最新价格 * @return 合约张数 张数=可用保证金*杠杆倍数/(面值*最新成交价) */ @Override public double countSheets(double earnestMoney, int level, double faceValue, double recentQuotation){ double result = earnestMoney * level / (faceValue * recentQuotation); BigDecimal bd = new BigDecimal(result).setScale(2, RoundingMode.DOWN); return bd.doubleValue(); } public static double a (double marginBalance, double faceValue, double contractQuantity, double openingPrice, double maintenanceMarginRate, double feeRate){ // 计算分子部分 trading-order-service/src/main/java/com/yami/trading/util/StrongLevelCalculationUtil.java
@@ -1,78 +1,78 @@ package com.yami.trading.util; /** * @program: trading-order-master * @description: 强平价格计算 * @create: 2025-01-15 15:56 **/ public class StrongLevelCalculationUtil { public static void main(String[] args) { // 给定参数 double marginBalance = 968.802; // 保证金余额 double faceValue = 0.01; // 合约面值(固定面值不能调整) double contractQuantity = 1; // 合约张数 张数=保证金/开仓均价*面值/杠杆 double openingPrice = 96880.2; // 开仓均价 double maintenanceMarginRate = 0.004; // 维持保证金率(固定不变) double feeRate = 0.0005; // 手续费率 根据实际设置 // 计算强平价 double liquidationPrice = calculateLiquidationPrice(marginBalance, faceValue, contractQuantity, openingPrice, maintenanceMarginRate, feeRate); // 输出结果 System.out.println("多仓预估强平价: " + liquidationPrice); // 计算空仓预估强平价 double liquidationPrice2 = calculateEmptyLiquidationPrice(marginBalance, faceValue, contractQuantity, openingPrice, maintenanceMarginRate, feeRate); // 输出结果 System.out.println("空仓预估强平价: " + liquidationPrice2); } /** * 多仓强平价格计算 多仓预估强平价 =(保证金余额-面值 *|张数|*开仓均价)/(面值*张数|*(维持保证金率+手续费率 -1)); * @param marginBalance 保证金余额 * @param faceValue 合约面值 * @param contractQuantity 合约张数 * @param openingPrice 开仓均价 * @param maintenanceMarginRate 维持保证金率 * @param feeRate 手续费率 * @return */ public static double calculateLiquidationPrice(double marginBalance, double faceValue, double contractQuantity, double openingPrice, double maintenanceMarginRate, double feeRate){ // 计算分子部分 double numerator = marginBalance - (faceValue * contractQuantity * openingPrice); // 计算分母部分 double denominator = faceValue * contractQuantity * (maintenanceMarginRate + feeRate - 1); // 计算强平价 return numerator / denominator; } /** * 空仓强平价格计算 空仓预估强平价 =(保证金余额+面值 *|张数|*开仓均价)/(面值*|张数|*(维持金率+王续费率 +1)) * @param marginBalance 保证金余额 * @param faceValue 合约面值 * @param contractQuantity 合约张数 * @param openingPrice 开仓均价 * @param maintenanceMarginRate 维持保证金率 * @param feeRate 手续费率 * @return */ public static double calculateEmptyLiquidationPrice(double marginBalance, double faceValue, double contractQuantity, double openingPrice, double maintenanceMarginRate, double feeRate){ // 计算分子部分 double numerator = marginBalance + (faceValue * contractQuantity * openingPrice); // 计算分母部分 double denominator = faceValue * contractQuantity * (maintenanceMarginRate + feeRate + 1); // 计算空仓预估强平价 return numerator / denominator; } } //package com.yami.trading.util; // ///** // * @program: trading-order-master // * @description: 强平价格计算 // * @create: 2025-01-15 15:56 // **/ //public class StrongLevelCalculationUtil { // // public static void main(String[] args) { // // 给定参数 // double marginBalance = 968.802; // 保证金余额 // double faceValue = 0.01; // 合约面值(固定面值不能调整) // double contractQuantity = 1; // 合约张数 可用保证金*杠杆倍数/(面值*最新成交价) // double openingPrice = 96880.2; // 开仓均价 // double maintenanceMarginRate = 0.004; // 维持保证金率(固定不变) // double feeRate = 0.0005; // 手续费率 根据实际设置 // // // 计算强平价 // double liquidationPrice = calculateLiquidationPrice(marginBalance, faceValue, contractQuantity, // openingPrice, maintenanceMarginRate, feeRate); // // // 输出结果 // System.out.println("多仓预估强平价: " + liquidationPrice); // // // 计算空仓预估强平价 // double liquidationPrice2 = calculateEmptyLiquidationPrice(marginBalance, faceValue, contractQuantity, // openingPrice, maintenanceMarginRate, feeRate); // // // 输出结果 // System.out.println("空仓预估强平价: " + liquidationPrice2); // } // // /** // * 多仓强平价格计算 多仓预估强平价 =(保证金余额-面值 *|张数|*开仓均价)/(面值*张数|*(维持保证金率+手续费率 -1)); // * @param marginBalance 保证金余额 // * @param faceValue 合约面值 // * @param contractQuantity 合约张数 // * @param openingPrice 开仓均价 // * @param maintenanceMarginRate 维持保证金率 // * @param feeRate 手续费率 // * @return // */ // public static double calculateLiquidationPrice(double marginBalance, double faceValue, double contractQuantity, // double openingPrice, double maintenanceMarginRate, double feeRate){ // // 计算分子部分 // double numerator = marginBalance - (faceValue * contractQuantity * openingPrice); // // // 计算分母部分 // double denominator = faceValue * contractQuantity * (maintenanceMarginRate + feeRate - 1); // // // 计算强平价 // return numerator / denominator; // } // // // /** // * 空仓强平价格计算 空仓预估强平价 =(保证金余额+面值 *|张数|*开仓均价)/(面值*|张数|*(维持金率+王续费率 +1)) // * @param marginBalance 保证金余额 // * @param faceValue 合约面值 // * @param contractQuantity 合约张数 // * @param openingPrice 开仓均价 // * @param maintenanceMarginRate 维持保证金率 // * @param feeRate 手续费率 // * @return // */ // public static double calculateEmptyLiquidationPrice(double marginBalance, double faceValue, double contractQuantity, // double openingPrice, double maintenanceMarginRate, double feeRate){ // // 计算分子部分 // double numerator = marginBalance + (faceValue * contractQuantity * openingPrice); // // // 计算分母部分 // double denominator = faceValue * contractQuantity * (maintenanceMarginRate + feeRate + 1); // // // 计算空仓预估强平价 // return numerator / denominator; // } //}