나는 이렇게 학습한다/Library

websockets _ Python 으로 비트코인 실시간 시세 가져오기 (feat. twelvedata)

daco2020 2022. 7. 24. 15:50
반응형

 

웹소켓으로 받아오는 실시간 데이터 모습

 

주식이나 암호화폐는 실시간으로 거래가 이루어지기 때문에 시세 변동 또한 실시간으로 이루어진다.

때문에 정확한 정보를 고객에게 전달하기 위해서는 시장의 실시간 데이터를 가져와 가공 및 분석하여 고객에게 제공할 수 있어야 한다.

 

이번 글에서는 누구나 쉽게 따라할 수 있는, Python과 websockets으로 비트코인 시세 가져오기를 구현해보겠다.

 

 

 

twelvedata

먼저 데이터를 어디서 가져올지 정해야하는데 이 글에서는 twelvedata를 사용하겠다.

 

twelvedata는 재무데이터를 제공해주는 여러 곳 중 하나인데, 공식문서가 비교적 쉽게 설명되어있고 웹소켓을 간단히 테스트할 수 있는 웹페이지도 제공해주기 때문에 초보자가 접근하기 쉽다. 참고로 무료 계정에서는 최대 8개의 심볼(종목)을 수신받을 수 있다.

 

 

사용방법은 간단하다.

 

먼저 twelvedata 로 접속한다.

Start now 버튼을 누르고 회원가입을 한다.

회원가입을 하면 아래와 같은 페이지로 이동하는데 API keys 탭을 누르면 시크릿 키를 확인할 수 있다. 

(시크릿 키는 자신의 메모장에 잘 저장해두자.)

 

 

 

 

해당 페이지에서 바로 웹소켓을 테스트해볼 수 있는데 아래 이미지에 적힌 순서대로  클릭 4번만 하면 우측 화면처럼 실시간 데이터를 받아볼 수 있다. 

 

 

실시간 데이터를 받는데 성공했다!

그럼 이제 Python 코드로 구현해보자!

 

 

 

 

 

 

Python과 websockets

코드를 보기 전에 요구사항을 간략하게 정리해보자.

  1. python 스크립트를 실행하면 요청 메시지를 websockets으로 전송한다.
  2. twelvedata로부터 비트코인 시세를 받아 csv 파일로 저장한다. 

 

 

전체 코드는 다음과 같다.

import asyncio
import csv
import json
import websockets
import config


PARAMS = {
    "action": "subscribe",
    "params": {
        "symbols": "ETH/BTC"
    }
}

async def run():
    websocket = await websockets.connect(config.url, ping_interval=10)
    await websocket.send(json.dumps(PARAMS)) 
    
    with open('histories.csv', 'a') as file:
        writer = csv.writer(file)
        while True:
            message = await websocket.recv()
            data = json.loads(message)
            
            print(data)

            writer.writerow(data.keys())
            writer.writerow(data.values())

if __name__ == "__main__":
    asyncio.run(run())

하나씩 설명해보겠다.

 

 

 

 

 

1번 요구사항

"""
python 스크립트를 실행하면 요청 메시지를 websockets으로 전송한다.
"""

# 이것이 미리 적어둔 비트코인 정보 요청에 대한 메시지 이다.
# 메시지 형식은 공식 문서를 참고해보라.
PARAMS = { 
    "action": "subscribe", # 구독을 하겠다는 의미이다.
    "params": {
        "symbols": "ETH/BTC" # ETH/BTC는 비트코인 심볼이다.
    }
}


async def run(): 
    # websockets 모듈을 가져와 연결을 한다. 연결에는 대상 url이 필요하며, 
    # ping_interval은 10초 간격으로 핑을 통해 연결을 유지하겠다는 의미이다.
    websocket = await websockets.connect(config.url, ping_interval=10) 
    
    # 위에 기재한 메시지를 json으로 바꾸어 연결된 웹소켓을 통해 전달한다.
    await websocket.send(json.dumps(PARAMS)) 
    
    
# 이 코드는 비동기 함수인 run을 실행하는 코드이다. 
# 이 스크립트를 메인으로 사용하는 경우에만 실행한다.
if __name__ == "__main__":
    asyncio.run(run())

 

'config.url' 의 경우 내 개인 api key가 있기 때문에 다른 곳에서 불러왔다. 여러분은 아래 url을 넣으면 된다.

 

api key는 위 twelvedata 페이지에서 확인했던 그 api Key이다.  

wss://ws.twelvedata.com/v1//quotes/price?apikey="자신의 api key를 넣어주세요"

 

 

더 자세한 내용은 공식문서에 친절히 나와있다. 링크를 함께 남기니 추후 자세히 살펴보면 좋다. 공식문서

 

 

 

 

 

2번 요구사항

"""
twelvedata로부터 비트코인 시세를 받아 csv 파일로 저장한다. 
"""

    # 'histories' 라는 csv 파일을 만들고 쓸 준비를 한다.
    with open('histories.csv', 'a') as file:
        writer = csv.writer(file)
        
        # 탈출하기 전까지 무한 루프를 돈다.
        while True:
            # twelvedata로 부터 받는 메시지를 dict로 형변환한다.
            message = await websocket.recv()
            data = json.loads(message)

            # 데이터 상태를 터미널애서 확인하기 위해 출력해본다.
            print(data)
            
            # data의 key 와 value 를 분리하여 csv파일에 입력한다.
            writer.writerow(data.keys())
            writer.writerow(data.values())

 

 

 

 

결과물

구글에서 확인한 비트코인 시세
웹소켓으로 받아온 비트코인 시세 데이터, price 가 0.071051 로 실제 시세와 일치한다.

 

결과물을 보면 터미널에 출력된 마지막 데이터가 csv파일에서도 마지막에 입력되어 있는 것을 볼 수 있다.

데이터를 csv에 저장할 때 키와 값을 분리했는데 이는 데이터를 어떻게 가공할 것인지에 따라 다르게 저장할 수 있다.

 

나의 경우 파일시스템을 사용하였지만 여러분은 DB나 스프레드 시트, 노션 데이터베이스와 같은 외부 데이터 저장소를 활용할 수도 있다.

 

 

 

마무리

Python과 websockets 을 활용해 실시간 데이터를 가져와보았다.

이런 방식으로 비트코인 뿐만아니라 다른 재무 데이터들, 그 외 웹소켓을 지원하는 모든 API의 실시간 데이터를 가져올 수 있다. (권한에 따라 다를 수 있다)

 

평소 실시간 데이터에 흥미를 가지고 있었다면 오늘 배운 것으로 자그마한 프로젝트에 도전해보면 어떨까.

 

 

 

 

에필로그

웹소켓 기술은 '소켓멍'으로도 활용할 수 있다 :)

 

 

 

반응형