From 75018b2f492444248d8b476d9703bb312d2befc3 Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Sat, 08 Feb 2025 16:51:19 +0800
Subject: [PATCH] 项目提交
---
trading-order-bean/src/main/java/com/yami/trading/bean/contract/domain/ContractOrder.java | 48
trading-order-bean/src/main/java/com/yami/trading/bean/vo/FinanceVo.java | 113 ++
trading-order-bean/src/main/java/com/yami/trading/bean/item/domain/Item.java | 8
trading-order-admin/src/main/resources/application-local.yml | 4
trading-order-bean/src/main/java/com/yami/trading/bean/finance/Finance.java | 106 ++
trading-order-service/src/main/java/com/yami/trading/service/impl/AwsS3OSSFileServiceImpl.java | 41
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiCapitaltWalletWalletController.java | 68 +
trading-order-admin/src/main/java/com/yami/trading/admin/task/cms/XueQiuInfomationGet.java | 8
trading-order-bean/src/main/java/com/yami/trading/bean/model/Miner.java | 155 +++
trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderService.java | 267 ++++-
trading-order-service/src/main/java/com/yami/trading/service/impl/CapitaltWalletServiceImpl.java | 115 ++
trading-order-service/src/main/java/com/yami/trading/service/impl/RechargeBlockchainOrderServiceImpl.java | 18
trading-order-service/src/main/java/com/yami/trading/service/impl/WalletServiceImpl.java | 151 ++
trading-order-service/src/main/java/com/yami/trading/service/item/ItemUserOptionalListService.java | 21
trading-order-bean/src/main/java/com/yami/trading/bean/finance/FinanceOrder.java | 149 +++
trading-order-service/src/main/java/com/yami/trading/service/finance/FinanceService.java | 13
trading-order-service/src/main/java/com/yami/trading/service/StrongLevelCalculationService.java | 15
trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerOrder.java | 79 +
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiIndexController.java | 1
trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerController.java | 22
trading-order-admin/src/main/java/com/yami/trading/admin/model/TransferModel.java | 36
trading-order-service/src/main/java/com/yami/trading/dao/finance/FinanceMapper.java | 15
trading-order-sys/src/main/java/com/yami/trading/sys/model/SysMenu.java | 2
trading-order-sys/src/main/resources/mapper/SysMenuMapper.xml | 12
trading-order-admin/src/main/resources/config/system.properties | 3
trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java | 32
trading-order-security-common/src/main/java/com/yami/trading/security/common/config/CorsConfig.java | 20
trading-order-admin/src/main/java/com/yami/trading/admin/controller/contract/ContractOrderController.java | 2
trading-order-service/src/main/java/com/yami/trading/util/StrongLevelCalculationUtil.java | 78 +
trading-order-admin/src/main/java/com/yami/trading/admin/controller/finance/FinanceController.java | 129 ++
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWalletController.java | 15
trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java | 13
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractOrderController.java | 2
trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/HobiDataServiceImpl.java | 74
trading-order-admin/src/main/java/com/yami/trading/admin/task/AStockPanKouTask.java | 2
trading-order-service/src/main/java/com/yami/trading/service/contract/ContractApplyOrderService.java | 67 +
trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java | 192 ++-
trading-order-service/src/main/java/com/yami/trading/service/finance/impl/FinanceServiceImpl.java | 19
trading-order-service/src/main/java/com/yami/trading/service/impl/UserServiceImpl.java | 14
trading-order-admin/src/main/java/com/yami/trading/api/dto/OpenAction.java | 5
trading-order-huobi/src/main/java/com.yami.trading.huobi/data/internal/AdjustmentValueServiceImpl.java | 6
trading-order-service/src/main/java/com/yami/trading/service/impl/StrongLevelCalculationServiceImpl.java | 140 +++
trading-order-admin/src/main/java/com/yami/trading/admin/task/InitHandle.java | 24
trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerPara.java | 35
trading-order-bean/src/main/java/com/yami/trading/bean/model/CapitaltWallet.java | 48 +
trading-order-service/src/main/java/com/yami/trading/util/ConverterUtil.java | 44 +
trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractApplyOrderController.java | 132 +-
trading-order-service/src/main/java/com/yami/trading/service/CapitaltWalletService.java | 16
trading-order-service/src/main/java/com/yami/trading/dao/CapitaltWalletMapper.java | 9
49 files changed, 2,160 insertions(+), 428 deletions(-)
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/contract/ContractOrderController.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/contract/ContractOrderController.java
index f4a8975..1f29622 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/contract/ContractOrderController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/contract/ContractOrderController.java
@@ -124,7 +124,7 @@
while (true) {
if (this.contractOrderService.lock(order_no)) {
- this.contractOrderService.saveClose(partyId, order_no);
+ this.contractOrderService.saveClose(partyId, order_no,null);
// 处理完退出
break;
}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/finance/FinanceController.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/finance/FinanceController.java
new file mode 100644
index 0000000..015e97c
--- /dev/null
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/finance/FinanceController.java
@@ -0,0 +1,129 @@
+package com.yami.trading.admin.controller.finance;
+
+import com.yami.trading.admin.model.LoginModel;
+import com.yami.trading.bean.finance.Finance;
+import com.yami.trading.bean.vo.FinanceVo;
+import com.yami.trading.common.domain.Result;
+import com.yami.trading.common.exception.YamiShopBindException;
+import com.yami.trading.common.util.ConvertUtil;
+import com.yami.trading.common.util.GoogleAuthenticator;
+import com.yami.trading.security.common.bo.UserInfoInTokenBO;
+import com.yami.trading.security.common.enums.SysTypeEnum;
+import com.yami.trading.security.common.vo.TokenInfoVO;
+import com.yami.trading.service.finance.FinanceService;
+import com.yami.trading.sys.model.SysUser;
+import com.yami.trading.util.ConverterUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.ObjectUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * @program: trading-order-master
+ * @description: 理财
+ * @create: 2025-01-22 17:13
+ **/
+@RestController
+@RequestMapping("finance")
+@Api(tags = "理财")
+@Slf4j
+public class FinanceController {
+
+ @Autowired
+ FinanceService service;
+
+ @PostMapping("/add")
+ @ApiOperation(value = "理财-添加")
+ public Result<?> login(@Valid @RequestBody FinanceVo vo) {
+ Finance finance = ConverterUtil.convert(vo, Finance.class);
+ service.save(finance);
+ return Result.ok("添加成功");
+ }
+
+ /**
+ * 修改理财
+ */
+ @PutMapping("/update/{id}")
+ @ApiOperation(value = "理财-修改")
+ public Result<?> updateFinance(@PathVariable Long id, @Valid @RequestBody FinanceVo vo) {
+ // 查询该理财产品是否被用户持有
+// boolean isHeldByUsers = userFinanceService.isFinanceHeldByUsers(id);
+// if (isHeldByUsers) {
+// return Result.failed("该理财产品已被用户持有,无法修改");
+// }
+
+ // 如果没有用户持有,继续进行修改操作
+ return Optional.ofNullable(service.getById(id))
+ .map(finance -> {
+ finance.setName(vo.getName());
+ finance.setName_en(vo.getName_en());
+ finance.setName_cn(vo.getName_cn());
+ finance.setName_kn(vo.getName_kn());
+ finance.setName_jn(vo.getName_jn());
+ finance.setImg(vo.getImg());
+ finance.setCycle(vo.getCycle());
+ finance.setDaily_rate(vo.getDaily_rate());
+ finance.setDaily_rate_max(vo.getDaily_rate_max());
+ finance.setToday_rate(vo.getToday_rate());
+ finance.setDefault_ratio(vo.getDefault_ratio());
+ finance.setInvestment_min(vo.getInvestment_min());
+ finance.setInvestment_max(vo.getInvestment_max());
+ finance.setState(vo.getState());
+ finance.setBuyCurrency(vo.getBuyCurrency());
+ finance.setOutputCurrency(vo.getOutputCurrency());
+
+ service.save(finance);
+ return Result.ok("修改成功");
+ })
+ .orElseGet(() -> Result.failed("理财信息不存在"));
+ }
+
+
+ /**
+ * 删除理财
+ */
+ @DeleteMapping("/delete/{id}")
+ @ApiOperation(value = "理财-删除")
+ public Result<?> deleteFinance(@PathVariable Long id) {
+ boolean removed = service.removeById(id);
+ if (removed) {
+ // 查询该理财产品是否被用户持有
+// boolean isHeldByUsers = userFinanceService.isFinanceHeldByUsers(id);
+// if (isHeldByUsers) {
+// return Result.failed("该理财产品已被用户持有,无法删除");
+// }
+ return Result.ok("删除成功");
+ } else {
+ return Result.failed("理财信息不存在");
+ }
+ }
+
+ /**
+ * 查询单个理财
+ */
+ @GetMapping("/find/{id}")
+ @ApiOperation(value = "理财-查询")
+ public Result<?> getFinance(@PathVariable Long id) {
+ return Optional.ofNullable(service.getById(id))
+ .map(Result::ok)
+ .orElseGet(() -> Result.failed("理财信息不存在"));
+ }
+
+ /**
+ * 查询所有理财
+ */
+ @GetMapping("/list")
+ @ApiOperation(value = "理财-查询所有")
+ public Result<?> getAllFinances() {
+ List<Finance> finances = service.list();
+ return Result.ok(finances.isEmpty() ? Collections.emptyList() : finances);
+ }
+}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerController.java b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerController.java
new file mode 100644
index 0000000..adfa70c
--- /dev/null
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/controller/miner/MinerController.java
@@ -0,0 +1,22 @@
+package com.yami.trading.admin.controller.miner;
+
+import io.swagger.annotations.Api;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @program: trading-order-master
+ * @description: 矿机
+ * @create: 2025-01-22 17:10
+ **/
+@RestController
+@RequestMapping("miner")
+@Api(tags = "矿机")
+@Slf4j
+public class MinerController {
+
+
+
+
+}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/model/TransferModel.java b/trading-order-admin/src/main/java/com/yami/trading/admin/model/TransferModel.java
new file mode 100644
index 0000000..adcc983
--- /dev/null
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/model/TransferModel.java
@@ -0,0 +1,36 @@
+package com.yami.trading.admin.model;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import java.math.BigDecimal;
+
+/**
+ * @program: trading-order-master
+ * @description:
+ * @create: 2025-01-09 10:59
+ **/
+@Data
+@ApiModel
+public class TransferModel {
+ /**
+ * contract : 合约
+ * capital : 资金
+ */
+ @ApiModelProperty("划转账户")
+ private String deductAccount;
+
+ @ApiModelProperty("接收账户")
+ private String receiveAccount;
+
+ @ApiModelProperty("账变金额(不能小于0)")
+ @Min(0)
+ private BigDecimal moneyRevise;
+
+ @ApiModelProperty("登录人资金密码")
+ @NotBlank
+ private String safePassword;
+}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/task/AStockPanKouTask.java b/trading-order-admin/src/main/java/com/yami/trading/admin/task/AStockPanKouTask.java
index 3e34de2..c871ada 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/admin/task/AStockPanKouTask.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/task/AStockPanKouTask.java
@@ -40,7 +40,7 @@
@Autowired
private XueQiuDataServiceImpl xueQiuDataService;
- @Scheduled(cron = "*/5 * * * * ?")
+// @Scheduled(cron = "*/5 * * * * ?") 雪球
public void sendTask() throws InterruptedException {
List<String> collect = itemService.list().stream().filter(t -> Item.A_STOCKS.equalsIgnoreCase(t.getOpenCloseType())).map(Item::getSymbol).collect(Collectors.toList());
for (String symbols: collect) {
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/task/InitHandle.java b/trading-order-admin/src/main/java/com/yami/trading/admin/task/InitHandle.java
index 2b0ed70..8ea6c61 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/admin/task/InitHandle.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/task/InitHandle.java
@@ -48,10 +48,10 @@
protected KlineService klineService;
@Autowired
protected HighLowHandleJob highLowHandleJob;
- @Autowired
- protected StockGetDataJob stockGetDataJob;
- @Autowired
- protected ForexGetDataJob forexGetDataJob;
+// @Autowired 外汇
+// protected StockGetDataJob stockGetDataJob;
+// @Autowired
+// protected ForexGetDataJob forexGetDataJob;
@Autowired
protected CryptosGetDataJob cryptosGetDataJob;
@Autowired
@@ -77,8 +77,8 @@
private RealtimePushJob realtimePushJob;
@Autowired
private CleanDataJob cleanDataJob;
- @Autowired
- private StockGetMarketJob stockGetMarketJob;
+// @Autowired etf
+// private StockGetMarketJob stockGetMarketJob;
/**
* 交割合约持仓单盈亏计算线程启动
*/
@@ -130,15 +130,15 @@
}
klineLoadCache.loadCache();
- String symbols = items.stream().map(Item::getSymbol).collect(Collectors.joining(","));
+// String symbols = items.stream().map(Item::getSymbol).collect(Collectors.joining(","));
// 数据有问题初始化一下
- klineInitService.klineInit(symbols);
+// klineInitService.klineInit(symbols); 外汇
// 高低修正
highLowHandleJob.start();
- stockGetMarketJob.start();
- // 获取realtime实时数据
- stockGetDataJob.start();
- forexGetDataJob.start();
+// stockGetMarketJob.start();
+// // 获取realtime实时数据
+// stockGetDataJob.start();
+// forexGetDataJob.start();
cryptosGetDataJob.start();
fakeSymbolGetDataJob.start();
// 实时数据批量保存线程
diff --git a/trading-order-admin/src/main/java/com/yami/trading/admin/task/cms/XueQiuInfomationGet.java b/trading-order-admin/src/main/java/com/yami/trading/admin/task/cms/XueQiuInfomationGet.java
index 75a50fb..c66bee4 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/admin/task/cms/XueQiuInfomationGet.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/admin/task/cms/XueQiuInfomationGet.java
@@ -27,10 +27,10 @@
@Autowired
private XueQiuDataServiceImpl xueQiuDataService;
- @Scheduled(cron = "0 0/30 * ? * *")
- public void crawl(){
- xueQiuDataService.getInformation();
- }
+// @Scheduled(cron = "0 0/30 * ? * *") 雪球
+// public void crawl(){
+// xueQiuDataService.getInformation();
+// }
@Scheduled(cron = "0 */5 * ? * *")
public void translate(){
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiCapitaltWalletWalletController.java b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiCapitaltWalletWalletController.java
new file mode 100644
index 0000000..30e706c
--- /dev/null
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiCapitaltWalletWalletController.java
@@ -0,0 +1,68 @@
+package com.yami.trading.api.controller;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.yami.trading.admin.model.TransferModel;
+import com.yami.trading.admin.model.UpdateWalltModel;
+import com.yami.trading.bean.contract.domain.ContractOrder;
+import com.yami.trading.bean.item.domain.Item;
+import com.yami.trading.common.annotation.SysLog;
+import com.yami.trading.common.domain.Result;
+import com.yami.trading.common.exception.BusinessException;
+import com.yami.trading.common.exception.YamiShopBindException;
+import com.yami.trading.common.util.StringUtils;
+import com.yami.trading.common.web.ResultObject;
+import com.yami.trading.security.common.util.SecurityUtils;
+import com.yami.trading.service.CapitaltWalletService;
+import com.yami.trading.service.contract.ContractOrderService;
+import com.yami.trading.service.user.UserService;
+import com.yami.trading.sys.service.SysUserService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.checkerframework.checker.units.qual.A;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: trading-order-master
+ * @description: 合约账户
+ * @create: 2025-01-08 17:57
+ **/
+@RestController
+@RequestMapping("api/wallet")
+@Api(tags = "合约账户")
+public class ApiCapitaltWalletWalletController {
+
+ @Autowired
+ SysUserService sysUserService;
+
+ @Autowired
+ CapitaltWalletService capitaltWalletService;
+
+
+ @ApiOperation(value = "划转")
+ @PostMapping("transfer.action")
+ public Result updateWallt(@Valid @RequestBody TransferModel model) {
+ String partyId = SecurityUtils.getCurrentUserId();
+ if(!StringUtils.isNotEmpty(partyId)){
+ throw new YamiShopBindException("请登录!");
+ }
+ boolean b = sysUserService.checkSafeWord(model.getSafePassword());
+ if(!b){
+ throw new YamiShopBindException("资金密码错误");
+ }
+ return capitaltWalletService.updateWallt(partyId,model.getDeductAccount(),model.getReceiveAccount(),model.getMoneyRevise());
+ }
+
+
+
+}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractApplyOrderController.java b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractApplyOrderController.java
index efc3b31..b87162a 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractApplyOrderController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractApplyOrderController.java
@@ -1,6 +1,8 @@
package com.yami.trading.api.controller;
+import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.trading.api.dto.CloseAction;
import com.yami.trading.api.dto.OpenAction;
@@ -191,70 +193,104 @@
*/
@RequestMapping(action + "open.action")
public Result<String> open(@Valid OpenAction openAction) throws IOException, InterruptedException {
- String symbol = openAction.getSymbol();
-// Item bySymbol = itemService.findBySymbol(symbol);
-// if(bySymbol == null){
-// throw new YamiShopBindException("当前币对不存在");
-// }
-// boolean isOpen = MarketOpenChecker.isMarketOpenByItemCloseType(bySymbol.getOpenCloseType());
-// if(!isOpen){
-// throw new YamiShopBindException("当前已经休市");
-// }
-
String partyId = SecurityUtils.getUser().getUserId();
RLock rLock = redissonClient.getLock("contract_open_" + partyId);
- boolean lockResult = rLock.tryLock(5, TimeUnit.SECONDS);
- if (!lockResult) {
- throw new YamiShopBindException("请稍后再试");
- }
+ boolean lockAcquired = false;
try {
- User user = userService.getById(partyId);
- if (!user.isEnabled()) {
- throw new YamiShopBindException("用户已锁定");
+ // 尝试获取锁,最多等待5秒
+ lockAcquired = rLock.tryLock(5, TimeUnit.SECONDS);
+ if (!lockAcquired) {
+ log.warn("无法获取锁: contract_open_{}", partyId);
+ throw new YamiShopBindException("请稍后再试");
}
- Syspara syspara = sysparaService.find("stop_user_internet");
- String stopUserInternet = syspara.getSvalue();
- if(org.apache.commons.lang3.StringUtils.isNotEmpty(stopUserInternet)) {
- String[] stopUsers = stopUserInternet.split(",");
+ // 校验当前用户订单状态
+ checkContractOrderStatus(openAction, partyId);
- System.out.println("userName = " + user.getUserName());
- System.out.println("stopUserInternet = " + stopUserInternet);
+ // 校验用户是否被锁定
+ checkUserStatus(partyId);
- if(Arrays.asList(stopUsers).contains(user.getUserName())){
- throw new YamiShopBindException("无网络");
- }
- }
+ // 校验用户网络限制
+ checkUserNetworkRestriction(partyId);
- ContractApplyOrder order = new ContractApplyOrder();
- order.setPartyId(partyId);
- order.setSymbol(openAction.getSymbol());
- order.setDirection(openAction.getDirection());
- order.setOffset(ContractApplyOrder.OFFSET_OPEN);
- 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);
- this.contractApplyOrderService.saveCreate(order);
+ // 创建新的合约申请订单
+ createContractApplyOrder(openAction, partyId);
+ } catch (YamiShopBindException e) {
+ log.error("错误信息: {}", e.getMessage(), e);
+ throw e; // 重新抛出自定义异常
} catch (Exception e) {
- log.error("下单失败" , e);
- return Result.failed(e.getMessage());
-
+ log.error("系统异常: {}", e.getMessage(), e);
+ throw new YamiShopBindException("操作失败,请稍后再试");
} finally {
- rLock.unlock();
+ // 确保释放锁
+ if (lockAcquired && rLock.isHeldByCurrentThread()) {
+ rLock.unlock();
+ }
}
- return Result.succeed(null,"ok");
-
-
+ return Result.succeed(null, "ok");
}
+ // 校验合约订单状态
+ private void checkContractOrderStatus(OpenAction openAction, String partyId) {
+ LambdaQueryWrapper<ContractOrder> wrapper = new LambdaQueryWrapper<>();
+ wrapper.eq(ContractOrder::getPartyId, partyId);
+ wrapper.eq(ContractOrder::getState, "submitted");
+ wrapper.eq(ContractOrder::getLocationType, openAction.getLocationType() == 0 ? 1 : 0);
+
+ List<ContractOrder> list = contractOrderService.list(wrapper);
+ if (CollectionUtil.isNotEmpty(list)) {
+ String errorMessage = openAction.getLocationType() == 0 ?
+ "下单失败,当前持有全仓仓位,不支持逐仓下单!" :
+ "下单失败,当前持有逐仓仓位,不支持全仓下单!";
+ throw new YamiShopBindException(errorMessage);
+ }
+ }
+
+ // 校验用户状态
+ private void checkUserStatus(String partyId) {
+ User user = userService.getById(partyId);
+ if (!user.isEnabled()) {
+ throw new YamiShopBindException("用户已锁定");
+ }
+ }
+
+ // 校验用户网络限制
+ private void checkUserNetworkRestriction(String partyId) {
+ Syspara syspara = sysparaService.find("stop_user_internet");
+ String stopUserInternet = syspara.getSvalue();
+
+ if (StringUtils.isNotEmpty(stopUserInternet)) {
+ String[] stopUsers = stopUserInternet.split(",");
+ User user = userService.getById(partyId);
+ if (Arrays.asList(stopUsers).contains(user.getUserName())) {
+ throw new YamiShopBindException("无网络");
+ }
+ }
+ }
+
+ // 创建合约申请订单
+ private void createContractApplyOrder(OpenAction openAction, String partyId) {
+ ContractApplyOrder order = new ContractApplyOrder();
+ order.setPartyId(partyId);
+ order.setSymbol(openAction.getSymbol());
+ order.setDirection(openAction.getDirection());
+ order.setOffset(ContractApplyOrder.OFFSET_OPEN);
+ 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);
+
+ contractApplyOrderService.saveCreate(order);
+ }
+
+
/**
* 平仓
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractOrderController.java b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractOrderController.java
index c4514d5..436a1e9 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractOrderController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiContractOrderController.java
@@ -401,7 +401,7 @@
} else {
// if (ContractLock.add(order_no)) {
if (contractLockService.getContractLock(order_no)) {
- this.contractOrderService.saveClose(partyId, order_no);
+ this.contractOrderService.saveClose(partyId, order_no,null);
// 处理完退出
break;
}
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiIndexController.java b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiIndexController.java
index 06bd082..f16eb48 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiIndexController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiIndexController.java
@@ -20,6 +20,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWalletController.java b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWalletController.java
index 658d71a..b9a9916 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWalletController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/controller/ApiWalletController.java
@@ -7,6 +7,7 @@
import com.yami.trading.api.service.UserCacheService;
import com.yami.trading.bean.data.domain.Realtime;
import com.yami.trading.bean.item.domain.Item;
+import com.yami.trading.bean.model.CapitaltWallet;
import com.yami.trading.bean.model.ChannelBlockchain;
import com.yami.trading.bean.model.Wallet;
import com.yami.trading.bean.model.WalletExtend;
@@ -18,10 +19,7 @@
import com.yami.trading.common.util.HttpContextUtils;
import com.yami.trading.common.util.StringUtils;
import com.yami.trading.security.common.util.SecurityUtils;
-import com.yami.trading.service.ChannelBlockchainService;
-import com.yami.trading.service.RechargeBlockchainOrderService;
-import com.yami.trading.service.WalletService;
-import com.yami.trading.service.WithdrawService;
+import com.yami.trading.service.*;
import com.yami.trading.service.data.DataService;
import com.yami.trading.service.item.ItemService;
import com.yami.trading.service.syspara.SysparaService;
@@ -71,6 +69,8 @@
ItemService itemService;
@Autowired
WalletLogService walletLogService;
+ @Autowired
+ CapitaltWalletService capitaltWalletService;
@GetMapping("/getUsdt")
@ApiOperation(value = "获取usdt余额")
@@ -215,12 +215,13 @@
df2.setRoundingMode(RoundingMode.FLOOR);
// String partyId ="dcc0dd35a49c383dadabc4dc030afe70";
String partyId = SecurityUtils.getCurrentUserId();
- Wallet usdt = null;
+ CapitaltWallet usdt = null;
if (StringUtils.isNotEmpty(partyId)) {
- usdt = this.walletService.saveWalletByPartyId(partyId);
+// usdt = this.walletService.saveWalletByPartyId(partyId);
+ usdt = capitaltWalletService.getUserIdWallet(partyId);
}
if (null == usdt) {
- usdt = new Wallet();
+ usdt = new CapitaltWallet();
usdt.setMoney(new BigDecimal(0));
usdt.setLockMoney(new BigDecimal(0));
usdt.setFreezeMoney(new BigDecimal(0));
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java b/trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java
index 1bd69e7..0c3eb29 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/controller/exchange/ApiExchangeApplyOrderController.java
@@ -4,10 +4,7 @@
import com.yami.trading.bean.exchange.ExchangeApplyOrder;
import com.yami.trading.bean.exchange.dto.ExchangeSymbolDto;
import com.yami.trading.bean.exchange.dto.SumEtfDto;
-import com.yami.trading.bean.model.RealNameAuthRecord;
-import com.yami.trading.bean.model.User;
-import com.yami.trading.bean.model.Wallet;
-import com.yami.trading.bean.model.WalletExtend;
+import com.yami.trading.bean.model.*;
import com.yami.trading.bean.purchasing.dto.ExchangeLock;
import com.yami.trading.bean.syspara.domain.Syspara;
import com.yami.trading.common.domain.Result;
@@ -17,6 +14,7 @@
import com.yami.trading.common.util.StringUtils;
import com.yami.trading.common.util.ThreadUtils;
import com.yami.trading.security.common.util.SecurityUtils;
+import com.yami.trading.service.CapitaltWalletService;
import com.yami.trading.service.RealNameAuthRecordService;
import com.yami.trading.service.SessionTokenService;
import com.yami.trading.service.WalletService;
@@ -64,6 +62,8 @@
RealNameAuthRecordService realNameAuthRecordService;
@Autowired
ItemService itemService;
+ @Autowired
+ CapitaltWalletService capitaltWalletService;
/**
* 兑换币 如果是使用usdt兑换其他币种,则直接执行正常买币open流程 如果是其他币种--》usdt 则是直接卖币流程
@@ -338,11 +338,12 @@
public Result openview() {
Map<String, Object> data = new HashMap<String, Object>();
String partyId = SecurityUtils.getUser().getUserId();
- Wallet wallet = walletService.saveWalletByPartyId(partyId);
+// Wallet wallet = walletService.saveWalletByPartyId(partyId);
+ CapitaltWallet userIdWallet = capitaltWalletService.getUserIdWallet(partyId);
// 账户剩余资金
DecimalFormat df = new DecimalFormat("#.##");
df.setRoundingMode(RoundingMode.FLOOR);// 向下取整
- data.put("volume", df.format(wallet.getMoney()));
+ data.put("volume", df.format(userIdWallet.getMoney()));
String session_token = sessionTokenService.savePut(partyId);
data.put("session_token", session_token);
data.put("fee", sysparaService.find("exchange_apply_order_buy_fee").getSvalue());
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/dto/OpenAction.java b/trading-order-admin/src/main/java/com/yami/trading/api/dto/OpenAction.java
index 535e3ee..07932ae 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/api/dto/OpenAction.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/dto/OpenAction.java
@@ -17,6 +17,11 @@
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class OpenAction {
+ /**
+ * 仓位类型:0:逐仓 1:全仓
+ */
+ private Integer locationType = 0;
+
@NotBlank
private String symbol;
/**
diff --git a/trading-order-admin/src/main/resources/application-local.yml b/trading-order-admin/src/main/resources/application-local.yml
index c445822..9e26538 100644
--- a/trading-order-admin/src/main/resources/application-local.yml
+++ b/trading-order-admin/src/main/resources/application-local.yml
@@ -1,5 +1,5 @@
server:
- port: 8085
+ port: 8086
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/trading_order?allowMultiQueries=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&zeroDateTimeBehavior=convertToNull&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
@@ -46,4 +46,4 @@
maxTotal: 50
host: 127.0.0.1
port: 6379
-# password: xJjSHKNYbJXzWTim
+# password: xJjSHKNYbJXzWTim
\ No newline at end of file
diff --git a/trading-order-admin/src/main/resources/config/system.properties b/trading-order-admin/src/main/resources/config/system.properties
index f28d9b2..b3bef0e 100644
--- a/trading-order-admin/src/main/resources/config/system.properties
+++ b/trading-order-admin/src/main/resources/config/system.properties
@@ -3,6 +3,9 @@
admin_url=https://127.0.0.1:8080/admin
web_url=http://127.0.0.1:8080/wap/
+http.server.host=D:/jystp/images/
+images.dir=/mydata/img/
+loca.images.dir=D:/testimg
email.host=smtp.gmail.com
email.username= test
email.password= test
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/contract/domain/ContractOrder.java b/trading-order-bean/src/main/java/com/yami/trading/bean/contract/domain/ContractOrder.java
index c7a844f..ff44aa4 100644
--- a/trading-order-bean/src/main/java/com/yami/trading/bean/contract/domain/ContractOrder.java
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/contract/domain/ContractOrder.java
@@ -133,6 +133,11 @@
private String orderPriceType;
+ /**
+ * 仓位类型:0:逐仓 1:全仓
+ */
+ private Integer locationType = 0;
+
public BigDecimal getAmountClose() {
if(amountClose == null){
amountClose = BigDecimal.ZERO;
@@ -178,25 +183,32 @@
}
public BigDecimal getChangeRatio() {
- if(amountClose == null){
- amountClose = BigDecimal.ZERO;
- }
- if(profit == null){
- profit = BigDecimal.ZERO;
- }
- if(deposit == null){
- deposit = BigDecimal.ZERO;
- }
- if(depositOpen == null){
- depositOpen = BigDecimal.ZERO;
- }
- if (STATE_SUBMITTED.equals(state)) {
- changeRatio = amountClose.add(profit).add(deposit).subtract(depositOpen).divide(depositOpen,10 , RoundingMode.HALF_UP);
- } else {
- changeRatio = amountClose.add(deposit).subtract(depositOpen).divide(depositOpen, 10 , RoundingMode.HALF_UP);
- }
+// if(amountClose == null){
+// amountClose = BigDecimal.ZERO;
+// }
+// if(profit == null){
+// profit = BigDecimal.ZERO;
+// }
+// if(deposit == null){
+// deposit = BigDecimal.ZERO;
+// }
+// if(depositOpen == null){
+// depositOpen = BigDecimal.ZERO;
+// }
+// if (STATE_SUBMITTED.equals(state)) {
+// changeRatio = amountClose.add(profit).add(deposit).subtract(depositOpen).divide(depositOpen,10 , RoundingMode.HALF_UP);
+// } else {
+// changeRatio = amountClose.add(deposit).subtract(depositOpen).divide(depositOpen, 10 , RoundingMode.HALF_UP);
+// }
+//
+// changeRatio = changeRatio.multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP);
+ // 计算收益率,指定除法时的精度
+ BigDecimal changeRatio = profit.divide(depositOpen, 10, BigDecimal.ROUND_DOWN) // 设置精度为10位
+ .multiply(new BigDecimal("100"));
- changeRatio = changeRatio.multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP);
+ // 保留两位小数
+ changeRatio = changeRatio.setScale(2, BigDecimal.ROUND_DOWN);
+
return changeRatio;
}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/finance/Finance.java b/trading-order-bean/src/main/java/com/yami/trading/bean/finance/Finance.java
new file mode 100644
index 0000000..5ecf3d7
--- /dev/null
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/finance/Finance.java
@@ -0,0 +1,106 @@
+package com.yami.trading.bean.finance;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+
+/**
+ * @program: trading-order-master
+ * @description: 理财
+ * @create: 2025-01-22 16:36
+ **/
+@EqualsAndHashCode(callSuper = false)
+@TableName("t_finance")
+@Data
+public class Finance {
+
+ @TableId(type = IdType.AUTO,value = "id")
+ private int id;
+
+ /**
+ * 产品名称
+ */
+ private String name;
+
+ /**
+ * 产品名称英文
+ */
+ private String name_en;
+
+ /**
+ * 产品名称繁体
+ */
+ private String name_cn;
+
+ /**
+ * 产品名称 韩语
+ */
+ private String name_kn;
+
+ /**
+ * 产品名称 日语
+ */
+ private String name_jn;
+
+ /**
+ * 产品图片
+ */
+ private String img;
+
+ /**
+ * 周期-天数
+ */
+ private int cycle;
+
+ /**
+ * 日利率最低(%)
+ */
+ private double daily_rate;
+
+ /**
+ * 日利率最高(%)
+ */
+ private double daily_rate_max;
+
+ /**
+ * 今日利率(%)
+ *
+ */
+ private double today_rate;
+
+ /**
+ * 违约结算比例(%)
+ */
+ private double default_ratio;
+
+ /**
+ * 投资金额区间(USDT)
+ */
+ private double investment_min;
+
+ /**
+ * 投资金额区间(USDT)
+ */
+ private double investment_max;
+
+ /**
+ * 状态。0 停用, 1 启用
+ */
+ private String state = "0";
+
+ /**
+ * 理财购买币种
+ */
+ private String buyCurrency = "usdt";
+
+ /**
+ * 理财购买币种
+ */
+ private String outputCurrency = "usdt";
+
+
+}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/finance/FinanceOrder.java b/trading-order-bean/src/main/java/com/yami/trading/bean/finance/FinanceOrder.java
new file mode 100644
index 0000000..0703eb2
--- /dev/null
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/finance/FinanceOrder.java
@@ -0,0 +1,149 @@
+package com.yami.trading.bean.finance;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * @program: trading-order-master
+ * @description: 理财订单
+ * @create: 2025-01-22 16:45
+ **/
+@EqualsAndHashCode(callSuper = false)
+@TableName("t_finance_order")
+@Data
+public class FinanceOrder {
+
+
+ @TableId(type = IdType.AUTO,value = "id")
+ private int id;
+
+ /**
+ * 用户ID
+ */
+ private int partyId;
+
+ /**
+ * 订单 号
+ */
+ private String order_no;
+
+ /**
+ * 理财产品名称
+ */
+ private String financeName;
+
+ /**
+ * 理财产品名称繁体
+ */
+ private String financeName_cn;
+
+ /**
+ * 理财产品名称英文
+ */
+ private String financeName_en;
+
+ /**
+ * 理财产品Id
+ */
+ private String financeId;
+
+ /**
+ * 金额
+ */
+ private double amount;
+
+ /**
+ * 买入时间
+ */
+ private Date create_time;
+
+ /**
+ * 起息时间 从买入时间第二天开始算
+ */
+ private Date earn_time;
+
+ /**
+ * 截止时间
+ */
+ private Date stop_time;
+
+ /**
+ * 赎回时间=截止时间+1天
+ */
+ private Date close_time;
+
+ /**
+ * 收益
+ */
+ private double profit;
+
+ /**
+ * 之前或累计收益
+ */
+ private double profit_before;
+
+ /**
+ * 状态。0.正常赎回, 1 托管中 ,2提前赎回 (违约)3.取消
+ */
+ private String state = "1";
+
+ /**
+ * 托管时间,周期
+ */
+ private int cycle;
+
+ /**
+ * 理财产品图片
+ */
+ private String img;
+
+ /**
+ * 剩余天数
+ */
+ private int days;
+
+ /**
+ * 赎回时间=截止时间+1天
+ */
+ private String close_timeStr;
+
+ /**
+ * 买入时间
+ */
+ private String create_timeStr;
+ /**
+ * 起息时间 从买入时间第二天开始算
+ */
+ private String earn_timeStr;
+
+ /**
+ * 截止时间
+ */
+ private String stop_timeStr;
+
+ /**
+ * 日利率(%)
+ */
+ private String daily_rate;
+ /**
+ * 预计收益
+ */
+ private double profit_may;
+
+ /**
+ * 理财购买币种
+ */
+ private String buyCurrency = "usdt";
+
+ /**
+ * 理财购买币种
+ */
+ private String outputCurrency = "usdt";
+
+}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/item/domain/Item.java b/trading-order-bean/src/main/java/com/yami/trading/bean/item/domain/Item.java
index 556dcfc..b916445 100644
--- a/trading-order-bean/src/main/java/com/yami/trading/bean/item/domain/Item.java
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/item/domain/Item.java
@@ -116,11 +116,11 @@
*/
private BigDecimal adjustmentValue;
/**
- * 每张金额
+ * 每张金额 合约下单一张等于=开仓价格*面值/杠杆
*/
private BigDecimal unitAmount;
/**
- * 每张手续费
+ * 手续费
*/
private BigDecimal unitFee;
/**
@@ -147,6 +147,10 @@
private String type;
private String category;
+ /**
+ * 面值:固定0.01 合约下单一张等于=开仓价格*面值/杠杆
+ */
+ private double faceValue = 0.01;
private String openCloseType;
private String fake;
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/model/CapitaltWallet.java b/trading-order-bean/src/main/java/com/yami/trading/bean/model/CapitaltWallet.java
new file mode 100644
index 0000000..b1c54c3
--- /dev/null
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/model/CapitaltWallet.java
@@ -0,0 +1,48 @@
+package com.yami.trading.bean.model;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
+import com.yami.trading.common.domain.BaseEntity;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+
+/**
+ * @program: trading-order-master
+ * @description: 合约账户
+ * @create: 2025-01-08 17:41
+ **/
+@Data
+@TableName("tz_capital_wallet")
+@Slf4j
+public class CapitaltWallet extends BaseEntity {
+
+ /**
+ * 关联 party entity
+ */
+ private String userId;
+ /**
+ * 现金
+ */
+ private BigDecimal money =new BigDecimal(0);
+
+
+ /**
+ * 锁定金额
+ */
+ private BigDecimal lockMoney =new BigDecimal(0);
+
+ /**
+ * 冻结金额
+ */
+ private BigDecimal freezeMoney =new BigDecimal(0);
+
+ @Version
+ private int version;
+
+ public void setMoney(BigDecimal money) {
+ this.money = money;
+ }
+
+}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/model/Miner.java b/trading-order-bean/src/main/java/com/yami/trading/bean/model/Miner.java
new file mode 100644
index 0000000..eb987fb
--- /dev/null
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/model/Miner.java
@@ -0,0 +1,155 @@
+package com.yami.trading.bean.model;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+/**
+ * 矿机
+ */
+@EqualsAndHashCode(callSuper = false)
+@TableName("t_miner")
+@Data
+public class Miner {
+
+ @TableId(type = IdType.AUTO,value = "id")
+ private int id;
+
+ /**
+ * 矿机名称(简体中文)
+ */
+ private String name;
+
+ /**
+ * 矿机名称(英文)
+ */
+ private String name_en;
+
+ /**
+ * 矿机名称(繁体)
+ */
+ private String name_cn;
+
+ /**
+ * 周期-天数(现做矿机等级判定)
+ */
+ private int cycle;
+
+ /**
+ * ----可解锁周期-- 截止后方可解锁 CYCLE_CLOSE
+ */
+ private int cycle_close;
+
+ /**
+ * 日利率(%)
+ */
+ private double daily_rate;
+
+ /**
+ * 展示日利率(%)
+ */
+ private double show_daily_rate;
+
+ /**
+ * 最低投资金额(USDT)
+ */
+ private double investment_min;
+
+ /**
+ * 最高投资金额(USDT)
+ */
+ private double investment_max;
+
+ /**
+ * 上下架。0 下架, 1 上架,
+ */
+ private String state = "0";
+
+ /**
+ * 是否自主购买 0需管理员手动增加,1可自行购买
+ */
+ private String on_sale = "0";
+
+ /**
+ * 是否是体验产品
+ */
+ private boolean test = false;
+
+ /**
+ * 适用算法
+ */
+ private String algorithm;
+
+ /**
+ * 算力
+ */
+ private double computing_power;
+
+ /**
+ * 算力单位
+ */
+ private String computing_power_unit;
+
+ /**
+ * 功耗
+ */
+ private double power;
+
+ /**
+ * 生产厂家
+ */
+ private String product_factory;
+
+ /**
+ * 外箱尺寸
+ */
+ private String product_size;
+
+ /**
+ * 整机重量
+ */
+ private double weight;
+
+ /**
+ * 工作温度区间(最小值)
+ */
+ private double work_temperature_min;
+
+ /**
+ * 工作温度区间(最大值)
+ */
+ private double work_temperature_max;
+
+ /**
+ * 工作湿度区间(最小值)
+ */
+ private double work_humidity_min;
+
+ /**
+ * 工作湿度区间(最大值)
+ */
+ private double work_humidity_max;
+
+ /**
+ * 网络连接
+ */
+ private String internet;
+
+ /**
+ * 基础计息金额
+ */
+ private double base_compute_amount;
+
+ /**
+ * 矿机购买币种
+ */
+ private String buyCurrency;
+
+ /**
+ * 矿机购买币种
+ */
+ private String outputCurrency;
+}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerOrder.java b/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerOrder.java
new file mode 100644
index 0000000..c0a55f5
--- /dev/null
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerOrder.java
@@ -0,0 +1,79 @@
+package com.yami.trading.bean.model;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@EqualsAndHashCode(callSuper = false)
+@TableName("t_miner_order")
+@Data
+public class MinerOrder{
+
+ @TableId(type = IdType.AUTO,value = "id")
+ private int id;
+
+ private Serializable partyId;
+
+ /**
+ * 订单 号
+ */
+ private String order_no;
+
+ /**
+ * 矿机产品Id
+ */
+ private String minerId;
+
+ /**
+ * 金额
+ */
+ private double amount;
+
+ /**
+ * 买入时间
+ */
+ private Date create_time;
+
+ /**
+ * 起息时间 从买入时间第二天开始算
+ */
+ private Date earn_time;
+
+ /**
+ * 截止时间
+ */
+ private Date stop_time;
+
+ /**
+ * 累计收益
+ */
+ private double profit;
+
+ /**
+ * 状态。0.正常赎回, 1 托管中 ,2提前赎回 (违约)3.取消
+ */
+ private String state = "1";
+ /**
+ * 上次结息日期纪录,(如遇服务中途停止,可根据该字段判定是否需要重新计算)
+ */
+ private Date compute_day;
+ /**
+ * 赎回时间
+ */
+ private Date close_time;
+
+ /**
+ * 是否首次购买: 1:首次购买,0不是首次
+ */
+ private String first_buy;
+
+ /**
+ * 基础计息金额
+ */
+ private double base_compute_amount;
+}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerPara.java b/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerPara.java
new file mode 100644
index 0000000..40b6b3a
--- /dev/null
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/model/MinerPara.java
@@ -0,0 +1,35 @@
+package com.yami.trading.bean.model;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+/**
+ * 矿机配置参数
+ */
+@EqualsAndHashCode(callSuper = false)
+@TableName("t_miner_para")
+@Data
+public class MinerPara{
+
+ @TableId(type = IdType.AUTO,value = "id")
+ private int id;
+
+ /**
+ * 矿机id
+ */
+ private String miner_id;
+
+ /**
+ * 购买周期
+ */
+ private int cycle;
+
+ /**
+ * 购买价格
+ */
+ private double amount;
+}
diff --git a/trading-order-bean/src/main/java/com/yami/trading/bean/vo/FinanceVo.java b/trading-order-bean/src/main/java/com/yami/trading/bean/vo/FinanceVo.java
new file mode 100644
index 0000000..e08cca3
--- /dev/null
+++ b/trading-order-bean/src/main/java/com/yami/trading/bean/vo/FinanceVo.java
@@ -0,0 +1,113 @@
+package com.yami.trading.bean.vo;
+
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @program: trading-order-master
+ * @description: 理财
+ * @create: 2025-01-22 17:15
+ **/
+@Data
+@ApiModel
+public class FinanceVo {
+
+ /**
+ * 产品名称
+ */
+ @NotBlank(message = "产品名称不能为空")
+ private String name;
+
+ /**
+ * 产品名称英文
+ */
+ @NotBlank(message = "产品名称英文不能为空")
+ private String name_en;
+
+ /**
+ * 产品名称繁体
+ */
+ @NotBlank(message = "产品名称繁体不能为空")
+ private String name_cn;
+
+ /**
+ * 产品名称 韩语
+ */
+ @NotBlank(message = "产品名称韩语不能为空")
+ private String name_kn;
+
+ /**
+ * 产品名称 日语
+ */
+ @NotBlank(message = "产品名称日语不能为空")
+ private String name_jn;
+
+ /**
+ * 产品图片
+ */
+ @NotBlank(message = "产品图片不能为空")
+ private String img;
+
+ /**
+ * 周期-天数
+ */
+ @NotNull(message = "周期不能为空")
+ private Integer cycle;
+
+ /**
+ * 日利率最低(%)
+ */
+ @NotNull(message = "日利率最低不能为空")
+ private Double daily_rate;
+
+ /**
+ * 日利率最高(%)
+ */
+ @NotNull(message = "日利率最高不能为空")
+ private Double daily_rate_max;
+
+ /**
+ * 今日利率(%)
+ */
+ @NotNull(message = "今日利率不能为空")
+ private Double today_rate;
+
+ /**
+ * 违约结算比例(%)
+ */
+ @NotNull(message = "违约结算比例不能为空")
+ private Double default_ratio;
+
+ /**
+ * 投资金额区间(USDT)
+ */
+ @NotNull(message = "投资金额最小值不能为空")
+ private Double investment_min;
+
+ /**
+ * 投资金额区间(USDT)
+ */
+ @NotNull(message = "投资金额最大值不能为空")
+ private Double investment_max;
+
+ /**
+ * 状态。0 停用, 1 启用
+ */
+ @NotBlank(message = "状态不能为空")
+ private String state;
+
+ /**
+ * 理财购买币种
+ */
+ @NotBlank(message = "理财购买币种不能为空")
+ private String buyCurrency;
+
+ /**
+ * 理财购买币种
+ */
+ @NotBlank(message = "理财输出币种不能为空")
+ private String outputCurrency;
+}
diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/internal/AdjustmentValueServiceImpl.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/internal/AdjustmentValueServiceImpl.java
index 4d8b6e5..9f6f207 100644
--- a/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/internal/AdjustmentValueServiceImpl.java
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/data/internal/AdjustmentValueServiceImpl.java
@@ -34,9 +34,9 @@
Realtime realtime = dataService.realtime(symbol).get(0);
BigDecimal new_price = realtime.getClose();
BigDecimal plus = value.abs();
- if (plus.divide(new_price, 2, RoundingMode.HALF_UP).compareTo(new BigDecimal("0.1")) > 0) {
- throw new YamiShopBindException("调整偏差过大,超过10%");
- }
+// if (plus.divide(new_price, 2, RoundingMode.HALF_UP).compareTo(new BigDecimal("0.1")) > 0) {
+// throw new YamiShopBindException("调整偏差过大,超过10%");
+// }
if (second <= 0) {
/**
diff --git a/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/HobiDataServiceImpl.java b/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/HobiDataServiceImpl.java
index 51cde5f..9aa50b4 100644
--- a/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/HobiDataServiceImpl.java
+++ b/trading-order-huobi/src/main/java/com.yami.trading.huobi/hobi/internal/HobiDataServiceImpl.java
@@ -229,36 +229,38 @@
if ((depth == null || item.getAdjustmentValue() == null || item.getAdjustmentValue().intValue() == 0) && (item.getMultiple().intValue() == 0 || item.getMultiple().intValue() == 1)) {
return depth;
}
+ if(CollectionUtil.isNotEmpty(depth.getAsks()) ){
+ List<DepthEntry> asks = depth.getAsks();
+ for (int i = 0; i < asks.size(); i++) {
+ DepthEntry depthEntry = asks.get(i);
- List<DepthEntry> asks = depth.getAsks();
- for (int i = 0; i < asks.size(); i++) {
- DepthEntry depthEntry = asks.get(i);
-
- /**
- * 调整交易量倍数和 行情值
- */
- if (item.getMultiple().doubleValue() > 0) {
- depthEntry.setAmount(Arith.mul(depthEntry.getAmount(), item.getMultiple().doubleValue()));
- } else {
- depthEntry.setAmount(depthEntry.getAmount());
+ /**
+ * 调整交易量倍数和 行情值
+ */
+ if (item.getMultiple().doubleValue() > 0) {
+ depthEntry.setAmount(Arith.mul(depthEntry.getAmount(), item.getMultiple().doubleValue()));
+ } else {
+ depthEntry.setAmount(depthEntry.getAmount());
+ }
+ depthEntry.setPrice(Arith.add(depthEntry.getPrice(), item.getAdjustmentValue().doubleValue()));
}
- depthEntry.setPrice(Arith.add(depthEntry.getPrice(), item.getAdjustmentValue().doubleValue()));
}
- List<DepthEntry> bids = depth.getBids();
- for (int i = 0; i < bids.size(); i++) {
- DepthEntry depthEntry = bids.get(i);
- /**
- * 调整交易量倍数和 行情值
- */
- if (item.getMultiple().doubleValue() > 0) {
- depthEntry.setAmount(Arith.mul(depthEntry.getAmount(), item.getMultiple().doubleValue()));
- } else {
- depthEntry.setAmount(depthEntry.getAmount());
+ if(CollectionUtil.isNotEmpty(depth.getBids())){
+ List<DepthEntry> bids = depth.getBids();
+ for (int i = 0; i < bids.size(); i++) {
+ DepthEntry depthEntry = bids.get(i);
+ /**
+ * 调整交易量倍数和 行情值
+ */
+ if (item.getMultiple().doubleValue() > 0) {
+ depthEntry.setAmount(Arith.mul(depthEntry.getAmount(), item.getMultiple().doubleValue()));
+ } else {
+ depthEntry.setAmount(depthEntry.getAmount());
+ }
+ depthEntry.setPrice(Arith.add(depthEntry.getPrice(), item.getAdjustmentValue().doubleValue()));
}
- depthEntry.setPrice(Arith.add(depthEntry.getPrice(), item.getAdjustmentValue().doubleValue()));
}
-
return depth;
}
@@ -372,19 +374,21 @@
if ((trade == null || item.getAdjustmentValue() == null || item.getAdjustmentValue().doubleValue() == 0) && (item.getMultiple().doubleValue() == 0 || item.getMultiple().doubleValue() == 1)) {
return trade;
}
- List<TradeEntry> data = trade.getData();
- for (int i = 0; i < data.size(); i++) {
- TradeEntry tradeEntry = data.get(i);
+ if(CollectionUtil.isNotEmpty(trade.getData())){
+ List<TradeEntry> data = trade.getData();
+ for (int i = 0; i < data.size(); i++) {
+ TradeEntry tradeEntry = data.get(i);
- /**
- * 调整交易量倍数和 行情值
- */
- if (item.getMultiple().doubleValue() > 0) {
- tradeEntry.setAmount(Arith.mul(tradeEntry.getAmount(), item.getMultiple().doubleValue()));
- } else {
- tradeEntry.setAmount(tradeEntry.getAmount());
+ /**
+ * 调整交易量倍数和 行情值
+ */
+ if (item.getMultiple().doubleValue() > 0) {
+ tradeEntry.setAmount(Arith.mul(tradeEntry.getAmount(), item.getMultiple().doubleValue()));
+ } else {
+ tradeEntry.setAmount(tradeEntry.getAmount());
+ }
+ tradeEntry.setPrice(Arith.add(tradeEntry.getPrice(), item.getAdjustmentValue().doubleValue()));
}
- tradeEntry.setPrice(Arith.add(tradeEntry.getPrice(), item.getAdjustmentValue().doubleValue()));
}
return trade;
diff --git a/trading-order-security-common/src/main/java/com/yami/trading/security/common/config/CorsConfig.java b/trading-order-security-common/src/main/java/com/yami/trading/security/common/config/CorsConfig.java
index f0ef448..098c1cd 100644
--- a/trading-order-security-common/src/main/java/com/yami/trading/security/common/config/CorsConfig.java
+++ b/trading-order-security-common/src/main/java/com/yami/trading/security/common/config/CorsConfig.java
@@ -5,19 +5,25 @@
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @author yami
*/
@Configuration
-public class CorsConfig {
+public class CorsConfig implements WebMvcConfigurer {
- /**
- * 修改为添加而不是设置,* 最好生产环境改为实际的需要, 这里可以用多个add配置多个域名
- * configuration.addAllowedOrigin("http://localhost:8080");
- * configuration.addAllowedOrigin("http://192.168.1.6:8080");
- * @return CorsConfigurationSource
- */
+ @Override
+ public void addCorsMappings(CorsRegistry registry) {
+ registry.addMapping("/**")
+ .allowedOriginPatterns("*") // 使用 * 允许所有来源
+ .allowCredentials(true) // 允许凭证
+ .allowedMethods("GET", "POST", "PUT", "DELETE") // 指定允许的 HTTP 方法
+ .allowedHeaders("Content-Type", "Authorization") // 指定允许的头部
+ .maxAge(3600); // 可选,指定预检请求缓存时间
+ }
+
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
diff --git a/trading-order-service/src/main/java/com/yami/trading/dao/CapitaltWalletMapper.java b/trading-order-service/src/main/java/com/yami/trading/dao/CapitaltWalletMapper.java
new file mode 100644
index 0000000..ac977c2
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/dao/CapitaltWalletMapper.java
@@ -0,0 +1,9 @@
+package com.yami.trading.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yami.trading.bean.model.CapitaltWallet;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface CapitaltWalletMapper extends BaseMapper<CapitaltWallet> {
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/dao/finance/FinanceMapper.java b/trading-order-service/src/main/java/com/yami/trading/dao/finance/FinanceMapper.java
new file mode 100644
index 0000000..8bbbb42
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/dao/finance/FinanceMapper.java
@@ -0,0 +1,15 @@
+package com.yami.trading.dao.finance;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yami.trading.bean.finance.Finance;
+import com.yami.trading.bean.item.domain.Item;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @program: trading-order-master
+ * @description: 理财
+ * @create: 2025-01-22 17:18
+ **/
+@Mapper
+public interface FinanceMapper extends BaseMapper<Finance> {
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/CapitaltWalletService.java b/trading-order-service/src/main/java/com/yami/trading/service/CapitaltWalletService.java
new file mode 100644
index 0000000..d4ce451
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/CapitaltWalletService.java
@@ -0,0 +1,16 @@
+package com.yami.trading.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yami.trading.bean.model.CapitaltWallet;
+import com.yami.trading.common.domain.Result;
+
+import java.math.BigDecimal;
+
+public interface CapitaltWalletService extends IService<CapitaltWallet> {
+
+ CapitaltWallet getUserIdWallet(String userId);
+
+ Result updateWallt(String userId,String deductAccount, String receiveAccount, BigDecimal moneyRevise);
+
+ void update(CapitaltWallet capitaltWallet, double amount1);
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/StrongLevelCalculationService.java b/trading-order-service/src/main/java/com/yami/trading/service/StrongLevelCalculationService.java
new file mode 100644
index 0000000..d8f9155
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/StrongLevelCalculationService.java
@@ -0,0 +1,15 @@
+package com.yami.trading.service;
+
+/**
+ * @program: trading-order-master
+ * @description: 强平价格计算
+ * @create: 2025-01-15 15:56
+ **/
+public interface StrongLevelCalculationService {
+ public double calculateLiquidationPrice ( double marginBalance, double faceValue, double contractQuantity,
+ double openingPrice, double maintenanceMarginRate, double feeRate);
+
+
+ public double calculateEmptyLiquidationPrice ( double marginBalance, double faceValue, double contractQuantity,
+ double openingPrice, double maintenanceMarginRate, double feeRate);
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractApplyOrderService.java b/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractApplyOrderService.java
index 9c4e34c..31fadb1 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractApplyOrderService.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractApplyOrderService.java
@@ -38,6 +38,7 @@
import org.springframework.web.bind.annotation.RequestParam;
import java.math.BigDecimal;
+import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -145,10 +146,16 @@
if(realtime.size()>=1){
map.put("mark_price", realtime.get(0).getClose());
}
- map.put("amount", order.getVolume().multiply(order.getUnitAmount()));
- map.put("amount_open", order.getVolumeOpen().multiply(order.getUnitAmount()));
- map.put("fee", order.getFee());
- map.put("deposit", order.getDeposit());
+ map.put("amount", (order.getVolume() != null && order.getUnitAmount() != null)
+ ? order.getVolume().multiply(order.getUnitAmount())
+ : BigDecimal.ZERO);
+
+ map.put("amount_open", (order.getVolumeOpen() != null && order.getUnitAmount() != null)
+ ? order.getVolumeOpen().multiply(order.getUnitAmount())
+ : BigDecimal.ZERO);
+
+ map.put("fee", order.getFee() != null ? order.getFee() : BigDecimal.ZERO);
+ map.put("deposit", order.getDeposit() != null ? order.getDeposit() : BigDecimal.ZERO);
data.add(map);
}
return data;
@@ -218,34 +225,48 @@
order.setOrderNo(DateUtil.getToday("yyMMddHHmmss") + RandomUtil.getRandomNum(8));
- order.setUnitAmount(item.getUnitAmount());
- order.setFee(item.getUnitFee().multiply(order.getVolume()));
- order.setDeposit(item.getUnitAmount().multiply(order.getVolume()));
+
+ 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);
+
if (order.getLeverRate() != null) {
/**
* 加上杠杆
*/
- order.setVolume(order.getVolume().multiply(order.getLeverRate()));
- order.setFee(order.getFee().multiply(order.getLeverRate()));
+ // 设置订单数量
+ 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.getVolume());
+ order.setVolumeOpen(order.getVolumeOpen());
Wallet wallet = this.walletService.findByUserId(order.getPartyId());
BigDecimal amountBefore = wallet.getMoney();
BigDecimal totalAmountCost = order.getDeposit().add(order.getFee());
+
if (amountBefore.compareTo(totalAmountCost) < 0) {
throw new YamiShopBindException("余额不足");
}
- 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() + "]"
- );
- save(order);
+ //如果是限价单先扣钱
+ if(order.getOrderPriceType().equals("limit")){
+ 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() + "]"
+ );
+ }
+ save(order);
}
/**
@@ -297,11 +318,13 @@
return;
}
order.setState("canceled");
- walletService.updateMoney(order.getSymbol(),
- order.getPartyId(),
- order.getDeposit().add(order.getFee()),
- BigDecimal.ZERO,
- Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT, Constants.MONEYLOG_CONTENT_CONTRACT_CONCEL, "撤单,订单号[" + order.getOrderNo() + "]");
+ if(order.getOrderPriceType().equals("limit")){
+ walletService.updateMoney(order.getSymbol(),
+ order.getPartyId(),
+ order.getDeposit().add(order.getFee()),
+ BigDecimal.ZERO,
+ Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT, Constants.MONEYLOG_CONTENT_CONTRACT_CONCEL, "撤单,订单号[" + order.getOrderNo() + "]");
+ }
updateById(order);
}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java
index 54a2976..d7bbba7 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderCalculationServiceImpl.java
@@ -1,9 +1,12 @@
package com.yami.trading.service.contract;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.trading.bean.contract.domain.ContractOrder;
import com.yami.trading.bean.data.domain.Realtime;
+import com.yami.trading.bean.item.domain.Item;
import com.yami.trading.bean.model.Wallet;
import com.yami.trading.common.util.ThreadUtils;
+import com.yami.trading.service.StrongLevelCalculationService;
import com.yami.trading.service.WalletService;
import com.yami.trading.service.data.DataService;
import com.yami.trading.service.item.ItemService;
@@ -17,6 +20,7 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
+import java.util.Map;
@Slf4j
@Service
@@ -39,6 +43,10 @@
private DataService dataService;
@Autowired
private WalletService walletService;
+
+ @Autowired
+ private StrongLevelCalculationService strongLevelCalculationService;
+
private SysparaService sysparaService;
public void saveCalculation(String order_no, List<ContractOrder> partyContractOrders) {
@@ -92,7 +100,15 @@
}
/**
- * 盈亏计算
+ * 盈亏计算 收益=(平仓均价-开仓均价)*面值*张数
+ *
+ * USDT保证金合约做多:收益=(平仓均价-开仓均价)*面值*张数
+ * USDT保证金合约做空:收益=(开仓均价-平仓均价)*面值*张数
+ * 以BTC为例,BTC一张合约面值为0.01BTC,在价格19000的时候,开了10张多单。当价格涨到20000的时候,小明的收益=(20000-19000)*0.01*10=100USDT
+ * 币本位合约:
+ * 做多:收益=面值*张数/开仓价-面值*张数/平仓价
+ * 做空:收益=面值*张数/平仓价-面值*张数/开仓价
+ * 以BTC为例,BTC一张合约面值为100美元,小明在价格20000的时候,开了5张空单。当价格下跌到19000的时候,小明的收益=100*5/19000-100*5/20000=0.
*
* @param profit_loss profit 盈 loss亏
* @param currentPrice 当前点位
@@ -101,19 +117,77 @@
/**
* 偏差点位
*/
- BigDecimal point = currentPrice.subtract(order.getTradeAvgPrice()).abs().divide(order.getPips(), 10, RoundingMode.HALF_UP);
+ BigDecimal point = currentPrice.subtract(order.getTradeAvgPrice());
/*
* 根据偏 差点数和手数算出盈亏金额
*/
- BigDecimal amount = order.getPipsAmount().multiply(point).multiply(order.getVolume());
+ BigDecimal amount = point.multiply(new BigDecimal("0.01")).multiply(order.getVolumeOpen()).setScale(4, BigDecimal.ROUND_DOWN);;
- if ("profit".equals(profit_loss)) {
- /**
- * 盈 正数
- */
- order.setProfit(amount);
- } else if ("loss".equals(profit_loss)) {
- order.setProfit(amount.negate());
+ Item item = itemService.findBySymbol(order.getSymbol());
+
+// if ("profit".equals(profit_loss)) {
+// /**
+// * 盈 正数
+// */
+// order.setProfit(amount);
+// } else if ("loss".equals(profit_loss)) {
+// order.setProfit(amount);
+//
+// }
+
+ order.setProfit(amount);
+
+ double faceValue = 0.01; // 合约面值(固定面值不能调整)
+ double maintenanceMarginRate = 0.004; // 维持保证金率(固定不变)
+
+
+ /**
+ * 全仓收益加入保证金计算
+ */
+ BigDecimal earnings;
+
+ if (order.getLocationType() == 1) {
+ earnings = BigDecimal.ZERO;
+
+ // 统计非当前订单的其他收益
+ List<ContractOrder> list = contractOrderService.list(new LambdaQueryWrapper<>(ContractOrder.class)
+ .eq(ContractOrder::getState, ContractOrder.STATE_SUBMITTED)
+ .eq(ContractOrder::getPartyId, order.getPartyId())
+ .ne(ContractOrder::getOrderNo, order.getOrderNo())
+ );
+
+ // 提前计算 currentPrice 与 order.getTradeAvgPrice() 的差值,避免重复计算
+ BigDecimal priceDifference = currentPrice.subtract(order.getTradeAvgPrice());
+
+ // 计算所有订单的收益
+ for (ContractOrder contractOrder : list) {
+ BigDecimal profit = priceDifference
+ .multiply(new BigDecimal("0.01"))
+ .multiply(contractOrder.getVolumeOpen())
+ .setScale(4, RoundingMode.DOWN);
+
+ earnings = earnings.add(profit); // 累加收益
+ }
+
+ // 获取当前账户余额并加到收益中
+ Map<String, Object> moneyAll = walletService.getMoneyAll(order.getPartyId());
+ earnings = earnings.add(new BigDecimal(moneyAll.get("money_all_coin").toString()));
+
+ } else {
+ // 如果不符合条件,直接使用 order.getDepositOpen() 作为收益
+ earnings = order.getDepositOpen();
+ }
+
+ if(ContractOrder.DIRECTION_BUY.equals(order.getDirection())){
+ double forceClosePrice = strongLevelCalculationService.calculateLiquidationPrice(earnings.doubleValue(),
+ faceValue, order.getVolumeOpen().doubleValue(), order.getTradeAvgPrice().doubleValue()
+ , maintenanceMarginRate, item.getUnitFee().doubleValue());
+ order.setForceClosePrice(BigDecimal.valueOf(forceClosePrice).toString());
+ }else{
+ double forceClosePrice = strongLevelCalculationService.calculateLiquidationPrice(earnings.doubleValue(),
+ faceValue, order.getVolumeOpen().doubleValue(), order.getTradeAvgPrice().doubleValue()
+ , maintenanceMarginRate, item.getUnitFee().doubleValue());
+ order.setForceClosePrice(BigDecimal.valueOf(forceClosePrice).toString());
}
/**
* 多次平仓价格不对,后续修
@@ -130,7 +204,7 @@
* 买涨
*/
if (currentPrice.compareTo(profitStop) >= 0) {
- this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo());
+ this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo(),null);
return;
}
} else if (profitStop != null && profitStop.compareTo(BigDecimal.ZERO) > 0
@@ -139,7 +213,7 @@
* 买跌
*/
if (currentPrice.compareTo(profitStop) <= 0) {
- this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo());
+ this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo(),null);
return;
}
}
@@ -154,7 +228,7 @@
* 买涨
*/
if (currentPrice.compareTo(loss_stop) <= 0) {
- this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo());
+ this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo(),null);
return;
}
@@ -164,93 +238,45 @@
*/
if (currentPrice.compareTo(loss_stop) >= 0) {
- this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo());
+ this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo(),null);
return;
}
}
- if (order_close_line_type == 1) {
- /**
- * 收益
- */
- BigDecimal profit = BigDecimal.ZERO;
-
- List<ContractOrder> list = partyContractOrders;
- for (int i = 0; i < list.size(); i++) {
- ContractOrder close_line = list.get(i);
- profit = profit.add(close_line.getProfit()).add(close_line.getDeposit());
- }
+ /**
+ * 强平计算
+ */
+ //判断是全仓还是逐仓
+ if (order.getLocationType() == 1) {
+// /**
+// * 收益
+// */
+// BigDecimal profit = BigDecimal.ZERO;
+//
+// List<ContractOrder> list = partyContractOrders;
+// for (int i = 0; i < list.size(); i++) {
+// ContractOrder close_line = list.get(i);
+// profit = profit.add(close_line.getProfit()).add(close_line.getDeposit());
+// }
- Wallet wallet = this.walletService.findByUserId(order.getPartyId().toString());
- // 计算所有除自己以外的profit
- BigDecimal profitExptThis = profit.subtract(order.getProfit()).subtract(order.getDeposit());
- /**
- * profitAll+wallet<=0
- * profitAll<=wallet 强平
- * p1 +E (p2~pn) <=wallet
- * (currentPrice-tradavg)*pipAmount*volume/pips + depost1 <=wallet-E(p2~pn)
- */
- BigDecimal left = wallet.getMoney().negate().subtract(profitExptThis).subtract(order.getDeposit());
- BigDecimal overLine = (left.multiply(order.getPips()).divide(order.getPipsAmount(), 10, RoundingMode.HALF_UP)
- .divide(order.getVolume(), 10, RoundingMode.HALF_UP));
- Integer decimal = itemService.getDecimal(order.getSymbol());
- BigDecimal forceClose = BigDecimal.ZERO;
- // 买多,从买价跌多少
- if (order.getDirection().equalsIgnoreCase(ContractOrder.DIRECTION_BUY)) {
- forceClose = order.getTradeAvgPrice().add(overLine).setScale(decimal, RoundingMode.HALF_UP);
- //买跌,涨到多少
- } else {
- forceClose = order.getTradeAvgPrice().subtract(overLine).setScale(decimal, RoundingMode.HALF_UP);
- }
- if (forceClose.compareTo(BigDecimal.ZERO) < 0) {
- forceClose = BigDecimal.ZERO;
- }
- order.setForceClosePrice(forceClose.toPlainString());
+// Wallet wallet = this.walletService.findByUserId(order.getPartyId().toString());
this.contractOrderService.updateByIdBuffer(order);
- if (profit.add(wallet.getMoney()).compareTo(BigDecimal.ZERO) <= 0) {
+// if (profit.add(wallet.getMoney()).compareTo(BigDecimal.ZERO) <= 0) {
+ if (currentPrice.toString().compareTo(order.getForceClosePrice()) <= 0) {//达到强平价
/**
* 触发全仓强平
*/
- this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo());
- ThreadUtils.sleep(100);
- for (int i = 0; i < list.size(); i++) {
- ContractOrder close_line = list.get(i);
- if (!order.getOrderNo().equals(close_line.getOrderNo())) {
- try {
- if (ContractLock.add(close_line.getOrderNo())) {
- this.contractOrderService.saveClose(close_line.getPartyId().toString(),
- close_line.getOrderNo());
- }
- } catch (Exception e) {
- log.error("error:", e);
- } finally {
- ContractLock.remove(close_line.getOrderNo());
- }
-
- }
- }
+ this.contractOrderService.allClose(order.getPartyId());
}
} else {
- BigDecimal divide = order.getDeposit().divide(order.getProfit().abs(), 10, RoundingMode.HALF_UP);
- if (order.getProfit().compareTo(BigDecimal.ZERO) < 0 && divide.compareTo(order_close_line.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP)) <= 0) {
- /**
- * 低于系统默认平仓线,进行强平
- */
- this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo());
- return;
+ if (currentPrice.toString().compareTo(order.getForceClosePrice()) <= 0) {//达到强平价
+ this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrderNo(),"强平");
}
}
}
-
-// @Override
-// public void afterPropertiesSet() throws Exception {
-// order_close_line = this.sysparaService.find("order_close_line").getDouble();
-// order_close_line_type = this.sysparaService.find("order_close_line_type").getInteger();
-//
-// }
public void setDataService(DataService dataService) {
this.dataService = dataService;
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderService.java b/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderService.java
index 3a38af1..6c6d187 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderService.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/contract/ContractOrderService.java
@@ -3,6 +3,7 @@
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -19,10 +20,12 @@
import com.yami.trading.common.constants.Constants;
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.service.StrongLevelCalculationService;
import com.yami.trading.service.data.DataService;
import com.yami.trading.service.system.TipService;
import com.yami.trading.service.user.UserDataService;
@@ -45,6 +48,7 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
@@ -92,6 +96,9 @@
@Lazy
private ContractApplyOrderService contractApplyOrderService;
+ @Autowired
+ private StrongLevelCalculationService strongLevelCalculationService;
+
public IPage<ContractOrderDTO> listRecord(Page page, ContractOrderQuery query) {
return baseMapper.listRecord(page, query);
}
@@ -127,7 +134,7 @@
public List<ContractOrder> findSubmitted(String partyId, String symbol, String direction, String startTime, String endTime, String symbolType) {
QueryWrapper<ContractOrder> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(StrUtil.isNotBlank(partyId), "party_id", partyId);
- queryWrapper.eq(StrUtil.isNotBlank(symbol), "symbol", symbol);
+// queryWrapper.eq(StrUtil.isNotBlank(symbol), "symbol", symbol);
queryWrapper.eq(StrUtil.isNotBlank(direction), "direction", direction);
queryWrapper.eq("state", "submitted");
List<String> symbols = itemService.findByType(symbolType).stream().map(Item::getSymbol).collect(Collectors.toList());
@@ -218,7 +225,7 @@
public List<Map<String, Object>> getPaged(int pageNo, int pageSize, String partyId, String symbol, String type, String startTime, String endTime, String symbolType) {
QueryWrapper<ContractOrder> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(StrUtil.isNotBlank(partyId), "party_id", partyId);
- queryWrapper.eq(StrUtil.isNotBlank(symbol), "symbol", symbol);
+// queryWrapper.eq(StrUtil.isNotBlank(symbol), "symbol", symbol);
if ("orders".equals(type)) {
queryWrapper.eq("state", "submitted");
} else if ("hisorders".equals(type)) {
@@ -243,61 +250,129 @@
/**
* 平仓,按订单进行平仓
*/
- public ContractOrder saveClose(String partyId, String orderNo) {
+ private final Object lock = new Object();
+
+ @Transactional
+ public ContractOrder saveClose(String partyId, String orderNo,String describe) {
/*
* 平仓
*/
- ContractOrder order = this.findByOrderNo(orderNo);
- if (order == null || !ContractOrder.STATE_SUBMITTED.equals(order.getState())
- || !partyId.equals(order.getPartyId()) || order.getVolume().compareTo(BigDecimal.ZERO) <= 0) {
+ synchronized (lock) {
+ ContractOrder order = this.findByOrderNo(orderNo);
+ if (order == null || !ContractOrder.STATE_SUBMITTED.equals(order.getState())
+ || !partyId.equals(order.getPartyId()) || order.getVolume().compareTo(BigDecimal.ZERO) <= 0) {
+ /**
+ * 状态已改变,退出处理
+ */
+ return null;
+ }
+
/**
- * 状态已改变,退出处理
+ * 收益
*/
- return null;
+ BigDecimal volume = order.getVolume();
+ BigDecimal profit = settle(order, order.getVolume());
+
+ Wallet wallet = walletService.findByUserId(order.getPartyId());
+
+ if (wallet.getMoney().add(profit).compareTo(BigDecimal.ZERO) < 0) {
+ // 如果结果是负数,就归零
+ if (wallet.getMoney().compareTo(BigDecimal.ZERO) < 0) {
+ profit = BigDecimal.ZERO;
+ }
+ }
+
+ walletService.updateMoney(order.getSymbol(), partyId, profit, BigDecimal.ZERO,
+ Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT, Constants.MONEYLOG_CONTENT_CONTRACT_CLOSE, describe+"平仓,平仓合约数[" + volume + "],订单号[" + order.getOrderNo() + "]");
+ order.setState(ContractOrder.STATE_CREATED);
+ order.setVolume(BigDecimal.ZERO);
+ order.setDeposit(BigDecimal.ZERO);
+ order.setCloseTime(DateUtil.currentSeconds());
+ order.setCloseTimeTs(DateUtil.currentSeconds());
+ update(order);
+
+ /**
+ * 合约产品平仓后添加当前流水setWithdraw_limit_now_amount
+ */
+ User party = userService.getById(order.getPartyId());
+ party.setWithdrawLimitNowAmount(party.getWithdrawLimitNowAmount().add(order.getDepositOpen()));
+ userService.updateById(party);
+ if (ObjectUtils.isEmpty(order.getCloseAvgPrice())) {
+ order.setCloseAvgPrice(BigDecimal.ZERO);
+ }
+ return order;
}
+ }
- /**
- * 收益
- */
- BigDecimal volume = order.getVolume();
- BigDecimal profit = settle(order, order.getVolume());
-// if (profit > 0) {
- Wallet wallet = walletService.findByUserId(order.getPartyId());
- BigDecimal amount_before = wallet.getMoney();
+ /**
+ * 全仓强平
+ */
+ private final Object allCloseLock = new Object();
-// wallet.setMoney(Arith.add(wallet.getMoney(), profit));
- if (wallet.getMoney().add(profit).compareTo(BigDecimal.ZERO) < 0) {
- profit = wallet.getMoney().negate();
+ @Transactional
+ public void allClose(String partyId) {
+ synchronized (allCloseLock) {
+ /*
+ * 平仓
+ */
+ //所有订单
+ List<ContractOrder> list = list(new LambdaQueryWrapper<>(ContractOrder.class)
+ .eq(ContractOrder::getState, ContractOrder.STATE_SUBMITTED)
+ .eq(ContractOrder::getPartyId, partyId)
+ );
+ //计算所有亏损
+ BigDecimal finalProfit = BigDecimal.ZERO; // 初始化为 0
+ String symbol = null;
+ String orderNo = null;
+ String volume = null;
+ for (ContractOrder order : list) {
+ /**
+ * 计算收益
+ */
+ BigDecimal earnings = settle(order, order.getVolume());
+ finalProfit = finalProfit.add(earnings);
+
+
+ order.setState(ContractOrder.STATE_CREATED);
+ order.setVolume(BigDecimal.ZERO);
+ order.setDeposit(BigDecimal.ZERO);
+ order.setCloseTime(DateUtil.currentSeconds());
+ order.setCloseTimeTs(DateUtil.currentSeconds());
+ update(order);
+
+ /**
+ * 合约产品平仓后添加当前流水setWithdraw_limit_now_amount
+ */
+ User party = userService.getById(order.getPartyId());
+ party.setWithdrawLimitNowAmount(party.getWithdrawLimitNowAmount().add(order.getDepositOpen()));
+ userService.updateById(party);
+ if (ObjectUtils.isEmpty(order.getCloseAvgPrice())) {
+ order.setCloseAvgPrice(BigDecimal.ZERO);
+ }
+
+ if (StringUtils.isNotEmpty(symbol)) {
+ symbol += "," + order.getSymbol();
+ } else {
+ symbol = order.getSymbol();
+ }
+
+ if (StringUtils.isNotEmpty(orderNo)) {
+ orderNo += "," + order.getOrderNo();
+ } else {
+ orderNo = order.getOrderNo();
+ }
+
+ if (StringUtils.isNotEmpty(volume)) {
+ volume += "," + "订单号:" + order.getOrderNo() + "数量:" + order.getVolumeOpen();
+ } else {
+ volume = "订单号:" + order.getOrderNo() + "数量:" + order.getVolumeOpen();
+ }
+
+ }
+ walletService.updateMoney(symbol, partyId, finalProfit, BigDecimal.ZERO,
+ Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT, Constants.MONEYLOG_CONTENT_CONTRACT_CLOSE, "强制平仓,平仓合约数" + list.size() + "[" + volume + "],订单号[" + orderNo + "]");
}
-
- walletService.updateMoney(order.getSymbol(), partyId, profit, BigDecimal.ZERO,
- Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET_USDT, Constants.MONEYLOG_CONTENT_CONTRACT_CLOSE, "平仓,平仓合约数[" + volume + "],订单号[" + order.getOrderNo() + "]");
- order.setState(ContractOrder.STATE_CREATED);
- order.setVolume(BigDecimal.ZERO);
- order.setDeposit(BigDecimal.ZERO);
- order.setCloseTime(DateUtil.currentSeconds());
- order.setCloseTimeTs(DateUtil.currentSeconds());
-// List<Realtime> list = this.dataService.realtime(order.getSymbol());
-// // 平仓时候把当前价格先更新回去
-// if (list.size() != 0) {
-// Realtime realtime = list.get(0);
-// BigDecimal close = realtime.getClose();
-// order.setCloseAvgPrice(close);
-// }
- update(order);
-
- /**
- * 合约产品平仓后添加当前流水setWithdraw_limit_now_amount
- */
- User party = userService.getById(order.getPartyId());
- party.setWithdrawLimitNowAmount(party.getWithdrawLimitNowAmount().add(order.getDepositOpen()));
- userService.updateById(party);
- if (ObjectUtils.isEmpty(order.getCloseAvgPrice())) {
- order.setCloseAvgPrice(BigDecimal.ZERO);
- }
- return order;
-
}
/**
@@ -405,10 +480,18 @@
*/
public BigDecimal settle(ContractOrder order, BigDecimal volume) {
/**
- * 平仓比率
+ * 偏差点位
*/
+ List<Realtime> list = this.dataService.realtime(order.getSymbol());
+ if (list.size() == 0) {
+ order.getProfit();
+ }
+ Realtime realtime = list.get(0);
+ BigDecimal close = realtime.getClose();
+ BigDecimal point = close.subtract(order.getTradeAvgPrice());
+ BigDecimal profit = point.multiply(new BigDecimal("0.01")).multiply(order.getVolumeOpen()).setScale(4, BigDecimal.ROUND_DOWN);;
+ BigDecimal rentalProfit = order.getDeposit().add(profit);
BigDecimal rate = volume.divide(order.getVolumeOpen(), 2, RoundingMode.HALF_UP);
- BigDecimal profit = order.getDeposit().add(order.getProfit()).multiply(rate);
order.setAmountClose(order.getAmountClose().add(profit));
order.setVolume(order.getVolume().subtract(volume));
order.setDeposit(order.getDeposit().subtract(order.getDepositOpen().multiply(rate)));
@@ -418,11 +501,8 @@
order.setCloseTimeTs(DateUtil.currentSeconds());
}
- return profit;
+ return rentalProfit;
}
-
-
-
public void saveOpen(ContractApplyOrder applyOrder, Realtime realtime) {
Item item = this.itemService.findBySymbol(applyOrder.getSymbol());
@@ -433,32 +513,58 @@
order.setOrderNo(orderNo);
order.setDirection(applyOrder.getDirection());
order.setLeverRate(applyOrder.getLeverRate());
- order.setVolume(applyOrder.getVolume());
- order.setVolumeOpen(applyOrder.getVolumeOpen());
order.setOrderPriceType(applyOrder.getOrderPriceType());
- order.setUnitAmount(applyOrder.getUnitAmount());
- order.setFee(applyOrder.getFee());
- order.setDeposit(applyOrder.getDeposit());
- order.setDepositOpen(applyOrder.getDeposit());
- order.setTradeAvgPrice(realtime.getClose());
+ order.setTradeAvgPrice(applyOrder.getPrice());
order.setStopPriceProfit(applyOrder.getStopPriceProfit());
order.setStopPriceLoss(applyOrder.getStopPriceLoss());
order.setPips(item.getPips());
order.setPipsAmount(item.getPipsAmount());
- // 爆仓是爆整个钱包
-// BigDecimal forceClose = BigDecimal.ZERO;
-// BigDecimal base = order.getDepositOpen().multiply(order.getPips()).divide(order.getPipsAmount(), 10, RoundingMode.HALF_UP).divide(order.getVolume(),10, RoundingMode.HALF_UP);
-// if(order.getDirection().equalsIgnoreCase(ContractOrder.DIRECTION_BUY)){
-// forceClose = order.getTradeAvgPrice().subtract(base).setScale(item.getDecimals(), RoundingMode.HALF_UP);
-// }else if(order.getDirection().equalsIgnoreCase(ContractOrder.DIRECTION_SELL)) {
-// forceClose = order.getTradeAvgPrice().add(base).setScale(item.getDecimals(), RoundingMode.HALF_UP);
-// }
-// if(forceClose.compareTo(BigDecimal.ZERO) <0 ){
-// forceClose = BigDecimal.ZERO;
-// }
-// order.setForceClosePrice(forceClose.toPlainString());
+ if(applyOrder.getOrderPriceType().equals("opponent")){//市价单,创建订单在计算和扣款
+ BigDecimal unitAmount = applyOrder.getPrice().multiply(BigDecimal.valueOf(item.getFaceValue()));
+ unitAmount = unitAmount.setScale(4, RoundingMode.DOWN);
+
+ 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);
RedisUtil.set(ContractRedisKeys.CONTRACT_ORDERNO + order.getOrderNo(), order);
@@ -528,7 +634,6 @@
BigDecimal profit = this.settle(order, volume);
update(order);
Wallet wallet = this.walletService.findByUserId(order.getPartyId());
- BigDecimal amount_before = wallet.getMoney();
if (wallet.getMoney().add(profit).compareTo(BigDecimal.ZERO) < 0) {
profit = wallet.getMoney().negate();
@@ -614,18 +719,7 @@
map.put("deposit", order.getDeposit());
map.put("deposit_open", order.getDepositOpen());
map.put("change_ratio", order.getChangeRatio());
- /**
- * 收益
- */
-// if (ContractOrder.STATE_SUBMITTED.equals(order.getState())) {
-// map.put("profit",
-// df.format(Arith.sub(
-// Arith.add(Arith.add(order.getAmount_close(), order.getProfit()), order.getDeposit()),
-// order.getDeposit_open())));
-// } else {
-// map.put("profit", df.format(
-// Arith.sub(Arith.add(order.getAmount_close(), order.getDeposit()), order.getDeposit_open())));
-// }
+
if(order.getProfit()!=null){
map.put("profit", order.getProfit().setScale(4, RoundingMode.HALF_UP));
}else{
@@ -633,6 +727,7 @@
}
map.put("volume", order.getVolume());
map.put("volume_open", order.getVolumeOpen());
+ map.put("force_close_rice", order.getForceClosePrice());
return map;
}
@@ -651,7 +746,7 @@
if (!CollectionUtils.isEmpty(findSubmittedContractOrders)) {
for (ContractOrder order : orders) {
if (ContractOrder.STATE_SUBMITTED.equals(order.getState())) {
- saveClose(order.getPartyId().toString(), order.getOrderNo());
+ saveClose(order.getPartyId().toString(), order.getOrderNo(),null);
}
RedisUtil.del(ContractRedisKeys.CONTRACT_ORDERNO + order.getOrderNo());
}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java
index 517bbe1..3cd3b94 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/exchange/impl/ExchangeApplyOrderServiceImpl.java
@@ -13,6 +13,7 @@
import com.yami.trading.bean.exchange.dto.ExchangeSymbolDto;
import com.yami.trading.bean.exchange.dto.SumEtfDto;
import com.yami.trading.bean.item.domain.Item;
+import com.yami.trading.bean.model.CapitaltWallet;
import com.yami.trading.bean.model.MoneyLog;
import com.yami.trading.bean.model.Wallet;
import com.yami.trading.bean.model.WalletExtend;
@@ -21,6 +22,7 @@
import com.yami.trading.common.exception.YamiShopBindException;
import com.yami.trading.common.util.*;
import com.yami.trading.dao.exchange.ExchangeApplyOrderMapper;
+import com.yami.trading.service.CapitaltWalletService;
import com.yami.trading.service.MoneyLogService;
import com.yami.trading.service.WalletService;
import com.yami.trading.service.data.DataService;
@@ -58,6 +60,8 @@
MoneyLogService moneyLogService;
@Autowired
UserDataService userDataService;
+ @Autowired
+ CapitaltWalletService capitaltWalletService;
@Override
public List<ExchangeApplyOrder> findSubmitted() {
@@ -107,9 +111,12 @@
double amount = Arith.mul(sub, realtime.getClose().doubleValue());
order.setCloseTime(new Date());
order.setClosePrice(realtime.getClose().doubleValue());
- Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId());
- double amount_before = wallet.getMoney().doubleValue();
- this.walletService.update(wallet.getUserId().toString(), amount);
+// Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId());
+ CapitaltWallet capitaltWallet = capitaltWalletService.getUserIdWallet(order.getPartyId());
+ double amount_before = capitaltWallet.getMoney().doubleValue();
+// this.walletService.update(userIdWallet.getUserId().toString(), amount);
+ this.capitaltWalletService.update(capitaltWallet, amount);
+
/*
* 保存资金日志
*/
@@ -117,7 +124,7 @@
moneylog_deposit.setCategory(Constants.MONEYLOG_CATEGORY_EXCHANGE);
moneylog_deposit.setAmountBefore(new BigDecimal(amount_before));
moneylog_deposit.setAmount(new BigDecimal(amount));
- moneylog_deposit.setAmountAfter(wallet.getMoney());
+ moneylog_deposit.setAmountAfter(capitaltWallet.getMoney());
moneylog_deposit.setLog("委托单,订单号[" + order.getOrderNo() + "]");
moneylog_deposit.setUserId(order.getPartyId());
moneylog_deposit.setWalletType(Constants.WALLET);
@@ -607,11 +614,9 @@
// 可以买的数量
double amount = Arith.div(sub, order.getClosePrice(), 8);
order.setSymbolValue(amount);
- Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId());
- double amount_before = wallet.getMoney().doubleValue();
- WalletExtend walletExtend = walletService.saveExtendByPara(order.getPartyId(), order.getSymbol());
-// walletExtend.setAmount(Arith.add(walletExtend.getAmount(), amount));
-// this.walletService.update(walletExtend);
+// Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId());
+ CapitaltWallet userIdWallet = capitaltWalletService.getUserIdWallet(order.getPartyId());
+ double amount_before = userIdWallet.getMoney().doubleValue();
// 如果是计划委托,则先不扣钱
if (order.isTriggerOrder()) {
@@ -632,12 +637,11 @@
save(order);
}
if (!order.isTriggerOrder()) {
- if (wallet.getMoney().doubleValue() < order.getVolume().doubleValue()) {
+ if (userIdWallet.getMoney().doubleValue() < order.getVolume().doubleValue()) {
throw new YamiShopBindException("余额不足");
}
- this.walletService.update(wallet.getUserId().toString(), Arith.sub(0, order.getVolume()));
-// this.walletService.updateExtend(walletExtend.getPartyId().toString(), walletExtend.getWallettype(), amount);
-
+// this.walletService.update(userIdWallet.getUserId().toString(), Arith.sub(0, order.getVolume()));
+ capitaltWalletService.update(userIdWallet, Arith.sub(0, order.getVolume()));
/*
* 保存资金日志
*/
@@ -645,7 +649,7 @@
moneylog_deposit.setCategory(Constants.MONEYLOG_CATEGORY_EXCHANGE);
moneylog_deposit.setAmountBefore(new BigDecimal(amount_before));
moneylog_deposit.setAmount(new BigDecimal(Arith.sub(0, order.getVolume().doubleValue())));
- moneylog_deposit.setAmountAfter(new BigDecimal(Arith.sub(wallet.getMoney().doubleValue(), order.getVolume())));
+ moneylog_deposit.setAmountAfter(new BigDecimal(Arith.sub(userIdWallet.getMoney().doubleValue(), order.getVolume())));
moneylog_deposit.setLog("币币交易,订单号[" + order.getOrderNo() + "]");
moneylog_deposit.setUserId(order.getPartyId());
moneylog_deposit.setWalletType(Constants.WALLET);
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/finance/FinanceService.java b/trading-order-service/src/main/java/com/yami/trading/service/finance/FinanceService.java
new file mode 100644
index 0000000..4b995b5
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/finance/FinanceService.java
@@ -0,0 +1,13 @@
+package com.yami.trading.service.finance;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yami.trading.bean.finance.Finance;
+import com.yami.trading.bean.vo.FinanceVo;
+
+/**
+ * 理财
+ */
+public interface FinanceService extends IService<Finance> {
+
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/finance/impl/FinanceServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/finance/impl/FinanceServiceImpl.java
new file mode 100644
index 0000000..ae803e4
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/finance/impl/FinanceServiceImpl.java
@@ -0,0 +1,19 @@
+package com.yami.trading.service.finance.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.trading.bean.finance.Finance;
+import com.yami.trading.bean.model.ChannelBlockchain;
+import com.yami.trading.dao.finance.FinanceMapper;
+import com.yami.trading.dao.user.ChannelBlockchainMapper;
+import com.yami.trading.service.ChannelBlockchainService;
+import com.yami.trading.service.finance.FinanceService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @program: trading-order-master
+ * @description: 理财
+ * @create: 2025-01-22 17:18
+ **/
+@Service
+public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> implements FinanceService {
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/impl/AwsS3OSSFileServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/impl/AwsS3OSSFileServiceImpl.java
index 8ef4d4b..dd3863e 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/impl/AwsS3OSSFileServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/impl/AwsS3OSSFileServiceImpl.java
@@ -4,6 +4,7 @@
import com.alibaba.fastjson2.JSONObject;
import com.yami.trading.common.exception.BusinessException;
import com.yami.trading.common.exception.YamiShopBindException;
+import com.yami.trading.common.util.PropertiesUtil;
import com.yami.trading.service.AwsS3OSSFileService;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
@@ -30,6 +31,7 @@
@Service
@Slf4j
public class AwsS3OSSFileServiceImpl implements AwsS3OSSFileService {
+
@Value("${oss.aws.s3.bucketName}")
private String bucketName;
//
@@ -159,25 +161,36 @@
if (StrUtil.isEmpty(fileType) || fileType.contains("blob")) {
fileType = "blob.png";
}
+
+ // 生成唯一的文件名
String id = UUID.randomUUID().toString();
- String path = moduleName + "/" + LocalDate.now() + "/" + id + fileType;
- log.info("AwsS3OSSFileService putS3Object bucketName:{},objectKey:{},objectPath:{}", bucketName, path, file.getName());
+ String path = LocalDate.now() + "/" + id + fileType;
+
+ // 确保目标文件夹存在
+ File targetDir = new File(PropertiesUtil.getProperty("loca.images.dir") + "/" + LocalDate.now());
+ if (!targetDir.exists()) {
+ targetDir.mkdirs();
+ }
+
+ // 构建本地文件路径
+ File localFile = new File(targetDir, id + fileType);
+
+ // 打印上传路径
+ log.info("LocalFileUploadService uploadFile localFilePath: {}", localFile.getAbsolutePath());
+
try {
+ // 将文件保存到本地
+ file.transferTo(localFile);
+
+ // 如果需要自定义元数据,可以在此处理
Map<String, String> metadata = new HashMap<>();
- metadata.put("x-amz-meta-myVal", "test");
- PutObjectRequest putOb = PutObjectRequest.builder()
- .bucket(bucketName)
- .key(path)
- .metadata(metadata)
- .build();
- S3Client s3Client = getS3Client();
- s3Client.putObject(putOb, RequestBody.fromInputStream(file.getInputStream(), file.getSize()));
+ metadata.put("x-amz-meta-myVal", "test"); // 如果需要元数据,可以放在文件名或其他地方
+
+ // 返回相对路径
return path;
- } catch (S3Exception e) {
- log.error("AwsS3OSSFileService putS3Object S3Exception", e.getMessage(), e.awsErrorDetails().errorMessage(), e);
- throw new YamiShopBindException("文件上传失败");
+
} catch (IOException e) {
- log.error("AwsS3OSSFileService putS3Object IOException", e.getMessage(), e);
+ log.error("LocalFileUploadService uploadFile IOException", e.getMessage(), e);
throw new YamiShopBindException("文件上传失败");
}
}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/impl/CapitaltWalletServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/impl/CapitaltWalletServiceImpl.java
new file mode 100644
index 0000000..46c11a7
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/impl/CapitaltWalletServiceImpl.java
@@ -0,0 +1,115 @@
+package com.yami.trading.service.impl;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yami.trading.bean.contract.domain.ContractOrder;
+import com.yami.trading.bean.model.CapitaltWallet;
+import com.yami.trading.bean.model.Wallet;
+import com.yami.trading.common.domain.Result;
+import com.yami.trading.common.exception.YamiShopBindException;
+import com.yami.trading.common.util.Arith;
+import com.yami.trading.dao.CapitaltWalletMapper;
+import com.yami.trading.service.CapitaltWalletService;
+import com.yami.trading.service.WalletService;
+import com.yami.trading.service.contract.ContractOrderService;
+import lombok.extern.slf4j.Slf4j;
+import org.checkerframework.checker.units.qual.A;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * @program: trading-order-master
+ * @description: 合约账户
+ * @create: 2025-01-08 17:59
+ **/
+@Service
+@Slf4j
+public class CapitaltWalletServiceImpl extends ServiceImpl<CapitaltWalletMapper, CapitaltWallet> implements CapitaltWalletService {
+
+ @Autowired
+ WalletService walletService;
+
+ @Autowired
+ private ContractOrderService contractOrderService;
+
+ @Override
+ public CapitaltWallet getUserIdWallet(String userId) {
+ return getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
+ .eq(CapitaltWallet::getUserId,userId).last(" limit 1"));
+ }
+
+ /**
+ *capital 资金
+ *contract 合约
+ * @param userId 用户id
+ * @param deductAccount 划转账户
+ * @param receiveAccount 接收账户
+ * @param moneyRevise 划转金额
+ * @return
+ */
+ @Override
+ @Transactional
+ public Result updateWallt(String userId, String deductAccount, String receiveAccount, BigDecimal moneyRevise) {
+ // 获取合约账户(contract)
+ Wallet wallet = walletService.saveWalletByPartyId(userId);
+
+ // 获取资金账户(capital)
+ CapitaltWallet capitaltWallet = getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
+ .eq(CapitaltWallet::getUserId, userId).last(" limit 1 "));
+
+ // 判断划转账户类型
+ if (deductAccount.equals("capital") && receiveAccount.equals("contract")) {
+ // 从资金账户(capital)到合约账户(contract)的划转
+ if (capitaltWallet != null && capitaltWallet.getMoney().compareTo(moneyRevise) >= 0) {
+ // 执行从资金账户到合约账户的划转操作
+ capitaltWallet.setMoney(capitaltWallet.getMoney().subtract(moneyRevise)); // 减少资金账户余额
+ wallet.setMoney(wallet.getMoney().add(moneyRevise)); // 增加合约账户余额
+ // 更新账户余额
+ walletService.updateById(wallet); // 保存合约账户的更新
+ updateById(capitaltWallet); // 保存资金账户的更新
+ return Result.succeed();
+ } else {
+ throw new YamiShopBindException("资金账户余额不足");
+ }
+ } else if (deductAccount.equals("contract") && receiveAccount.equals("capital")) {
+
+ LambdaQueryWrapper<ContractOrder> wrapper = new LambdaQueryWrapper<ContractOrder>();
+ wrapper.eq(ContractOrder::getPartyId, userId);
+ wrapper.eq(ContractOrder::getLocationType, 1);
+ wrapper.eq(ContractOrder::getState,"submitted");
+ List<ContractOrder> list = contractOrderService.list(wrapper);
+ if(CollectionUtil.isNotEmpty(list)){
+ throw new YamiShopBindException("当前持有全仓仓位,不支持划转!");
+ }
+
+ // 从合约账户(contract)到资金账户(capital)的划转
+ if (wallet != null && wallet.getMoney().compareTo(moneyRevise) >= 0) {
+ // 执行从合约账户到资金账户的划转操作
+ wallet.setMoney(wallet.getMoney().subtract(moneyRevise)); // 减少合约账户余额
+ capitaltWallet.setMoney(capitaltWallet.getMoney().add(moneyRevise)); // 增加资金账户余额
+ // 更新账户余额
+ walletService.updateById(wallet); // 保存合约账户的更新
+ updateById(capitaltWallet); // 保存资金账户的更新
+ return Result.succeed();
+ } else {
+ throw new YamiShopBindException("合约账户余额不足");
+ }
+ } else {
+ // 如果划转账户和接收账户不符合预期,返回错误信息
+ throw new YamiShopBindException("不支持的账户划转类型");
+ }
+ }
+
+ @Override
+ public void update(CapitaltWallet capitaltWallet, double amount1) {
+ capitaltWallet.setMoney(new BigDecimal(Arith.add(capitaltWallet.getMoney().doubleValue(), amount1)));
+ if (!updateById(capitaltWallet)) {
+ throw new YamiShopBindException("操作钱包失败!");
+ }
+ }
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/impl/RechargeBlockchainOrderServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/impl/RechargeBlockchainOrderServiceImpl.java
index 7540945..45ba050 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/impl/RechargeBlockchainOrderServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/impl/RechargeBlockchainOrderServiceImpl.java
@@ -1,5 +1,6 @@
package com.yami.trading.service.impl;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -49,6 +50,8 @@
@Autowired
SysparaService sysparaService;
+ @Autowired
+ CapitaltWalletService capitaltWalletService;
@Autowired
WalletLogService walletLogService;
@@ -124,12 +127,17 @@
if ("usdt".equals(recharge.getSymbol())) {
double amount1 = recharge.getVolume();
- Wallet wallet = new Wallet();
- wallet = walletService.saveWalletByPartyId(recharge.getPartyId());
+// Wallet wallet = new Wallet();
+// wallet = walletService.saveWalletByPartyId(recharge.getPartyId());
+//
+// double amount_before = wallet.getMoney().doubleValue();
+//
+// walletService.update(wallet.getUserId(), amount1);
- double amount_before = wallet.getMoney().doubleValue();
-
- walletService.update(wallet.getUserId(), amount1);
+ CapitaltWallet capitaltWallet = capitaltWalletService.getOne(new LambdaQueryWrapper<>(CapitaltWallet.class)
+ .eq(CapitaltWallet::getUserId, recharge.getPartyId()).last(" limit 1 "));
+ double amount_before = capitaltWallet.getMoney().doubleValue();
+ capitaltWalletService.update(capitaltWallet,amount1);
// 保存资金日志
MoneyLog moneyLog = new MoneyLog();
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/impl/StrongLevelCalculationServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/impl/StrongLevelCalculationServiceImpl.java
new file mode 100644
index 0000000..a3d1f88
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/service/impl/StrongLevelCalculationServiceImpl.java
@@ -0,0 +1,140 @@
+package com.yami.trading.service.impl;
+
+import com.yami.trading.service.StrongLevelCalculationService;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+/**
+ * @program: trading-order-master
+ * @description:
+ * @create: 2025-01-15 16:12
+ **/
+@Service
+public class StrongLevelCalculationServiceImpl implements StrongLevelCalculationService {
+
+
+ public static void main(String[] args) {
+ // 给定参数
+ double marginBalance = 100; // 保证金余额
+ double faceValue = 0.01; // 合约面值(固定面值不能调整)
+ double contractQuantity = 5; // 合约张数 张数=保证金/开仓均价*面值/杠杆
+ double openingPrice = 97016.44; // 开仓均价
+ double maintenanceMarginRate = 0.004; // 维持保证金率(固定不变)
+ double feeRate = 0.0005; // 手续费率 根据实际设置
+
+ // 计算强平价
+ double liquidationPrice = a(marginBalance, faceValue, contractQuantity,
+ openingPrice, maintenanceMarginRate, feeRate);
+
+ // 输出结果
+ System.out.println("多仓预估强平价: " + liquidationPrice);
+
+ // 计算空仓预估强平价
+ double liquidationPrice2 = b(marginBalance, faceValue, contractQuantity,
+ openingPrice, maintenanceMarginRate, feeRate);
+
+ // 输出结果
+ System.out.println("空仓预估强平价: " + liquidationPrice2);
+ }
+
+ /**
+ * 多仓强平价格计算 多仓预估强平价 =(保证金余额-面值 *|张数|*开仓均价)/(面值*张数|*(维持保证金率+手续费率 -1));
+ * @param marginBalance 保证金余额
+ * @param faceValue 合约面值
+ * @param contractQuantity 合约张数
+ * @param openingPrice 开仓均价
+ * @param maintenanceMarginRate 维持保证金率
+ * @param feeRate 手续费率
+ * @return
+ */
+ @Override
+ public 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);
+
+ // 计算强平价
+ double result = numerator / denominator;
+ if (result < 0) {
+ return 0;
+ }
+ return new BigDecimal(result).setScale(2, RoundingMode.HALF_UP).doubleValue();
+ }
+
+
+ /**
+ * 空仓强平价格计算 空仓预估强平价 =(保证金余额+面值 *|张数|*开仓均价)/(面值*|张数|*(维持金率+王续费率 +1))
+ * @param marginBalance 保证金余额
+ * @param faceValue 合约面值
+ * @param contractQuantity 合约张数
+ * @param openingPrice 开仓均价
+ * @param maintenanceMarginRate 维持保证金率
+ * @param feeRate 手续费率
+ * @return
+ */
+ @Override
+ public 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);
+
+ // 计算空仓预估强平价
+ double result = numerator / denominator;
+ if (result < 0) {
+ return 0;
+ }
+ return new BigDecimal(result).setScale(2, RoundingMode.HALF_UP).doubleValue();
+ }
+
+ public static double a (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);
+
+ // 计算强平价
+ double result = numerator / denominator;
+ if (result < 0) {
+ return 0;
+ }
+ return new BigDecimal(result).setScale(2, RoundingMode.HALF_UP).doubleValue();
+ }
+
+
+ /**
+ * 空仓强平价格计算 空仓预估强平价 =(保证金余额+面值 *|张数|*开仓均价)/(面值*|张数|*(维持金率+王续费率 +1))
+ * @param marginBalance 保证金余额
+ * @param faceValue 合约面值
+ * @param contractQuantity 合约张数
+ * @param openingPrice 开仓均价
+ * @param maintenanceMarginRate 维持保证金率
+ * @param feeRate 手续费率
+ * @return
+ */
+ public static double b (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);
+
+ // 计算空仓预估强平价
+ double result = numerator / denominator;
+ if (result < 0) {
+ return 0;
+ }
+ return new BigDecimal(result).setScale(2, RoundingMode.HALF_UP).doubleValue();
+ }
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/impl/UserServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/impl/UserServiceImpl.java
index 7b78e15..30acaba 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/impl/UserServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/impl/UserServiceImpl.java
@@ -2,7 +2,6 @@
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -17,16 +16,14 @@
import com.yami.trading.common.constants.Constants;
import com.yami.trading.common.exception.YamiShopBindException;
import com.yami.trading.common.util.*;
+import com.yami.trading.dao.CapitaltWalletMapper;
import com.yami.trading.dao.user.UserMapper;
-import com.yami.trading.service.IdentifyingCodeTimeWindowService;
-import com.yami.trading.service.MoneyLogService;
-import com.yami.trading.service.OnlineUserService;
+import com.yami.trading.service.*;
import com.yami.trading.service.data.DataService;
import com.yami.trading.service.system.LogService;
import com.yami.trading.service.user.UserDataService;
import com.yami.trading.service.user.UserRecomService;
import com.yami.trading.service.user.UserService;
-import com.yami.trading.service.WalletService;
import com.yami.trading.service.syspara.SysparaService;
import com.yami.trading.service.user.WalletExtendService;
import lombok.extern.slf4j.Slf4j;
@@ -52,6 +49,8 @@
UserRecomService userRecomService;
@Autowired
WalletService walletService;
+ @Autowired
+ CapitaltWalletMapper capitaltWalletMapper;
@Autowired
PasswordEncoder passwordEncoder;
@Autowired
@@ -1306,6 +1305,11 @@
wallet.setUserId(user.getUserId());
wallet.setCreateTime(now);
walletService.save(wallet);
+ //资金账户
+ CapitaltWallet capitaltWallet = new CapitaltWallet();
+ capitaltWallet.setUserId(user.getUserId());
+ capitaltWallet.setCreateTime(now);
+ capitaltWalletMapper.insert(capitaltWallet);
//
Log log = new Log();
log.setCategory(Constants.LOG_CATEGORY_SECURITY);
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/impl/WalletServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/impl/WalletServiceImpl.java
index 0ac07ba..c1acf6d 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/impl/WalletServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/impl/WalletServiceImpl.java
@@ -1,6 +1,8 @@
package com.yami.trading.service.impl;
+import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -46,8 +48,12 @@
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
@Slf4j
@Service
@@ -165,7 +171,11 @@
Date now = new Date();
Wallet wallet = findByUserId(userId);
BigDecimal amountBefore = wallet.getMoney();
+
wallet.setMoney(wallet.getMoney().add(money));
+ if(wallet.getMoney().compareTo(BigDecimal.ZERO) < 0){
+ wallet.setMoney(BigDecimal.ZERO);
+ }
wallet.setUpdateTime(now);
if (wallet.getMoney().doubleValue() < 0) {
throw new YamiShopBindException("余额不足");
@@ -191,58 +201,102 @@
/*
* 获取 所有订单 永续合约总资产、总保证金、总未实现盈利,当日盈利
*/
+ @Override
public Map<String, Double> getMoneyContract(Serializable partyId, String symbolType) {
- double money_contract = 0;
- double money_contract_deposit = 0;
- double money_contract_profit = 0;
- double money_contract_profit_today = 0;
+ double money_contract = 0;//总资产
+ double money_contract_deposit = 0;//总保证金
+ double money_contract_profit = 0;//浮动盈亏
+ double money_contract_profit_today = 0;//当日盈亏
- ContractOrderService contractOrderService = ApplicationContextUtils.getBean(ContractOrderService.class);
- List<ContractOrder> contractOrders = contractOrderService.findSubmitted(partyId.toString(), "", "");
+ List<ContractOrder> contractOrders = getContractOrders(partyId);
if (contractOrders != null) {
- for (ContractOrder order : contractOrders) {
- String symbol = order.getSymbol();
- Item bySymbol = itemService.findBySymbol(symbol);
- if (bySymbol == null) {
- continue;
- }
- // 类型不对直接continue
- if (StringUtils.isNotEmpty(symbolType)) {
- if (!bySymbol.getType().equalsIgnoreCase(symbolType)) {
- continue;
- }
+// for (ContractOrder order : contractOrders) {
+// String symbol = order.getSymbol();
+// Item bySymbol = itemService.findBySymbol(symbol);
+// if (bySymbol == null) {
+// continue;
+// }
+// // 类型不对直接continue
+// if (StringUtils.isNotEmpty(symbolType)) {
+// if (!bySymbol.getType().equalsIgnoreCase(symbolType)) {
+// continue;
+// }
+//
+// }
+// // 真正下单里
+// double order_volume = 1;
+//
+// if (order.getLeverRate() != null && order.getLeverRate().compareTo(BigDecimal.ZERO) != 0) {
+// order_volume = order.getVolumeOpen().divide(order.getLeverRate()).doubleValue();
+// } else {
+// order_volume = order.getVolumeOpen().doubleValue();
+// }
+//
+// double amount = Arith.add(Arith.mul(order_volume, order.getUnitAmount().doubleValue()), order.getProfit().doubleValue());
+// money_contract = Arith.add(amount, money_contract);
+// money_contract_deposit = Arith.add(order.getDeposit().doubleValue(), money_contract_deposit);
+// money_contract_profit = Arith.add(order.getProfit().doubleValue(), money_contract_profit);
+// // 只需要计算当日盈亏比例*金额就是当日盈亏
+//
+// List<Realtime> realtimes = dataService.realtime(symbol);
+// if (CollectionUtils.isNotEmpty(realtimes)) {
+// Realtime realtime = realtimes.get(0);
+// // 当前每张金额*加杠杆后多少金额
+// // 今天总体涨跌幅
+// BigDecimal changeRatio = realtime.getClose().subtract(realtime.getOpen()).divide(realtime.getOpen(), 10, RoundingMode.HALF_UP);
+// Double todayProfit = order.getUnitAmount().multiply(order.getVolumeOpen()).multiply(changeRatio).setScale(10, RoundingMode.HALF_UP).doubleValue();
+// money_contract_profit_today += todayProfit;
+// }
+// }
- }
- // 真正下单里
- double order_volume = 1;
- if (order.getLeverRate() != null && order.getLeverRate().compareTo(BigDecimal.ZERO) != 0) {
- order_volume = order.getVolumeOpen().divide(order.getLeverRate()).doubleValue();
- } else {
- order_volume = order.getVolumeOpen().doubleValue();
- }
+ Map<String, List<ContractOrder>> groupedOrders = contractOrders.stream()
+ .collect(Collectors.groupingBy(ContractOrder::getState));
+ //持仓订单
+ List<ContractOrder> submittedOrderList = groupedOrders.get(ContractOrder.STATE_SUBMITTED);
- double amount = Arith.add(Arith.mul(order_volume, order.getUnitAmount().doubleValue()), order.getProfit().doubleValue());
- money_contract = Arith.add(amount, money_contract);
- money_contract_deposit = Arith.add(order.getDeposit().doubleValue(), money_contract_deposit);
- money_contract_profit = Arith.add(order.getProfit().doubleValue(), money_contract_profit);
- // 只需要计算当日盈亏比例*金额就是当日盈亏
+ //总资产计算
+ if(CollectionUtils.isNotEmpty(submittedOrderList)){
+ //持仓单盈亏
+ BigDecimal totalProfit = submittedOrderList.stream()
+ .map(ContractOrder::getProfit)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
- List<Realtime> realtimes = dataService.realtime(symbol);
- if (CollectionUtils.isNotEmpty(realtimes)) {
- Realtime realtime = realtimes.get(0);
- // 当前每张金额*加杠杆后多少金额
- // 今天总体涨跌幅
- BigDecimal changeRatio = realtime.getClose().subtract(realtime.getOpen()).divide(realtime.getOpen(), 10, RoundingMode.HALF_UP);
- Double todayProfit = order.getUnitAmount().multiply(order.getVolumeOpen()).multiply(changeRatio).setScale(10, RoundingMode.HALF_UP).doubleValue();
- money_contract_profit_today += todayProfit;
- }
+ //持仓单保证金
+ BigDecimal totalDeposit = submittedOrderList.stream()
+ .map(ContractOrder::getDepositOpen)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+ money_contract = totalProfit.add(totalDeposit).doubleValue();
}
+
+ //浮动盈亏
+ if(CollectionUtils.isNotEmpty(submittedOrderList)){
+ BigDecimal totalProfit = submittedOrderList.stream()
+ .map(ContractOrder::getProfit)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ money_contract_profit = totalProfit.doubleValue();
+ }
+
+ //当日盈亏
+ LocalDateTime startOfDay = LocalDate.now().atStartOfDay();
+ LocalDateTime endOfDay = LocalDate.now().atTime(LocalTime.MAX);
+ // 获取今天的订单
+ BigDecimal totalRevenue = contractOrders.stream()
+ .filter(order -> {
+ LocalDateTime orderDate = toLocalDateTime(order.getCreateTime()); // 转换为 LocalDateTime
+ return !orderDate.isBefore(startOfDay) && !orderDate.isAfter(endOfDay);
+ })
+ .map(ContractOrder::getProfit) // 获取订单的收益
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+
+
+ money_contract_profit_today = totalRevenue.doubleValue();
}
Map<String, Double> moneys_contract = new HashMap<String, Double>();
- moneys_contract.put("money_contract", money_contract);
+
moneys_contract.put("money_contract_deposit", money_contract_deposit);
moneys_contract.put("money_contract_profit", money_contract_profit);
moneys_contract.put("money_contract_profit_today", money_contract_profit_today);
@@ -251,11 +305,24 @@
if (!"".equals(partyId) && partyId != null) {
wallet = findByUserId(partyId.toString());
}
- moneys_contract.put("money_wallet", wallet.getMoney().doubleValue());
-
+ moneys_contract.put("money_wallet", wallet.getMoney().doubleValue());//可用余额
+ moneys_contract.put("money_contract", wallet.getMoney().doubleValue()+money_contract);
return moneys_contract;
}
+ private static LocalDateTime toLocalDateTime(Date date) {
+ return LocalDateTime.ofInstant(date.toInstant(), java.time.ZoneId.systemDefault());
+ }
+
+ private static List<ContractOrder> getContractOrders(Serializable partyId) {
+ ContractOrderService contractOrderService = ApplicationContextUtils.getBean(ContractOrderService.class);
+ QueryWrapper<ContractOrder> queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq(StrUtil.isNotBlank(partyId.toString()), "party_id", partyId);
+ queryWrapper.orderByDesc("create_time");
+ List<ContractOrder> contractOrders = contractOrderService.list(queryWrapper);
+ return contractOrders;
+ }
+
// /**
// * 获取总资产
// *
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/item/ItemUserOptionalListService.java b/trading-order-service/src/main/java/com/yami/trading/service/item/ItemUserOptionalListService.java
index ff09a58..b6d1759 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/item/ItemUserOptionalListService.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/item/ItemUserOptionalListService.java
@@ -103,22 +103,35 @@
allSymbos.add(dto.getSymbol());
}
- for(String symbol: optionalSymbols ){
- if(allSymbos.contains(symbol)){
+ for (String symbol : optionalSymbols) {
+ if (allSymbos.contains(symbol)) {
continue;
}
ItemUserOptionalItemDTO dto = new ItemUserOptionalItemDTO();
dto.setSymbol(symbol);
Item bySymbol = itemService.findBySymbol(dto.getSymbol());
- if(!bySymbol.getType().equalsIgnoreCase(type)){
+ if (!bySymbol.getType().equalsIgnoreCase(type)) {
continue;
}
dto.setName(bySymbol.getName());
- Realtime realtime = dataService.realtime(dto.getSymbol()).get(0);
+
+ // 获取实时数据
+ List<Realtime> realtimeList = dataService.realtime(dto.getSymbol());
+
+ // 检查实时数据列表是否为空
+ if (realtimeList.isEmpty()) {
+ continue; // 如果列表为空,跳过当前循环
+ }
+
+ // 获取第一个实时数据
+ Realtime realtime = realtimeList.get(0);
+
+ // 设置 DTO 属性
dto.setClose(realtime.getClose());
dto.setChangeRatio(realtime.getChangeRatio());
dto.setTurnoverRate(realtime.getTurnoverRate());
dto.setVolumeRatio(realtime.getVolumeRatio());
+
allSymbos.add(dto.getSymbol());
models.add(dto);
}
diff --git a/trading-order-service/src/main/java/com/yami/trading/util/ConverterUtil.java b/trading-order-service/src/main/java/com/yami/trading/util/ConverterUtil.java
new file mode 100644
index 0000000..764be0c
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/util/ConverterUtil.java
@@ -0,0 +1,44 @@
+package com.yami.trading.util;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @description:
+ * @create: 2024-08-19 18:29
+ **/
+public class ConverterUtil {
+
+ public static <T, V> V convert(T pojo, Class<V> voClass) {
+ try {
+ V vo = voClass.newInstance();
+ Field[] pojoFields = pojo.getClass().getDeclaredFields();
+ Field[] voFields = voClass.getDeclaredFields();
+ for (Field pojoField : pojoFields) {
+ pojoField.setAccessible(true);
+ for (Field voField : voFields) {
+ voField.setAccessible(true);
+ if (pojoField.getName().equals(voField.getName()) && pojoField.getType().equals(voField.getType())) {
+ voField.set(vo, pojoField.get(pojo));
+ break;
+ }
+ }
+ }
+ return vo;
+ } catch (InstantiationException | IllegalAccessException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ public static <T, V> List<V> convertToList(List<T> pojoList, Class<V> voClass) {
+ List<V> voList = new ArrayList<>();
+ for (T pojo : pojoList) {
+ V vo = convert(pojo, voClass);
+ voList.add(vo);
+ }
+ return voList;
+ }
+
+
+}
diff --git a/trading-order-service/src/main/java/com/yami/trading/util/StrongLevelCalculationUtil.java b/trading-order-service/src/main/java/com/yami/trading/util/StrongLevelCalculationUtil.java
new file mode 100644
index 0000000..0945125
--- /dev/null
+++ b/trading-order-service/src/main/java/com/yami/trading/util/StrongLevelCalculationUtil.java
@@ -0,0 +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;
+ }
+}
diff --git a/trading-order-sys/src/main/java/com/yami/trading/sys/model/SysMenu.java b/trading-order-sys/src/main/java/com/yami/trading/sys/model/SysMenu.java
index 18177ca..249277e 100644
--- a/trading-order-sys/src/main/java/com/yami/trading/sys/model/SysMenu.java
+++ b/trading-order-sys/src/main/java/com/yami/trading/sys/model/SysMenu.java
@@ -82,4 +82,6 @@
@TableField(exist=false)
private List<?> list;
+ //0:显示 1:隐藏
+ private Integer isShow;
}
diff --git a/trading-order-sys/src/main/resources/mapper/SysMenuMapper.xml b/trading-order-sys/src/main/resources/mapper/SysMenuMapper.xml
index 21789b9..61fe2eb 100644
--- a/trading-order-sys/src/main/resources/mapper/SysMenuMapper.xml
+++ b/trading-order-sys/src/main/resources/mapper/SysMenuMapper.xml
@@ -4,7 +4,7 @@
<mapper namespace="com.yami.trading.sys.dao.SysMenuMapper">
<select id="listMenuIdByRoleId" resultType="Long">
- select menu_id from tz_sys_role_menu where role_id = #{roleId}
+ select menu_id from tz_sys_role_menu where role_id = #{roleId} and is_show = 0
</select>
<!-- 查询用户的所有菜单 -->
@@ -15,22 +15,22 @@
</select>
<!-- 查询所有菜单 -->
<select id="listMenu" resultType="com.yami.trading.sys.model.SysMenu">
- select * from tz_sys_menu where `type` != 2 order by order_num
+ select * from tz_sys_menu where `type` != 2 and is_show = 0 order by order_num
</select>
<select id="listSimpleMenuNoButton" resultType="com.yami.trading.sys.model.SysMenu">
- select menu_id ,parent_id ,`name` from tz_sys_menu where `type` != 2 order by order_num
+ select menu_id ,parent_id ,`name` from tz_sys_menu where `type` != 2 and is_show = 0 order by order_num
</select>
<select id="listRootMenu" resultType="com.yami.trading.sys.model.SysMenu">
- select menu_id,`name` from tz_sys_menu where `type` = 0
+ select menu_id,`name` from tz_sys_menu where `type` = 0 and is_show = 0
</select>
<select id="listChildrenMenuByParentId" resultType="com.yami.trading.sys.model.SysMenu">
- select menu_id,`name` from tz_sys_menu where parent_id = #{parentId}
+ select menu_id,`name` from tz_sys_menu where parent_id = #{parentId} and is_show = 0
</select>
<select id="listMenuAndBtn" resultType="com.yami.trading.sys.model.SysMenu">
- select * from tz_sys_menu order by order_num
+ select * from tz_sys_menu where is_show = 0 order by order_num
</select>
</mapper>
--
Gitblit v1.9.3