아비트라지: 거래소 API

아비트라지를 자동화 하기 위하여 이용할 ‘거래소 API’에 대해 알아본다.

개요

지난번 글에서 짧게 언급한 바와 같이, 우리는 아비트라지를 진행하기 위해 수동이 아닌 자동거래를 해야 한다는 것을 이미 알고 있다. 이를 가능하게 해주는 핵심파트는 거래소와 내 주문의 현재 상태를 알아낸 후 주문을 변경하는 데에 있고, 이 과정은 거래소가 제공하는 API를 통하여 실현이 가능하다.

API란?

거래소가 제공하는 API(Application Programming Interface)란, 유저의 다양한 요청에 의하여 해당하는 정보를 리턴해주거나 특정한 동작을 수행해주는 인터페이스를 뜻한다. 즉, 거래소는 하나의 프로그램이며 자체적으로 동작하고 있는데, 외부에서 유저가 자신들의 프로그램을 이용하여 거래소와 정보를 주고 받고 싶을 때 API를 이용하여 서로 통신하게 된다.

실제로 제공되고 있는 API들을 접속 방식으로 나누어 보면 크게 웹소켓 방식과 REST방식으로 나눌수 있고, 인증여부에 따라서 public API와 private API로 나눌 수 있으며, 제공하는 서비스에 따라서 조회전용, 거래가능, 이체가능 등으로 나누어 볼 수도 있다.

출처: https://www.coinstaker.com/bitcoin-exchanges/cex-review/
(아무 그림도 넣지 않을 경우 썸네일에 내 얼굴이 뜨길래 화들짝 놀라서 아무 그림이나 갖다 넣어보았다)

무슨 정보가 필요할까?

아비트라지를 하기 위해서 필요한 정보를 정리해 보자. 아래의 정보 정도가 최소한으로 필요할 것이다.

  • 현재 오더북 상태 (bid/ask 양쪽의 가격과 수량정보)
  • 내 잔고 현황, 내 주문 처리 상황 (오픈오더와 체결정보), 파생시장의 경우 포지션 정보
  • 주문 넣기 / 변경하기 / 취소하기

웹소켓(web-socket) 방식

웹소켓에 대한 일반적인 소개는 굳이 이 글에서 할 필요는 없으리라 생각된다. 거래소가 제공하는 웹소켓 API를 이용하여 유저와 거래소는 지속적인 커넥션을 유지하고, 주기적으로 혹은 상태의 변경이 있을 때마다 원하는 정보를 전달 받는다. 일반적으로 반응속도가 빠른 것이 장점이지만, 계속 연결을 유지하고 있으므로 전체 시스템에서는 부담이 되는 요인이 된다.

웹소켓 자체가 거래소에 부담이 될 수 있기 때문에, 많은 거래소에서 웹소켓 API가 다룰 수 있는 정보의 종류를 상당히 좁게 한정 시켜두었다. 아비트라지를 하기 위해서 웹소켓을 이용하여 1) 현재 오더북 상태 2) 내 잔고 현황 3) 오픈 오더의 상태 4) 포지션 정보 등을 일반 적으로 얻을 수 있다.

이 때 체결정보를 주는 거래소가 있고, 그렇지 않은 거래소가 있는데, 만약 체결정보를 주지 않는 거래소라면 오픈오더의 변경값을 이용하여 체결량을 계산해야 한다. 또한, 오더북의 경우에도 전체 오더북을 다 받는 경우도 있을 수 있지만, 변경된 정보만을 받는 경우도 있으므로, 이 경우 기존의 오더북에 변경량을 적용하여 전체 오더북을 업데이트 하는 방식으로 유지할 수도 있다. 이런 경우 직접 코드를 작성하기 보다는 거래소 API를 라이브러리화 해둔 오픈소스 등을 이용하는 것이 편리하다.

참고로, 거래소에 따라 차이가 크게 있을 수 있지만, 웹소켓 정보의 수신 빈도는 보통 1초에 몇번 정도의 빈도인 것으로 보인다. 단, 체결량 정보를 주는 경우 한참 동안 아무런 정보가 오지 않을 수도 있다. 구현하기 전에 거래소 별로 충분한 테스트가 필요하고, 그에 따른 전략의 수정이 요구된다.

REST 방식

REST(Representational State Transfer) 방식을 이용한 API 이용은 우리에게 보다 친숙한 형태이다. HTTP(S) 프로토콜을 이용하여 호출하고, 모니터 화면으로 그 결과를 확인하는 것도 가능하다. (보통 JSON 오브젝트를 리턴해 준다.) 이 방식은 호출을 할 때만 거래소와 커넥션을 만들고 바로 그 커넥션을 끊어버리기 때문에 거래소 입장에서는 부담이 덜 한 방식이고, 따라서 일반적으로 REST 형식에서는 거의 대부분의 기능을 제공하는 것이 일반적이다. 즉, REST 방식의 API는 앞서의 웹소켓 API가 제공하는 정보를 거의 다 포함하고 있으며, 여기에 추가적인 기능을 제공하고 있다.

유저 입장에서는 웹소켓으로 처리하는 것이 빠르고 확실하므로 되도록 많은 부분을 웹소켓으로 처리하고, 그 외의 부분을 REST로 처리하는 것이 이득이 되는데, 결국 새로운 주문을 생성하기, 기존의 주문을 변경하기, 취소하기를 여기서 담당하게 된다. 물론 주문의 생성/변경/취소를 웹소켓을 통하여 지원하는 거래소도 분명히 있겠지만, 대부분의 거래소 API들은 주문 관련 액션들은 REST로만 지원하고 있었다.

그래서 어떻게 만들어야 하는거지?

다양한 방식으로 본인만의 아비트라저를 만들 수 있겠지만 큰 틀은 변하지 않을 것이라 생각한다. 웹소켓을 이용하여 현재의 오더북 상태를 받아들이고 주문이 필요한 시점인지 아닌지를 판단한다. 주문이 필요한 시점인 경우 기존의 내 주문 정보 중 체결되지 않고 남은 수량과 현재의 내 잔고정보를 이용하여 얼마의 가격에 얼마의 수량을 추가로 주문해야 하는지, 혹은 변경하거나 취소해야 하는지를 계산한다.

만약 주문중에 새로이 체결되는 정보가 있다면, 그에 상응하는 추가 주문처리를 할 수도 있다.

전체적인 구현 방법은 알고리즘에 대한 고려가 있어야 하고, 구체적이고 긴 설명이 필요할 듯 하므로 우선은 이정도로 거래소 API에 대한 소개를 마친다. 어쨌거나 아비트라지 자동화를 위해서 한걸음 더 다가선 기분이 든다.

— Written by cys with Extales