이 시리즈는 개인 투자 자동화 시스템을 처음부터 직접 설계하고 운영한 기록입니다.
코드 공유보다 "왜 이렇게 만들었는가"에 집중합니다.
왜 자동화를 시작했나
미국 주식을 시작한 건 2년쯤 전이다. 처음에는 종목이 몇 개 없어서 관리가 쉬웠다. 문제는 종목이 10개를 넘어가면서 시작됐다.
매일 아침 각 종목의 뉴스를 하나씩 검색하고, 영어 기사를 읽으며 "오늘 이 종목은 어떻게 됐지?"를 파악하는 데만 30분이 넘게 걸렸다.
더 큰 문제는 일관성이었다. 바쁜 날은 대충 훑거나 건너뛰었고, 투자 일지도 어느 순간부터 빈 날짜가 쌓였다.
나중에 "왜 그날 샀는지"를 복기하려면 결국 기억에 의존해야 했다. 이 상황을 바꾸고 싶었다.
문제를 먼저 정의했다
자동화에 앞서, 내가 실제로 반복하는 작업이 무엇인지 먼저 정리했다.
| 보유 종목 뉴스 검색 및 읽기 | 30~40분 | 영어 해석 피로, 일관성 없음 |
| 시장 지수 수동 확인 | 5~10분 | 정보 분산, 기록 없음 |
| 투자 판단 메모 작성 | 10~20분 | 빈 날짜 누적, 복기 불가 |
| 매매 이력 기록 | 5분 | 밀리면 기억에 의존 |
목표는 하나였다. "아침에 일어나면 분석이 이미 끝나 있는 상태"를 만드는 것.

파이프라인 설계
해결책을 정리하다 보니 자연스럽게 파이프라인 구조가 나왔다.
- 뉴스 수집: Finnhub API + Yahoo Finance RSS
- 정제 및 분류: Google Gemini (영문 → 한글 요약 + 감성 분류)
- 투자 분석: ChatGPT (종목별 BUY / HOLD / SELL 판단)
- 블로그 생성: Claude (분석 결과 → 마크다운 초안)
- 동기화 및 알림: Notion 업로드 + Telegram 성공/실패 알림
매일 오전 9시 40분이면 그날의 투자 일지 초안이 Notion에 올라와 있다.
내가 할 일은 초안을 읽고, 데이터 이상만 확인한 뒤 발행 여부를 결정하는 것뿐이다.

기술 스택 선택 기준
트렌드를 따르지 않았다. 내가 가장 잘 쓸 수 있고, 개인 프로젝트 수준에서 운영 부담이 적은 것을 골랐다.
백엔드: Spring Boot + MyBatis + Java 17
ORM 대신 MyBatis를 선택했다. 금융 데이터는 단순 CRUD보다 복잡한 집계 쿼리가 훨씬 많다.
SQL을 직접 작성하는 편이 디버깅과 튜닝 면에서 유리하다.
인증: JWT Stateless
세션 관리가 필요 없는 REST API 구조이고, 개인 사용 시스템이라 복잡한 권한 체계가 필요하지 않았다.
스케줄링: @Scheduled + Quartz 병행
가벼운 정리 작업은 @Scheduled로, 실행 이력을 DB에 남겨야 하는 핵심 파이프라인은 Quartz JDBC 방식으로 운영한다.
프론트엔드: Vue 3 + Vuetify
대시보드 성격의 화면에 Material Design 컴포넌트가 잘 맞았다.
빠르게 만들어야 했기 때문에 Vuetify 기성 컴포넌트가 큰 도움이 됐다.
인프라: Docker Compose 4 컨테이너
Spring Boot, Vue.js, MySQL, Nginx를 각각 컨테이너로 분리했다.
Nginx가 리버스 프록시로 모든 외부 트래픽을 받아 프론트엔드와 백엔드로 분기한다.

전체 시스템 구조
완성된 시스템은 크게 두 흐름으로 나뉜다.
자동화 파이프라인: 매일 새벽부터 오전까지 스케줄러가 알아서 돌아간다. 시장 지수 수집(06:20)으로 시작해서 9단계를 거쳐 Notion 동기화(09:40)로 끝난다.
사용자 대시보드: Vue.js 기반 SPA. 포트폴리오 현황, 시장 지수, 뉴스 분석 결과, 블로그 초안을 한 화면에서 확인한다

이 시리즈에서 다룰 내용
단순 코드 공유가 아니라 "왜 이렇게 만들었는가"에 집중한다. 잘 된 것도, 실패한 것도 그대로 기록한다.
| 2편 | Spring Boot + MyBatis + JWT 백엔드 설계 |
| 3편 | 9단계 자동화 파이프라인 스케줄러 설계 |
| 4편 | 7개 외부 API 연동 전략 (Finnhub, Yahoo, FRED) |
| 5편 | Gemini + GPT + Claude 분업 투자 분석 |
| 6편 | 블로그 자동 생성 + Notion 동기화 + Telegram 알림 |
| 7편 | Docker Compose 4컨테이너 운영 구성 |
| 8편 | 3개월 운영 후기와 기술 부채 정리 |
- 이전 글: (없음 — 시리즈 첫 번째 글)
- 다음 글: 2편 — Spring Boot + MyBatis + JWT로 백엔드 기반 잡기2탄