修改了平仓后保证金未释放的问题、修改了获取实时数据报错导致盈利高的问题、优化了对冲交易的保证金计算逻辑、修改了可用资金存在却不能交易的问题

master
yz
parent 937bb33720
commit 1dca0585d6

@ -35,6 +35,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
@ -119,8 +120,8 @@ public class MemberController {
member.setCumulativeProfitLoss(0.0);
}
Double totalAssets = initialCapital+cumulativeProfitLoss; //总资产=初始资金+累计盈亏
Double netValue = bigDecimalUtils.add(totalAssets, positionProfitLoss);
member.setTotalAssets(totalAssets); //设置总资产
Double netValue = bigDecimalUtils.add(totalAssets, positionProfitLoss,2);
member.setTotalAssets(bigDecimalUtils.add(totalAssets,0.0,2)); //设置总资产
member.setNetValue(netValue); //设置净值
Double marginUsed = member.getMarginUsed(); //获取已用保证金

@ -19,6 +19,7 @@ import com.sztzjy.forex.trading_trading.util.RedisUtil;
import com.sztzjy.forex.trading_trading.util.ResultEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@ -237,9 +238,14 @@ public class TakeStashController {
//当前持仓平仓 status设置为2
@AnonymousAccess
@Transactional
@PostMapping("closeTakeStash")
public ResultEntity closeTakeStash(@RequestBody JSONObject jsonObject) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return new ResultEntity(HttpStatus.BAD_REQUEST, "请稍后再试");
}
String stashId = jsonObject.getString("stashId");
String memberId = jsonObject.getString("memberId");
TakeStash takeStashNew = takeStashService.selectByPrimaryKey(stashId);
@ -278,6 +284,14 @@ public class TakeStashController {
Double marginUsed = member.getMarginUsed();//未修改前member表中成员保证金
marginUsed = bigDecimalUtils.mul(marginUsed-margin,1,2); //修改成员保证金
//处理保证金为负数的情况和保证金未释放的情况
List<TakeStash> takeStashList = takeStashService.selectAllByMemberIdAndStatus(memberId, 0);
if (takeStashList==null || takeStashList.size()==0){
marginUsed=0.0;
}
if(marginUsed<0){
marginUsed=0.0;
}
member.setMarginUsed(marginUsed);
Integer closingTrades = member.getClosingTrades();
if(closingTrades==null){
@ -299,6 +313,7 @@ public class TakeStashController {
takeStash.setProfitAndLossByClose(bigDecimalUtils.mul(profitAndLoss,1,2));
takeStash.setTimeTransactionClose(new Date());
takeStashService.updateByPrimaryKeySelective(takeStash);
redisUtil.del("trainingId_"+takeStashNew.getTrainingId()+"_stashId_"+stashId);
// wainingService.compareMarginLevels(member.getMemberId(), member.getTrainingId());//更改可用保证金后 调用预警
@ -323,7 +338,7 @@ public class TakeStashController {
margin=transactionVolume*priceTransaction*Constant.LEVERQUANTITY;
}
return margin;
}else {
}else if(takeStashList.size()>1){
for (int i = 0; i < takeStashList.size(); i++) {
TakeStash takeStash = takeStashList.get(i);
String buySellTypeTakeStash = takeStash.getBuySellType();
@ -338,6 +353,8 @@ public class TakeStashController {
}
totalVolumeTransaction=totalVolumeTransaction+volumeTransactionTakeStash;
}
}else {
return 0.0;
}
if (buyTotalVolumeTransaction>=sellTotalVolumeTransaction){ //设置平仓前 sell\buy的最高交易交易总量
@ -378,7 +395,7 @@ public class TakeStashController {
if(takeStashList.size()==1){
margin=transactionVolume*Constant.LEVERQUANTITY;
return margin;
}else {
}else if (takeStashList.size()>1){
for (int i = 0; i < takeStashList.size(); i++) {
TakeStash takeStash = takeStashList.get(i);
String buySellTypeTakeStash = takeStash.getBuySellType();
@ -388,6 +405,8 @@ public class TakeStashController {
sellTotalVolumeTransaction=sellTotalVolumeTransaction+takeStash.getVolumeTransaction();
}
}
}else {
margin=0.0;
}
if(Constant.BUY_BUYSELLTYPE.equals(buySellType)){
if(buyTotalVolumeTransaction>=sellTotalVolumeTransaction){

@ -240,19 +240,19 @@ public class MemberService {
memberMapper.deleteByExample(example);
}
//获取可用资金
//获取可用资金 可用资金=净值-已用保证金 净值=总资产+未平仓持单的浮动盈亏
public Double getAvailableFunds(Member member) {
Double positionProfitLoss = flashTotalPositionProfitLoss(member.getMemberId());
if (positionProfitLoss == null) {
positionProfitLoss = 0.0;
}
Double initialCapital = member.getInitialCapital();//初始资金
Double totalAssets = initialCapital + positionProfitLoss;
Double netValue = bigDecimalUtils.add(totalAssets, positionProfitLoss);
Double cumulativeProfitLoss = member.getCumulativeProfitLoss(); //累计盈亏
if (cumulativeProfitLoss == null) {
member.setCumulativeProfitLoss(0.0);
}
Double totalAssets = initialCapital + cumulativeProfitLoss;
Double netValue = bigDecimalUtils.add(totalAssets, positionProfitLoss);
Double marginUsed = member.getMarginUsed(); //获取已用保证金
if (marginUsed == null) {
marginUsed = 0.0;

@ -96,15 +96,12 @@ public class ScheduledTask {
List<ForexMarketData> forexMarketDataList = ForexMarketData.copyToForexData(forexData);
forexMarketDataService.insertAll(forexMarketDataList);
redisUtil.set("ForexDateList", forexMarketDataList);
log.info("--------真实数据插入成功------");
}
//每10秒执行一次 根据真实汇率数据生成模拟汇率数据
@Scheduled(cron = "0/5 * * * * ?")
public void insertSimulatedForexMarketData() {
// if(!timerEnable){
// return;
// }
//获取batchId相同的最后入库的数据
List<ForexMarketData> forexMarketDataList=redisUtil.get("ForexDateList");
// forexMarketDataList = forexMarketDataService.selectLastForexMarketData();
@ -116,7 +113,28 @@ public class ScheduledTask {
List<ForexMarketData> forexMarketData = new ArrayList<>();
String batchId = IdUtil.simpleUUID();
for (ForexMarketData data : forexMarketDataList) {
Double buyPic = modifyDecimal(data.getBuyPic(), random);
Double buyPic = subtractLastDigit(data.getBuyPic(), random);
BigDecimal sp = BigDecimal.valueOf(buyPic);
int randomNumber = random.nextInt(10);
if(randomNumber==1){
sp= BigDecimal.valueOf(buyPic-0.0001).setScale(4, BigDecimal.ROUND_UP);
}else if(randomNumber==2){
sp= BigDecimal.valueOf(buyPic-0.0001).setScale(4, BigDecimal.ROUND_UP);
}else if(randomNumber==3){
sp= BigDecimal.valueOf(buyPic-0.0001).setScale(4, BigDecimal.ROUND_UP);
}else if(randomNumber==4){
sp= BigDecimal.valueOf(buyPic-0.0002).setScale(4, BigDecimal.ROUND_UP);
}else if(randomNumber==5){
sp= BigDecimal.valueOf(buyPic-0.0002).setScale(4, BigDecimal.ROUND_UP);
}else if(randomNumber==6){
sp= BigDecimal.valueOf(buyPic-0.0003).setScale(4, BigDecimal.ROUND_UP);
}else if(randomNumber==7){
sp= BigDecimal.valueOf(buyPic-0.0004).setScale(4, BigDecimal.ROUND_UP);
}else if(randomNumber==8){
sp= BigDecimal.valueOf(buyPic-0.0005).setScale(4, BigDecimal.ROUND_UP);
}else if(randomNumber==9){
sp= BigDecimal.valueOf(buyPic-0.0006).setScale(4, BigDecimal.ROUND_UP);
}
// Double openPriDouble = Double.valueOf(data.getOpenPri());
String diffAmo = bigDecimalUtils.sub(String.valueOf(buyPic), data.getOpenPri()).toString();
ForexMarketData resultData = new ForexMarketData(
@ -131,7 +149,8 @@ public class ScheduledTask {
data.getLowPic(),
data.getOpenPri(),
data.getRanges(),
String.valueOf(modifyDecimal(Double.parseDouble(data.getSellPic()), random)),
sp.toString(),
// String.valueOf(modifyDecimal(Double.parseDouble(data.getSellPic()), random)),
data.getYesPic(),
diffAmo,
data.getDiffPer(),
@ -140,7 +159,7 @@ public class ScheduledTask {
}
// forexMarketDataService.insertAllByMarketData(forexMarketData);
redisUtil.set("ForexDateList", forexMarketData);
log.info("--------插入模拟汇率数据成功------");
// log.info("--------插入模拟汇率数据成功------");
}catch (Exception e) {
log.error("----------插入模拟汇率数据失败:", e.getMessage());
}
@ -177,6 +196,60 @@ public class ScheduledTask {
public double subtractLastDigit(Double num,Random random) {
// 将数字转换为字符串
String numStr="";
numStr = Double.toString(num);
// 提取小数点后的部分
String decimalPart = numStr.split("\\.")[1];
Boolean flag=true;
if (decimalPart.startsWith("0")){
decimalPart="1"+decimalPart.substring(1);
flag=false;
}
if(decimalPart.length()<=3){
decimalPart=decimalPart+"0";
}
if (decimalPart.length()>6){
decimalPart=decimalPart.substring(0,4);
}
// 将提取的小数部分转换为整数
int decimalInt = Integer.parseInt(decimalPart);
// 对最后一位进行减一操作
int randomNumber = random.nextInt(7);
if(randomNumber==1){
decimalInt=decimalInt-1;
}else if(randomNumber==2){
decimalInt=decimalInt-2;
}else if(randomNumber==3){
decimalInt=decimalInt-3;
}else if(randomNumber==4){
decimalInt=decimalInt+1;
}else if(randomNumber==5){
decimalInt=decimalInt+2;
}else if(randomNumber==6){
decimalInt=decimalInt+3;
}
// 构造新的数字
String newNumStr = numStr.split("\\.")[0] + "." + decimalInt;
// 将新的数字转换为double类型并返回
Double v = Double.parseDouble(newNumStr);
if (flag==false){
v=v-0.1;
}
String formattedNum = String.format("%.4f", v); // 保留小数点后四位
Double result = Double.parseDouble(formattedNum);
return result;
}
//监听止损止盈 根据code获取当前买卖价格 如果价格高于/低于止损止盈 则按照止损止盈的值进行平仓
//查询实训表中状态为1的所有实训并获取ID 获取持仓表中所有状态为0 且止损和止盈不为空的所有数据 获取当前价位如果
@Scheduled(cron = "0 */2 * * * ?")
@ -210,28 +283,44 @@ public class ScheduledTask {
Double sellPic = Double.valueOf(forexMarketData.getSellPic());
if(stopLoss!=-1 && sellPic<=stopLoss){
Double margin = takeStashController.startUSDMarginNeed(trainingId, memberId, 0, tradingCode, buySellType, transactionVolume);
if (margin==0.0){
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
continue;
}
Double profitLoss=(stopLoss-priceTransaction)*transactionVolume*Constant.PEACEQUANTITY/stopLoss; //止损盈利
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,sellPic);
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,stopLoss);
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
}
if(stopWin!=-1 && sellPic>=stopWin){
Double margin = takeStashController.startUSDMarginNeed(trainingId, memberId, 0, tradingCode, buySellType, transactionVolume);
if (margin==0.0){
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
continue;
}
Double profitLoss=(stopWin-priceTransaction)*transactionVolume*Constant.PEACEQUANTITY/stopWin; //止盈盈利
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,sellPic);
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,stopWin);
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
}
}else { //开仓方式为卖 则平仓方式为买 先获取买价
Double buyPic = forexMarketData.getBuyPic();
if(stopLoss!=-1 && buyPic<=stopLoss){
Double margin = takeStashController.startUSDMarginNeed(trainingId, memberId, 0, tradingCode, buySellType, transactionVolume);
if (margin==0.0){
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
continue;
}
Double profitLoss=(priceTransaction-stopLoss)*transactionVolume*Constant.PEACEQUANTITY/stopLoss;
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,buyPic);
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,stopLoss);
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
}
if(stopWin!=-1 && buyPic>=stopWin){
Double margin = takeStashController.startUSDMarginNeed(trainingId, memberId, 0, tradingCode, buySellType, transactionVolume);
if (margin==0.0){
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
continue;
}
Double profitLoss=(priceTransaction-stopWin)*transactionVolume*Constant.PEACEQUANTITY/stopWin;
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,buyPic);
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,stopWin);
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
}
}
@ -240,28 +329,44 @@ public class ScheduledTask {
Double sellPic = Double.valueOf(forexMarketData.getSellPic());
if(stopLoss!=-1 && sellPic<=stopLoss){
Double margin = takeStashController.endUSDMarginNeed( trainingId, memberId,0 , tradingCode, buySellType, transactionVolume, priceTransaction);
if (margin==0.0){
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
continue;
}
Double profitLoss=(stopLoss-priceTransaction)*transactionVolume*Constant.PEACEQUANTITY;
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,sellPic);
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,stopLoss);
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
}
if(stopWin!=-1 && sellPic>=stopWin){
Double margin = takeStashController.endUSDMarginNeed( trainingId, memberId,0 , tradingCode, buySellType, transactionVolume, priceTransaction);
if (margin==0.0){
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
continue;
}
Double profitLoss=(stopWin-priceTransaction)*transactionVolume*Constant.PEACEQUANTITY;
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,sellPic);
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,stopWin);
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
}
}else { //开仓方式为卖 则平仓方式为买 先获取买价
Double buyPic = forexMarketData.getBuyPic();
if(stopLoss!=-1 && buyPic<=stopLoss){
Double margin = takeStashController.endUSDMarginNeed( trainingId, memberId,0 , tradingCode, buySellType, transactionVolume, priceTransaction);
if (margin==0.0){
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
continue;
}
Double profitLoss=(priceTransaction-stopLoss)*transactionVolume*Constant.PEACEQUANTITY;
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,buyPic);
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,stopLoss);
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
}
if(stopWin!=-1 && buyPic>=stopWin){
Double margin = takeStashController.endUSDMarginNeed( trainingId, memberId,0 , tradingCode, buySellType, transactionVolume, priceTransaction);
if (margin==0.0){
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
continue;
}
Double profitLoss=(priceTransaction-stopWin)*transactionVolume*Constant.PEACEQUANTITY;
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,buyPic);
takeStashController.updateMemberAndTakeStash(memberId,stashId,profitLoss,margin,stopWin);
redisUtil.del("trainingId_"+trainingId+"_stashId_"+stashId);
}
}

@ -15,6 +15,12 @@ public class BigDecimalUtils {
return b1.add(b2).doubleValue();
}
public double add(double v1, double v2,int scale) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
*
*

Loading…
Cancel
Save