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");
|
String tradeId = autoOrder.getString("trade_id");
|
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,
|
tradeId);
|
if (getGridTradeService() != null) {
|
getGridTradeService().onAutoOrder(orderId, status, reason, orderType, tradeId);
|
}
|
}
|
} catch (Exception e) {
|
log.error("[{}] 处理数据失败", CHANNEL_NAME, e);
|
}
|
return true;
|
}
|
}
|