package com.xcong.excoin.modules.okxApi; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.nio.charset.StandardCharsets; @Slf4j public class OkxRestClient { private final String baseUrl; private final String apiKey; private final String secretKey; private final String passphrase; private final boolean isSimulate; public OkxRestClient(String baseUrl, String apiKey, String secretKey, String passphrase, boolean isSimulate) { this.baseUrl = baseUrl; this.apiKey = apiKey; this.secretKey = secretKey; this.passphrase = passphrase; this.isSimulate = isSimulate; } public boolean setPositionMode(String posMode) { JSONObject params = new JSONObject(); params.put("posMode", posMode); JSONObject result = post("/api/v5/account/set-position-mode", params); return isSuccess(result, "设置持仓方式"); } public boolean setLeverage(String instId, String lever, String mgnMode) { JSONObject params = new JSONObject(); params.put("instId", instId); params.put("lever", lever); params.put("mgnMode", mgnMode); JSONObject result = post("/api/v5/account/set-leverage", params); return isSuccess(result, "设置杠杆"); } public String fetchInstIdCode(String instType, String instId) { String path = "/api/v5/account/instruments?instType=" + instType + "&instId=" + instId; JSONObject result = get(path); if (result == null || !"0".equals(result.getString("code"))) { log.error("[REST] 获取instIdCode失败, code:{}, msg:{}", result != null ? result.getString("code") : "null", result != null ? result.getString("msg") : "no response"); return null; } com.alibaba.fastjson.JSONArray data = result.getJSONArray("data"); if (data == null || data.isEmpty()) { log.error("[REST] 获取instIdCode失败: data为空"); return null; } JSONObject first = data.getJSONObject(0); String instIdCode = first.getString("instIdCode"); log.info("[REST] 获取instIdCode成功, instId:{}, instIdCode:{}", instId, instIdCode); return instIdCode; } private JSONObject get(String path) { HttpURLConnection conn = null; try { String timestamp = OkxWsUtil.getIso8601Timestamp(); String sign = OkxWsUtil.signRest(timestamp, "GET", path, "", secretKey); URL url = new URL(baseUrl + path); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(15000); conn.setReadTimeout(15000); conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("OK-ACCESS-KEY", apiKey); conn.setRequestProperty("OK-ACCESS-SIGN", sign); conn.setRequestProperty("OK-ACCESS-TIMESTAMP", timestamp); conn.setRequestProperty("OK-ACCESS-PASSPHRASE", passphrase); if (isSimulate) { conn.setRequestProperty("x-simulated-trading", "1"); } int code = conn.getResponseCode(); String response = readResponse(conn); log.info("[REST] GET {} → HTTP {} body:{}", path, code, response); return JSON.parseObject(response); } catch (Exception e) { log.error("[REST] GET {} 失败: {}", path, e.getMessage()); return null; } finally { if (conn != null) { conn.disconnect(); } } } private JSONObject post(String path, JSONObject body) { HttpURLConnection conn = null; try { String bodyStr = body.toJSONString(); String timestamp = OkxWsUtil.getIso8601Timestamp(); String sign = OkxWsUtil.signRest(timestamp, "POST", path, bodyStr, secretKey); URL url = new URL(baseUrl + path); conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setConnectTimeout(15000); conn.setReadTimeout(15000); conn.setRequestProperty("Content-Type", "application/json"); conn.setRequestProperty("OK-ACCESS-KEY", apiKey); conn.setRequestProperty("OK-ACCESS-SIGN", sign); conn.setRequestProperty("OK-ACCESS-TIMESTAMP", timestamp); conn.setRequestProperty("OK-ACCESS-PASSPHRASE", passphrase); if (isSimulate) { conn.setRequestProperty("x-simulated-trading", "1"); } try (OutputStream os = conn.getOutputStream()) { os.write(bodyStr.getBytes(StandardCharsets.UTF_8)); os.flush(); } int code = conn.getResponseCode(); String response = readResponse(conn); log.info("[REST] POST {} → HTTP {} body:{}", path, code, response); return JSON.parseObject(response); } catch (Exception e) { log.error("[REST] POST {} 失败: {}", path, e.getMessage()); return null; } finally { if (conn != null) { conn.disconnect(); } } } private String readResponse(HttpURLConnection conn) throws Exception { StringBuilder sb = new StringBuilder(); String line; if (conn.getResponseCode() >= 200 && conn.getResponseCode() < 300) { try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8))) { while ((line = br.readLine()) != null) { sb.append(line); } } } else { try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getErrorStream(), StandardCharsets.UTF_8))) { while ((line = br.readLine()) != null) { sb.append(line); } } } return sb.toString(); } private boolean isSuccess(JSONObject result, String label) { if (result == null) { log.error("[REST] {}失败: 无响应", label); return false; } String code = result.getString("code"); if ("0".equals(code)) { log.info("[REST] {}成功", label); return true; } if ("59000".equals(code)) { log.info("[REST] {}已设置(59000:配置未变更)", label); return true; } log.error("[REST] {}失败, code:{}, msg:{}", label, code, result.getString("msg")); return false; } }