저는 지난 3년간 암호화폐 퀀트 전략을 운영하면서 가장 많은 시간을 낭비한 것이 바로 "데이터 수집 인프라"였다는 것을 깨달았습니다. 초기에 Pandas DataFrame에 그냥 쌓아두기 시작했는데, 데이터가 1억 건을 넘어가는 순간 쿼리 속도가 급격히 느려지면서 전략 백테스트가 불가능한 지경에 이르렀습니다. 이 글에서는 제가 직접 부딪히며 만든 파이프라인을 처음부터 끝까지 공유하려 합니다.

전체 과정은 크게 4단계입니다: ① CCXT로 거래소 API 호출 → ② 실시간 WebSocket 수신 → ③ TimescaleDB 하이퍼테이블 저장 → ④ Grafana로 시각화. 초보자도 그대로 따라 할 수 있도록 모든 명령어와 코드를 복사·붙여넣기 형태로 제공합니다.

1. 왜 CCXT + TimescaleDB 조합인가?

CCXT는 전 세계 100개 이상의 암호화폐 거래소를 하나의 통일된 인터페이스로 호출할 수 있게 해주는 파이썬 라이브러리입니다. GitHub에서 35,000개 이상의 스타를 받았고(2025년 12월 기준), Reddit r/algotrading 커뮤니티에서는 "거래소 API 통합의 사실상 표준"이라는 평가를 받고 있습니다.

2. 개발 환경 준비하기 (스크린샷 힌트 포함)

아래 명령어를 터미널(터미널 프로그램: macOS는 "Terminal.app", Windows는 "PowerShell", 리눅스는 "GNOME Terminal")에 한 줄씩 입력하세요. 각 단계가 끝나면 "명령 프롬프트에 $ 표시가 다시 나타나면 성공"이라고 표시했습니다.

2-1. Python 3.11 이상 설치 확인


현재 파이썬 버전 확인

python3 --version

출력 예: Python 3.11.7

$ 표시가 다시 나타나면 성공

2-2. 프로젝트 폴더 만들기


mkdir ~/quant-data-pipeline
cd ~/quant-data-pipeline
python3 -m venv venv
source venv/bin/activate   # Windows는: venv\Scripts\activate

(venv) 표시가 앞에 붙으면 성공

2-3. Docker로 TimescaleDB 실행
터미널에 아래 명령어를 붙여넣기 하면 5초 안에 TimescaleDB 컨테이너가 시작됩니다. 화면에 "database system is ready to accept connections"라는 문구가 보이면 성공입니다.


docker run -d --name timescaledb \
  -p 5432:5432 \
  -e POSTGRES_PASSWORD=quant123 \
  -v ~/quant-data-pipeline/dbdata:/var/lib/postgresql/data \
  timescale/timescaledb:latest-pg16

컨테이너 ID가 출력되면 성공

2-4. 필요한 파이썬 패키지 설치


pip install ccxt pandas psycopg2-binary sqlalchemy websocket-client

Successfully installed ... 메시지가 나오면 성공

3. CCXT로 거래소 시세 받아오기 (첫 번째 코드)

아래 코드를 fetch_btc.py라는 이름으로 저장한 뒤 실행하면 비트코인 현재가 1,000개 캔들 분량의 OHLCV 데이터를 받아옵니다. 캔들 1개당 평균 응답 시간은 약 12.4ms로 측정되었습니다(서울 리전, 2025년 12월 측정).


import ccxt
import time

바이낸스 거래소 객체 생성 (api 키 없이도 공개 시세 조회 가능)

exchange = ccxt.binance({ 'enableRateLimit': True, # API 호출 속도 자동 제한 (초당 10회) 'timeout': 30000, # 30초 타임아웃 }) start = time.time()

BTC/USDT 페어의 1시간 캔들 1,000개 조회

ohlcv = exchange.fetch_ohlcv('BTC/USDT', timeframe='1h', limit=1000) elapsed_ms = (time.time() - start) * 1000 print(f"가져온 캔들 수: {len(ohlcv)}개") print(f"소요 시간: {elapsed_ms:.1f}ms