3. 비트코인 선물/3-1. 바이비트 선물 연구일지

(비트코인 자동매매API) (1) 비트코인 과거 1분봉 데이터 한번에 받기

봄이오네 2022. 10. 28. 08:13
반응형
목 차
1. 들어가며
2. 사전준비
① 설명경로
② HTTP Request
③ 입력 인자 (필수 3개, 선택 1개)
④ 받아오는 변수 (9개)
⑤ 바이비트API에 요청/수신받는 데이터형태
3. 코드 설명
4. 전체코드 및 결과
5. 마치며

1. 들어가며

지난 글에서는 UNIX시간에 대해 알아보았다.
사용자에게 친숙하지 않는 UNIX시간은
인터넷 검색을 통해 "Unix 타임 스탬프 변환"을 활용하여
우리에게 익숙한 GMT 시간으로 바꿀 수 있다.

이번 글에서는 바이비트API를 활용하여
비트코인(선물)의 과거 데이터를 받아오는 방법을 알아보자.

1분봉 받는 방법은 바이비트API 접속하여
CSV파일에 담아오도록 하겠다.
(자료 받아올 때, 엑셀은 너무 무거운 느낌이 들어서 CSV를 활용)

참고로, API 키/API secret는 별도로 필요없다.


2. 사전준비

바이비트API 사용 설명서를 먼저 살펴보자.
원문을 보는게 좋을 것 같아서, 영어로 표시하였다.
구글로 바이비트API 홈페이지에 들어가면 "영어/한글"이 나온다.
사용자 편의대로 영어/한글 택1을 하면 될 것이다.

그림1. 바이비트API 설명자료


설명경로 : Market Data Endpoints(시장데이터 엔드포인트) > Query Kline(쿼리 클라인)

HTTP Request : 바이비트API를 통해 서버에 요청함

입력 인자 (필수 3개, 선택 1개)
과거데이터를 받기위해 입력해야 되는 인자이다.

  • symbol(필수) : str형이며, 코인(선물) 이름. ex) "BTCUSD"
  • interval(필수) : str형이며, 분봉 유무. ex) 1분봉이면 1, 3분봉이면 3
  • from_time(필수) : int형이며, Unix 시간으로 표기된 시작시점
  • limit(선택) : int형이며, 화면에 출력한 최대 분봉 갯수 (최대 200개)

※ 여기서 기억할 것은 2가지이다.
1) 설명서에서 interval은 str형인데도 불구하고,
interval = 1로 표기해도 에러가 나지 않는다.
(일봉 D를 받기 위해 문자형으로 표기하였나 보다)
2) from_time(시작시점)이지만,
for문을 돌려줄 것이므로, from_time은 크게 의미없다.
아래에서 확인하겠지만, 필수요소인 만큼 임의의 "aaa"값을 넣어준다.
(임의의 aaa값을 넣어주어도 잘 실행된다.)

받아오는 변수 (9가지를 받아오나, 5개만 활용 예정)

  • symbol : str형이며, 코인(선물) 이름. ex) "BTCUSD"
  • interbal : str형이며, 1분봉, 3분봉, 일봉 등
  • open_time : int형이며, 일시/시간을 나타낸다. ex) 2022-10-28 13:19
  • open : str형이며, 시가
  • high : str형이며, 고가
  • low : str형이며, 저가
  • close : str형이며, 종가
  • volume : str형이며, 거래량
  • turnover : str형이며, 거래대금

⑤ 파이썬을 통해 바이비트API에 요청/수신받는 데이터형태이다.

  • 요청할 때는 query_kline 함수를 이용하며,
  • 수신받을 때는 딕셔너리-리스트(result)-딕셔너리 형태로 받아오는 것을 확인할 수 있다.

3. 코드 설명

바이비트API에 접속하여 받은 5가지(날짜, 시가, 고가, 저가, 종가) 데이터를
CSV 파일에 저장하는 방법에 대해 설명한다.

그림2-1. 필요한 모듈을 임포트하고, CSV파일에 담기 위해데이터프레임 형태로 만든다.


1줄 : 바이비트API 접근을 위해 pybit 모듈을 임포트한다.
(pybit는 파이참 실행창에서 pip install pybit로 설치하자)
2줄 : 52줄~55줄에서 CSV파일에 저장하기 위해, 데이터프레임 형태를 만들어주기 위해 임포트한다.
3줄 : 50줄에서 설정한 의 파일 경로를 알아보기 위해 os모듈을 임포트한다.
4줄 : Unix타임을 활용하기 위해 임포트한다.
5줄 : Unix타임을 GMT로 만들어주기 위해 임포트한다.

7줄 : 시작시간을 설정한다. (59줄에서 소요시간을 파악하기 위함)
9줄 : 시작 시점(from_time)을 설정한다. (18줄의 for문에서 활용)
(설정한 시작시점 1647702000은 2022-04-20 00:00분이다)
10줄 : 끝나는 시점(end_time)을 설정한다. (18줄의 for문에서 활용)
(설정한 끝나는 시점 165038044은 2022-05-20 00:00분이다)
11줄 : for문이 빠르게 돌고 있는 관계로, sleep타임 0.01를 주었다.

13줄 : bybit_minute_get() 임의의 함수를 선언하였다.
14줄~15줄 : session에 http://api.bybit.com 접근을 변수화한다.(endpoint)

18줄 : 이 글의 핵심이다.
① for문의 변수로 aaa를 넣었다.(23줄의 from_time을 첫번째 시작 변수로 넣었다)
② for문의 range 안에는 9줄과 10줄에서 정의한 시간이 들어갔다.
range 끝에 있는 60은 60초 간격의 데이터를 달라는 것이다.
→ 이 부분이 약간 어려웠다. 23줄의 limit=200와 헷갈렸다. ㅠㅠ
예를 들어, 00:00분의 데이터 → 00:01분의 데이터 → 00:02분의 데이터....
(60초마다 for문을 돌려달라는 것이 아니라,
Unix타임으로 설정된 for문의 데이터를 60초 후의 자료를 달라는 내용이다)
※ 23줄의 내용과 헷갈리면 안된다.

예를 들어보자. range(...., 1260), limit=200으로 설정한 경우를 생각해보자.
1260초이면, 21분이다. 위와 같이 설정하였다면,
00:00 → 00:21 → 00:42 → 01:03... 이렇게 띄엄띄엄 데이터를 받아온다.

필자가 원하는 데이터는 연결된 1분봉이다.
00:00 → 00:01 → 00:02 → 00:03.... 이렇게 받으려면 range안에는 60이 들어가야 한다.

19줄 : 14줄에서 바이비트API 홈페이지 접근을 변수화한 session을 통해
바이비트에서 제공하는 query_kline 함수를 변수 resp에 담는다.
20줄~23줄 : 코인이름은 "BTCUSD", 인터벌은 1분봉, limit는 200개(선택사항), from_time은 aaa로 설정

26줄~30줄 : 19줄에서 정의한 변수 resp에서 데이터를 추출한다.
딕셔너리 형태인 result에서 리스트 형태인 첫번째 인수
딕셔너리 형태인 open_time을 data에 담는다. (27줄~30줄 동일)

32줄 : 26줄에서 받아온 data는 Unix타임 형태이므로,
가독성을 위해 GMT 형태로 바꾸어준다.

34줄 : 임의로 선언한 딕셔너리 형태인 minute_coin에 5가지(날짜/시가/고가/저가/종가)를 넣는다.
36줄~40줄 : 34줄 딕셔너리 형태인 minute_coin에 내용을 추가해준다.
for문으로 계속 돌아가고 있으므로, 계속 추가된다.

그림2-2. 데이터프레임의 데이터를 CSV파일에 보낸다.

42줄 : 2줄에서 임포트한 pandas를 활용하여, 32줄의 minute_coin을 데이터프레임 형태로 만든다.
(CSV 파일에 넣어주기 위한 사전작업)
43줄 : 5가지(data, open, high, low, close) 구분란을 만들기 위해,
첫번줄과 두번째 줄을 넣어달라는 내용이다.
(df3는 56줄로 전달되어, CSV파일을 만들어 때 최초 적용된다)

그림2-3. 1줄과 2줄에 구분/데이터가 각각 들어가 있는 엑셀 화면

44줄 : 18줄의 for문을 통해 받아오는 자료는 df4로 정의하여
53줄의 CSV 파일에 담는다.

48줄 : 11줄에서 time.sleep는 0.01초로 설정하였다.

50줄 : 1분봉이 저장될 경로의 파일명을 기재하면 된다.

  • 바탕화면으로 설정하고, 임의의 파일명.csv로 설정하면,
  • 프로그램 실행되면서 알아서 파일 만들고, 데이터를 추가한다

52줄~53줄 : 50줄에서 설정한 경로에 CSV파일이 있으면,
44줄 df4 데이터를 CSV파일에 추가하라.
54줄~55줄 : 50줄에서 설정한 경로에 CSV파일이 없으면,
43줄 df3 데이터를 CSV파일을 만들고, 그 파일에 담아라.

57줄 : 7줄 start_time 과 함께 데이터 받는 시간을 알아보기 위해 end_time 설정하였다.
58줄 : 18줄 for문의 range 안에서 "설정한 시간 데이터"에 도달하여
데이터를 다 받으면, 소요되는 시간 출력
61줄 : 임의로 선언한 13줄 bybit_minute_get 함수를 실행하라


4. 전체코드 및 결과

from pybit.inverse_perpetual import HTTP
import pandas as pd
import os
import time
import datetime as dt

start_time = time.time()

begin_time_minute = 1647702000
end_time_muinute = 1650380400
sleep_time = 0.01

def bybit_minute_get():
    session = HTTP(
        endpoint="https://api.bybit.com",
    )                                                           # 2020-01-01 00:00:00 → 1577804400
                                                                # 2021-01-01 00:00:00 → 1609426800
    for aaa in range(begin_time_minute, end_time_muinute, 60):  # 2021-06-30 00:00:00 → 1624978800
        resp = session.query_kline(                             # 2022-01-01 00:00:00 → 1640962800
            symbol="BTCUSD",                                    # 2022-10-16 00:00:00 → 1665846000
            interval=1,
            limit=200,
            from_time=aaa
        )

        data = resp['result'][0]['open_time']
        open = resp['result'][0]['open']
        high = resp['result'][0] ['high']
        low = resp['result'][0]['low']
        close = resp['result'][0]['close']

        data = dt.datetime.fromtimestamp(data)

        minute_coin = {'data': [], 'open': [], 'high': [], 'low': [], 'close': []}

        minute_coin['data'].append(data)
        minute_coin['open'].append(open)
        minute_coin['high'].append(high)
        minute_coin['low'].append(low)
        minute_coin['close'].append(close)

        df3 = pd.DataFrame(minute_coin, columns=['data', 'open', 'high', 'low', 'close'])
        df3 = df3.head(2)
        df4 = df3.tail(1)

        # print(df4)

        time.sleep(sleep_time)

        dir = r"C:\Users\User\Desktop\bitcoin_minute.csv"

        if os.path.exists(dir):
            df4.to_csv(dir, mode = "a", index=False, header=False)
        else:
            df3.to_csv(dir, mode = "w", index=False)

    end_time = time.time()

    print(f"{dt.datetime.fromtimestamp(begin_time_minute)}부터 {dt.datetime.fromtimestamp(end_time_muinute)}까지 1분봉을 받는 시간은 {end_time-start_time}초가 소요되었습니다.")

bybit_minute_get()

5. 마치며

파이썬을 통해 바이비트API에서 비트코인 1분봉 데이터를 받아오는 내용을 알아보았다.
키움증권OpenAPI보다는 직관적인 점이 마음에 든다.
향후 패턴을 분석해 보고, 진입/청산 시점 설정시 1분봉 데이터 모음을 활용해야겠다.

데이터를 받아오는데, 생각보다 시간이 걸린 점이 조금은 아쉽다.
굉장히 빨리 받아올 줄 알았는데,
1달치(4.5만개) 받아오는데 2시간 조금 더 걸린다.

다음 글에서는 time.sleep 변경에 따라,
1달 분량의 1분봉 데이터를 받아오는 시간이 어떻게 변경되는지,
그리고 이상적인 time.sleep는 몇 초가 적당한지 알아볼 것이다.

반응형