BaseConsumer로 웹소켓 수신의 기본 뼈대를 구성하였습니다. 7-2장에서 FMP 소개 있었습니다. 그중 주식에 대해 무료로 넉넉하게 웹소켓을 제공하는 것은 핀허브정도 입니다. 코인은 바이낸스를 사용하면 됩니다.
웹소켓 형식은 해당 사이트의 API 문서를 확인하시면 되나 찾기가 매우 어려우니 아래 내용을 참고 하시고 실행 하시면 됩니다.
FDP별 WebSocket API 형식
Finnhub(핀허브)
핀허브로 미국 주식 데이터를 실시간으로 가져오려면 가입하고 AIP키를 발급 받아야 합니다.
- Finnhub로 이동합니다. 사이트 우측 상단에 있는 Register를 클릭하고 가입합니다.
- https://finnhub.io/dashboard로 이동합니다. API Key 및 Webhook 를 복사합니다.

- backend/.env 에 붙여 넣습니다.
FMP_API_KEY=yourapikeyFINNHUB_API_KEY=yourapikey FINNHUB_SECRET_KEY=yoursecretkey
웹소켓 요청 API
wss://ws.finnhub.io
- 샘플코드
#https://pypi.org/project/websocket_client/import websocket
def on_message(ws, message): print(message)
def on_error(ws, error): print(error)
def on_close(ws): print("### closed ###")
def on_open(ws): ws.send('{"type":"subscribe","symbol":"AAPL"}') ws.send('{"type":"subscribe","symbol":"AMZN"}') ws.send('{"type":"subscribe","symbol":"BINANCE:BTCUSDT"}') ws.send('{"type":"subscribe","symbol":"IC MARKETS:1"}')if __name__ == "__main__": websocket.enableTrace(True) ws = websocket.WebSocketApp("wss://ws.finnhub.io?token=your_token_here", on_message = on_message, on_error = on_error, on_close = on_close) ws.on_open = on_open ws.run_forever()
- 응답 코드
{ "data": [ { "p": 7296.89, "s": "BINANCE:BTCUSDT", "t": 1575526691134, "v": 0.011467 } ], "type": "trade"}
Binance (바이낸스)
바이낸스는 무료로 열려있는 FDP라 별도의 API 키 없이도 웹소켓 실시간 방송을 받아볼수 있습니다. 다만 종목 기호를 적을 때 BTC가 아니라 BTCUSDT처럼 짝꿍(페어)을 맞춰 적어야 합니다.
웹소켓 요청 API
wss://stream.binance.com:9443/ws
- 샘플 코드
import websocketimport json
def on_message(ws, message): print(message)
def on_error(ws, error): print(error)
def on_close(ws): print("### closed ###")
def on_open(ws): # 바이낸스는 연결 후 구독할 코인 목록(소문자)을 전송합니다. subscribe_msg = { "method": "SUBSCRIBE", "params": [ "btcusdt@trade", "ethusdt@trade" ], "id": 1 } ws.send(json.dumps(subscribe_msg))if __name__ == "__main__": websocket.enableTrace(True) ws = websocket.WebSocketApp("wss://[stream.binance.com:9443/ws](https://stream.binance.com:9443/ws)", on_message = on_message, on_error = on_error, on_close = on_close) ws.on_open = on_open ws.run_forever()
- 응답 코드 형식
{ "e": "trade", // 이벤트 타입 (trade) "E": 1672531200000, // 이벤트 시간 (ms) "s": "BTCUSDT", // 심볼 "t": 12345678, // 거래 ID "p": "50000.00", // 가격(price) "q": "0.01", // 수량(quantity) "b": 87654321, // 매수자 주문 ID "a": 87654322, // 매도자 주문 ID "T": 1672531199999, // 거래 시간 "m": true, // 매수자 마켓 메이커 여부 "M": true // 무시 (Best match)}
🤖 실전! Finnhub 컨슈머 추가(2-12)
🧠 이번 실습의 목적은 BaseConsumer에서 상속받은finnhub_consumer.py를 만들어 실시간 주식 가격 데이터를 가져 올수 있게 하는 과정입니다.
✨ 사용자의 의도(Vibe)
backend/app/services/websocket/base_consumer.py에 있는 BaseConsumer를 상속받아서, WebSocket 컨슈머를 만드는 계획을 마크다운 파일로 수립해줘
- 파일 위치 : backend/app/services/websocket/finnhub_consumer.py
- 웹소켓 요청 API
wss://ws.finnhub.io
- 샘플코드
#https://pypi.org/project/websocket_client/import websocket
def on_message(ws, message): print(message)
def on_error(ws, error): print(error)
def on_close(ws): print("### closed ###")
def on_open(ws): ws.send('{"type":"subscribe","symbol":"AAPL"}') ws.send('{"type":"subscribe","symbol":"AMZN"}') ws.send('{"type":"subscribe","symbol":"BINANCE:BTCUSDT"}') ws.send('{"type":"subscribe","symbol":"IC MARKETS:1"}')if __name__ == "__main__": websocket.enableTrace(True) ws = websocket.WebSocketApp("wss://ws.finnhub.io?token=your_token_here", on_message = on_message, on_error = on_error, on_close = on_close) ws.on_open = on_open ws.run_forever()
- 응답 코드
{ "data": [ { "p": 7296.89, "s": "BINANCE:BTCUSDT", "t": 1575526691134, "v": 0.011467 } ], "type": "trade"}
- 완료후 테스트 시행
🚨 주의사항
- 핀허브 FINNHUB_API_KEY 및 FINNHUB_SECRET_KEY는 ./backend/.env에 있음
- 응답 결과는 항상 BaseConsumer 에서 정의한 표준화된 형식 으로 반환되게 만들어 줘.
- 초보자가 이해하기 쉽게 한글 주석을 달아줘.
💻 AI가 생성한 코드 (Syntax)
- 수립된 계획을 확인하고 실행합니다.
- backend/app/services/websocket/finnhub_consumer.py
import jsonimport loggingimport osfrom typing import Listfrom dotenv import load_dotenvfrom app.services.websocket.base_consumer import BaseConsumer# .env 파일 로드 (FINNHUB_API_KEY 등을 읽어옴)load_dotenv()logger = logging.getLogger(__name__)class FinnhubConsumer(BaseConsumer): 생략
def __init__(self, symbols: List[str]): 생략 async
def _listen(self): 생략 await super()._listen()
🤖 실전! Binance 컨슈머 추가(2-13)
🧠 이번 실습의 목적은 BaseConsumer에서 상속받은binance_consumer.py를 만들어 실시간 코인 가격 데이터를 가져 올수 있게 하는 과정입니다.
✨ 사용자의 의도(Vibe)
backend/app/services/websocket/base_consumer.py에 있는 BaseConsumer를 상속받아서, WebSocket 컨슈머를 만드는 계획을 마크다운 파일로 수립해줘
- 파일 위치 : backend/app/services/websocket/binance_consumer.py
- 웹소켓 요청 API
wss://stream.binance.com:9443/ws
- 샘플 코드
import websocketimport json
def on_message(ws, message): print(message)
def on_error(ws, error): print(error)
def on_close(ws): print("### closed ###")
def on_open(ws): # 바이낸스는 연결 후 구독할 코인 목록(소문자)을 전송합니다. subscribe_msg = { "method": "SUBSCRIBE", "params": [ "btcusdt@trade", "ethusdt@trade" ], "id": 1 } ws.send(json.dumps(subscribe_msg))if __name__ == "__main__": websocket.enableTrace(True) ws = websocket.WebSocketApp("wss://[stream.binance.com:9443/ws](https://stream.binance.com:9443/ws)", on_message = on_message, on_error = on_error, on_close = on_close) ws.on_open = on_open ws.run_forever()
- 응답 코드 형식
{ "e": "trade", // 이벤트 타입 (trade) "E": 1672531200000, // 이벤트 시간 (ms) "s": "BTCUSDT", // 심볼 "t": 12345678, // 거래 ID "p": "50000.00", // 가격(price) "q": "0.01", // 수량(quantity) "b": 87654321, // 매수자 주문 ID "a": 87654322, // 매도자 주문 ID "T": 1672531199999, // 거래 시간 "m": true, // 매수자 마켓 메이커 여부 "M": true // 무시 (Best match)}
- 완료후 테스트 시행
🚨 주의사항
- 응답 결과는 항상 BaseConsumer 에서 정의한 표준화된 형식 으로 반환되게 만들어 줘.
- 초보자가 이해하기 쉽게 한글 주석을 달아줘.
💻 AI가 생성한 코드 (Syntax)
- 수립된 계획을 확인하고 실행합니다.
- backend/app/services/websocket/binance_consumer.py
import jsonimport loggingfrom typing import Listfrom app.services.websocket.base_consumer import BaseConsumerlogger = logging.getLogger(__name__)class BinanceConsumer(BaseConsumer): 생략
def __init__(self, symbols: List[str]): 생략 async
def _listen(self): """ 생략 await super()._listen()