package com.xcong.excoin.modules.okxNewPrice.okxWs; import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.CoinEnums; import com.xcong.excoin.modules.okxNewPrice.okxWs.enums.OrderParamEnums; import com.xcong.excoin.modules.okxNewPrice.utils.WsMapBuild; import com.xcong.excoin.modules.okxNewPrice.utils.WsParamBuild; import lombok.extern.slf4j.Slf4j; import org.java_websocket.client.WebSocketClient; import java.math.BigDecimal; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * 交易订单处理类,负责构建和发送订单请求到OKX WebSocket * * @author Administrator */ @Slf4j public class TradeOrderWs { public static final Map TRADEORDERWSMAP = new ConcurrentHashMap<>(); public static final String ORDERWS_CHANNEL = "order"; public static void orderEvent(WebSocketClient webSocketClient, String side) { log.info("开始执行TradeOrderWs......"); // 校验必要参数 if (StrUtil.isBlank(side)) { log.warn("下单参数 side 为空,取消发送"); return; } String buyCnt = ""; if (OrderParamEnums.HOLDING.getValue().equals(side)){ log.info("当前状态为持仓中,取消发送"); return; }else if (OrderParamEnums.OUT.getValue().equals(side)){ log.info("当前状态为止损"); side = OrderParamEnums.SELL.getValue(); buyCnt = String.valueOf(PositionsWs.POSITIONSWSMAP.get("pos")); }else if (OrderParamEnums.INIT.getValue().equals(side)){ log.info("当前状态为初始化"); side = OrderParamEnums.BUY.getValue(); buyCnt = InstrumentsWs.INSTRUMENTSWSMAP.get(CoinEnums.BUY_CNT.name()); }else if (OrderParamEnums.BUY.getValue().equals(side)){ log.info("当前状态为加仓"); buyCnt = InstrumentsWs.INSTRUMENTSWSMAP.get(CoinEnums.BUY_CNT.name()); }else if (OrderParamEnums.SELL.getValue().equals(side)){ log.info("当前状态为减仓"); buyCnt = String.valueOf(PositionsWs.POSITIONSWSMAP.get("pos")); }else{ log.warn("交易状态异常,取消发送"); return; } if (StrUtil.isBlank(buyCnt)) { log.warn("下单数量 buyCnt 为空,取消发送"); return; } try { String clOrdId = WsParamBuild.getOrderNum(side); JSONArray argsArray = new JSONArray(); JSONObject args = new JSONObject(); args.put("instId", CoinEnums.HE_YUE.getCode()); args.put("tdMode", CoinEnums.CROSS.getCode()); args.put("clOrdId", clOrdId); args.put("side", side); args.put("posSide", CoinEnums.POSSIDE_LONG.getCode()); args.put("ordType", CoinEnums.ORDTYPE_MARKET.getCode()); args.put("sz", buyCnt); argsArray.add(args); String connId = WsParamBuild.getOrderNum(ORDERWS_CHANNEL); JSONObject jsonObject = WsParamBuild.buildJsonObject(connId, ORDERWS_CHANNEL, argsArray); webSocketClient.send(jsonObject.toJSONString()); log.info("发送下单频道:{},数量:{}", side, buyCnt); WsMapBuild.saveStringToMap(TRADEORDERWSMAP, "clOrdId", clOrdId); WsMapBuild.saveStringToMap(TRADEORDERWSMAP, "state", CoinEnums.ORDER_FILLED.getCode()); } catch (Exception e) { log.error("下单构建失败", e); } } /** * 计算盈亏金额。 * * @param faceValue 面值 * @param position 持仓数量 * @param markPrice 标记价格 * @param openPrice 开仓价格 * @param isLong 是否为多头仓位 * @param minTickSz 最小变动单位精度 * @return 盈亏金额,保留指定精度的小数位 */ public BigDecimal profit(BigDecimal faceValue, BigDecimal position, BigDecimal markPrice, BigDecimal openPrice, boolean isLong, int minTickSz) { BigDecimal profit = BigDecimal.ZERO; if (isLong) { profit = markPrice.subtract(openPrice) .multiply(faceValue) .multiply(position); } else { profit = openPrice.subtract(markPrice) .multiply(faceValue) .multiply(position); } return profit.setScale(minTickSz, BigDecimal.ROUND_DOWN); } }