package project.contract.job;
|
|
import java.text.DecimalFormat;
|
import java.util.List;
|
import java.util.Map;
|
|
import kernel.util.StringUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import kernel.util.Arith;
|
import kernel.util.ThreadUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.util.ObjectUtils;
|
import project.contract.ContractLock;
|
import project.contract.ContractOrder;
|
import project.contract.ContractOrderService;
|
import project.contract.ContractRedisKeys;
|
import project.data.DataService;
|
import project.data.model.Realtime;
|
import project.redis.RedisHandler;
|
import project.syspara.SysparaService;
|
import project.wallet.AssetService;
|
import project.wallet.Wallet;
|
import project.wallet.WalletRedisKeys;
|
import project.wallet.WalletService;
|
import project.wallet.consumer.WalletMessage;
|
|
public class ContractOrderCalculationServiceImpl implements ContractOrderCalculationService {
|
private static final Logger logger = LoggerFactory.getLogger(ContractOrderCalculationServiceImpl.class);
|
private ContractOrderService contractOrderService;
|
private DataService dataService;
|
private WalletService walletService;
|
private RedisHandler redisHandler;
|
private AssetService assetService;
|
public final static String STATE_SUBMITTED = "submitted";
|
public final static String STATE_CREATED = "created";
|
/**
|
* 平仓线 110%(订金价值 /收益=110%)
|
*/
|
public double order_close_line = 1.1;
|
/**
|
* 平仓方式 1全仓 2单个持仓
|
*/
|
public int order_close_line_type = 1;
|
private SysparaService sysparaService;
|
|
public void saveCalculation(String order_no) {
|
|
try {
|
ContractOrder order = contractOrderService.findByOrderNo(order_no);
|
if (order == null || !ContractOrder.STATE_SUBMITTED.equals(order.getState())) {
|
/**
|
* 状态已改变,退出处理
|
*/
|
return;
|
}
|
List<Realtime> list = this.dataService.realtime(order.getSymbol());
|
if (list.size() == 0) {
|
return;
|
}
|
Realtime realtime = list.get(0);
|
|
double close = realtime.getClose();
|
|
if (ContractOrder.DIRECTION_BUY.equals(order.getDirection())) {
|
/*
|
* 0 买涨
|
*/
|
logger.info("当前价格:"+close+"---------价格:"+Arith.add(order.getTrade_avg_price(), order.getPips()));
|
if (close >= Arith.add(order.getTrade_avg_price(), order.getPips())) {
|
settle(order, "profit", close);
|
}
|
|
if (close <= Arith.sub(order.getTrade_avg_price(), order.getPips())) {
|
settle(order, "loss", close);
|
}
|
|
} else {
|
/*
|
* 1 买跌
|
*/
|
if (close <= Arith.sub(order.getTrade_avg_price(), order.getPips())) {
|
settle(order, "profit", close);
|
}
|
if (close >= Arith.add(order.getTrade_avg_price(), order.getPips())) {
|
settle(order, "loss", close);
|
}
|
}
|
} catch (Throwable e) {
|
logger.error("OrderCalculationServiceImpll run fail", e);
|
}
|
|
}
|
|
/**
|
* 盈亏计算
|
*
|
* @param profit_loss profit 盈 loss亏
|
* @param currentPrice 当前点位
|
*/
|
public void settle(ContractOrder order, String profit_loss, double currentPrice) {
|
|
double mul = Arith.mul(order.getDeposit_open(), order.getLever_rate());//仓位
|
double div = Arith.div(mul, order.getTrade_avg_price());//持有币的数量
|
double amount = Arith.mul(div, Arith.sub(currentPrice, order.getTrade_avg_price()));
|
logger.info("---------盈亏金额:"+amount);
|
logger.info("---------盈亏:"+profit_loss);
|
if ("profit".equals(profit_loss)) {
|
/**
|
* 盈 正数
|
*/
|
order.setProfit(Arith.add(0.0D, Math.abs(amount)));
|
} else if ("loss".equals(profit_loss)) {
|
order.setProfit(Arith.sub(0.0D,Math.abs(amount) ));
|
|
//--------------------------------------------- 这一段代码是新加的,服务器上面现在是注释的
|
//定义一个 总浮动亏损的值
|
logger.info("----------fffffffffffffff-------"+redisHandler);
|
logger.info("----------ssssssssssss-------"+order.getPartyId().toString());
|
Double contractAssetsProfit = (Double) this.redisHandler.get(ContractRedisKeys.CONTRACT_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString());
|
logger.info("----------bbbbbbbbbbbbbbbbbb-------"+contractAssetsProfit);
|
double contractProfit = null == contractAssetsProfit ? 0.000D : contractAssetsProfit;
|
logger.info("----------contractProfit-------"+contractProfit);
|
if(contractProfit <= 0){
|
redisHandler.setSync("MONEY_CONTRACT_PROFIT_"+order.getPartyId().toString(), contractProfit);
|
}
|
logger.info("----------1111111111111-------");
|
//修改余额,每次修改取平仓前余额减去浮动亏损
|
Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId().toString());
|
logger.info("----------wallet-------"+wallet);
|
Object money = redisHandler.get("PARTY_ID_MONEY_" + order.getPartyId().toString());
|
Object profit = redisHandler.get("MONEY_CONTRACT_PROFIT_" + order.getPartyId().toString());
|
logger.info("----------money-------"+money);
|
logger.info("----------profit-------"+profit);
|
if(!ObjectUtils.isEmpty(money) && !ObjectUtils.isEmpty(profit)){
|
wallet.setMoney(Arith.sub(Double.parseDouble(money.toString()),Double.parseDouble(profit.toString())));
|
}
|
logger.info("----------2222222222222-------");
|
redisHandler.setSync(WalletRedisKeys.WALLET_PARTY_ID + wallet.getPartyId().toString(), wallet);
|
logger.info("----------3333333333333333------");
|
redisHandler.pushAsyn(WalletRedisKeys.WALLET_QUEUE_UPDATE, new WalletMessage(order.getPartyId().toString(), amount));
|
logger.info("----------4444444444444-------");
|
//------------------------------------------
|
}
|
|
double changeRatio;
|
changeRatio = Arith.mul(Arith.div(order.getProfit(), order.getDeposit_open()), 100);
|
DecimalFormat df = new DecimalFormat("#.##");
|
order.setChange_ratio(Double.valueOf(df.format(changeRatio)));
|
|
/**
|
* 多次平仓价格不对,后续修
|
*/
|
order.setClose_avg_price(currentPrice);
|
this.contractOrderService.update(order);
|
/**
|
* 止盈价
|
*/
|
Double profit_stop = order.getStop_price_profit();
|
if (profit_stop != null && profit_stop > 0 && ContractOrder.DIRECTION_BUY.equals(order.getDirection())) {
|
/*
|
* 买涨
|
*/
|
if (currentPrice >= profit_stop) {
|
this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrder_no());
|
return;
|
}
|
} else if (profit_stop != null && profit_stop > 0
|
&& ContractOrder.DIRECTION_SELL.equals(order.getDirection())) {
|
/**
|
* 买跌
|
*/
|
if (currentPrice <= profit_stop) {
|
this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrder_no());
|
return;
|
}
|
}
|
|
/**
|
* 止亏线
|
*/
|
Double loss_stop = order.getStop_price_loss();
|
|
if (loss_stop != null && loss_stop > 0 && ContractOrder.DIRECTION_BUY.equals(order.getDirection())) {
|
/*
|
* 买涨
|
*/
|
if (currentPrice <= loss_stop) {
|
this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrder_no());
|
return;
|
|
}
|
} else if (loss_stop != null && loss_stop > 0 && ContractOrder.DIRECTION_SELL.equals(order.getDirection())) {
|
/**
|
* 买跌
|
*/
|
|
if (currentPrice >= loss_stop) {
|
this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrder_no());
|
return;
|
}
|
}
|
logger.info("order_close_line_type:"+order_close_line_type);
|
if (order_close_line_type == 1) {
|
/**
|
* 收益
|
*/
|
double profit = 0;
|
|
List<ContractOrder> list = contractOrderService.findSubmitted(order.getPartyId().toString(), null, null);
|
for (int i = 0; i < list.size(); i++) {
|
ContractOrder close_line = list.get(i);
|
profit = Arith.add(profit, Arith.add(close_line.getProfit(), close_line.getDeposit()));
|
}
|
Wallet wallet = this.walletService.saveWalletByPartyId(order.getPartyId().toString());
|
double totleMoney = wallet.getMoney();
|
if (Arith.add(profit,totleMoney) <= 0) {
|
/**
|
* 触发全仓强平
|
*/
|
this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrder_no());
|
ThreadUtils.sleep(100);
|
for (int i = 0; i < list.size(); i++) {
|
ContractOrder close_line = list.get(i);
|
if (!order.getOrder_no().equals(close_line.getOrder_no())) {
|
try {
|
|
while (true) {
|
if (ContractLock.add(close_line.getOrder_no())) {
|
this.contractOrderService.saveClose(close_line.getPartyId().toString(),
|
close_line.getOrder_no());
|
/**
|
* 处理完退出
|
*/
|
break;
|
}
|
ThreadUtils.sleep(500);
|
|
}
|
|
} catch (Exception e) {
|
logger.error("error:", e);
|
} finally {
|
ContractLock.remove(close_line.getOrder_no());
|
ThreadUtils.sleep(100);
|
}
|
|
}
|
}
|
|
}
|
} else {
|
logger.info("---------进入单个持仓----------------");
|
logger.info("---------order.getProfit()----------------"+order.getProfit());
|
logger.info("---------order.getDeposit()----------------"+order.getDeposit());
|
logger.info("---------order_close_line----------------"+order_close_line);
|
if (order.getProfit() < 0 && (Arith.div(order.getDeposit(), Math.abs(order.getProfit())) <= Arith
|
.div(order_close_line, 100))) {
|
logger.info("---------进入强平了----------------");
|
/**
|
* 低于系统默认平仓线,进行强平
|
*/
|
this.contractOrderService.saveClose(order.getPartyId().toString(), order.getOrder_no());
|
return;
|
}
|
}
|
|
}
|
public void setDataService(DataService dataService) {
|
this.dataService = dataService;
|
}
|
|
public void setSysparaService(SysparaService sysparaService) {
|
this.sysparaService = sysparaService;
|
}
|
|
public void setContractOrderService(ContractOrderService contractOrderService) {
|
this.contractOrderService = contractOrderService;
|
}
|
|
public void setWalletService(WalletService walletService) {
|
this.walletService = walletService;
|
}
|
|
public void setOrder_close_line(double order_close_line) {
|
this.order_close_line = order_close_line;
|
}
|
|
public void setOrder_close_line_type(int order_close_line_type) {
|
this.order_close_line_type = order_close_line_type;
|
}
|
|
public void setRedisHandler(RedisHandler redisHandler) {
|
this.redisHandler = redisHandler;
|
}
|
|
public void setAssetService(AssetService assetService) {
|
this.assetService = assetService;
|
}
|
|
|
}
|