| | |
| | | import org.java_websocket.client.WebSocketClient; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.concurrent.ExecutorService; |
| | | import java.util.concurrent.LinkedBlockingQueue; |
| | |
| | | */ |
| | | @Slf4j |
| | | public class OkxTradeExecutor { |
| | | |
| | | private static final String ORDER_TYPE_CLOSE_LONG = "plan-close-long-position"; |
| | | private static final String ORDER_TYPE_CLOSE_SHORT = "plan-close-short-position"; |
| | | |
| | | private final String contract; |
| | | private final String marginMode; |
| | |
| | | executor.execute(() -> { |
| | | String posSide; |
| | | String side; |
| | | if (ORDER_TYPE_CLOSE_LONG.equals(orderType)) { |
| | | if (OkxEnums.ORDER_TYPE_CLOSE_LONG.equals(orderType)) { |
| | | posSide = OkxEnums.POSSIDE_LONG; |
| | | side = OkxEnums.SIDE_SELL; |
| | | } else { |
| | | } else if (OkxEnums.ORDER_TYPE_CLOSE_SHORT.equals(orderType)) { |
| | | posSide = OkxEnums.POSSIDE_SHORT; |
| | | side = OkxEnums.SIDE_BUY; |
| | | } else { |
| | | log.error("[TradeExec] 未知止盈类型: {}", orderType); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | TradeRequestParam param = buildParam(side, posSide, size, OkxEnums.ORDTYPE_LIMIT); |
| | | param.setMarkPx(triggerPrice.toString()); |
| | | if (wsClient == null || !wsClient.isOpen()) { |
| | | log.warn("[TradeExec] WS未连接,跳过止盈单"); |
| | | return; |
| | | } |
| | | if (BigDecimal.ZERO.compareTo(new BigDecimal(size)) >= 0) { |
| | | log.warn("[TradeExec] 止盈数量<=0,跳过"); |
| | | return; |
| | | } |
| | | |
| | | List<TradeRequestParam> params = new ArrayList<>(); |
| | | params.add(param); |
| | | sendBatchOrders(params); |
| | | JSONArray argsArray = new JSONArray(); |
| | | JSONObject args = new JSONObject(); |
| | | args.put("instId", contract); |
| | | args.put("tdMode", marginMode); |
| | | args.put("side", side); |
| | | args.put("posSide", posSide); |
| | | args.put("ordType", OkxEnums.ORDTYPE_CONDITIONAL); |
| | | args.put("sz", size); |
| | | args.put("tpTriggerPx", triggerPrice.toString()); |
| | | args.put("tpOrdPx", "-1"); |
| | | argsArray.add(args); |
| | | |
| | | String connId = OkxWsUtil.getOrderNum("algo"); |
| | | JSONObject msg = OkxWsUtil.buildJsonObject(connId, "order-algo", argsArray); |
| | | wsClient.send(msg.toJSONString()); |
| | | log.info("[TradeExec] 止盈单已发送, 触发价:{}, 类型:{}, size:{}", triggerPrice, orderType, size); |
| | | } catch (Exception e) { |
| | | log.error("[TradeExec] 止盈单发送失败, 触发价:{}, size:{}, 立即市价止盈", triggerPrice, size, e); |
| | |
| | | return param; |
| | | } |
| | | |
| | | private JSONObject buildOrderArgs(TradeRequestParam param) { |
| | | JSONObject args = new JSONObject(); |
| | | args.put("instId", param.getInstId()); |
| | | args.put("tdMode", param.getTdMode()); |
| | | args.put("clOrdId", param.getClOrdId()); |
| | | args.put("side", param.getSide()); |
| | | args.put("posSide", param.getPosSide()); |
| | | args.put("ordType", param.getOrdType()); |
| | | args.put("sz", param.getSz()); |
| | | return args; |
| | | } |
| | | |
| | | private void sendOrder(TradeRequestParam param) { |
| | | if (wsClient == null || !wsClient.isOpen()) { |
| | | log.warn("[TradeExec] WS未连接,跳过下单"); |
| | |
| | | } |
| | | |
| | | JSONArray argsArray = new JSONArray(); |
| | | JSONObject args = new JSONObject(); |
| | | args.put("instId", param.getInstId()); |
| | | args.put("tdMode", param.getTdMode()); |
| | | args.put("clOrdId", param.getClOrdId()); |
| | | args.put("side", param.getSide()); |
| | | args.put("posSide", param.getPosSide()); |
| | | args.put("ordType", param.getOrdType()); |
| | | args.put("sz", param.getSz()); |
| | | argsArray.add(args); |
| | | argsArray.add(buildOrderArgs(param)); |
| | | |
| | | String connId = OkxWsUtil.getOrderNum("order"); |
| | | JSONObject msg = OkxWsUtil.buildJsonObject(connId, "order", argsArray); |
| | |
| | | |
| | | JSONArray argsArray = new JSONArray(); |
| | | for (TradeRequestParam p : params) { |
| | | JSONObject args = new JSONObject(); |
| | | args.put("instId", p.getInstId()); |
| | | args.put("tdMode", p.getTdMode()); |
| | | args.put("clOrdId", p.getClOrdId()); |
| | | args.put("side", p.getSide()); |
| | | args.put("posSide", p.getPosSide()); |
| | | args.put("ordType", p.getOrdType()); |
| | | args.put("sz", p.getSz()); |
| | | args.put("px", p.getMarkPx()); |
| | | argsArray.add(args); |
| | | argsArray.add(buildOrderArgs(p)); |
| | | } |
| | | |
| | | String connId = OkxWsUtil.getOrderNum(null); |