[신투 프디아] 너가 내려라 시세데이터...(feat Kafka)

YUZE·2025년 10월 2일

안녕하세요...
오늘은 실시간 체결가로 시세를 된 사륜구동 CTO YUZE입니다.


이 과정에서 많은 시행착오가 있었고, 그 과정에 대해서 공유해 드리려고 글로 남깁니다.

저희 서비스의 시세데이터 아키텍처는 다음과 같습니다.

저희 서비스는 유저가 전략을 생성하고, 전략마다 pod 1개가 할당되는 구조입니다.

따라서, pod가 스스로 전략에 대한 조건을 체크하기 위해서 중앙에서 시세를 내려줘야 합니다.

프로젝트 모듈 중, 시세 데이터를 수집해 pod에게 뿌려주는 모듈을 market-service로 정의했고

한국투자증권의 체결 데이터를 구독해서, 실시간 체결가를 1분봉으로 계산하는 구조로 아키텍처를 구성했습니다.




구현 방법


  • 중앙 시세 서버에 체결가 시세가 내려옴
  • 중앙 시세 서버에서 1분봉으로 만든다
  • 보조지표를 계산한 다음에 전략 pod들한테 뿌린다



실시간으로 체결가 가져오기


한국투자증권 실시간 체결가

위 api를 통해서 한국투자증권 체결가를 구독하면, 체결가가 실시간으로 내려옵니다.

한투 api 틱단위로 제공해주는 것


주요 필드 매핑

  class ResponseBody:
    MKSC_SHRN_ISCD: str    #유가증권 단축 종목코드
    STCK_CNTG_HOUR: str    #주식 체결 시간
    STCK_PRPR: float    #주식 현재가
    PRDY_VRSS_SIGN: str    #전일 대비 부호
    PRDY_VRSS: float    #전일 대비
    PRDY_CTRT: float    #전일 대비율
    WGHN_AVRG_STCK_PRC: float    #가중 평균 주식 가격 (VWAP)
    STCK_OPRC: float    #주식 시가
    STCK_HGPR: float    #주식 최고가
    STCK_LWPR: float    #주식 최저가
    ASKP1: float    #매도호가1
    BIDP1: float    #매수호가1
    CNTG_VOL: float    #체결 거래량
    ACML_VOL: float    #누적 거래량
    ACML_TR_PBMN: float    #누적 거래 대금
    SELN_CNTG_CSNU: float    #매도 체결 건수
    SHNU_CNTG_CSNU: float    #매수 체결 건수
    NTBY_CNTG_CSNU: float    #순매수 체결 건수
    CTTR: float    #체결강도
    SELN_CNTG_SMTN: float    #총 매도 수량
    SHNU_CNTG_SMTN: float    #총 매수 수량
    CCLD_DVSN: str    #체결구분
    SHNU_RATE: float    #매수비율
    PRDY_VOL_VRSS_ACML_VOL_RATE: float    #전일 거래량 대비 등락율
    OPRC_HOUR: str    #시가 시간
    OPRC_VRSS_PRPR_SIGN: str    #시가대비구분
    OPRC_VRSS_PRPR: float    #시가대비
    HGPR_HOUR: str    #최고가 시간
    HGPR_VRSS_PRPR_SIGN: str    #고가대비구분
    HGPR_VRSS_PRPR: float    #고가대비
    LWPR_HOUR: str    #최저가 시간
    LWPR_VRSS_PRPR_SIGN: str    #저가대비구분
    LWPR_VRSS_PRPR: float    #저가대비
    BSOP_DATE: str    #영업 일자
    NEW_MKOP_CLS_CODE: str    #신 장운영 구분 코드
    TRHT_YN: str    #거래정지 여부
    ASKP_RSQN1: float    #매도호가 잔량1
    BIDP_RSQN1: float    #매수호가 잔량1
    TOTAL_ASKP_RSQN: float    #총 매도호가 잔량
    TOTAL_BIDP_RSQN: float    #총 매수호가 잔량
    VOL_TNRT: float    #거래량 회전율
    PRDY_SMNS_HOUR_ACML_VOL: float    #전일 동시간 누적 거래량
    PRDY_SMNS_HOUR_ACML_VOL_RATE: float    #전일 동시간 누적 거래량 비율
    HOUR_CLS_CODE: str    #시간 구분 코드
    MRKT_TRTM_CLS_CODE: str    #임의종료구분코드
    VI_STND_PRC: float    #정적VI발동기준가

시세데이터가 위와같이 틱단위로 내려오게 되면, 이것을 체결가를 STCK_CNTG_HOUR(체결시간)을 쌓았다가 1분 단위로 분봉 데이터를 만들어, 보죄표를 계산합니다.

저희가 계산해야되는 보조지표는,

틱 단위 체결 데이터로 1분봉 만들기


[Step 1] 시세 데이터를 받아온 다음에 1분봉 만드는 로직 부르기



[Step 2] 1분봉을 만든다

update_candle() 동작 방식

(1) 같은 분일 때

  • high: 현재 고가와 비교해서 더 높은 값으로 갱신
  • low: 현재 저가와 비교해서 더 낮은 값으로 갱신
  • close: 최신 체결가로 갱신
  • volume: 누적 합
  • vwap_num, vwap_den: 거래량 가중 평균가 계산을 위한 값 누적


(2) 분이 바뀌었을 때
  • 직전 current_candle을 closed로 확정
  • candles_1m.append(closed) 로 1분봉 리스트에 저장
  • 새로운 current_candle을 초기화 (open, high, low, close = 현재 체결가)

[step 3] closed_candle이 만들어졌다면(1분봉이 만들어졌다면) 보조 지표계산 on_candle


분봉이 보조지표가 원하는 만큼 모였을 때, 지표를 계산해서 카프카 Producer로 발행

[step 4] 카프카 프로듀서 발행

  • 카프카 도커 컴포즈
    경량 카프카를 사용해서, 간단하게 로컬에서 카프카 테스트를 수행

  • 카프카 토픽의 메시지로 발행하는 코드

  • 테스트를 위한 카프카 컨슈머 코드

  • 실행 결과
    분봉 단위로 보조지표가 잘 계산돼서 컨슈머들이 받고 있다
profile
안녕하세요

0개의 댓글