BitMEX 인증, 포지션 구독 및 JSON 데이터 처리
이전 글에서 WebSocket을 통한 BitMEX 인증 절차를 다뤘습니다. 이번 글에서는 인증 후 전달되는 포지션(Position) 이벤트를 Java에서 안전하게 파싱하고, 파싱한 정보를 기반으로 트레이딩 로직을 실시간으로 적용하는 방법을 심도 있게 설명합니다. BitMEX 인증, 포지션 구독 및 JSON 데이터 처리 관점에서 실무에 바로 적용 가능한 패턴을 제시합니다.
1. 🔑 인증 및 포지션 구독 (복습)
실시간 포지션을 안정적으로 처리하려면 WebSocket 연결과 서명 기반 인증이 먼저 완료되어야 합니다. 인증 이후에는 서버로부터 포지션 업데이트를 받기 위해 구독 명령을 전송합니다. 아래 예시는 인증 후 포지션 채널을 구독하는 최소한의 순서입니다.
// 1. 인증 요청: authKeyExpires 전송 (API_KEY, EXPIRES, SIGNATURE 포함)
// 2. 구독 요청
ws.sendText("{\"op\" : \"subscribe\" , \"args\" : [\"position:XBTUSD\"]}");
2. 📝 수신된 포지션 JSON 데이터 구조 분석
BitMEX에서 전달되는 포지션 업데이트는 여러 필드를 포함하는 JSON 객체로 옵니다. 핵심은 상위의 table과 action 필드이며, 실제 값은 data 배열 안에 들어 있습니다. 이 정보를 바탕으로 필요한 필드만 추출해 상태를 갱신하면 됩니다.
수신 JSON 예시 (초기 데이터 또는 업데이트)
{
"table": "position",
"action": "partial" | "update", // partial: 초기 데이터, update: 갱신 데이터
"data": [
{
"symbol": "XBTUSD",
"currentQty": 1000, // 현재 포지션 크기 (롱: 양수, 숏: 음수)
"avgEntryPrice": 60000.0, // 평균 진입 가격
"unrealisedPnl": 0.0001, // 미실현 손익 (BTC)
"liquidationPrice": 55000.0, // 청산 가격
"marginUsedPcnt": 0.05,
// ... (수십 개의 다른 필드)
"timestamp": "2025-11-12T12:00:00.000Z"
}
]
}
목표는 이 JSON을 Java 객체로 직렬화(Deserialization)해 currentQty, avgEntryPrice 같은 필드에 빠르게 접근하고, 변경사항이 생길 때마다 비즈니스 로직으로 처리하는 것입니다.
3. 🚀 JSON 파싱 및 데이터 처리 (with Jackson)
Java에서는 Jackson을 이용해 JSON을 POJO로 매핑하는 것이 효율적입니다. Spring Boot 환경에서는 기본 설정으로 Jackson을 사용하기 때문에 별도 설정 없이도 안정적인 파싱이 가능합니다.
3.1. 필요한 데이터 모델 (DTO/VO) 정의
수신되는 객체의 모든 필드를 모델링할 필요는 없습니다. 관심 필드만 담은 간결한 DTO를 만들어 가독성과 유지보수성을 높이세요. 미지의 필드는 무시하도록 처리하면 파싱 오류를 줄일 수 있습니다.
Java PositionData.java
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
// 알 수 없는 필드는 무시하여 파싱 오류 방지
@JsonIgnoreProperties(ignoreUnknown = true)
public class PositionData {
private String symbol;
private Long currentQty;
private Double avgEntryPrice;
private Double liquidationPrice;
// Getter and Setter (또는 Lombok)
public String getSymbol() { return symbol; }
public Long getCurrentQty() { return currentQty; }
// ... (나머지 Getter/Setter)
}
3.2. WebSocket 리스너에서 파싱 및 처리
실시간 메시지 수신 핸들러에서는 먼저 최상위 노드의 table 과 action을 확인합니다. 해당 채널의 데이터일 때만 data 배열을 DTO로 변환해 비즈니스 처리 함수에 전달하면 안전합니다.
Java WebSocketAdapter (onTextMessage)
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
// ... (클래스 정의 및 import 생략)
public class WebSocketChatClient {
private static final ObjectMapper MAPPER = new ObjectMapper();
// ... (인증 로직 생략)
public static void main(String[] args) throws Exception {
// ... (ws 연결 및 인증 로직 생략)
.addListener(new WebSocketAdapter() {
@Override
public void onTextMessage(WebSocket ws, String message) {
try {
// 1. JSON 문자열을 JsonNode로 파싱
JsonNode rootNode = MAPPER.readTree(message);
// 2. 테이블과 액션 확인
String table = rootNode.get("table").asText();
String action = rootNode.get("action").asText();
if ("position".equals(table) && rootNode.has("data")) {
// 3. 'data' 배열을 PositionData 객체 리스트로 변환
JsonNode dataArray = rootNode.get("data");
for (JsonNode dataNode : dataArray) {
PositionData position = MAPPER.treeToValue(dataNode, PositionData.class);
// 4. 비즈니스 로직 실행
processPositionUpdate(position, action);
}
}
} catch (Exception e) {
System.err.println("JSON 파싱 오류: " + e.getMessage());
}
}
}).connect();
}
private static void processPositionUpdate(PositionData position, String action) {
System.out.println("----------------------------------------");
System.out.printf("액션: %s, 심볼: %s\n", action, position.getSymbol());
System.out.printf("포지션 크기: %d, 진입가: %.2f\n", position.getCurrentQty(), position.getAvgEntryPrice());
// 예시: 롱 포지션일 경우 특정 로직 수행
if (position.getCurrentQty() > 0) {
System.out.println("-> 롱 포지션 상태, 청산가 확인 필요.");
}
}
}
위 예시에서는 예외를 포착해 로그로 남기고, 각 포지션 이벤트를 분리해 처리합니다. 이 패턴은 BitMEX 인증, 포지션 구독 및 JSON 데이터 처리 흐름을 안정적으로 관리하는 데 유용합니다.
🚀 이 주제, 우리 서비스에 어떻게 적용할까요?
BitMEX 인증, 포지션 구독 및 JSON 데이터 처리를 실제 서비스와 조직에 녹여보고 싶다면, 현재 아키텍처와 운영 방식을 한 번 점검해 보는 것부터 시작해 보세요. 팀 위키나 기술 블로그, 사내 스터디 주제로도 아주 좋습니다.
이 글이 도움이 됐다면, 비슷한 엔터프라이즈 사례 글들도 함께 살펴보면서 우리 조직에 맞는 운영 상용구를 정의해 보세요.
4. 💡 결론 및 요약
요약하면, BitMEX WebSocket 통합은 서명 기반의 인증과, 수신된 JSON을 신뢰성 있게 객체화하여 처리하는 두 단계로 나뉩니다. 인증이 완료되면 포지션 채널을 구독하고, partial 과 update 액션을 기준으로 상태를 갱신해야 합니다.
실무에서는 DTO를 최소화하고, 액션별로 처리 로직을 분리하며, 예외 상황(파싱 실패, 예상치 못한 필드)을 로깅해 복구 전략을 갖추는 것이 핵심입니다. 이렇게 하면 실시간 포지션을 기반으로 한 자동화 트레이딩 로직을 신뢰성 있게 운영할 수 있습니다.
댓글
댓글 쓰기