요청을 주고 받는 API가 아니라 Websocket을 이용한 실시간 데이터 처리가 필요한 경우가 더러 있습니다.
오늘은 시시각각 변하는 코인의 가격데이터를 확인하는 방법을 알아보겠습니다.
대상 거래소는 업비트이며 사용 언어는 파이썬입니다.
먼저 전종목코드를 얻어오는 함수를 만들어보겠습니다.
# encoding: utf-8
import pyupbit
import uuid
import json
import asyncio
import websockets
import traceback
def get_all_ticker():
"""
데이터 수신할 TICKER 목록
"""
krw_ticker = pyupbit.get_tickers(fiat="KRW")
return krw_ticker
다음으로 실행해보면 전체 종목목록이 리스트로 나옵니다.
if __name__ == "__main__":
print(get_all_ticker())
# ['KRW-BTC', 'KRW-ETH', 'KRW-NEO', 'KRW-MTL', 'KRW-XRP', 'KRW-ETC', 'KRW-OMG', 'KRW-SNT', 'KRW-WAVES', 'KRW-XEM', 'KRW-QTUM', 'KRW-LSK', 'KRW-STEEM', 'KRW-XLM', 'KRW-ARDR', 'KRW-ARK', 'KRW-STORJ', 'KRW-GRS', 'KRW-REP', 'KRW-ADA', 'KRW-SBD', 'KRW-POWR', 'KRW-BTG', 'KRW-ICX', 'KRW-EOS', 'KRW-TRX', 'KRW-SC', 'KRW-ONT', 'KRW-ZIL', 'KRW-POLY', 'KRW-ZRX', 'KRW-LOOM', 'KRW-BCH', 'KRW-BAT', 'KRW-IOST', 'KRW-RFR', 'KRW-CVC', 'KRW-IQ', 'KRW-IOTA', 'KRW-MFT', 'KRW-ONG', 'KRW-GAS', 'KRW-UPP', 'KRW-ELF', 'KRW-KNC', 'KRW-BSV', 'KRW-THETA', 'KRW-QKC', 'KRW-BTT', 'KRW-MOC', 'KRW-ENJ', 'KRW-TFUEL', 'KRW-MANA', 'KRW-ANKR', 'KRW-AERGO', 'KRW-ATOM', 'KRW-TT', 'KRW-CRE', 'KRW-MBL', 'KRW-WAXP', 'KRW-HBAR', 'KRW-MED', 'KRW-MLK', 'KRW-STPT', 'KRW-ORBS', 'KRW-VET', 'KRW-CHZ', 'KRW-STMX', 'KRW-DKA', 'KRW-HIVE', 'KRW-KAVA', 'KRW-AHT', 'KRW-LINK', 'KRW-XTZ', 'KRW-BORA', 'KRW-JST', 'KRW-CRO', 'KRW-TON', 'KRW-SXP', 'KRW-HUNT', 'KRW-PLA', 'KRW-DOT', 'KRW-SRM', 'KRW-MVL', 'KRW-STRAX', 'KRW-AQT', 'KRW-GLM', 'KRW-SSX', 'KRW-META', 'KRW-FCT2', 'KRW-CBK', 'KRW-SAND', 'KRW-HUM', 'KRW-DOGE', 'KRW-STRK', 'KRW-PUNDIX', 'KRW-FLOW', 'KRW-DAWN', 'KRW-AXS', 'KRW-STX', 'KRW-XEC', 'KRW-SOL', 'KRW-MATIC', 'KRW-NU', 'KRW-AAVE', 'KRW-1INCH', 'KRW-ALGO', 'KRW-NEAR', 'KRW-WEMIX', 'KRW-AVAX', 'KRW-T', 'KRW-CELO', 'KRW-GMT', 'KRW-APT']
이상태에서 Websocket 을 사용하는 코드는 다음과 같습니다.
async def connect_socket():
"""
UPBIT 소켓연결(샘플)
:return: None
"""
while True:
try:
async with websockets.connect('wss://api.upbit.com/websocket/v1', ping_interval=None, ping_timeout=30, max_queue=10000) as websocket:
subscribe_fmt = [
{'ticket': str(uuid.uuid4())[:6]},
{
'type': 'ticker',
'codes': get_all_ticker(),
'isOnlyRealtime': True
},
]
subscribe_data = json.dumps(subscribe_fmt)
await websocket.send(subscribe_data)
while True:
try:
data = await websocket.recv()
data = json.loads(data)
if 'code' not in data: # 응답 데이터(딕셔너리)에 code가 없는 경우 제외
print("[Data error]", data)
continue
# base_ticker = data['code'].split('-')[0] # KRW-BTC > KRW(기준통화)
ticker = data['code'].split('-')[1] # KRW-BTC > BTC(시세조회대상 코인)
print(ticker, data) # 결과출력 테스트(주석)
except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed):
try:
pong = await websocket.ping()
await asyncio.wait_for(pong, timeout=30)
except:
await asyncio.sleep(30)
break
except:
traceback.print_exc()
except:
await asyncio.sleep(30)
connect_socket 함수를 보면 while문을 이용해 무한루프를 만들었습니다. 혹시 Websocket의 연결이 끊어지더라도 다시 재연결하도록 만들기 위해서입니다.
upbit의 Websocket server 주소는 다음과 같습니다.
wss://api.upbit.com/websocket/v1
with 구문을 이용해 연결한 websocket에 구독할 데이터 포멧(subscribe_fmt)을 전달합니다.
subscribe_fmt = [
{'ticket': str(uuid.uuid4())[:6]},
{
'type': 'ticker',
'codes': get_all_ticker(),
'isOnlyRealtime': True
},
]
subscribe_data = json.dumps(subscribe_fmt)
await websocket.send(subscribe_data)
해외거래소를 사용하면 하나의 정보당 한번씩 요청해야해서 websocket.send를 여러번해야할 때도 있지만 upbit는 한번에 끝나서 편합니다. codes 필드에는 get_all_ticker 함수의 결과를 전달합니다.
이후부터는 다시 무한루프 while문을 이용해 계속 데이터를 수신(websocket.recv)합니다.
while True:
try:
data = await websocket.recv()
data = json.loads(data)
if 'code' not in data: # 응답 데이터(딕셔너리)에 code가 없는 경우 제외
print("[Data error]", data)
continue
# base_ticker = data['code'].split('-')[0] # KRW-BTC > KRW(기준통화)
ticker = data['code'].split('-')[1] # KRW-BTC > BTC(시세조회대상 코인)
print(ticker, data) # 결과출력 테스트(주석)
except (asyncio.TimeoutError, websockets.exceptions.ConnectionClosed):
try:
pong = await websocket.ping()
await asyncio.wait_for(pong, timeout=30)
except:
await asyncio.sleep(30)
break
except:
traceback.print_exc()
try-except를 사용해 에러가 나더라도 잠시 대기 후 재연결하도록 되어있습니다.
마지막으로 run 함수를 이용해 create_task를 만들고 run해줍니다.
async def run():
"""
:return:
"""
await asyncio.wait([
asyncio.create_task(connect_socket()),
])
if __name__ == "__main__":
asyncio.run(run())
그 결과는 다음과 같습니다.
결과를 보면 다음과 같습니다.
앞에 ticker는 제가 출력한 것이고 뒤에 딕셔너리가 Websocket을 이용해 수신한 데이터의 원본(?)입니다.
WEMIX {'type': 'ticker', 'code': 'KRW-WEMIX', 'opening_price': 2545, 'high_price': 2630, 'low_price': 1870, 'trade_price': 1895, 'prev_closing_price': 2545.0, 'acc_trade_price': 179061621306.1007, 'change': 'FALL', 'change_price': 650.0, 'signed_change_price': -650.0, 'change_rate': 0.2554027505, 'signed_change_rate': -0.2554027505, 'ask_bid': 'ASK', 'trade_volume': 518.13471502, 'acc_trade_volume': 79932981.81375916, 'trade_date': '20221027', 'trade_time': '160539', 'trade_timestamp': 1666886739097, 'acc_ask_volume': 49742376.32154966, 'acc_bid_volume': 30190605.49220951, 'highest_52_week_price': 13490.0, 'highest_52_week_date': '2022-01-11', 'lowest_52_week_price': 1865.0, 'lowest_52_week_date': '2022-05-12', 'market_state': 'ACTIVE', 'is_trading_suspended': False, 'delisting_date': None, 'market_warning': 'CAUTION', 'timestamp': 1666886739154, 'acc_trade_price_24h': 181321633451.3138, 'acc_trade_volume_24h': 80807551.9126393, 'stream_type': 'REALTIME'}
같이 읽어보면 좋은 글
2022.12.27 - [파이썬/가상화폐] - [전자책] 바이낸스 코인선물자동매매 시스템 개발 방법을 담은 책이 출시되었습니다.
2022.11.05 - [파이썬/가상화폐] - [공지] 코인거래소별 프리미엄 체크봇 개발 가이드와 풀소스 전자책 | binance bybit | 업비트 김치프리미엄
2022.07.26 - [파이썬/가상화폐] - Python Binance Websocket 비트코인 실시간 데이터 조회
'파이썬 > 가상화폐' 카테고리의 다른 글
[전자책] 바이낸스 코인선물자동매매 시스템 개발 방법을 담은 책이 출시되었습니다. (6) | 2022.12.27 |
---|---|
[공지] 코인거래소별 프리미엄 체크봇 개발 가이드와 풀소스 전자책 | binance bybit | 업비트 김치프리미엄 (0) | 2022.11.05 |
Python 비트코인 선물자동매매 프로그램 개발후기, 추세? 역추세매매? (5) | 2022.09.20 |
비트코인 알트코인 추석빔, 업비트 김치 프리미엄 알아보는 방법? (프리미엄 알림봇) (0) | 2022.09.09 |
[공지] 코인 거래소간 프리미엄 알림 채널 무료모집! #김치프리미엄 #업비트 (8) | 2022.08.28 |
댓글