5분브리핑 1차

ehllll·2025년 6월 16일

-5분브리핑 1차-

📊 실시간 주식 분봉 데이터 저장 시스템 구현기



크게 문제 정의, 해결 방법, 구현 내용, 결과, 그리고 회고 순서로 말씀드리겠습니다



문제정의

먼저 문제를 정의해보았습니다.

주식 차트를 그리기 위해서는 분봉, 즉 몇 분 단위의 가격 데이터가 필요하지만,

이런 기초 데이터가 비어 있어서 차트 시각화나 다른 종목과의 비교가 어렵다는 점이 있었습니다.

또한, 이 데이터를 자동으로 수집해서 DB에 저장하는 기능도 없어서,
매번 수동으로 API를 호출해야 했습니다.

이 문제를 해결하는 것이 이번 구현의 핵심 목표였습니다.



해결방법 & 기술선택

그래서 저는 다음과 같은 방식으로 문제를 해결하고자 했습니다.

먼저, 주식 분봉 데이터를 정해진 시간마다 자동으로 수집해서 DB에 저장하는 구조를 만들었고,
이렇게 사전에 데이터를 쌓아두면 사용자가 나중에 필요할 때
원하는 시점의 주식 정보를 빠르게 조회할 수 있도록 설계했습니다.

또한, 1분, 3분, 5분 단위의 인터벌에 맞춰 데이터를 주기적으로 수집하도록 구성했습니다.

사용한 기술 스택은 다음과 같습니다.

Spring Boot는 경량화된 구조로 빠르게 REST API를 만들 수 있어서 선택했고,

JPA는 주식 캔들 데이터를 DB에 쉽게 매핑하고 조회할 수 있도록 도와줍니다.

RestTemplate은 외부 HANTU 오픈 API와 통신하는 데 사용했고,

@Scheduled를 이용해 주식 시장 시간에 맞춰 자동으로 API 요청과 저장이 이뤄지도록 구성했습니다.



구현 내용

전체 구현 흐름은

자동 스케줄링 → API 요청 → 응답 파싱 → DB 저장 순서로 진행됩니다.

구체적으로 설명드리면,
평일 오전 9시, 11시, 1시에 자동 실행되도록 @Scheduled 애노테이션으로 설정해두었고,
등록된 모든 종목 코드에 대해 반복적으로 요청이 수행됩니다.

분봉 데이터는 1분, 3분, 5분 단위로 수집되도록 설정되어 있으며,
인터벌마다 요청 시작 시간이 다르게 정해져 있어
예를 들어 1분봉은 오전 시간대에 여러 번 수집되고,
3분봉과 5분봉은 더 간격이 긴 시간대로 설정되어 효율적으로 처리됩니다.

API 요청은 HANTU 오픈 API를 사용했습니다.
요청 URL에는 종목 코드, 시간대, 그리고 분봉 간격 정보가 들어가고,
헤더에는 인증을 위한 토큰, appKey, appSecret, tr_id 등을 포함시켰습니다.

요청은 HANTU 오픈 API를 사용하며,
요청 URL에는 종목 코드, 날짜, 시간대, 인터벌 정보가 포함됩니다.
요청 헤더에는 access token, appKey, appSecret, tr_id 등을 포함하여 인증을 처리합니다.

이렇게 요청을 보내면,
JSON 형태의 주식 분봉 데이터가 응답으로 오고,
이 중 output2 배열을 파싱해서 DB에 저장하는 구조입니다.

만약 응답이 비어 있거나 API 호출에 실패해도
각 단계에 예외 처리를 분리해서 전체 흐름이 멈추지 않도록 설계했습니다.


응답 데이터 중에서 핵심은 output2라는 배열입니다.
이 배열 안에는 각 분봉 데이터가 JSON 객체 형태로 들어 있으며,
이를 하나씩 꺼내서 DTO로 매핑한 뒤, 엔티티 객체로 변환합니다.

변환된 엔티티는 해당 종목 코드에 매핑되는 Stock 객체와 함께
하나의 캔들 데이터로 저장되며, 전체 데이터를 한 번에 saveAll()로 DB에 저장합니다.

각 필드 값은 응답 JSON에서 직접 가져오고,
특히 날짜나 시간 정보는 문자열로 되어 있기 때문에,
이를 LocalDate나 LocalDateTime 객체로 파싱해서 정확하게 변환해 저장하도록 처리했습니다.

또한, 종목 코드에 해당하는 Stock 엔티티가 존재하지 않는 경우에는
에러 로그를 출력하고 해당 데이터 저장은 건너뛰는 방식으로
전체 저장 로직이 중단되지 않도록 구성했습니다.


실제 운영 환경에서는 외부 API 서버 문제나 응답 지연,
예상치 못한 데이터 형식 등으로 인해 예외 상황이 자주 발생할 수 있습니다.

이런 상황에 대비해서, 코드 곳곳에 try-catch 블록을 사용했습니다.
API 호출이나 JSON 파싱 중 문제가 발생하더라도
전체 흐름이 멈추지 않고 다음 종목이나 인터벌로 넘어갈 수 있도록 설계했습니다.

또한, 데이터 저장 중 일부 캔들에서 오류가 발생하더라도
나머지 정상 데이터는 그대로 저장되도록 해서
실시간성 유지와 장애 회피 측면에서 안정적인 구조를 만들었습니다.

수집된 분봉 데이터는
다음과같은 형태의 API를 통해 조회할 수 있으며,
날짜와 인터벌을 파라미터로 전달하면
해당 조건에 맞는 데이터를 바로 응답받을 수 있습니다.



결과와 효과

이제 결과와 효과에 대해 말씀드리겠습니다.

과거에는 데이터를 얻기 위해 매번 API를 수동으로 호출해야 했기 때문에,
시간이 들고, 응답이 누락되거나 저장이 되지 않는 경우도 종종 발생했습니다.

하지만 지금은 @Scheduled 기능을 통해
평일 오전 9시, 11시, 1시에 자동으로 API 요청이 실행되도록 구성해서,
더 이상 수동 작업 없이도 지정된 시간마다 분봉 데이터가 자동으로 수집되고 저장됩니다.

또한 API 요청 시 필요한 헤더 설정과 access token 발급 처리를 안정적으로 구성하면서,
조회 API의 호출 성공률도 이전보다 훨씬 향상되었고,
오류 발생 시 쉽게 추적할 수 있도록 디버깅용 로그도 충분히 남기도록 설계했습니다.

정확한 수치를 측정하진 않았지만,
초기에는 API 누락, 응답 미처리, 저장 실패 등으로 인해
분봉 차트가 제대로 출력되지 않는 경우가 많았던 반면,
현재는 자동 수집 및 저장 구조 덕분에 거의 모든 데이터가 안정적으로 관리되고 있는 상황입니다.



회고 & 개선 아이디어

이번 기능을 구현하면서 가장 어려웠던 점은 API 호출 시 발생하는 다양한 예외 상황을 예측하고 처리하는 것이었습니다.
처음에는 단순히 URL과 헤더만 넣어서 호출하면 끝날 줄 알았는데,
토큰 만료, 잘못된 주식 코드, 시간 간격 오류 등 다양한 문제에 직면했습니다.

이 문제들을 해결하기 위해

로그를 꼼꼼히 출력하며 요청흐름과 응답구조를 익히게 되었습니다

이 과정을 통해 단순히 코드를 짜는 것이 아니라
코드 흐름을 이해하고 디버깅하는 능력이 얼마나 중요한지를 배웠습니다.

기술적으로는 RestTemplate 사용법, @Scheduled 활용, 그리고 응답 파싱 등을 배웠고,
DB와 연동해서 자동 저장하는 로직까지 자연스럽게 익히게 된 좋은 경험이었습니다.

현재는 설정된 시간대마다 데이터를 수집하지만,

실제 장중 실시간 업데이트는 어렵습니다

다음에 개선 기회가 있다면,
실시간으로 캔들을 계속 저장하는 구조로 확장하거나,
사용자 맞춤형 알림 기능도 붙여보고 싶습니다.





0개의 댓글