| New file |
| | |
| | | package com.xcong.excoin.modules.gateApi.wsHandler.handler; |
| | | |
| | | import com.alibaba.fastjson.JSONArray; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.xcong.excoin.modules.gateApi.GateGridTradeService; |
| | | import com.xcong.excoin.modules.gateApi.wsHandler.AbstractPrivateChannelHandler; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.java_websocket.client.WebSocketClient; |
| | | |
| | | /** |
| | | * 自动订单频道处理器(futures.autoorders)。 |
| | | * |
| | | * <h3>数据用途</h3> |
| | | * 订阅用户自动订单(条件单)更新推送。当条件单状态变更(已触发、已取消等)时, |
| | | * 获得订单 ID、状态、触发信息等,可用于跟踪条件单生命周期。 |
| | | * |
| | | * <h3>与 futures.orders 的区别</h3> |
| | | * {@code futures.autoorders} 推送的是条件订单(价格触发单)的状态变更, |
| | | * 而 {@code futures.orders} 推送的是普通订单(市价单、限价单)的成交/取消。 |
| | | * |
| | | * <h3>关键推送字段</h3> |
| | | * <ul> |
| | | * <li>id:自动订单 ID</li> |
| | | * <li>status:订单状态(open / finished / cancelled)</li> |
| | | * <li>reason:变更原因</li> |
| | | * <li>trigger.price / trigger.rule:触发条件</li> |
| | | * <li>order_type:止盈/止损类型</li> |
| | | * <li>trade_id:关联交易 ID</li> |
| | | * </ul> |
| | | * |
| | | * <h3>注意</h3> |
| | | * 此频道的 payload 仅需 [contract],无需 userId(与 futures.orders 不同)。 |
| | | * |
| | | * @author Administrator |
| | | */ |
| | | @Slf4j |
| | | public class AutoOrdersChannelHandler extends AbstractPrivateChannelHandler { |
| | | |
| | | private static final String CHANNEL_NAME = "futures.autoorders"; |
| | | |
| | | public AutoOrdersChannelHandler(String apiKey, String apiSecret, |
| | | String contract, |
| | | GateGridTradeService gridTradeService) { |
| | | super(CHANNEL_NAME, apiKey, apiSecret, contract, gridTradeService); |
| | | } |
| | | |
| | | /** |
| | | * 发送订阅请求,payload 仅需 [contract](此频道不需要 userId)。 |
| | | */ |
| | | @Override |
| | | public void subscribe(WebSocketClient ws) { |
| | | long timeSec = System.currentTimeMillis() / 1000; |
| | | JSONObject msg = new JSONObject(); |
| | | msg.put("id", timeSec * 1000000 + (System.currentTimeMillis() % 1000)); |
| | | msg.put("time", timeSec); |
| | | msg.put("channel", CHANNEL_NAME); |
| | | msg.put("event", "subscribe"); |
| | | JSONArray payload = new JSONArray(); |
| | | payload.add(getContract()); |
| | | msg.put("payload", payload); |
| | | JSONObject auth = new JSONObject(); |
| | | auth.put("method", "api_key"); |
| | | auth.put("KEY", apiKey); |
| | | auth.put("SIGN", hs512Sign("subscribe", timeSec)); |
| | | msg.put("auth", auth); |
| | | ws.send(msg.toJSONString()); |
| | | log.info("[{}] 订阅成功, 合约:{}", CHANNEL_NAME, getContract()); |
| | | } |
| | | |
| | | @Override |
| | | public boolean handleMessage(JSONObject response) { |
| | | if (!CHANNEL_NAME.equals(response.getString("channel"))) { |
| | | return false; |
| | | } |
| | | try { |
| | | JSONArray resultArray = response.getJSONArray("result"); |
| | | if (resultArray == null || resultArray.isEmpty()) { |
| | | return true; |
| | | } |
| | | for (int i = 0; i < resultArray.size(); i++) { |
| | | JSONObject autoOrder = resultArray.getJSONObject(i); |
| | | JSONObject initial = autoOrder.getJSONObject("initial"); |
| | | if (initial == null) { |
| | | continue; |
| | | } |
| | | if (!getContract().equals(initial.getString("contract"))) { |
| | | continue; |
| | | } |
| | | String orderId = String.valueOf(autoOrder.getLong("id")); |
| | | String status = autoOrder.getString("status"); |
| | | String reason = autoOrder.getString("reason"); |
| | | String orderType = autoOrder.getString("order_type"); |
| | | JSONObject trigger = autoOrder.getJSONObject("trigger"); |
| | | String triggerPrice = trigger != null ? trigger.getString("price") : null; |
| | | log.info("[{}] 自动订单更新, id:{}, status:{}, reason:{}, order_type:{}, trigger_price:{}, trade_id:{}", |
| | | CHANNEL_NAME, orderId, status, reason, orderType, triggerPrice, |
| | | autoOrder.get("trade_id")); |
| | | if (getGridTradeService() != null) { |
| | | getGridTradeService().onAutoOrder(orderId, status, reason, orderType); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("[{}] 处理数据失败", CHANNEL_NAME, e); |
| | | } |
| | | return true; |
| | | } |
| | | } |