galaxis-po/docs/plans/2026-03-18-analysis-report.md
머니페니 2ad2f56d31 docs: add project config docs, analysis report, and e2e signal cancel test
Add CLAUDE.md and AGENTS.md for AI-assisted development guidance,
analysis report with screenshots, and Playwright-based e2e test for
signal cancellation flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 23:18:16 +09:00

16 KiB

Galaxis-Po 코드 품질 및 완성도 심층 분석 보고서

분석일: 2026-03-18 분석 범위: Backend (FastAPI), Frontend (Next.js), DB 모델, 설계 문서


목차

  1. 미구현/불완전 기능 분석
  2. 코드 품질 이슈
  3. 보안/안정성 이슈
  4. 성능 이슈
  5. Walk-forward 분석 구현 가능성 평가
  6. 종합 평가 및 권고사항

1. 미구현/불완전 기능 분석

1.1 Backend API 엔드포인트 전수 현황

9개 라우터, 44개 엔드포인트 + 헬스체크 1개

라우터 경로 접두사 엔드포인트 수 인증 필요
auth /api/auth 4 부분적
admin /api/admin 8 전체
portfolio /api/portfolios 16 전체
strategy /api/strategy 4 전체
market /api/market 3 전체
backtest /api/backtest 7 전체
snapshot /api/portfolios/{id} 5 전체
data_explorer /api/data 6 전체
signal /api/signal 4 전체

1.2 Frontend 페이지 현황

15개 페이지, 32개 API 호출

페이지 경로 주요 기능
로그인 /login SHA-256 해시 비밀번호 로그인
대시보드 / 총자산, 수익률, 자산배분 차트
포트폴리오 목록 /portfolio 포트폴리오 카드 그리드
포트폴리오 생성 /portfolio/new 이름, 유형 선택
포트폴리오 상세 /portfolio/[id] 보유종목, 거래내역, 분석 탭
리밸런싱 /portfolio/[id]/rebalance 전략 선택, 수동 가격 입력, 적용
포트폴리오 이력 /portfolio/[id]/history 스냅샷, 수익률 추이
전략 목록 /strategy 4개 전략 카드
KJB 전략 /strategy/kjb 김종봉 전략 실행
멀티팩터 전략 /strategy/multi-factor 가중치 설정, 실행
퀄리티 전략 /strategy/quality F-Score 기반
가치모멘텀 전략 /strategy/value-momentum 가치+모멘텀 가중치
전략 비교 /strategy/compare 3개 전략 병렬 비교
백테스트 /backtest 생성, 결과 조회
백테스트 상세 /backtest/[id] 수익곡선, 드로다운, 거래내역
관리자 데이터 /admin/data 6개 수집기 실행/상태
데이터 탐색기 /admin/data/explorer 종목/ETF/섹터/밸류에이션 조회

1.3 API-UI 매핑 갭 분석

API 있으나 UI 없는 항목

API 엔드포인트 상태 설명
PUT /api/portfolios/{id} UI 없음 포트폴리오 이름/유형 수정 기능
DELETE /api/portfolios/{id} UI 없음 포트폴리오 삭제 기능
PUT /api/portfolios/{id}/targets UI 없음 목표 비중 설정 (독립 UI 없음, 리밸런싱에서 간접 사용)
PUT /api/portfolios/{id}/holdings UI 없음 보유종목 직접 설정
POST /api/portfolios/{id}/transactions UI 없음 수동 거래 추가 (신호 실행 외)
GET /api/portfolios/{id}/rebalance UI 없음 자동 리밸런싱 계산 (수동 계산만 UI에 있음)
POST /api/portfolios/{id}/rebalance/simulate UI 없음 추가 투자 시뮬레이션
GET /api/market/stocks/{ticker} UI 없음 개별 종목 상세 정보
GET /api/market/stocks/{ticker}/prices UI 없음 개별 종목 가격 차트 (data_explorer와 중복)
GET /api/market/search UI 없음 종목 검색 (독립 UI 없음)
DELETE /api/backtest/{id} UI 없음 백테스트 삭제
POST /api/auth/register 비활성 코드에서 403 반환으로 비활성화됨
POST /api/admin/collect/backfill UI 없음 과거 데이터 백필 기능

UI 있으나 실제 데이터가 아닌 항목

UI 요소 위치 설명
포트폴리오 가치 차트 /portfolio/[id] 90일 시뮬레이션 사인파 데이터 사용 (실제 스냅샷 기반 아님)

1.4 설계 문서 vs 구현 대조

설계 문서 구현 상태 미구현 항목
Phase 1: Foundation 완료 -
Phase 2: Data Collection 완료 Financial collector 설계는 있으나 UI에서 직접 트리거 불가
Phase 3: Portfolio Management 대부분 완료 포트폴리오 수정/삭제 UI 없음, 수동 거래 입력 UI 없음
Phase 4: Quant Strategy 완료 -
Phase 5: Backtest Engine 완료 백테스트 삭제/비교 UI 없음
Phase 6: Finishing 부분 완료 종합 테스트 미흡, 프로덕션 배포 문서화 미완
KJB 전략 설계 완료 DailyBacktestEngine, TradingPortfolio 모두 구현
리밸런싱 설계 완료 추가 투자 시뮬레이션 UI 없음
DC 시나리오 갭 분석 문서만 존재 6개 시나리오 검증 미구현
프로덕션 배포 설계 문서만 존재 Nginx, SSL, 모니터링 등 미구현

2. 코드 품질 이슈

2.1 TODO/FIXME/HACK 검색 결과

결과: 0건 - Backend/Frontend 모두 TODO, FIXME, HACK, XXX, NotImplementedError 없음.

2.2 에러 핸들링 이슈

Frontend - console.error만 있고 사용자 피드백 없는 경우

파일 위치 설명
frontend/src/app/signals/page.tsx L161, L176, L185 fetchTodaySignals, fetchHistorySignals, fetchPortfolios 에러 시 console만
frontend/src/app/signals/page.tsx L246-254 포지션 사이징 API 에러 무시
frontend/src/app/admin/data/explorer/page.tsx L121-135 ETF 가격 조회 에러 시 빈 배열로 대체
frontend/src/app/backtest/page.tsx 중첩 fetch 내부 상세 조회 실패 시 UI 피드백 없음

Frontend - Error Boundary 부재

  • 전체 프론트엔드에 React Error Boundary가 없음
  • 컴포넌트 렌더링 에러 시 전체 페이지 크래시 가능

2.3 타입 안전성 이슈

위치 설명
frontend/src/app/portfolio/[id]/rebalance/page.tsx L313 as { data: Portfolio[] } 강제 캐스팅
frontend/src/app/admin/data/explorer/page.tsx 다수 데이터 아이템 as 타입 단언 다수 사용

3. 보안/안정성 이슈

3.1 심각도별 분류

CRITICAL - 하드코딩된 시크릿

파일 라인 내용
backend/app/core/config.py L14 database_url 기본값에 비밀번호 포함: postgresql://galaxy:devpassword@localhost:5432/galaxy_po
backend/app/core/config.py L17 jwt_secret 기본값: "dev-jwt-secret-change-in-production"

pydantic-settings로 환경변수 오버라이드 가능하나, 소스코드에 기본값이 남아 있음

HIGH - JWT 토큰 관리

이슈 설명
토큰 무효화 불가 POST /api/auth/logout이 서버 측 토큰 무효화 없이 클라이언트에 의존
localStorage 저장 frontend/src/lib/api.ts L18,25,32 - XSS 공격 시 토큰 탈취 가능

MEDIUM - 인증 패턴

파일 설명
backend/app/api/backtest.py L96,143,176,217,259 백테스트 조회 시 user_id 필터 없이 전체 조회 후 소유권 확인 - 비효율적이며 정보 노출 가능

3.2 SQL 인젝션

위험도: 없음 - 모든 DB 쿼리가 SQLAlchemy ORM 사용. raw SQL 쿼리 없음.

3.3 민감 정보 로깅

위험도: 없음 - 비밀번호, 토큰, API 키 로깅 없음 확인.

3.4 인증 없이 접근 가능한 엔드포인트

엔드포인트 인증 비고
GET /health 불필요 정상 (헬스체크)
POST /api/auth/login 불필요 정상 (로그인)
POST /api/auth/register 불필요 비활성화 (403 반환)
POST /api/auth/logout 불필요 클라이언트 측 처리

그 외 모든 엔드포인트는 CurrentUser 의존성으로 인증 필수


4. 성능 이슈

4.1 N+1 쿼리 패턴

파일 위치 심각도 설명
backend/app/api/backtest.py L71-82 HIGH list_backtests에서 모든 백테스트 순회하며 bt.result lazy 로딩 → N+1
frontend/src/app/portfolio/page.tsx L55-70 MEDIUM 포트폴리오 목록에서 각 포트폴리오별 detail API 개별 호출

4.2 인덱스 누락 (DB)

현재 인덱스: users(email), users(id), job_logs(id), signals(date, ticker), 각 테이블 PK만 존재

Tier 1 - 백테스트 성능 (긴급)

-- 가격 데이터 (백테스트에서 가장 빈번하게 조회)
CREATE INDEX idx_price_date ON prices(date);

-- 종목 유니버스 필터링
CREATE INDEX idx_stock_market ON stocks(market);
CREATE INDEX idx_stock_market_cap ON stocks(market_cap DESC);

-- 밸류에이션 스크리닝
CREATE INDEX idx_valuation_base_date ON valuations(base_date);

Tier 2 - 포트폴리오/신호 (중요)

-- 신호 조회
CREATE INDEX idx_signal_status_date ON signals(status, date);

-- 거래 내역
CREATE INDEX idx_transaction_portfolio_executed ON transactions(portfolio_id, executed_at);

-- 백테스트 목록
CREATE INDEX idx_backtest_user_created ON backtests(user_id, created_at);
CREATE INDEX idx_backtest_status ON backtests(status);

Tier 3 - 최적화

-- 재무 데이터
CREATE INDEX idx_financial_base_date ON financials(base_date);

-- ETF 필터링
CREATE INDEX idx_etf_asset_class ON etfs(asset_class);
CREATE INDEX idx_etf_price_date ON etf_prices(date);

4.3 대용량 데이터 처리 이슈

파일 위치 설명
backend/app/services/backtest/engine.py L352 Stock.query.all() - 전체 종목 메모리 로드
backend/app/services/backtest/daily_engine.py L147-187 다수의 .all() 호출로 대용량 데이터 메모리 로드
backend/app/services/price_service.py L92,114,180 전체 가격 데이터 제한 없이 로드
backend/app/api/data_explorer.py L138,180 종목 가격 이력 페이지네이션 없이 전체 반환
backend/app/api/snapshot.py L49,230 스냅샷 전체 조회 제한 없음
backend/app/api/portfolio.py L39 포트폴리오 전체 조회 제한 없음

4.4 비동기 작업 관리

이슈 설명
데몬 스레드 사용 데이터 수집기가 daemon thread로 실행 → 앱 종료 시 작업 유실 가능
작업 큐 미사용 Celery/RQ 등 없이 in-process thread 실행 → 재시작 시 상태 복구 불가

5. Walk-forward 분석 구현 가능성 평가

5.1 현재 백테스트 엔진 구조

BacktestWorker.submit_backtest()
  ├── strategy_type == "kjb"
  │   └── DailyBacktestEngine  (신호 기반 일일 매매)
  │       ├── TradingPortfolio (개별 포지션 관리)
  │       └── KJBSignalGenerator (매수/매도 조건 판단)
  └── strategy_type != "kjb"
      └── BacktestEngine  (정기 리밸런싱)
          ├── VirtualPortfolio (균등 가중 포트폴리오)
          └── MetricsCalculator (수익률, MDD, 샤프 등)

핵심 클래스:

  • BacktestEngine (engine.py) - 주기적 리밸런싱 시뮬레이션
  • DailyBacktestEngine (daily_engine.py) - 일일 신호 기반 매매
  • VirtualPortfolio - 단순 포트폴리오 (리밸런싱용)
  • TradingPortfolio - 포지션 기반 포트폴리오 (손절/익절 관리)
  • MetricsCalculator - 독립적 성과 지표 계산

5.2 Walk-forward 구현 가능성: 높음 (HIGHLY FEASIBLE)

유리한 구조적 요소

요소 설명
데이터 분할 용이 _get_trading_days()가 날짜 범위 필터링 지원 → 학습/검증 윈도우 분할 가능
전략 재사용성 전략 인스턴스화가 분리됨 → 동일 전략을 다른 기간에 실행 가능
메트릭스 독립성 MetricsCalculator가 값 배열만 받음 → 백테스트 인스턴스와 무관
글로벌 상태 없음 BacktestEngine 인스턴스가 독립적 → 여러 기간 동시 실행 가능
결과 분리 저장 metrics, equity curve, holdings, transactions 별도 테이블 → 학습/검증 비교 가능

구현 방안

1. WalkForwardEngine 클래스 추가
   - train_window, test_window, step_size 파라미터
   - 롤링 윈도우 생성기

2. 각 윈도우에서:
   - 학습 기간: 기존 BacktestEngine으로 전략 실행 → 최적 파라미터 도출
   - 검증 기간: 학습된 파라미터로 별도 BacktestEngine 실행

3. 전체 검증 기간 결과 합산 → 최종 성과 지표 계산

예상 작업량

작업 예상 규모 설명
WalkForwardEngine 클래스 윈도우 분할 + 순차 실행 로직
파라미터 최적화 모듈 중~대 전략별 파라미터 그리드 서치 또는 최적화
DB 모델 추가 WalkForwardResult 테이블 (윈도우별 결과 저장)
API 엔드포인트 생성/조회/결과 반환
Frontend UI 설정 폼 + 윈도우별 결과 시각화
총합 중~대 규모 약 5-8개 파일 신규/수정

주의사항

  • 백테스트 실행 시간이 윈도우 수만큼 배수로 증가 → 백그라운드 실행 필수
  • 파라미터 최적화 시 과적합(overfitting) 방지 로직 필요
  • 현재 daemon thread 방식으로는 장시간 실행에 부적합 → Celery 도입 검토

6. 종합 평가 및 권고사항

6.1 종합 스코어카드

항목 점수 평가
기능 완성도 8/10 핵심 기능 구현 완료, CRUD UI 일부 누락
코드 품질 8/10 TODO/FIXME 없음, 일관된 코드 스타일
보안 6/10 SQL 인젝션 안전, 하드코딩 시크릿/토큰 관리 취약
성능 5/10 인덱스 부재, N+1 쿼리, 무제한 데이터 로드
테스트 커버리지 미측정 unit/e2e 구조 존재, 커버리지 분석 필요
프로덕션 준비도 4/10 작업 큐 없음, 모니터링/로깅 미흡

6.2 우선순위별 권고사항

즉시 조치 (P0)

  1. 하드코딩 시크릿 제거 - config.py의 database_url, jwt_secret 기본값을 환경변수 필수로 변경
  2. DB 인덱스 추가 - Tier 1 인덱스 마이그레이션 생성 (백테스트 성능 직결)
  3. N+1 쿼리 수정 - backtest.py list_backtests에 joinedload(Backtest.result) 추가

단기 개선 (P1)

  1. 포트폴리오 CRUD UI 완성 - 수정/삭제/수동 거래 입력 화면 추가
  2. 에러 핸들링 통일 - Frontend Error Boundary 추가, console.error를 사용자 피드백으로 전환
  3. 페이지네이션 적용 - 가격 이력, 스냅샷, 거래 내역 등 무제한 로드 수정
  4. 백테스트 삭제 UI - 불필요한 백테스트 정리 기능

중기 개선 (P2)

  1. JWT httpOnly 쿠키 전환 - localStorage에서 secure cookie로 변경
  2. 작업 큐 도입 - Celery/RQ로 데이터 수집 및 백테스트 실행 안정화
  3. 포트폴리오 가치 차트 실데이터화 - 시뮬레이션 사인파 → 스냅샷 기반 실제 데이터
  4. React Error Boundary 추가

장기 개선 (P3)

  1. Walk-forward 분석 구현 - 위 평가 참고
  2. 백테스트 비교 기능 - 전략 간 성과 비교 UI
  3. DC 시나리오 검증 - 6개 시나리오 자동 검증 파이프라인
  4. 프로덕션 인프라 - Nginx, SSL, 모니터링, 로깅 체계

6.3 파일별 이슈 요약

파일 이슈 유형 심각도
backend/app/core/config.py 하드코딩 시크릿 CRITICAL
backend/app/api/backtest.py N+1 쿼리, 비효율적 인증 패턴 HIGH
backend/app/services/backtest/engine.py 전체 종목 메모리 로드 MEDIUM
backend/app/services/backtest/daily_engine.py 다수 unbounded .all() MEDIUM
backend/app/services/price_service.py 무제한 가격 데이터 로드 MEDIUM
backend/app/api/data_explorer.py 가격 이력 페이지네이션 없음 MEDIUM
frontend/src/lib/api.ts localStorage 토큰 저장 MEDIUM
frontend/src/app/signals/page.tsx 에러 핸들링 누락 (console만) LOW
frontend/src/app/portfolio/[id]/page.tsx 시뮬레이션 차트 데이터 LOW
DB migrations 성능 인덱스 대부분 누락 HIGH