top of page

Machbase Neo를 활용한 코인 거래 데이터 수집과 분석

2일 전
3분 분량

코인 거래 데이터의 특징

코인 거래 데이터는 분석 재료로서 독특한 성격을 가지고 있습니다. 거래소는 24시간 쉬지 않고 열려 있고, 인기 종목은 1초에도 수십에서 수백 건의 체결이 일어납니다. 바이낸스에서 거래대금 상위 50개 코인의 체결과 호가 변화를 모으면 초당 5,000~7,000행, 하루 약 17GB가 쌓일 정도로 발생량이 많습니다.

반면 데이터를 얻기는 매우 쉽습니다. 주식 실시간 시세는 보통 증권사 계정이나 유료 피드가 있어야 받을 수 있지만, 코인 거래소는 공개 WebSocket으로 체결과 호가를 실시간으로 내보내므로 계정이나 API 키 없이도 받을 수 있습니다.

결국 문제는 데이터를 얻는 방법이 아니라, 끊임없이 쏟아지는 데이터를 놓치지 않고 모아 디스크 부담 없이 쌓아 두고, 필요할 때 원하는 구간을 빠르게 꺼내 분석하는 방법입니다. 이 글에서는 neo-pkg-coin-collector 패키지를 예로 들어 Machbase Neo로 이 문제를 푸는 방법을 소개합니다.


시계열 DB Machbase의 선택

체결 데이터는 종목과 시각을 따라 계속 추가될 뿐 수정할 일은 거의 없고, 조회도 "이 종목의 최근 1시간", "지난 일주일의 시봉"처럼 시간 구간 단위로 이루어집니다. 이런 데이터는 범용 관계형 DB보다 시계열 DB에 맞으며, Machbase는 세 가지 면에서 이 요구를 충족합니다.

  • 빠른 수집: Append API로 초당 수천 행 이상의 데이터를 SQL 조립 없이 바로 적재할 수 있습니다.

  • 압축 저장: TAG 테이블은 데이터를 압축해 저장하고, 보관 정책(retention)으로 오래된 원본을 DB가 알아서 정리합니다.

  • 빠른 검색: 태그 이름과 시각으로 원하는 구간을 바로 찾고, 롤업으로 분·시간 단위 요약을 미리 계산해 둡니다.

이 패키지는 체결을 CC_TICK TAG 테이블 하나에 저장합니다. 태그 이름(NAME)으로 BTC 현물은 BINANCE.BTCUSDT, BTC 선물은 BINANCE_F.BTCUSDT처럼 시장과 종목을 구분하므로, 종목마다 테이블을 만들지 않아도 같은 SQL로 모든 종목을 조회할 수 있습니다.

CREATE TAG TABLE CC_TICK (
    NAME     VARCHAR(40) PRIMARY KEY,  -- 거래소.종목
    TIME     DATETIME BASETIME,        -- 체결 시각
    VALUE    DOUBLE SUMMARIZED,        -- 체결가
    QTY      DOUBLE,                   -- 체결량 (매수 +, 매도 -)
    AMT      DOUBLE,                   -- 거래대금
    SAMT     DOUBLE,                   -- 순매수 대금
    TRADE_ID LONG
) WITH ROLLUP (MIN) EXTENSION;

손쉬운 데이터 수집

수집 환경을 따로 꾸릴 필요가 없습니다. Machbase Neo 8.7.0 이상에서 패키지 ZIP을 압축을 풀지 않은 채 설치 폴더의 public/에 두고 웹 UI의 App Store에서 설치하면, 테이블과 롤업, 보관 정책이 함께 만들어지고 거래대금 상위 50개 코인의 수집이 바로 시작됩니다. 수집기는 Neo에 내장된 JavaScript 실행 환경(JSH)에서 서비스로 돌기 때문에 별도의 서버나 Node.js 런타임도 필요 없습니다. 설치와 수집 조건

수집할 종목은 설정 화면에서 고르고, 종목마다 현물·선물 체결과 호가 수집 여부를 정하면 됩니다. 설정을 저장하면 수집기가 2초 안에 변경을 감지해 서비스 재시작 없이 연결만 새로 엽니다.

수집기는 받은 메시지를 분석하기 좋은 형태로 정리해서 저장합니다.

  • 서버가 받은 시각이 아니라 거래소의 체결 시각을 저장해 네트워크 지연이 섞이지 않게 합니다.

  • 매수 주도 체결은 양수, 매도 주도 체결은 음수 수량으로 저장해 방향을 구분합니다.

  • 1000PEPEUSDT 같은 선물 계약은 가격과 수량을 코인 1개 단위로 바꿔 현물과 같은 기준으로 비교할 수 있게 합니다.

적재는 메모리 버퍼에 모아 1초마다 Append로 넣는 방식이며, 핵심 코드는 다음과 같이 짧습니다.

const writer = conn.append('CC_TICK');

for (const row of trades) {
    writer.append(
        row.name, new Date(row.time), row.price, row.qty,
        row.price * Math.abs(row.qty),
        row.price * row.qty, row.tradeId
    );
}
writer.flush();

연결이 30초 동안 조용하면 다시 접속하고, DB에 잠시 문제가 생겨도 버퍼에 쌓아 두었다가 다시 적재합니다. 수집기 구현


분봉·시봉의 간편한 생성

차트에 쓰는 분봉이나 시봉을 만들 때 원본을 매번 집계하면 데이터가 쌓일수록 느려집니다. 한 종목에서 초당 100건씩 체결된다면 하루 원본은 864만 건이지만, 1분 단위로 요약하면 하루 1,440개 구간만 다루면 됩니다.

Machbase의 롤업은 이 요약을 DB가 자동으로 미리 계산해 두는 기능입니다. CC_TICK은 WITH ROLLUP (MIN) EXTENSION으로 만들어져 분·시간 단위의 최솟값·최댓값뿐 아니라 첫 값과 마지막 값까지 보관하므로, 시가·고가·저가·종가를 SQL 한 번으로 구할 수 있습니다.

-- BTC 선물 최근 1시간의 1분봉
SELECT ROLLUP('min', 1, TIME) AS candle_time,
       FIRST(TIME, VALUE) AS open, MAX(VALUE) AS high,
       MIN(VALUE) AS low, LAST(TIME, VALUE) AS close
FROM CC_TICK
WHERE NAME = 'BINANCE_F.BTCUSDT' AND TIME >= NOW - 1h
GROUP BY candle_time
ORDER BY candle_time;

5분봉은 ROLLUP('min', 5, TIME), 시봉은 ROLLUP('hour', 1, TIME)으로 바꾸기만 하면 됩니다. 거래대금 AMT와 순매수 대금 SAMT에도 분·시간 롤업을 걸어 두었기 때문에, 봉마다 매수 대금 (AMT + SAMT) / 2와 매도 대금 (AMT - SAMT) / 2도 함께 구할 수 있습니다. 캔들 쿼리

롤업 덕분에 원본을 오래 둘 필요도 없습니다. 이 패키지는 원본을 기본 1일만 보관하고 롤업은 계속 남겨 두므로, 최근 하루는 체결 단위로, 그 이전은 분봉·시봉으로 볼 수 있습니다. 원본 보관 기간은 1일·7일·30일·무제한 중에서 고를 수 있으며, 짧게 둘수록 디스크 사용량은 크게 줄고 장기 추세 분석은 그대로 가능합니다. 보관 정책


Neo 기능을 활용한 분석

Machbase Neo는 DB뿐 아니라 JavaScript 실행 환경, HTTP API, 웹 화면을 함께 제공하므로, 모은 데이터를 바로 분석 기능으로 연결할 수 있습니다. 이 패키지에 들어 있는 예는 다음과 같습니다.

  • 캔들 차트: 조회 기간에 맞춰 캔들 간격을 정하고, 1분 이상이면 롤업을, 그보다 짧으면 원본을 집계해 보여 줍니다.

  • 실시간 요약판: 수집 서비스가 들어오는 체결로 종목별 현재가, 최근 1분 거래대금, 체결강도를 계산해 화면에 전달합니다.

  • 고래 감지: 같은 종목·같은 방향의 체결을 1초 동안 합산해, 평소 거래 규모의 30배 이상이면서 50,000 USDT 이상인 흐름을 이벤트로 기록합니다.

  • 원본·롤업 비교: 같은 질문을 원본과 롤업으로 각각 실행해 SQL과 걸린 시간을 나란히 보여 줍니다.

이 기능들은 모두 Neo 안에서 JavaScript와 SQL만으로 만들어졌습니다. 같은 방식으로 현물·선물 가격 차이나 시간대별 거래량 변화 같은 분석도 SQL 몇 줄과 간단한 스크립트로 추가할 수 있습니다. 코인 거래 데이터를 직접 모아 분석해 보고 싶다면 neo-pkg-coin-collector부터 설치해 보시기 바랍니다.


 
 
call
english
bottom of page