- 기간
- 5주 프로젝트
- 팀
- 5인 팀 프로젝트
- 담당
- React UI · TypeScript 차트 엔진
- 환경
- 약 9천만 건 규모의 주식 틱 이벤트
제가 직접 구현한 핵심
차트 라이브러리를 붙이는 대신, 틱 데이터 엔진부터 만들었습니다.
기존 차트 API는 프로젝트에 필요한 틱 단위 데이터와 분석선을 같은 화면에 오버레이하는 방식을 지원하지 않았습니다. 그래서 데이터 조회·병합, 시간축과 가격축 계산, 캔들·거래량·분석선 렌더링까지 TypeScript로 직접 구현했습니다.
전체 데이터는 약 9천만 건 규모입니다. 전부 브라우저에 적재하지 않고 보이는 구간만 가져온 뒤 실시간 이벤트를 이어 붙였고, Canvas와 WebSocket은 이 구조를 동작시키기 위한 수단으로 사용했습니다.
서비스 흐름과 담당 범위
탐색부터 복기까지, 하나의 작업 공간으로
사용자가 종목을 찾고 판단한 뒤 거래를 다시 확인하는 흐름을 패널형 작업 공간으로 연결했습니다. 저는 이 흐름에서 React 조회 패널과 TypeScript 주식차트 엔진을 맡았습니다.
- 01탐색
시장과 종목 후보를 찾고
- 02분석
차트와 선정 근거를 확인하고
- 03주문
호가와 주문으로 연결하고
- 04복기
진입 전후 판단을 비교합니다.

- 43
- Panel Types
- 25
- Layout Commands
- 2
- Canvas Layers
- 48
- Test / Spec Files
React 패널 아키텍처
43종의 패널이 늘어나도 이동·크기 조절·닫기·오류 처리를 반복 구현하지 않도록 공통 프레임과 기능 콘텐츠의 책임을 분리했습니다. 패널 종류와 크기 제약은 TypeScript Registry에서 관리하고, Agent 명령은 계약을 통과한 경우에만 화면 상태로 변환했습니다.
REACT COMPONENT TREE
공통 상호작용과 기능 로직의 분리
SearchPanel · ChartPanel · OrderPanel은 도메인 로직만 유지합니다.
TYPESCRIPT CONTRACTS
등록 가능한 패널과 명령의 범위
kind · component · min/default/maxSpan · layoutWeight · insertablecreate · close · move · resize · replace · focus · setPriority25개 명령 타입을 Runtime Validation으로 확인합니다.
AGENT COMMAND PIPELINE
- Agent Output
- Schema Parse
- Normalize
- Registry Resolve
- Workspace State
Agent가 React 컴포넌트를 직접 생성하지 않고, 검증된 명령만 상태 변경으로 변환하도록 경계를 두었습니다.
- Unknown panel kind
- Registry에 없는 컴포넌트 생성 거부
- Invalid span / position
- 등록된 최소·최대 범위로 보정
- Unsupported command
- 상태를 바꾸지 않고 기록 후 무시
하나의 구조, 세 작업 화면
같은 패널 구조를 사용하되, 사용자의 목적에 따라 필요한 정보와 우선순위가 달라지도록 작업 화면을 구성했습니다. 자산 현황에서는 손익을, 시장 탐색에서는 판단 재료를, 거래 복기에서는 진입 전후의 근거를 먼저 보여줍니다.



실시간 주식차트
이 프로젝트에서 가장 많이 파고든 문제는 차트였습니다. 기존 API로는 필요한 틱 데이터를 분석선과 함께 오버레이할 수 없어서 데이터 조회부터 좌표 계산, 병합, 렌더링까지 직접 구현했습니다. 약 9천만 건 규모의 전체 데이터를 한 번에 브라우저로 옮기는 대신 현재 화면에 필요한 구간과 이후 변화만 연결했습니다.

초기·과거·누락 구간 중 화면에 필요한 범위만 조회
종목과 시각을 기준으로 과거 데이터와 최신 이벤트를 병합
초기 조회 이후의 변동만 기존 차트 상태에 반영
Reconnect마지막 수신 시각 이후의 누락 구간만 REST로 보완한 뒤 WebSocket 이벤트를 다시 이어 붙입니다.
데이터가 바뀔 때만
캔들 · 거래량 · 축 · 분석선
포인터가 움직일 때
크로스헤어 · 툴팁 · 선택 상태 · requestAnimationFrame
분석 결과를 설명하는 화면
지지·저항선을 그리는 데서 끝내지 않고, 어떤 후보가 어떤 기준을 통과했는지 같은 화면에서 확인할 수 있게 했습니다. 알고리즘의 결과를 사용자가 다시 판단할 수 있는 정보로 바꾸는 부분을 프론트엔드의 책임으로 두었습니다.
- 01Candle Data
가격 · 거래량
- 02Pivot
반전 지점 추출
- 03Candidate
군집 · 선형회귀
- 04Validation
접촉 · 반응 · 오차 · 돌파

WHY THIS LINE
결과와 선정 이유를 함께 표시
- Contact count
- Price reaction
- Allowed error
- Breakout status
후보 생성과 검증을 분리해 같은 입력과 조건에서는 같은 결과를 재현하고, 통과한 선만 근거와 함께 표시했습니다.
검증으로 확인한 경계
구현 수치만 나열하지 않고, 오류가 발생할 수 있는 지점마다 경계를 두고 명령·재연결·렌더링·알고리즘 결과를 검증했습니다.
| 위험 | 경계와 선택 | 검증 | 결과 |
|---|---|---|---|
| 잘못된 Agent 패널 명령 | Runtime Validation + Registry-only resolve | 미등록 kind, 범위 밖 span, 미지원 명령 | 검증된 React 컴포넌트만 화면 상태에 반영 |
| 과거·실시간 시계열의 중복과 누락 | REST Missing Range + WebSocket Merge | 종목·시각 병합, 재연결·backfill 시나리오 | 과거와 최신 이벤트를 하나의 차트 상태로 유지 |
| 포인터 이동마다 전체 차트 갱신 | Base / Overlay Canvas 분리 | 포인터 이벤트에서 Base draw 호출 여부 | Base 재렌더링 0회, Overlay만 rAF로 갱신 |
| 분석 후보의 불투명한 선정 기준 | 후보 생성 / 검증 단계 분리 | 동일 입력의 결정성과 평가 점수 | 선택된 선과 평가 근거를 같은 화면에 표시 |
상태에 들어오기 전 검증
Panel Registry와 명령 Schema로 허용 범위를 고정했습니다.
그리기 경계 확인
Base와 Overlay의 draw 호출을 나눠 포인터 갱신을 확인했습니다.
48개 Test / Spec 파일
계약, 재연결, 결정성, 렌더링 경계의 실패 조건을 확인했습니다.
다음 검증Core Web Vitals와 고빈도 렌더링 처리량은 배포 환경에서 별도로 측정해야 할 범위로 남겼습니다.
백엔드와 협업한 경계
프론트엔드와 백엔드의 책임을 섞지 않고, 과거 조회 범위와 실시간 이벤트 형식, 재연결 시 복구 기준을 함께 맞췄습니다. 이를 통해 화면 요구만 전달하는 것이 아니라 각 영역의 구조를 이해하며 협업했습니다.
제공 범위
과거 구간 REST 응답 · 최신 WebSocket 이벤트 · 재연결 기준
연결 범위
Missing Range 조회 · 종목/시각 병합 · 오류와 연결 상태
사용자에게 보이는 범위
조회 범위 · 실시간 변화 · 분석 결과와 선정 근거