바이낸스 API 시리즈 1부 – 포스트맨을 사용한 현물 거래
목차
들어가며
준비 사항
환경 생성하기
컬렉션 불러오기
요청하기
포스트맨을 사용한 디버깅
마치며
바이낸스 API 시리즈 1부 – 포스트맨을 사용한 현물 거래
아티클
바이낸스 API 시리즈 1부 – 포스트맨을 사용한 현물 거래

바이낸스 API 시리즈 1부 – 포스트맨을 사용한 현물 거래

고급
Published Jul 13, 2020Updated Aug 30, 2021
13m

들어가며

API를 이해하고 이를 암호화폐 거래에 사용한다면, 포지션에 진입하고 빠져 나오는 새로운 지평이 열립니다. 간단한 코딩 지식이 있다면, 여러분의 트레이딩 전략을 자동화하기 위해 거래소의 백엔드와 연결할 수 있습니다. 웹사이트를 이용하지 않아도 되기 때문에, 고성능 애플리케이션을 위한 훨씬 더 빠른 체결 엔진을 사용할 수 있습니다.

이 시리즈의 목적은 바이낸스의 REST API를 소개하는 것이며, 이와 상호 작용하는 방법을 전달하기 위합입니다. 글의 말미에서는 시장과 여러분의 포지션에 대한 정보를 요청하고 다양한 유형의 주문을 자신있게 제출할 수 있게 되기를 바랍니다.

이번 아티클에서 우리는 포스트맨을 사용해 거래소와 통신을 진행할 것입니다. 실제 자금의 위험부담 없이 진행하기 때문에 이는 걱정하지 않으셔도 됩니다.


준비 사항

테스트넷 키

우리는 목적에 맞게 테스트넷을 사용할 것입니다. 테스트넷에서는 실제 가치는 없는 자금을 사용해볼 수 있습니다. 테스트 자금은 실제 코인이나 토큰과 정확히 같은 방식으로 작동하기 때문에, API에 익숙해진 다음 실제 자금을 사용해 거래할 수 있습니다.


  1. 현물 테스트넷 네트워크로 이동합니다.
  2. 접속을 위해서는 깃허브 계정이 필요합니다. 깃허브 계정이 없다면 생성합니다.
  3. 인증을 클릭한 다음 깃허브를 통해 가입합니다.
  4. API 키 아래에서 등록된 키가 없다는 안내를 받을 것입니다. HMAC_SHA256 키 생성을 키 쌍을 생성합니다.
  5. 다음 화면에서 키에 라벨을 지정합니다. 원하는 이름을 입력하고, 생성 버튼을 클릭합니다. 
  6. API 키시크릿 키, 두 가지의 키가 표시될 것입니다. 이를 바로 기록해 둬야 합니다. 그렇지 않으면 키 생성 과정을 다시 시작해야 합니다. 해당 키들을 쉽게 복사해 붙여넣기 하기 위해, 기기의 노트 앱에 저장하는 것을 추천드립니다.
참조: 서로 다른 키를 관리하기 위해 실제 거래소를 사용할 때 키를 라벨로 표시하는 것은 좋은 일입니다. 여러분의 계정은 다른 권한을 가진 여러 키를 가질 수 있습니다. 여러 트레이딩 봇을 운영한다면, 설명 라벨이 있는 별도의 키를 사용하는 것이 모든 봇을 변경하지 않고, 권한을 관리하거나 개별 키를 삭제할 때 더 용이합니다.


포스트맨 다운로드 및 설치

포스트맨은 API 협력 플랫폼입니다. 우리는 한 줄의 코드도 작성할 필요 없이 테스트하려는 일련의 바이낸스 요청들에 접근할 수 있습니다.

해당 프로그램은 맥, 윈도우, 리눅스에서 사용할 수 있습니다. 다운로드 페이지로 이동하여 .zip 파일을 다운로드 하시기 바랍니다.

다운로드가 완료되면 여러분의 파일 탐색기에 이를 설치하시기 바랍니다. 애플리케이션을 실행하면, 이제 시작할 준비가 된 것입니다! 로그인을 하려면 계정을 생성해도 되지만, 필수는 아닙니다. 로그인 과정을 건너뛰고 싶다면, 화면 아래에 있는 옵션을 선택하면 됩니다.


환경 생성하기

이번 단계에서는 다음과 같은 인터페이스를 보게 될 것입니다.



우리는 첫 번째 환경을 생성하고자 합니다. 이는 우리가 사용할 일련의 요청에 변수를 추가하는 방법일 뿐입니다. 이를 위해 바이낸스 깃허브 저장소에서 정보를 받아야 할 것입니다. 이곳으로 이동하여 .zip 파일을 다운로드 합니다.



다운로드는 오래 걸리지 않을 것입니다. 파일 탐색기에서 해당 파일을 찾아 압축을 풉니다. 그리고 다시 포스트맨으로 돌아옵니다.



오른쪽 구석(이미지 상단)에 있는 톱니바퀴 아이콘을 클릭합니다. 환경 관리 팝업이 나타날 것입니다. 
  1. 불러오기(Import)를 클릭한 다음, 조금 전 압축을 푼 폴더를 지정합니다(binance-postman-api). 
  2. 다음으로 환경 설정 폴더를 입력합니다.
  3. 두 개의 파일을 보게 될 것입니다(하나는 메인넷, 다른 하나는 테스트넷). 우리가 원하는 것은 binance_com_spot_testnet_api.postman_environment.json입니다. 다른 환경에서는 키가 작동하지 않으므로, 정확한 파일을 선택하시기 바랍니다.



거의 다 됐습니다. 바이낸스 현물 테스트넷 API를 클릭하면, 아래와 같은 변수를 볼 수 있습니다. 빨간 테두리 안의 매개 변수에 이전에 저장해뒀던 키를 붙여넣습니다. 업데이트를 클릭하고 팝업 창을 빠져 나옵니다.



해당 창에서 타임스탬프와 서명란은 비워둡니다. 두 값은 요청에 따라 자동으로 생성될 것입니다.

마지막으로 할 일이 남았습니다. 환경 설정을 위해 클릭했던 오른쪽 톱니바퀴 아이콘에서 환경 없음(No Environment)라고 말하는 드롭다운 메뉴가 표시될 것입니다. 이를 클릭하여 바이낸스 현물 테스트넷 API를 선택합니다.


컬렉션 불러오기

이제 우리는 컬렉션을 불러올 것입니다. 컬렉션은 우리가 요청을 진행할 때, 우리를 도와주는 광범위한 요청들을 모아놓은 것입니다. 다음 과정을 통해 이를 우리의 환경으로 불러옵니다.

  1. 왼쪽 상단 코너의 불러오기(Import)를 클릭합니다.
  2. 팝업 창이 뜨면, 파일 탭 아래에서 업로드 파일을 선택합니다.
  3. 다시 한 번 binance-postman-api 폴더를 찾습니다. 위치를 지정하고 이를 엽니다.
  4. 이번에는 서브디렉토리에 컬렉션(collections)을 입력합니다.
  5. 다시 한 번 두 개의 파일이 보일 것입니다. 하나는 선물 API를 위한 것입니다. 우리는 현물 거래소에서 작업할 것이므로, binance_spot_api_v1.postman_collection.json 파일을 선택합니다.
  6. 이제 포스트맨 컬렉션 형식에 불러올 파일들을 확인하는 창이 보일 것입니다. 불러오기(Import)를 클릭합니다.

컬렉션 탭 아래에 있는 왼쪽 창에서 100개 이상의 요청이 있는 폴더를 볼 수 있을 것입니다. 축하드립니다! 잘 진행되었습니다. 다음 섹션에서는 우리가 생성할 수 있는 요청의 종류에 대해 살펴보도록 하겠습니다.


요청하기

컬랙션 탭 아래에 있는 폴더를 확장하면 우리가 생성할 수 있는 다양한 요청들을 발견할 수 있습니다. 컬러 코딩(color-coding)에서 다음과 같이 세 가지 방법을 사용할 수 있다는 것을 발견하실 것입니다.


  • GET: GET 메소드는 서버에서 무언가를 검색할 때 사용합니다. 우리는 이를 여러분의 계정 잔고와 자산 가격 등의 정보를 찾는 데 사용할 것입니다.
  • POST: POST 메소드는 보통 서버에서 정보를 생성할 때 사용합니다. 이는 주문 배치와 출금 요청 등에 필요합니다.
  • DELETE: DELETE 메소드는 서버에 정보 삭제 요청을 할 때 필요합니다. 주문 취소에 유용하게 사용될 것입니다.


심볼과 트레이딩 규칙 목록 찾기

첫 번째 요청을 생성할 시간입니다! 거래소에서 거래할 수 있는 심볼과 트레이딩 규칙을 불러올 것입니다.

GET /exchangeInfo


이는 추가적인 매개 변수를 취하지 않으며, 이를 주소창에 복사해서 붙여 넣으면 응답을 받게 될 것입니다. 여러 매개 변수를 포함시킬 수 있는 요청에 대해, 포스트맨은 이를 쉽게 보고 수정할 수 있게 해줍니다.

요청을 불러오려면 Market > Exchange Information을 클릭합니다. 다음과 같이 팝업이 표시될 것입니다.



여기서는 아무 것도 하지 않아도 되며, Send 버튼을 클릭합니다. 다음과 같은 응답을 받게 될 것입니다:



가장 위에 하이라이트 표시된 부분에서, 다음과 같은 중요한 정보를 볼 수 있습니다.

  • 응답 상태(200은 요청이 성공했다는 의미이며, 400-499는 문제가 있다는 의미)
  • 응답 수신까지 걸린 시간(1초 미만)

  • 응답 크기(~22KB)


두 번째 박스에는 응답들이 모여있습니다. 이는 정갈하게 표시되어 있기 때문에, 눈으로 보기가 쉽습니다. 여기에는 거래소 자체 정보와 거래할 수 있는 거래쌍, 최소/최대 금액이 포함됩니다.

정보가 많은 것 같아 보일 수 있지만, 이는 프로그램적으로 무척 다루기 쉬운 형태입니다. 상호작용을 위한 스크립트를 작성할 때는, 해당 응답에서 특정 요소의 특정 속성을 간단하게 선택할 수 있을 것입니다.


계정 잔고 확인

보유하고 있는 자산과 수량을 확인해 봅시다.

GET /account
이는 Trade > Account Information 아래에서 찾을 수 있습니다. 이를 클릭하면, 이전 레이아웃과 비슷한 화면을 보게 될 것입니다. 그러나 한 가지 알아두어야 할 것은 타임스탬프서명, 두 개의 변수가 있다는 것입니다. 서명은 보안 장치입니다. 이제 우리가 민감한 정보를 요청하고 있기 때문에, 해당 키는 우리가 계정 소유자라는 것을 증명해 줄 것입니다. 
타임스탬프는 서버에 요청이 전송된 시기를 말해줍니다. 네트워크가 불안정하거나 작동하지 않을 수 있기 때문에, 서버는 우리의 의도보다 훨씬 늦게서야 요청을 전달받을 수 있습니다. 너무 많은 시간이 지나버리면, 요청이 거부될 것입니다. 여러분은 recvWindow 매개 변수를 사용해 얼마나 오래 기다릴 것인지 구체적으로 명시할 수 있으며, 기본값은 5000 밀리세컨즈입니다.
포스트맨은 우리를 위해 타임스탬프와 서명을 생성해 줍니다. 전송을 클릭하면, 응답을 전달받게 될 것입니다. 잔고 아래에서 여섯 개의 자산 BNB, BTC, BUSD, ETH, LTC, TRX가 보여야 합니다. 해당 잔고는 자유 금액과 동결 금액으로 나눠질 것입니다. 우리가 동결한 자산은 없기 때문에, 현재는 모든 자산을 자유롭게 이용할 수 있습니다.

새로운(실제로는 존재하지 않는) 자산을 얻게 되신 걸 축하드립니다!


심볼의 현재 가격 불러오는 방법

우리는 다양한 방법으로 자산의 현재 가격을 불러올 수 있습니다. 가장 간단한 요청은 다음과 같을 것입니다.

GET /api/v3/ticker/24hr
여러분이 짐작하는 것처럼 이는 지난 24시간 동안의 자산 가격 정보를 전달해 줄 것입니다. 이는 Market > 24hr Ticker Price Change Statistics에서 확인할 수 있습니다. 처음으로 등장하는 심볼 변수는 BTCUSDT입니다. 
여러분은 세부적인 가격 정보를 살펴보기 위해 이를 즉시 전송할 수 있습니다. 또한 심볼을 변경(BNBUSD, LTCUSDT 등) 하거나, 40개의 거래쌍 데이터를 반환받지 않기 위해 변수들을 제외할 수도 있습니다.
간단한 호출(Market > Symbol Price Ticker)도 존재하며 이는 거래 중인 자산의 현재 가격을 반환합니다.
GET /api/v3/price

이전과 마찬가지로, 심볼 변수를 변경하거나 이를 모두 삭제할 수 있으며, 모든 심볼의 최신 가격을 불러올 수도 있습니다.


현재 오더북 깊이 확인

오더북 깊이(또는 시장 깊이, DOM)는 시장에 대해 많은 것을 말해줍니다. 우리는 다음을 통해 몇 가지 유용한 정보를 호출할 것입니다.

GET api/v3/depth

우리가 이를 기본 값으로 전송할 때(Market > Order Book), 우리는 BTCUSDT 매수 및 매도에 대한 응답을 전송하는 것입니다. 테스트넷 서버는 실제 서버보다 많은 정보를 보내지 않으며, 아래의 스크린샷은 실제 환경에서 보게 되는 것입니다.



위에서 하이라이트 된 영역에서 우리는 첫 번째 매수를 발견할 수 있습니다. 우리는 BTCUSDT 호가창을 보고 있기 때문에, 위의 숫자는 누군가 여러분의 BTC에 대한 대가로 지불할 가격입니다. 아래의 숫자는 구매하고자 하는 수량입니다. 그러므로 이 주문은 9704.65 USDT의 가격에 0.999 BTC를 매수하겠다는 것입니다. 스크롤을 아래로 내리면, 매수 가격이 내려가는 것을 볼 수 있으며, 이는 매수자가 더 적은 금액을 지불하겠다는 의미입니다.

여러분이 가장 매력적인 주문을 찾는다면 이는 가장 위의 주문일 것입니다. 그렇긴 하지만, 여러분이 시장가로 3 BTC를 매도하고자 한다면, 0.999 BTC만을 최고의 가격에 판매할 수 있을 것입니다. 여러분은 주문이 모두 체결될 때까지 이후의 (더 낮은 가격) 주문을 체결시켜야 합니다.



계속 스크롤을 내리면, 매도 주문을 볼 수 있습니다. 이는 매수 주문과 유사하며 다만, BTC를 USDT로 매도 하겠다는 것입니다. 


테스트 주문 생성

이제 우리는 테스트 주문을 생성해 볼 것입니다.

POST api/v3/order/test
우리가 테스트넷 자금을 사용하고 있기는 하지만, 해당 요청은 실제로 주문을 생성하지는 않을 것입니다. 이는 실제로 주문을 제출하기 전에 이를 테스트 해보는 데 유용합니다. Trade > Test New Order (TRADE)에서 이를 찾을 수 있습니다.



여러분은 더 많은 매개 변수가 포함되어 있는 것을 볼 수 있을 것입니다. 선택된 항목들을 살펴보겠습니다.


  • symbol – 이전에 우연히 이를 본 적이 있습니다. 이는 여러분이 거래하고자 하는 쌍입니다.
  • side – 여기서는 여러분의 매수 또는 매도 여부를 결정합니다. BTCUSDT 쌍에서 BUY는 USDT로 BTC를 구매하고 싶다는 것이며, SELL은 BTC를 USDT로 판매하고 싶다는 것입니다.
  • type – 여러분이 제출하고자 하는 주문 유형입니다. 가능한 값은 다음과 같습니다(여기에 자세히 설명되어 있음):
    • LIMIT
    • MARKET
    • STOP_LOSS
    • STOP_LOSS_LIMIT
    • TAKE_PROFIT
    • TAKE_PROFIT_LIMIT
    • LIMIT_MAKER
  • timeInForce– 이는 여러분의 주문을 어떻게 실행할지를 결정하는 매개 변수입니다.
    • GTC (good till canceled) – 가장 널리 사용되는 설정 중 하나일 GTC는 주문이 체결되거나 이를 취소하기 전까지 유효한 주문입니다.
    • FOK (fill or kill) – FOK 거래소에게 한 번에 주문을 실행하도록 지시합니다. 만약 그럴 수 없다면, 주문이 즉시 취소됩니다.
    • IOC (immediate or cancel) – 전부 혹은 일부 주문이 즉시 실행되거나 취소됩니다. FOK와 달리, 일부만 체겨될 수 있다면 주문은 취소되지 않습니다.
  • quantity – 여러분이 매수 또는 매도하고자 하는 자산 수량입니다.
  • price – 여러분이 매도하고자 하는 가격입니다. BTCUSDT 쌍에서는 USDT로 표시됩니다.
  • newClientOrderId – 주문 식별자입니다. 필수 영역은 아니지만, 나중에 쿼리를 쉽게 처리할 수 있도록 식별자로 설정할 수 있습니다. 그렇지 않은 경우, 거래소에 의해 임의로 생성됩니다.
좋습니다! 이제 테스트 주문을 생성해 봅시다. 우리는 자동으로 생성된 값을 통해 이를 진행할 것입니다. 해당 값은 $9000에 0.1 BTC를 USDT로 매도하는 지정가 주문입니다. 해당 작업이 성공적이었다면, 간단히 {}만을 응답으로 받게 될 것입니다. 

 

실제 주문 생성

이제 실제 테스트 주문을 배치해보겠습니다.

POST /api/v3/order
Trade > New Order로 이동합니다. 이제 테스트 주문에 익숙해 지셨을 것이기 때문에, 지금부터 보게 될 매개 변수들은 전혀 새로운 것은 아닐 것입니다. 모든 값은 그대로 두는 대신, 우리는 불장을 예측하기 때문에 $40,000 가격에 매도 주문을 진행한다고 하겠습니다. 값을 수정하고, Send 버튼을 클릭합니다.

주문이 성공적이었다면, 여러 세부 정보와 함께 응답이 전송될 것입니다.


미체결 주문 상태 확인

우리는 이전 섹션에서 주문이 생성되었다는 확인을 받았지만, 이후에는 이를 어떻게 확인할 수 있을까요? 우리의 요청을 처리할 몇 가지 방법이 있습니다.

GET /api/v3/openOrders
Trade > Current Open Orders (USER_DATA)에서 이를 찾을 수 있습니다. BTCUSDT가 기본 값으로 선택되어 있습니다. Send를 클릭하면, 여러분의 모든 미체결 BTCUSDT 주문을 받아올 수 있습니다. 심볼을 구체적으로 지정하지 않으면, 모든 미체결 주문을 받아올 수 있습니다.
GET /api/v3/allOrders
Trade > All Orders (USER_DATA)에서는 미체결 주문 뿐만 아니라 모든 주문을 볼 수 있습니다. orderId, startTime, endTime, limit 매개 변수를 사용해 상세 검색을 진행할 수 있습니다. 우리는 이들을 모두 체크하지 않은 상태로 두겠습니다. Send를 클릭하면, 전과 같은 응답을 받게될 것입니다. 종료되거나 취소된 주문 또한 이곳에 표시됩니다. 


마지막으로, 특정 주문을 요청할 수 있습니다.

GET /api/v3/order
Trade > Query Order (USER_DATA)에서 이를 찾을 수 있습니다. 여러분은 orderId 또는 origClientOrderId (주문에 추가할 수 있는 부가적 태그 “newClientOrderId” )를 제공해야 합니다. orderId 체크를 해제합니다. origClientOrderId에는 이전의 기본 태그인 ”my_order_id_1”를 입력합니다. 해당 칸을 채운다음, Send를 클릭해 응답을 요청합니다.


주문 취소

시간이 지난 후, $40,000 목표값이 지나치게 낙관적이었다고 판단하여, 이를 취소하고자 합니다. 이 경우에는 다음을 사용할 수 있습니다.

DELETE /api/v3/order
Trade > Cancel Order 아래에 있는 요청은 취소 주문을 선정할 수 있게 해주는 것입니다. orderIdnewClientOrderId 체크를 해제하고, origClientOrderId 값으로 “my_order_id_1”를 통과시킵니다.
해당 요청을 보내면 주문이 취소됩니다. 스크롤을 내려 “status”를 보면, 실제로 주문이 취소된 것을 확인할 수 있습니다. 이를 확인하려면, GET /api/v3/openOrders 엔드포인트를 다시 사용하거나(빈 목록을 제시함), origClientOrderId와 함께 GET /api/v3/order을 사용합니다.


즉시 체결 주문 생성

우리의 이전 주문은 지정가 주문으로 BTC 가격이 $40,000에 도달할 때만 실행되므로 체결되지 않았습니다. 시장가 주문의 경우, 이는 기본적으로 “현재 자산이 거래되고 있는 가격에 매수/매도를 진행”한다는 의미입니다. 시장가 주문은 즉시 체결됩니다.
이를 위해 Trade > New Order로 다시 돌아갑니다. 우리는 우리가 서버로부터 원하는 응답에 따라 변경할 수 있는 매개 변수인 응답 유형(newOrderRespType)을 설명할 것입니다. 여기에는 ACK, RESULT, FULL 세 가지 옵션이 있습니다. 각 응답의 예시는 이곳에서 확인할 수 있습니다. 우리는 주문이 접수되었음을 간단히 알려주는 ACK를 사용할 것입니다.

아래에서는 BNB를 현 시장 가격으로 BUSD를 판매하려는 시장가 주문을 살펴볼 수 있습니다.



해당 응답은 우리에게 최소한의 정보만을 제공한다는 점을 알아둘 필요가 있습니다.



주문 체결 확인은 /api/v3/allOrders 엔드포인트를 통해 확인할 수 있습니다.


거래 확인

마지막으로 거래를 확인하는 엔드포인트를 살펴보도록 하겠습니다.

GET /api/v3/myTrades
이는 Trade > Account Trade List (USER_DATA)에 위치해 있습니다. 이를 통해 특정 심볼의 거래들을 확인할 수 있습니다. 기본 심볼(BTCUSDT에 대한 모든 거래를 살펴보고자 한다면, 간단히 startTime, endTime, fromId를 체크하지 않으면 됩니다. 응답은 최대 500개 거래를 전달할 것이며, 더 많은 거래를 보고 싶다면 limit을 변경하면 됩니다.


포스트맨을 사용한 디버깅

포스트맨에서는 원시 HTTP 요청 및 응답을 추가로 요청할 수 있습니다.



이 메뉴는 각 요청의 세부 정보를 출력하는 포스트맨 콘솔을 엽니다.



마치며

이번 설명의 목적은 한 줄의 코드도 작성하지 않고, 바이낸스 API를 가볍게 설명하기 위함이었습니다. 각 과정들을 잘 따라오셨다면, 정보를 요청하고 제출하는 방법을 아실 것입니다.

다음 시리즈에서는 자동으로 암호화폐와 다른 디지털 자산을 매수 및 매도하는 몇 가지 기본 코딩 개념을 살펴보겠습니다. 
그동안에 질문이 있으시다면, 여러 개발자들과 함께 성장하고 있는 바이낸스 개발자 커뮤니티 포럼으로 오시거나 다음 문서를 살펴보시기 바랍니다.