포스트

가격이 아니라 이벤트를 팔자 — monticker 설계 철학

프로젝트를 시작한 동기

주식 앱을 처음 열었을 때 보이는 화면은 대부분 동일하다.

1
삼성전자  73,200  +1.4%  [캔들 차트]  [뉴스 목록]

숫자가 움직이는 건 알겠는데, 움직이는지 한눈에 들어오지 않는다. 뉴스 탭을 눌러야 하고, 거래량 탭을 따로 눌러야 하고, 공시 탭도 따로 있다. 정보가 파편화되어 있다.

실제로 트레이더들이 “이 차트 어떻게 봐야 해?”라는 질문에 시간 축 위에서 사건을 짚어가며 설명한다는 사실에서 monticker의 핵심 아이디어가 나왔다.

가격 차트 위에 이벤트를 직접 올리면 어떨까?


이벤트 중심(Event-Centric) UI란

일반적인 주식 앱:

1
2
3
4
10:00  |   70,000 ─────────────────────────
10:05  |   70,200
10:10  |   72,500 ← 왜 올랐지?
10:15  |   72,300

monticker:

1
2
3
4
10:10  ▲ PRICE_SPIKE  +3.2%
          ├── 거래량: 평균의 4.8×
          ├── 뉴스: "HBM 공급 확대 기대감"
          └── 공시: 없음

가격 변동의 원인을 타임라인에 직접 표시한다. 사용자가 차트와 뉴스를 오가며 수동으로 연결할 필요가 없다.

이 아이디어를 기술로 구현하면 다음과 같은 파이프라인이 된다.

1
2
3
4
5
6
7
External data sources
  → workers (price + news + disclosure collector)
  → Redis (latest price) + TimescaleDB (candles)
  → Event Detector (EMA 기반 이상 탐지)
  → stock_events (이벤트 테이블)
  → REST / WebSocket API
  → 차트 타임라인 오버레이 (web / mobile)

“이벤트”를 어떻게 정의했는가

monticker에서 이벤트는 5가지 유형으로 분류된다.

유형예시탐지 방법
PRICE_SPIKE5분 내 3% 이상 급등EMA 기반 변화율
VOLUME_SURGE평균 거래량의 3× 이상EMA 기반 비율
NEWS_POSITIVE긍정 뉴스 발행네이버 뉴스 + 감성 분석
DISCLOSURE공급 계약, 실적 발표DART API
PATTERN_DETECTED이중 바닥, 헤드앤숄더ZigZag 패턴 매칭

이 이벤트들이 하나의 stock_events 테이블에 모이고, 타임라인 API는 주어진 기간의 이벤트 목록을 차트 라이브러리가 소비할 수 있는 형식으로 반환한다.


제품이 확장된 방향

처음에는 순수하게 “왜 가격이 움직였는지 보여주는 앱”을 목표로 했다. 그런데 개발 과정에서 자연스럽게 이어진 질문들이 있었다.

“이 패턴이 반복되는지 확인하고 싶다” → Quant Lab (전략 백테스트)

“주문을 넣으면 어떻게 체결되는지 배우고 싶다” → 모의투자 + CLOB 체결 엔진

“내가 충동적으로 주문을 많이 넣는 것 같다” → Investment Wallet + 감정 태그

“내 전략이 어떤 시장에서 약한지 알고 싶다” → Quant Analytics (국면 감지 + 포트폴리오 최적화)

각 확장이 “가격이 왜 움직이는가”라는 원래 질문과 연결되어 있다는 점이 중요하다. 그냥 기능을 추가한 게 아니라, 투자자가 시장을 이해하는 사고 과정을 따라서 제품이 깊어진 것이다.


이 프로젝트에서 다루는 기술 스택

이후 시리즈에서 상세히 다룰 내용의 전체 그림이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌─── 수집 ──────────────────────────────┐
│  Go Market Gateway  →  Kafka          │
│  (goroutine-per-stock)   market.ticks │
└────────────────────────────────────────┘
           ↓
┌─── 처리 ──────────────────────────────┐
│  Kotlin Worker (Spring Boot)          │
│  ├── CandleAggregator  → TimescaleDB  │
│  ├── EventDetector     → stock_events │
│  └── RedisTickWriter   → Redis        │
└────────────────────────────────────────┘
           ↓
┌─── 서빙 ──────────────────────────────┐
│  Spring Boot API  →  REST / WS        │
│  Netty Broadcast  →  WebSocket 클라이언트 │
└────────────────────────────────────────┘
           ↓
┌─── 클라이언트 ─────────────────────────┐
│  Next.js 15 (App Router)              │
│  Expo React Native (mobile)           │
└────────────────────────────────────────┘
레이어기술이유
수집Gogoroutine의 가벼운 동시성
메시지 버스Kafka수집-처리 분리, 순서 보장
시계열 저장TimescaleDBPostgreSQL 호환 + Hypertable
캐시Redis최신 시세 서빙, 알람 쿨다운
API 서버Kotlin/Spring Boot도메인 모델링, 생태계
브로드캐스트Netty스레드 효율적인 WebSocket
프론트엔드Next.js 15SSR + App Router

이 시리즈를 읽는 방법

monticker 시리즈는 총 6개 주제로 구성된다.

시리즈주제편수
1. 아키텍처 설계제품 철학·기술 선택3
2. 실시간 파이프라인Go·Kafka·Netty4
3. 체결 엔진CLOB·리스크 게이트2
4. 이벤트 소싱원장·감정 태그2
5. Quant Lab룰 엔진·백테스트3
6. Quant Analytics최적화·패턴·국면5
보너스테스트·관측가능성3

다음 편에서는 마이크로서비스가 아닌 모듈식 모놀리스를 선택한 이유를 다룬다.

  1. 1 가격이 아니라 이벤트를 팔자 — monticker 설계 철학
  2. 2 모듈식 모놀리스를 선택한 이유 — MSA의 유혹을 거부하기
  3. 3 TimescaleDB를 시계열 DB로 고른 이유 — Hypertable과 연속 집계
  4. 4 Go goroutine으로 202개 종목 동시 수집하기 — Market Gateway 설계
  5. 5 Kafka로 시세 파이프라인 분리하기 — 토픽 설계와 at-least-once
  6. 6 Netty로 수만 연결에 시세 브로드캐스트하기 — NioEventLoopGroup 리액터 패턴
  7. 7 EMA 기반 이상 탐지 — 가격 급등과 거래량 서지 실시간 감지
  8. 8 TreeMap으로 CLOB 호가창 구현하기 — 가격/시간 우선 매칭과 슬리피지
  9. 9 주문 전 동기 리스크 게이트 설계 — VaR, 집중도, 일일손실 5가지 규칙
  10. 10 잔고를 저장하지 말고 재구성하라 — 이벤트 소싱 원장 설계
  11. 11 감정 태그 × 수익률 — 투자 습관을 데이터로 기록하기
  12. 12 룰 엔진: RSI·MACD 조건식을 JSON DSL로 — Quant Lab 설계
  13. 13 백테스트 엔진: look-ahead 없는 시뮬레이션 — Sharpe·MDD·PF 계산
  14. 14 전략 지문(SHA-256)으로 룰셋 보호하기 — 서버 사이드 실행과 역공학 방어
  15. 15 Markowitz 최적화를 솔버 없이 구현하기 — 프로젝션 경사하강법
  16. 16 Kelly Criterion: 수학적 파산 방지 베팅 비율 — Half Kelly와 백테스트 연동
  17. 17 ZigZag + 패턴 템플릿 매칭으로 차트 패턴 감지 — 헤드앤숄더·이중바닥
  18. 18 ADX로 시장 국면 분류하기 — BULL·BEAR·SIDEWAYS·HIGH_VOL
  19. 19 손익통산으로 세금 줄이기 — Tax-Loss Harvesting 시뮬레이션
  20. 20 MockK로 JdbcTemplate 목킹하기 — 311개 테스트 작성 경험
  21. 21 OpenTelemetry + Jaeger로 분산 추적 — 시세 파이프라인 지연 측정
  22. 22 Circuit Breaker로 외부 API 장애 격리 — Resilience4j + KIS·Yahoo 폴백 체인
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

댓글

아직 댓글이 없습니다