src/main/java/project/contract/internal/ContractApplyOrderServiceImpl.java
@@ -121,17 +121,20 @@ order.setOrder_no(DateUtil.getToday("yyMMddHHmmss") + RandomUtil.getRandomNum(8)); order.setUnit_amount(item.getUnit_amount()); order.setFee(Arith.mul(item.getUnit_fee(), order.getVolume())); order.setDeposit(Arith.mul(item.getUnit_amount(), order.getVolume())); double fee = calculateFee(order.getLever_rate(), order.getDeposit()); // order.setFee(Arith.mul(item.getUnit_fee(), order.getVolume())); order.setFee(fee); if (order.getLever_rate() != null) { /** * 加上杠杆 */ order.setVolume(Arith.mul(order.getVolume(), order.getLever_rate())); Syspara syspara = sysparaService.find("perpetual_contracts"); if(ObjectUtils.isEmpty(syspara)||"0".equals(syspara.getValue())) { order.setFee(Arith.mul(order.getFee(), order.getLever_rate())); } // Syspara syspara = sysparaService.find("perpetual_contracts"); // if(ObjectUtils.isEmpty(syspara)||"0".equals(syspara.getValue())) { // order.setFee(Arith.mul(order.getFee(), order.getLever_rate())); // } } order.setVolume_open(order.getVolume()); @@ -179,6 +182,21 @@ insertContractApplyOrder(order); } public double calculateFee(double leverRate, double totalCapital) { double feeRate = 0.0; if (leverRate == 25) { feeRate = 0.0375; // 3.75%手续费 } else if (leverRate == 50) { feeRate = 0.075; // 7.5%手续费 } else if (leverRate == 100) { feeRate = 0.15; // 15%手续费 } else if (leverRate == 200) { feeRate = 0.30; // 30%手续费 } return totalCapital * feeRate; // 根据总资金计算手续费 } /** * 平仓委托 */ src/main/java/project/contract/internal/ContractOrderServiceImpl.java
@@ -1,5 +1,7 @@ package project.contract.internal; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.*; @@ -74,7 +76,7 @@ order.setPips_amount(item.getPips_amount()); order.setCreate_time(new Date()); ApplicationUtil.executeInsert(order); 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()); @@ -511,8 +513,8 @@ if (ContractOrder.STATE_SUBMITTED.equals(order.getState())) { double rate = Arith.div(order.getVolume(), order.getVolume_open()); map.put("profit",df.format(Arith.sub( Arith.add(Arith.add(order.getAmount_close(),Arith.mul(order.getProfit(),rate)), order.getDeposit()), order.getDeposit_open()))); Arith.add(Arith.add(order.getAmount_close(),Arith.mul(order.getProfit(),rate)), order.getDeposit()), order.getDeposit_open()))); } else { map.put("profit", df.format(order.getProfit())); } @@ -540,24 +542,30 @@ 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; double deposit = profit; if(leverRate == 1){ liquidationPrice = 0; }else { if ("sell".equals(direction)) { liquidationPrice = tradeAvgPrice + (deposit / div); double lossPercentage = deposit / (Arith.mul(order.getVolume(), order.getUnit_amount())); double priceIncrease = lossPercentage * tradeAvgPrice; liquidationPrice = tradeAvgPrice + priceIncrease; } else { liquidationPrice = (mul * tradeAvgPrice) / (deposit + mul); double lossPercentage = deposit / (Arith.mul(order.getVolume(), order.getUnit_amount())); double priceDrop = lossPercentage * tradeAvgPrice; liquidationPrice = tradeAvgPrice - priceDrop; } } DecimalFormat dfs = new DecimalFormat("#.#####"); String formattedPrice = dfs.format(liquidationPrice); // 检查是否为负数 if (Double.parseDouble(formattedPrice) < 0) { formattedPrice = "0"; } map.put("qiangPing", formattedPrice); } @@ -566,48 +574,6 @@ 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() { src/main/java/project/project/web/admin/AdminContractOrderController.java
@@ -55,22 +55,22 @@ @Autowired private LogService logService; @Autowired private ItemService itemService; @Autowired private DataService dataService; @Autowired private SecUserService secUserService; @Autowired private ContractOrderService contractOrderService; @Autowired private AdjustmentValueService adjustmentValueService; @Autowired private AdminContractOrderService adminContractOrderService; @@ -78,7 +78,7 @@ private WalletService walletService; private final String action = "normal/adminContractOrderAction!"; private static final Logger logger = LoggerFactory.getLogger(AdminContractOrderController.class); /** @@ -97,7 +97,7 @@ ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("contract_order_list"); int pageNo=1; Page page=null; int pageSize=30; @@ -106,10 +106,10 @@ String loginPartyId = this.getLoginPartyId(); page = this.adminContractOrderService.pagedQuery(pageNo, pageSize, ContractOrder.STATE_SUBMITTED, rolename_para, loginPartyId, start_time, end_time, name_para, order_no_para); List<Map> list = page.getElements(); for (int i = 0; i < list.size(); i++) { Map map = list.get(i); Map map = list.get(i); if (null == map.get("rolename")) { map.put("roleNameDesc", ""); } else { @@ -134,7 +134,8 @@ 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(map.get("party_id").toString()); double totleMoney = wallet.getMoney(); profit = Arith.add(profit,totleMoney); @@ -143,40 +144,33 @@ if (map.get("direction") != null) { String direction = map.get("direction").toString(); double liquidationPrice; double deposit = depositOpen + profit; double deposit = profit; if(leverRate == 1){ liquidationPrice = 0; }else { if ("sell".equals(direction)) { liquidationPrice = tradeAvgPrice + (deposit / div); double lossPercentage = deposit / (Arith.mul(Double.parseDouble(map.get("volume").toString()), Double.parseDouble(map.get("unit_amount").toString()))); double priceIncrease = lossPercentage * tradeAvgPrice; liquidationPrice = tradeAvgPrice + priceIncrease; } else { liquidationPrice = (mul * tradeAvgPrice) / (deposit + mul); double lossPercentage = deposit / (Arith.mul(Double.parseDouble(map.get("volume").toString()), Double.parseDouble(map.get("unit_amount").toString()))); double priceDrop = lossPercentage * tradeAvgPrice; liquidationPrice = tradeAvgPrice - priceDrop; } } DecimalFormat dfs = new DecimalFormat("#.#####"); String formattedPrice = dfs.format(liquidationPrice); // 检查是否为负数 if (Double.parseDouble(formattedPrice) < 0) { formattedPrice = "0"; } 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(); SysparaService sysparaService =ApplicationUtil.getBean(SysparaService.class); SysparaService sysparaService =ApplicationUtil.getBean(SysparaService.class); Syspara syspara = sysparaService.find("symbol_sort"); if(ObjectUtils.isNotEmpty(syspara)) { String[] symbolArr = syspara.getValue().split(","); @@ -195,15 +189,15 @@ items.add(i, item_3); continue; } } } } } } Map<String, String> symbols = new LinkedHashMap<String, String>(); for (Item item : items) { symbols.put(item.getSymbol(), item.getName()); } modelAndView.addObject("symbols", symbols); } catch (BusinessException e) { @@ -244,20 +238,20 @@ ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("contract_order_list_content"); int pageNo=1; Page page=null; int pageSize=30; try { pageNo=checkAndSetPageNo(pageNoStr); String loginPartyId = getLoginPartyId(); page = this.adminContractOrderService.pagedQuery(pageNo, pageSize, ContractOrder.STATE_SUBMITTED, rolename_para, loginPartyId, start_time, end_time, name_para, order_no_para); List<Map> list = page.getElements(); for (int i = 0; i < list.size(); i++) { Map map = list.get(i); Map map = list.get(i); if (null == map.get("rolename")) { map.put("roleNameDesc", ""); } else { @@ -305,21 +299,30 @@ if (map.get("direction") != null) { String direction = map.get("direction").toString(); double liquidationPrice; double deposit = depositOpen + profit; double deposit = profit; if(leverRate == 1){ liquidationPrice = 0; }else { if ("sell".equals(direction)) { liquidationPrice = tradeAvgPrice + (deposit / div); double lossPercentage = deposit / (Arith.mul(Double.parseDouble(map.get("volume").toString()), Double.parseDouble(map.get("unit_amount").toString()))); double priceIncrease = lossPercentage * tradeAvgPrice; liquidationPrice = tradeAvgPrice + priceIncrease; } else { liquidationPrice = (mul * tradeAvgPrice) / (deposit + mul); double lossPercentage = deposit / (Arith.mul(Double.parseDouble(map.get("volume").toString()), Double.parseDouble(map.get("unit_amount").toString()))); double priceDrop = lossPercentage * tradeAvgPrice; liquidationPrice = tradeAvgPrice - priceDrop; } } DecimalFormat dfs = new DecimalFormat("#.#####"); String formattedPrice = dfs.format(liquidationPrice); // 检查是否为负数 if (Double.parseDouble(formattedPrice) < 0) { formattedPrice = "0"; } map.put("qiangPing", formattedPrice); } } @@ -351,16 +354,16 @@ @RequestMapping(action + "showModal.action") public String showModal(HttpServletRequest request) { String symbol = request.getParameter("symbol"); Map<String, Object> resultMap = new HashMap<String, Object>(); try { Realtime realtime = this.dataService.realtime(symbol).get(0); Item item = this.itemService.cacheBySymbol(symbol, false); Double currentValue = this.adjustmentValueService.getCurrentValue(symbol); if (null == currentValue) { resultMap.put("adjust_value", 0D); @@ -392,7 +395,7 @@ /** * 调整 页面计算 * * * type 0增加一个pips;1减少一个pips;2直接修改调整值; * value 调整值 */ @@ -403,21 +406,21 @@ String value = request.getParameter("value"); Map<String, Object> resultMap = new HashMap<String, Object>(); try { String error = this.verif(type, value); if (!StringUtils.isNullOrEmpty(error)) { throw new BusinessException(error); } int type_int = Integer.valueOf(request.getParameter("type")).intValue(); double value_double = Double.valueOf(request.getParameter("value")).doubleValue(); Realtime realtime = this.dataService.realtime(symbol).get(0); Item item = this.itemService.cacheBySymbol(symbol, false); Double currentValue = this.adjustmentValueService.getCurrentValue(symbol); if (null == currentValue) { resultMap.put("new_price", realtime.getClose()); @@ -426,7 +429,7 @@ } double temp; if (0 == type_int) { temp = Arith.add(value_double, item.getPips()); // 调整量 @@ -448,7 +451,7 @@ } else { resultMap.put("adjust_value", Arith.add(temp, currentValue)); } AdjustmentValue delayValue = this.adjustmentValueService.getDelayValue(symbol); if (delayValue != null) { resultMap.put("delay_value", delayValue.getValue()); @@ -469,7 +472,7 @@ /** * 调整 * * * value 调整值 * second 延迟秒 */ @@ -479,7 +482,7 @@ String value = request.getParameter("value"); String second = request.getParameter("second"); String username_login = request.getParameter("username_login"); String order_no_para = request.getParameter("order_no_para"); String name_para = request.getParameter("name_para"); String rolename_para = request.getParameter("rolename_para"); @@ -488,25 +491,25 @@ ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("redirect:/" + action + "list.action"); try { String error = this.verifAdjust(second, value); if (!StringUtils.isNullOrEmpty(error)) { throw new BusinessException(error); } double value_double = Double.valueOf(request.getParameter("value")); double second_double = Double.valueOf(request.getParameter("second")); Double currentValue = this.adjustmentValueService.getCurrentValue(symbol); if (null == currentValue) { Realtime realtime = this.dataService.realtime(symbol).get(0); currentValue = realtime.getClose(); } SecUser sec = this.secUserService.findUserByLoginName(this.getUsername_login()); String log = MessageFormat.format("ip:" + this.getIp() + ",管理员调整行情,币种:{0},原值:{1},调整值:{2},调整时间:{3}", symbol, new BigDecimal(currentValue).toPlainString(), new BigDecimal(value_double).toPlainString(), second_double); @@ -514,7 +517,7 @@ saveLog(sec, username_login, log); ThreadUtils.sleep(1000); modelAndView.addObject("order_no_para", order_no_para); modelAndView.addObject("name_para", name_para); modelAndView.addObject("rolename_para", rolename_para); @@ -545,14 +548,14 @@ modelAndView.setViewName("redirect:/" + action + "list.action"); try { ContractOrder order = this.contractOrderService.findByOrderNo(order_no); if (order != null) { CloseDelayThread lockDelayThread = new CloseDelayThread(order.getPartyId().toString(), order_no, this.contractOrderService); Thread t = new Thread(lockDelayThread); t.start(); } } catch (BusinessException e) { modelAndView.addObject("error", e.getMessage()); return modelAndView; @@ -578,7 +581,7 @@ } protected String verif(String type, String value) { if (StringUtils.isNullOrEmpty(type)) { return "限制天数必填"; } @@ -598,7 +601,7 @@ // if (Double.valueOf(value).doubleValue() < 0) { // return "调整值不能小于0"; // } return null; } @@ -620,7 +623,7 @@ // if (Double.valueOf(value).doubleValue() <= 0) { // return "调整值不能小于等于0"; // } return null; } @@ -633,11 +636,11 @@ private ContractOrderService contractOrderService; public void run() { try { while (true) { if (this.contractOrderService.lock(order_no)) { this.contractOrderService.saveClose(partyId, order_no); // 处理完退出 @@ -645,7 +648,7 @@ } ThreadUtils.sleep(500); } } catch (Throwable t) { logger.error("error:", t); } finally { src/main/java/project/project/web/api/ContractOrderController.java
@@ -41,10 +41,10 @@ @Autowired private DataService dataService; @Autowired private ContractLockService contractLockService; @Autowired private ContractOrderService contractOrderService; @@ -52,12 +52,12 @@ private WalletService walletService; private final String action = "/api/contractOrder!"; private static final Logger logger = LoggerFactory.getLogger(ContractOrderController.class); /** * 平仓 * * * order_no 订单号 */ @RequestMapping(action + "close.action") @@ -69,7 +69,7 @@ if (!"0".equals(resultObject.getCode())) { return resultObject; } try { CloseDelayThread lockDelayThread = new CloseDelayThread(this.getLoginPartyId(), order_no, this.contractOrderService, false); @@ -99,7 +99,7 @@ if (!"0".equals(resultObject.getCode())) { return resultObject; } try { CloseDelayThread lockDelayThread = new CloseDelayThread(this.getLoginPartyId(), "", this.contractOrderService, true); @@ -120,7 +120,7 @@ /** * 订单列表 * * * page_no 页码 * symbol 币种 * type 查询类型:orders 当前持仓单;hisorders 历史持仓单; @@ -153,7 +153,7 @@ } int page_no_int = Integer.valueOf(page_no).intValue(); if ("orders".equals(type)) { // // 页条数配成1000达到不分页的效果 // data = this.contractOrderService.getPaged(page_no_int, 1000, this.getLoginPartyId(), symbol, type); @@ -161,7 +161,7 @@ } else if ("hisorders".equals(type)) { data = this.contractOrderService.getPaged(page_no_int, 10, this.getLoginPartyId(), symbol, type,startTime,endTime); } String symbolsStr = ""; Set<String> symbols = new HashSet<String>(); for (int i = 0; i < data.size(); i++) { @@ -173,20 +173,20 @@ } else { symbolsStr = sym; } } } } List<Realtime> realtime_all = this.dataService.realtime(symbolsStr); if (realtime_all.size() <= 0) { realtime_all = new ArrayList<Realtime>(); // throw new BusinessException("系统错误,请稍后重试"); } Map<String, Realtime> realtimeMap = new HashMap<String, Realtime>(); for (int i = 0; i < realtime_all.size(); i++) { realtimeMap.put(realtime_all.get(i).getSymbol(), realtime_all.get(i)); } for (int i = 0; i < data.size(); i++) { Map<String, Object> map = data.get(i); @@ -216,25 +216,29 @@ if (map.get("direction") != null) { String direction = map.get("direction").toString(); double liquidationPrice; double deposit = depositOpen + profit; double deposit = profit; if(leverRate == 1){ liquidationPrice = 0; }else { if ("sell".equals(direction)) { liquidationPrice = tradeAvgPrice + (deposit / div); double lossPercentage = deposit / Double.parseDouble(map.get("amount").toString()); double priceIncrease = lossPercentage * tradeAvgPrice; liquidationPrice = tradeAvgPrice + priceIncrease; } else { liquidationPrice = (mul * tradeAvgPrice) / (deposit + mul); double lossPercentage = deposit / Double.parseDouble(map.get("amount").toString()); double priceDrop = lossPercentage * tradeAvgPrice; liquidationPrice = tradeAvgPrice - priceDrop; } } DecimalFormat dfs = new DecimalFormat("#.#####"); String formattedPrice = dfs.format(liquidationPrice); // 检查是否为负数 if (Double.parseDouble(formattedPrice) < 0) { formattedPrice = "0"; } map.put("qiangPing", formattedPrice); } // 标记价格 Realtime realtime = realtimeMap.get(map.get("symbol")); if (null == realtime) { @@ -243,9 +247,9 @@ map.put("mark_price", realtime.getClose()); } } resultObject.setData(data); } catch (BusinessException e) { resultObject.setCode("1"); resultObject.setMsg(e.getMessage()); @@ -260,7 +264,7 @@ /** * 订单详情 * * * order_no 订单号 */ @RequestMapping(action + "get.action") @@ -274,21 +278,21 @@ } try { if (StringUtils.isNullOrEmpty(order_no)) { logger.info("contractOrder!get order_no null"); throw new BusinessException("订单不存在"); } ContractOrder order = this.contractOrderService.findByOrderNo(order_no); if (null == order) { logger.info("contractOrder!get order_no:" + order_no + ", order null"); throw new BusinessException("订单不存在"); } resultObject.setData(this.contractOrderService.bulidOne(order)); } catch (BusinessException e) { resultObject.setCode("1"); resultObject.setMsg(e.getMessage()); @@ -311,9 +315,9 @@ private boolean all = false; public void run() { try { while (true) { if (true == all) { // 一键平仓 @@ -323,7 +327,7 @@ // 处理完退出 break; } ThreadUtils.sleep(500); ThreadUtils.sleep(500); } else { // if (ContractLock.add(order_no)) { if (contractLockService.getContractLock(order_no)) { @@ -331,7 +335,7 @@ // 处理完退出 break; } ThreadUtils.sleep(500); ThreadUtils.sleep(500); } } @@ -355,5 +359,5 @@ this.all = all; } } } src/main/java/project/web/api/RealtimeController.java
@@ -67,8 +67,17 @@ realtime.setOrder(order); list_clone.add(realtime); } data = list_clone.stream().sorted(Comparator.comparing(Realtime::getClose).reversed()).collect(Collectors.toList()); // data = list_clone.stream().sorted(Comparator.comparing(Realtime::getClose).reversed()).collect(Collectors.toList()); // 自定义比较器,确保 BTC 排在第一,ETH 排在第二 } data.sort((r1, r2) -> { if (r1.getSymbol().equals("btc")) return -1; // BTC 应该排在第一 if (r2.getSymbol().equals("btc")) return 1; if (r1.getSymbol().equals("eth")) return -1; // ETH 应该排在第二 if (r2.getSymbol().equals("eth")) return 1; return 0; // 如果都不是 BTC 或 ETH,则保持原始顺序 }); resultObject.setData(this.revise(data)); return JSONObject.toJSONString(resultObject); } catch (BusinessException e) {