[개발] 자바 - 바이낸스 거래소 데이터 가져오기

in #kr-dev7 years ago

본 글은 자바에 대한 기초적인 지식이 있는 컴파일을 하고 실행시킬수 있는 정도만 가능하시면 따라해보시는데 아무 지장이 없는 내용입니다.

이번 바이낸스 거래소를 추가하며 사용한 방법을 정리해봅니다. 처음으로 코인시세 정보조회 기능을 개발한다면 쉽게 참고가 되실 것입니다. 다른 거래소도 대동소이한 방법으로 추가하면 됩니다.

1. api 문서를 통해 스펙을 파악합니다.

우선 거래소의 홈페이지에 접속하도록 합니다. https://www.binance.com/

거래소들은 하단에 api 메뉴를 대부분 노출하고 있습니다. 이렇게요. 하단으로 스크롤하다 보면 보입니다.

연결해보니 github으로 연결되는 군요.

이렇게 여러가지 방식의 api가 나타나있습니다 . 당연히 시세 조회는 rest-api.md에 있을 것입니다.

여기서 먼저 봐야할 건 조회할수 있는 url과 제약조건이 어떤지를 확인하는 것입니다. 보통 거래소에 부하가 심하지 않도록 api 요청할 수 있는 제한을 두게 되는데 이 기준이 거래소마다 다릅니다. 어떤 거래소는 초당 1번, 어떤 거래소는 5초당 한번 이런식입니다.

바이낸스의 경우 api별로 weight를 부여하고 분당 weight limit을 설정해놓았습니다.

https://api.binance.com/api/v1/exchangeInfo

그 분당 리밋을 이 api를 통해서 확인할수 있습니다. 해당 주소로 확인해보면 여러가지 값이 나오지만 가장 위에 나오는 'requests'의 limit값만 우선 보면 됩니다.

{"timezone":"UTC","serverTime":1514803461718,"rateLimits":[{"rateLimitType":"REQUESTS","interval":"MINUTE","limit":1200},

분당 1200의 limit값을 가지고 있는데요. 여기서 우리가 원하는 ticker의 weight를 계산해서 적절하게 호출하도록 해야 서버나 pc에서 ip밴을 당하지 않을수 있습니다. 바이낸스 api에서는 지속적으로 과부하를 주는 서버의 ip는 최장 3일이나 밴을 때려버린다고 하니 잘 계산해서 주기를 설정해야 합니다.

코인 당 weight가 1이고 코인 기호가 생략인 경우 모든 코인의 수만큼 weight가 책정됩니다.

Weight: 1 for a single symbol; number of symbols that are TRADING when the symbol parameter is omitted

바이낸스의 코인마켓수는 총 230여종정도 됩니다. btc마켓, eth마켓, bnb마켓, usdt마켓 총 합쳐서요. 물론 코봇에서는 btc마켓만 사용할 예정이지만 나중의 확장성과 유연함을 가져가면서 개발 편의성까지 가져가기 위해서 코인 심볼을 코드상에 명시하지 않고 모든 코인의 값을 가져오도록 하였습니다. 그렇다면 당분간은 약 300종까지 늘어나는걸 생각해서 1분에 4번정도만 호출하면 되겠죠.

그래야 나중에 eth가 기축이 되어도 손쉽게 변경이 가능하겠죠. 코인 시세정보를 조회하는 url은 아래와 같습니다.

https://api.binance.com/api/v1/ticker/24hr

일부 발췌.

[{"symbol":"ETHBTC","priceChange":"0.00201200","priceChangePercent":"3.684","weightedAvgPrice":"0.05448623","prevClosePrice":"0.05455800","lastPrice":"0.05662600","lastQty":"0.05800000","bidPrice":"0.05656700","bidQty":"18.51800000","askPrice":"0.05662600","askQty":"13.02000000","openPrice":"0.05461400","highPrice":"0.05720000","lowPrice":"0.05230900","volume":"307686.65700000","quoteVolume":"16764.68517205","openTime":1514730078233,"closeTime":1514816478233,"firstId":12321963,"lastId":12723620,"count":401658},

바로 브라우저에 대고 호출하셔도 값을 확인하실 수 있으며 이걸 어떤 언어로든 가져와서 파싱해가지고 보여주면 됩니다. 거의 모든 거래소가 json 데이터 포맷을 사용하고 있으나 제각기 포맷이 달라 맞춰줘야 하는 점이 있습니다.

다른점들은 금액 단위가 다르거나, 전날에서의 변동율, 그리고 데이터의 변수 명칭, 순서정도가 다릅니다만 눈으로만 봐도 명확하게 어떤 값인지 보이기 때문에 그렇게 어렵진 않습니다.

2. url 요청을 통해 json string을 가져오도록 함수를 하나 만듭니다.

그렇다면 자바로 저 url을 호출해서 저 값들을 가져와봅시다. 이런 url을 통한 문자열을 얻어오는 함수를 짜면 편리합니다. 이미 잘 만들어져있는 아파치의 httpClient와 같은 라이브러리를 사용하면 편리하긴 하지만 전 라이브러리 사용을 별로 좋아하진 않습니다. 요는 'HttpURLConnection '이놈을 통해서 url을 호출해서 문자열로 값을 받아올수 있는 것이죠.

public static String getStringFromUrl(String url) throws Throwable {
        HttpURLConnection huc = (HttpURLConnection) new URL(url).openConnection();
        huc.setRequestMethod("GET");
        huc.addRequestProperty("User-Agent",
                "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0");
        huc.setRequestProperty("Accept", "application/json, text/javascript, */*; q=0.01");     
        huc.connect();
        InputStream in = null;
        if( huc.getResponseCode() != 200 ){
            in = huc.getErrorStream();
        }else{
            in = huc.getInputStream();
        }
        BufferedReader br = new BufferedReader(new InputStreamReader(  in , "UTF-8"));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        return sb.toString();
    }

3. json string을 json 라이브러리를 써서 파싱하여 사용합니다.

두번째로 가져왔으면 보기 좋게 파싱을 해야합니다. json 라이브러리는 gson이나 jackson 을 추천합니다. 저는 gson을 즐겨 사용합니다. 구글에서 만든 자바 json 라이브러리입니다. 이런식으로 데이터를 출력하는 함수를 만들어봅시다.

public static void printTicker() throws Throwable {     
        String json_str = URLUtil.getStringFromUrl("https://api.binance.com/api/v1/ticker/24hr");
        Gson gson = new Gson();     
        JsonArray ja = gson.fromJson(json_str, JsonElement.class).getAsJsonArray();
        for(int i = 0; i < ja.size();i++){          
            JsonObject market = ja.get(i).getAsJsonObject();
            System.out.println(market.get("symbol") + " : " + market);
        }
    }

출력결과 : 이런식으로 코인별로 각종 데이터를 얻어낼수 있습니다. 이후에 어떤 가공을 거쳐서 원하는 처리를 할지는 보시는 분의 몫입니다.

그럼 이제 자바를 사용해서 거래소 시세 데이터를 얻어오는 법을 아실것이고. 다른 거래소들도 대략 비슷하다고 생각하시면 됩니다. 혹시나 어려운 거래소 질문 주시면 답변하도록 하겠습니다. 감사합니다.

마지막으로 오늘은 정말 감개무량하네요. 스팀 12딸러를 외칠때가 오다니 12딸러 가즈아~!!!

Sort:  

Cheer Up!

  • from Clean STEEM activity supporter

나는 가입했지만 어떻게 게임을 이해할 수 없다.

나는 읽었지만 어떻게 당신의 코멘트를 이해할 수 없다.

아 빵터짐...

빵빵 ㅋㅋ

감사합니다. :)

스팀 가즈아!!!
kr-dev를 응원합니다 !

응원 감사드립니다~

이 글을 보고 이해할 수가 없는걸보면
아직 자바에 대한 기초적인 지식도 없는것 같아요
😂😂😂

아아... 어려운 프로그래밍...

들렸다갑니다.

요즘 안보이시는것 같아서 슬쩍 찾아봤다가
뭔 내용인지 이해가 안되어 슬쩍 도망갑니당

요즘 뒷구석에서 이런 비주류 포스팅을 하고 있습니다. ㅋㅋ 마흔 아니시죠? ㅋㅋ

허걱허걱 어렵습니다.... 역시 저랑 프로그래밍이랑은 친하지 않은지도.... 스팀은 왠지 더 오를듯 합니다. 가즈앗~

ㅠㅠ걱정입니다 너무 어려운거같아요 ㅎㅎ 포스팅은 너무 쉽게 잘 알려주신거 같은데 ㅎㅎ...ㅠㅠㅠㅠㅠㅠㅠㅠ

You got a 0.30% upvote from @upme requested by: @nhj12311.
Send at least 1.5 SBD to @upme with a post link in the memo field to receive upvote next round.
To support our activity, please vote for my master @suggeelson, as a STEEM Witness