키움증권 해외선물 자동매매 파이썬) (3) 실시간 데이터 받아오기

키움증권 해외선물 자동매매 파이썬) (3) 실시간 데이터 받아오기

여기서 더 세부적인 단위로 나누면 아래와 같다. 수신부는 UDP 멀티캐스트 그룹에 접속해서 데이터를 읽어옵니다. 참고해서 한국 거래소에서 데이터를 읽어오는 방식은 크게 두 가지가 있습니다. 멀티 캐스트란 같은 데이터를 특정 그룹에게 보내주어야 할 때 사용하는 인터넷 프로토콜입니다. 멀티 캐스트를 통해 집단 단위로 데이터를 통신할 있습니다. 처리부는 비즈니스 로직이 있는 곳으로, Redis에 저장하거나 문자 브로커를 통해 서비스에 전달합니다.


EventLoop
EventLoop

EventLoop

EventLoop는 ThreadPoolTaskExecutor의 corePoolSize 1, maxPoolSize 1로 만들 있습니다. 그리고 DiscardOldestPolicy를 적용합니다. 큐의 크기가 가득차면 맨 뒤 요소를 삭제합니다. 실시간 데이터에 적합 EventLoop가 1개라면 단일 스레드가 동작하는 것과 다를 바가 없습니다.. 하지만 EventLoop가 너무 많아도 아래의 단점이 생길 있습니다. Context Switching으로 인한 비용 증가 그래서 EventLoop 개수는 줄이면서도 더 효율적으로 동작하는 방안이 필요합니다.

그래서 아래의 3가지 방안을 적용할 수 있었어요. Non-Blocking I/O 사용

처리부 -> 레디스 저장 시 Blocking I/O가 발생했다.

활용될 라이브러리, 로그인 등의 내용은 정리를 생략합니다. 1줄35줄 활용될 라이브러리, 로그인 등의 내용은 정리를 생략합니다. 13줄 이 글의 첫번째 핵심입니다. 실시간 데이터를 받으려면 데이터 입력요청을 통해 키움증권에서 이벤트가 발생하는데, 사용자가 수신받을 함수46줄와 이벤트를 실시간 연결합니다. 38줄43줄 74줄에서 전달해준 2개 변수NQZ23, 1분을 키움증권에 입력SetInputValue 및 요청CommRqData합니다.

46줄68줄 이 글의 두번째 핵심입니다. 실시간 수신받을 함수를 선언합니다. 키움증권 서버에서 이벤트가 발생하면 11줄OnReceiveRealData와 연결되어서, 데이터를 실시간 수신GetCommRealData받는다. 46줄 키움서버에서 전달받은 종목, realtypefid 값 모음, realdata활용하지 않음의 3가지 정보를 수신받는 함수를 정의합니다.

Polling과 WebSocket
Polling과 WebSocket

Polling과 WebSocket

처음부터 실시간을 도입할 예정은 없었고 API Polling 방법을 채택하였습니다. 이유는 토스증권의 타깃은 주식 초심자들을 주요 타깃으로 보고 이들은 시세 정보의 실시간에 크게 민감하지 않을 것이라는 가설이 존재했습니다. 하지만 론칭을 앞두고 사용자에게 가능한 실시간 시세를 제공해야 한다는 의견에 팀원들이 공감하였으며 WebSocket을 채택하게 됩니다. 이외에 Server Side Event도 고려되었지만 이후 양방향 통신 기능 확장성을 위하여 WebSocket을 채택하였습니다.

다만 SSE가 방화벽 연관 이슈가 덜 발생하기 때문에 단방향 통신인 시세 시스템은 SSE도 충분히 고려해볼 만할 것 같습니다.

웹홈페이지 시세를 사용하는 방법
웹홈페이지 시세를 사용하는 방법

웹홈페이지 시세를 사용하는 방법

또 다른 방법으로는 인베스팅닷컴 사이트나 구글 금융업 사이트를 통해 확인할 수 있습니다. 인베스팅닷컴이라고 검색하면 한국어 버전이 뜹니다. 클릭합니다. 상단에 있는 입력란에 해즈브로를 입력하고 검색 아이콘을 클릭합니다. 나스닥의 해즈브로 종목을 클릭합니다. 그래도 약간 시간차가 나는 것 같습니다. 이번엔 웹브라우저에서 구글 파이낸스를 검색했습니다. 검색된 구글 금융업 사이트를 클릭합니다.

상단 탭 중에서 내 주식 정보 탭을 클릭합니다. 최근 검색 항목에서 해즈브로Hasbro를 클릭합니다. 현지 시간으로 표시가 되며 실시간입니다. 이 주가를 보고 매수가를 써내면 될 것 같습니다.

Recv 0

이럴때 RecvQ가 지속적으로 0보다. 크다면 데이터가 처리되지 못하고 쌓이는 것을 의미합니다. 이럴때 아래의 방법을 사용할 있습니다. NioEventLoop 확인

데이터 변환, 객체 생성, 로깅 등 사소한 처리도 제거 혹은 다른 스레드에 위임 CPU Profiling

CPU 사용량을 확인해서 불필요한 Thread를 찾아내어 제거하거나 개수를 줄이면 ContextSwitching이 줄어들게 됩니다. 예를 들어 기본적으로 할당되는 Spring의 Tomcat Thread를 1로 줄이는 것 NioEventLoop를 여러 개 사용하기

Socket 버퍼 읽기 개선 지금까지 살펴본 내용들로 개착한 결과는 아래와 같다.

22,000 TPS 상태에서 1ms 이하 처리 시간이라는 결과를 얻을 수 있었다고 합니다.

자주 묻는 질문

EventLoop

EventLoop는 ThreadPoolTaskExecutor의 corePoolSize 1, maxPoolSize 1로 만들 있습니다. 자세한 내용은 본문을 참고하세요.

Polling과

처음부터 실시간을 도입할 예정은 없었고 API Polling 방법을 채택하였습니다. 좀 더 자세한 사항은 본문을 참고해 주세요.

웹홈페이지 시세를 사용하는

또 다른 방법으로는 인베스팅닷컴 사이트나 구글 금융업 사이트를 통해 확인할 수 있습니다. 궁금한 사항은 본문을 참고하시기 바랍니다.