차세대 주식 트레이딩 플랫폼
GOPS는 시장 탐색부터 종목 분석, 주문, 포트폴리오 관리와 거래 복기까지 이어지는 개인 맞춤형 AI 주식 트레이딩 플랫폼이다.
시장·기업·뉴스·차트 데이터를 Logic으로 구조화하고, LLM이 서로 다른 근거를 사용자의 맥락 안에서 연결한다. 규칙만으로 다루기 어려운 해석에는 LLM을 활용하되, 수치와 작도, 조건은 재현 가능한 Logic으로 계산했다. 근거가 결과만큼 중요한 주식 분석의 특성에 맞춰, 해석과 함께 그 바탕이 된 정보와 분석 과정도 투명하게 보여준다.
KRAFTON Jungle의 지원으로 4명의 팀원과 함께 약 한 달간 진행한 PBL 프로젝트다. stargops.com을 통해 2주간 운영했으며, 현재는 시장 데이터 구독료와 AWS 운영비로 배포를 중단했다.
차트 분석·렌더링 엔진은 단독으로 설계·구현했고, 실시간 데이터 처리·저장 구조는 팀과 함께 설계했다.
투자자의 언어를 Logic으로


투자 전략은 정확한 수치로 설명하기 어렵다. 그래서 투자자들은 “거래대금이 실린 상승 종목을 찾고 싶다”거나 “안정성보다 성장 가능성을 더 중요하게 보고 싶다”는 식으로 관심과 의도를 표현한다.
GOPS는 이러한 자연어를 거래대금, 추세, 변동성, 기업가치 등 추천 수식의 가중치로 번역한다. 사용자의 개입 역시 가능하며, GOPS의 Agent와 사용자가 같은 인터페이스를 바라보도록 설계했다.
추천 이후에도 사용자는 시장과 종목에 대해 자유롭게 질문할 수 있다. 차트·뉴스·재무 Agent가 각자의 관점에서 근거를 수집하고, 분석의 중심에 있는 GraphDB가 기업과 산업, 시장 사건의 관계를 연결한다. 오른쪽 이미지는 투자자가 Agent에게 궁금한 정보를 참조시키고 질문하는 과정이다.
가격을 읽는 기하학



OHLCV Geometry 분석과 작도 엔진
점·선·면의 관계로 공간의 질서를 읽듯, 주식 차트의 OHLCV 데이터를 (시간, 가격, 거래량)의 점들로 구성된 공간으로 보고 그 관계를 살폈다. 동일한 데이터에서 동일한 구조를 찾고, 지지·저항·추세·패턴의 선택과 탈락 과정을 재현할 수 있는 결정론적 분석 엔진을 설계했다.
개발 과정에서는 정규화된 OHLCV 처리와 후보 판정 규칙을 관리했고, 테스트 루프를 만들어 Codex로 후보 생성 로직을 반복 구현했다.
아래 설명에서 대표 작도는 작도 예산 안에서 최종 선택된 구조이고, 유효 후보는 런타임 조건을 통과했으나 최종 선택에서 제외된 구조이다. 이후 차트 렌더링에서 대표 작도는 지지·저항·추세·패턴으로, 유효 후보는 작도 근거로 시각화된다. 다이어그램의 실선은 런타임 처리, 점선은 개발 단계의 테스트 루프를 나타낸다.
1. 전체 분석·작도 흐름
| 입력 | 완료된 정규화 OHLCV 봉 |
| 출력 | PostgreSQL에 저장된 대표 작도, 유효 후보, 평가 기록 |
| 처리 | ATR과 거래량으로 공유 Pivot을 추출하고 수평·대각·패턴 후보를 평가한 뒤 전체 후보에서 작도 데이터를 조립 |
정규화된 OHLCV에서 ATR(Average True Range, 평균진폭지수)로 Pivot(국소 고점·저점)을 찾고, 그 점 데이터를 모든 분석이 공유하도록 설계했다. 수평 분석은 반복적으로 반응한 가격대를 찾고, 대각 분석은 시간에 따라 유지된 방향과 채널을 찾는다. 패턴 조합은 두 결과의 관계를 하나의 형상으로 해석한다. 각 분기는 후보 생성과 유형별 런타임 평가를 완료하고 작도 후보를 출력한다.
작도 데이터 조립에서 세 분기의 작도 후보를 모아 중복과 신뢰도를 관리하고, 대표 작도와 유효 후보로 구분한다. 선택 결과와 평가 기록은 PostgreSQL에 저장되며, 이후 차트 분석 에이전트의 해석 자료가 되거나 렌더링 엔진으로 화면에 투영된다.
이 전체 흐름을 테스트 루프로 관리했고, 각 분기의 테스트 루프는 전체 테스트 루프의 산하에 뒀다. Codex 서브 에이전트를 활용해 각 분기를 구현했고, 전체 테스트 코드의 결과와 판단 사항을 문서화하여 각 분기의 에이전트에게 전달했다. 각 분기의 구현은 독립적인 테스트 루프를 가지며, 동시에 전체 테스트의 결과를 참고한다.
런타임 평가
- 좌표 일관성 확보: 세 분석의 공유 Pivot·ATR 좌표 사용 여부 확인
- 후보 품질 통제: 유형별 필수 판정 조건과 최대 선택 개수 충족 여부 확인
- 선택 재현성 확보: 점수·최근성·좌표에 따른 후보 순서 확인
- 저장 계약 보장: 대표 작도·유효 후보·평가 기록의 식별자 연결 확인
테스트 루프
- 결정성 확보: 동일 차트 3회 결과가 일치하도록 정렬 및 동점 처리 규칙 조정
- 작도 완결성 확보: 5개 기준 종목에서 수평·대각·패턴 작도가 모두 생성되는 것을 완료 조건으로 두고 ATR 범위·접촉·반응·탐색 구간 반복 조정
- 회귀 방지: 전체 판단 사항을 분기별 테스트의 기대 결과로 고정
5개 기준 종목: CSCO·CRH·CF·TSLA·SNDK (개발 당시 다수의 투자자가 동일한 보조지표를 작도한 종목)
2. 수평 분석: 지지·저항 후보 작도
| 입력 | 공유 Pivot, ATR, 가격대별 거래량 |
| 출력 | 수평 작도 후보와 접촉·반응 기록 |
| 처리 | 근접 Pivot을 ATR 가격 영역으로 묶고 반복 반응과 현재 가격을 기준으로 지지·저항 역할을 분류 |
시장이 반복적으로 반응한 가격대를 찾아 수평선을 작도한다. ATR 기반 가격 영역으로 종목과 주기마다 다른 변동 규모를 하나의 기준으로 비교할 수 있도록 했다. 시간적으로 가까운 연속 봉은 하나의 접촉 사건으로 묶고, 접촉 이후 가격이 영역에서 벗어난 정도를 반응으로 계산했다. 수평선은 Pivot의 반응으로 가격 영역을 먼저 찾고, 가중 평균으로 작도된다. 거래가 집중되는 가격 영역을 평가 요소로 사용하기 위해 가격대별 거래량 집중도를 확인했다.
작도선 후보는 현재 가격과의 관계에 따라 지지 또는 저항 역할을 갖는다. 역할별 후보가 필수 런타임 조건을 통과하면 평가 기록과 함께 수평 작도 후보로 출력된다.
런타임 평가 (작도선 신뢰도)
- 반복 가격대 판별: 시간적으로 분리된 최소 3회 접촉과 2회 반응 확인
- 현재 역할 판별: 현재 가격의 위치와 돌파·복귀·재접촉에 따른 지지·저항 상태 확인
- 후보 현재성 확보: 마지막 접촉 시점과 현재 가격까지의 거리 확인
- 가격대 신뢰도 보강: 가격대별 거래량의 집중도 확인
테스트 루프
- 접촉 과대계상 억제: 연속 봉의 접촉 병합 간격과 최소 접촉·반응 횟수 조정
- 변동성 적응: ATR 기반 군집 폭과 접촉 이후 최소 반응 거리 조정
- 현재성 보정: 마지막 접촉의 최근성과 현재 가격 거리 가중치 조정
- 안정화: 돌파 무효화·복귀·재접촉 판정 임계값 조정
3. 대각 분석: 추세선·채널 후보 작도
| 입력 | 공유 Pivot, ATR, 상대 거래량 |
| 출력 | 대각 작도 후보와 접촉·잔차 기록 |
| 처리 | Pivot 조합으로 직선 후보를 만들고 다른 Pivot의 접촉·잔차와 반대편 경계의 평행성을 계산해 추세와 채널로 분류 |
시장에서 시간에 따라 반복적으로 확인된 방향을 찾아 대각선을 작도한다. Pivot 조합에서 y = mx + b 형태의 직선 후보를 만들고, 다른 Pivot과 직선 사이의 가격 오차를 | Pivot 가격 - 직선 위 가격 | / ATR로 정규화해 적합도를 판단한다. 접촉 반응과 경계 돌파의 신뢰도를 보강하고자 상대 거래량을 평가 요소로 사용했다.
반대편 Pivot에서 유사한 기울기가 형성되면 두 경계의 평행성과 폭을 계산해 채널 후보로 확장했다. 필수 런타임 조건을 통과하면 평가 기록과 함께 대각 작도 후보로 출력된다.
런타임 평가 (작도선 신뢰도)
- 2점 과적합 억제: 앵커 외 접촉을 포함한 최소 3회 접촉과 2회 반응 확인
- 선형 적합도 확보: Pivot과 직선 사이의 ATR 정규화 잔차 확인
- 채널 안정성 판별: 양 경계의 기울기 차이·폭·가격 포함률 확인
- 현재 유효성 판별: 최근 완료 봉의 경계 이탈과 반응 시점의 상대 거래량 확인
테스트 루프
- 직선 과적합 억제: 앵커 외 최소 접촉·반응 횟수 조정
- 종목 간 오차 통일: 가격 잔차를 ATR 단위로 변환하고 허용 범위 조정
- 채널 오인식 억제: 기울기 차이·채널 폭과 넓은 봉의 양쪽 접촉 중복 조건 조정
- 안정화: 최근 이탈 기간과 구조 무효화 우선순위 조정
4. 패턴 조합: 패턴 여부 판단 및 후보 작도
| 입력 | 공유 Pivot, 수평·대각 작도 후보, OHLCV, ATR, 상대 거래량 |
| 출력 | 패턴 후보와 경계·돌파 확인 기록 |
| 처리 | 수평·대각 작도 후보를 상·하단 경계로 조합하고 여러 최근 구간에서 기울기 관계와 선행 움직임을 해석 |
수평·대각 경계 사이의 관계를 하나의 형상으로 해석한다. 짧게 형성되는 패턴과 장기간 유지되는 패턴을 함께 탐지하고자 20·40·60·90·120봉을 탐색 범위로 설정하고, 구간별 후보의 접촉 횟수·형상 적합도·중복 정도를 비교해 유효한 패턴을 선택했다. 경계 관계는 삼각형·쐐기·깃발형·페넌트·직사각형·채널 이탈로 분류했다.
필수 런타임 조건을 통과하면 평가 기록과 함께 패턴 작도 후보로 출력된다. 각 후보는 상단선, 하단선을 하나의 작도선 묶음으로 구성하며 돌파 확인 여부를 상태로 포함한다. 패턴이 없는 차트에서는 후보 없음을 출력하도록 했다.
런타임 평가 (작도선 신뢰도)
- 경계 구조 유효성 확보: 상·하단의 반복 접촉·ATR 잔차·가격 포함률 확인
- 형상 분류 일관성 확보: 경계 수렴률·평행성·폭 안정성 확인
- 돌파 신뢰도 확보: 0.25 ATR 이상 경계 침투와 다음 종가 유지 또는 1.5배 상대 거래량 확인
테스트 루프
- 최근 형상 우선 탐색: 탐색 구간을 20·40·60·90·120봉으로 분리하고 최근성 가중치 조정
- 형상 왜곡 억제: 분석 Pivot 범위와 이상 Pivot 제외 기준 조정
- 유사 형상 분리: 수렴률·잔차·포함률과 쐐기·삼각형의 판정 임계값 조정
- 재현성 확보: 점수·최근성·좌표 순으로 정렬 및 동점 처리 규칙 조정
5. 결과와 한계
- 정규화된 OHLCV와 공유 Pivot을 기준으로 모든 작도의 시간·가격 좌표를 통일했다.
- 접촉·반응·잔차·현재성 조건을 평가 기록으로 남겨 후보의 선택과 탈락 과정을 재현할 수 있게 했다.
- 동일 입력의 반복 실행과 회귀 사례를 통해 작도 좌표·후보 순서·출력 형식의 결정성을 확인했다.
- 5개 기준 종목을 중심으로 누락과 과잉 작도를 조정했다. 엔진의 기하학적 정합성과 재현성은 검증했지만, 사용자 관점의 효용성과 투자 성과에 대한 외부 타당성은 검증하지 않았다.
- 과거 시점별 Walk-forward 평가를 수행하지 않아 작도 이후의 가격 반응률, 돌파 지속률, 무효화율을 정량적으로 검증하지 못했다. 따라서 런타임 신뢰도는 기하학적 구조의 적합도를 의미하며 미래 가격의 예측 확률을 의미하지 않는다.
화면으로 답하는 Agent



GOPS는 Agent의 출력 형식에 인터페이스를 포함한다. 사용자의 질문과 현재 작업을 해석한 Layout Agent가 필요한 패널을 선택하고, 위치와 크기, 우선순위를 조정한다.
자산을 점검할 때는 수익률과 보유 종목을 중심으로, 시장에 대응할 때는 차트와 알림을 중심으로 화면을 구성한다. 거래 이후에는 당시의 가격 움직임과 매매 근거, 결과를 함께 보여주는 복기 화면으로 전환한다.
세 이미지는 같은 포트폴리오 데이터를 자산 현황, 실시간 대응, 거래 복기라는 서로 다른 관점으로 구성한 결과다. 사용자의 질문에 따라 Agent의 답변은 문장, 차트, 데이터 패널과 인터랙션으로 표현된다.
동일 분석 요청의 중복 제어


주식 시장에서는 개장 직후나 급격한 가격 변동이 발생했을 때 특정 종목으로 관심이 집중된다. 이때 많은 사용자가 같은 종목과 시간 구간의 차트를 거의 동시에 요청한다. 요청은 서로 다르지만, 서버가 조회하는 캔들과 계산하는 기술지표·패턴은 동일하다.
각 요청을 독립적으로 처리하면 같은 데이터를 반복해서 읽고 같은 분석을 여러 번 수행하게 된다. 요청이 몰릴수록 데이터베이스와 CPU 부하는 증가하고, 시장의 움직임을 가장 빠르게 확인해야 하는 순간에 응답이 느려진다.
종목, 시간 단위, 조회 범위와 분석 조건을 해시 키로 묶어 동일한 작업을 식별했다. 먼저 완성된 결과가 있는지 캐시를 확인하고, 계산이 필요하면 Redis Lock을 통해 하나의 서버만 작업 권한을 얻는다. 나머지 요청은 같은 계산에 합류해 완료된 결과를 공유한다.
동일한 요청 100건이 동시에 들어와도 실제 분석은 한 번만 수행됐다. 요청 수만큼 서버를 확장하는 대신 중복 작업을 제거해 CPU 사용량과 p95 응답 시간을 줄였다.
Kafka 기반 시장 데이터 처리 구조


실시간 시세 하나는 캔들 생성과 저장, 보조지표 계산, 차트 분석과 알림 등 여러 기능에 사용된다. GOPS는 외부 시세를 공통 형식의 이벤트로 변환해 Kafka에 기록하고, 각 기능이 필요한 이벤트를 독립적으로 가져가도록 구성했다.
실시간 데이터의 처리·저장 구조는 팀과 함께 설계했다. Kafka 기반 Event-Driven Architecture를 제안해 최종 시스템에 적용했고, 데이터 처리 서비스는 다른 팀원이 구현했다. 적용 과정에서 발생한 문제는 함께 해결했다.
Kafka는 들어온 이벤트를 순서대로 보관하는 분산 Queue이자 Event Log다. 데이터를 만드는 쪽과 사용하는 쪽을 분리하고, 처리되지 않은 이벤트를 Queue에 보관해 순간적인 데이터 증가를 흡수한다. 일부 기능의 처리가 늦어져도 시세 수집과 다른 기능은 계속 작동한다.
개발 과정에서 보조지표 계산과 차트 분석 Logic이 추가됐을 때도 기존 시세 수집 흐름을 변경할 필요가 없었다. 같은 이벤트를 구독하는 Consumer를 추가하는 방식으로 기능을 확장했고, 각 Consumer는 처리량에 따라 별도로 확장할 수 있었다. 중단된 Consumer는 마지막 Offset 이후부터 작업을 재개하므로, 기능 추가와 장애 복구가 하나의 데이터 흐름 안에서 이루어진다.
전체 서비스는 Kubernetes 환경에 배포·운영했으며, Kafka Consumer와 저장 계층도 이 환경에서 관리했다.