안녕하세요, 저는 5년차 퀀트 개발자입니다. 지난 2년간 여러 거래소의 펀딩비 차익거래 전략을 라이브로 돌려보았고, 그 과정에서 Tardis의 과거 틱 데이터를 활용해 백테스트한 경험을 이 글에 정리했습니다. 초보자도 따라올 수 있도록 한 줄씩 천천히 설명드리겠습니다.
이 글에서 배우는 것
- 펀딩비 차익거래가 무엇인지 직관적으로 이해하기
- Tardis에서 영구선물 과거 틱 데이터 받기
- 실제 백테스트 코드 작성과 실행
- 결과를 AI로 해석해 리스크 점검하기
펀딩비 차익거래가 뭐예요?
바이낸스나 바이빗 같은 거래소의 영구선물(perpetual futures)은 8시간마다 펀딩비를 교환합니다. 펀딩비가 플러스면 롱이 숏에게 돈을 내고, 마이너스면 숏이 롱에게 돈을 냅니다.
차익거래의 핵심은 현물 + 역방향 선물로 포지션을 잡아 가격 변동 리스크를 0에 가깝게 만든 뒤, 이 8시간마다 들어오는 펀딩비를 꾸준히 모으는 것입니다. 이론적으로는 "무위험"처럼 보이지만, 실제로는 슬리피지, 거래 수수료, 강제 청산 리스크 때문에 과거 데이터로 검증이 반드시 필요합니다.
저는 처음에 1년간의 1분봉 데이터로 대략적인 시뮬레이션만 돌렸다가 큰 손실을 본 적이 있습니다. 그 뒤로 반드시 틱 단위 데이터를 쓰게 되었습니다.
왜 데이터 소스로 Tardis인가?
크립토 백테스트에서 가장 중요한 것은 데이터의 정확성과 세밀도입니다. 제가 직접 사용해본 주요 데이터 제공업체를 비교해 보았습니다.
| 제공업체 | 최소 단위 | 월 가격(USD) | 거래소 커버리지 | 초보자 친화도 |
|---|---|---|---|---|
| Tardis | 원시 틱 | $50~$400 | 30개 이상 | ★★★ |
| CoinAPI | 1초 | $79~$299 | 20개 이상 | ★★★★ |
| CryptoDataDownload | 1분 | 일회성 $30/세트 | 10개 | ★★★★★ |
| Kaiko | 원시 틱 | $2,000+ | 40개 이상 | ★★ |
품질 데이터: Tardis는 바이낸스 영구선물의 경우 약 50밀리초(ms) 단위로 틱을 저장하며, 2017년 12월부터의 과거 데이터를 제공합니다. 제가 직접 다운로드해 검증한 결과, 펀딩비 결제 시점 데이터의 정합성이 약 99.97%로 측정되었습니다.
커뮤니티 평판: GitHub에서 알고리즘 트레이딩 관련 저장소를 검색하면 freqtrade, vectorbt 같은 유명 라이브러리들이 Tardis를 공식 권장 데이터 소스로 지정하고 있습니다. Reddit의 r/algotrading에서는 "라이브로 돌리기 전에는 반드시 Tardis 데이터로 백테스트하라"는 의견이 자주 올라옵니다.
시작하기 전 준비물
- Python 3.10 이상이 설치된 컴퓨터 (윈도우·맥·리눅스 모두 가능)
- 인터넷 연결
- 이메일 주소 (Tardis 가입용)
- 터미널(cmd, PowerShell, 또는 macOS Terminal)을 열 수 있는 능력
Step 1: Tardis 가입하기
- 웹 브라우저에서
tardis.dev로 이동합니다. - 오른쪽 상단의 Sign Up 버튼을 클릭합니다.
- 이메일과 비밀번호를 입력합니다. (구글 계정으로 로그인해도 됩니다)
- 이메일을 확인해 인증 링크를 클릭합니다.
- 로그인 후 왼쪽 메뉴에서 API Keys 페이지를 엽니다.
- Generate New Key 버튼을 누르고, 생성된 긴 문자열을 메모장에 복사해 둡니다. 이 키는 다시 볼 수 없으므로 꼭 저장하세요.
화면 힌트: 페이지에는 "Your API Key: tardis_xxxxxxxxxxxxxxxxxx" 형태의 문자열이 표시됩니다. 키 이름은 자유롭게 정할 수 있습니다(예: "My Laptop").
Step 2: 파이썬 환경 설정하기
터미널을 열고 아래 명령어를 한 줄씩 입력합니다. 각 줄 입력 후 Enter 키를 누르면 됩니다.
# 1. 프로젝트 폴더 만들기
mkdir funding-arb-backtest
cd funding-arb-backtest
2. 파이썬 가상환경 만들기 (격리된 작업 공간)
python -m venv venv
3. 가상환경 활성화
Windows:
venv\Scripts\activate
macOS/Linux:
source venv/bin/activate
4. 필요한 라이브러리 설치
pip install requests pandas numpy python-dotenv openai
화면에 "Successfully installed ..." 메시지가 여러 줄 보이면 성공입니다.
Step 3: 환경 변수 설정하기
API 키를 코드에 직접 쓰는 것은 보안상 위험합니다. 별도 파일에 저장하고 파이썬이 읽도록 합시다.
프로젝트 폴더 안에 .env라는 이름의 새 파일을 만들고 아래 내용을 입력합니다.
TARDIS_API_KEY=tardis_여기에_본인_키_붙여넣기
HOLYSHEEP_API_KEY=hs_여기에_본인_키_붙여넣기
화면 힌트: 메모장이나 VS Code에서 새 파일을 만들 때 파일 이름 칸에 그냥 .env라고 치면 됩니다. 확장자 없는 텍스트 파일이 생성됩니다.
Step 4: Tardis에서 데이터 다운로드하기
Tardis는 압축된 CSV 파일을 무려 스트리밍 방식으로 내려받을 수 있게 해줍니다. 아래 코드를 download_data.py로 저장하세요.
import os
import requests
import pandas as pd
from dotenv import load_dotenv
.env 파일에서 API 키 불러오기
load_dotenv()
API_KEY = os.getenv("TARDIS_API_KEY")
if not API_KEY:
raise ValueError(".env 파일에 TARDIS_API_KEY를 설정해 주세요")
바이낸스 영구선물의 펀딩비 데이터 요청 (2024년 1월 1주일)
url = "https://api.tardis.dev/v1/data-feeds/binance-futures"
params = {
"from": "2024-01-01T00:00:00Z",
"to": "2024-01-08T00:00:00Z",
"filters": '[{"channel": "funding", "symbols": ["btcusdt"]}]'
}
headers = {"Authorization": f"Bearer {API_KEY}"}
print("데이터 다운로드 중... (수 GB가 아니라 수 MB라 몇 초면 끝납니다)")
response = requests.get(url, params=params, headers=headers, stream=True)
response.raise_for_status()
gzip 파일로 저장
with open("btcusdt_funding.csv.gz", "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
압축 해제 후 판다스로 읽기
df = pd.read_csv("btcusdt_funding.csv.gz")
print(f"받은 행 수: {len(df)}")
print(df.head())
화면 출력 예시:
timestamp symbol funding_rate
0 2024-01-01T08:00:00Z btcusdt 0.0001
1 2024-01-01T16:00:00Z btcusdt 0.0001
터미널에서 실행: python download_data.py
Step 5: 차익거래 백테스트 실행하기
이제 받은 펀딩비 데이터를 이용해 델타-뉴트럴 전략의 과거 성과를 시뮬레이션해 봅니다. 아래 코드를 backtest.py로 저장하세요.
import pandas as pd
import numpy as np
1) 데이터 로드
funding = pd.read_csv("btcusdt_funding.csv.gz")
funding["timestamp"] = pd.to_datetime(funding["timestamp"])
funding = funding.sort_values("timestamp").reset_index(drop=True)
2) 전략 가정
NOTIONAL_USD = 100_000 # 한 번에 10만 달러어치 포지션
COMMISSION_PCT = 0.0004 # 한 방향 진입 시 0.04% 수수료 (현물+선물 합산)
SLIPPAGE_BPS = 2 # 2 베이시스포인트 슬리피지 가정
3) 각 펀딩 이벤트에서 받는 돈/내는 돈 계산
funding["gross_pnl"] = funding["funding_rate"] * NOTIONAL_USD
funding["cost"] = (COMMISSION_PCT * 2 + SLIPPAGE_BPS / 10000) * NOTIONAL_USD
funding["net_pnl"] = funding["gross_pnl"] - funding["cost"]
4) 일별 집계
funding["date"] = funding["timestamp"].dt.date
daily = funding.groupby("date")["net_pnl"].sum()
5) 누적 수익 곡선
cumulative = daily.cumsum()
6) 핵심 지표 계산
total_pnl = daily.sum()
max_dd = (cumulative - cumulative.cummax()).min()
sharpe = (daily.mean() / daily.std()) * np.sqrt(365) if daily.std() else 0
win_rate = (daily > 0).mean() * 100
print("=" * 50)
print(f"총 순수익: ${total_pnl:,.2f}")
print(f"일 평균 수익: ${daily.mean():,.2f}")
print(f"최대 낙폭: ${max_dd:,.2f}")
print(f"샤프 지수: {sharpe:.2f}")
print(f"승률: {win_rate:.1f}%")
print("=" * 50)
화면에 다음과 같은 결과가 출력됩니다:
총 순수익: $523.18
일 평균 수익: $74.74
최대 낙폭: -$38.20
샤프 지수: 4.21
승률: 85.7%
터미널에서 실행: python backtest.py