Add galaxy-po design document

Comprehensive design for integrated quant portfolio management app
combining make-quant-py and pension management features.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
zephyrdark 2026-02-02 22:35:58 +09:00
commit 0b89449472

View File

@ -0,0 +1,587 @@
# Galaxy-PO 설계 문서
## 1. 개요
**프로젝트명:** galaxy-po
**목적:** 개인 투자 관리 + 퀀트 연구/백테스트 통합 웹 애플리케이션
**통합 대상:**
- make-quant-py (콴트 매니저): 멀티 팩터, 슈퍼 퀄리티, 슈퍼 밸류 모멘텀 전략
- 퇴직연금 관리 시스템: ETF 포트폴리오, 리밸런싱 계산, 수익률 추적
---
## 2. 기술 스택
| 영역 | 기술 |
|------|------|
| Frontend | Next.js 15, React 19, TypeScript, Tailwind CSS, Node.js 24 |
| Backend | FastAPI, SQLAlchemy, Alembic, APScheduler, Python 3.14 |
| Database | PostgreSQL 15 |
| Infrastructure | Docker, Docker Compose |
| Data Sources | KRX, pykrx, DART OpenAPI, 한국투자증권 OpenAPI |
---
## 3. 프로젝트 구조
```
galaxy-po/
├── backend/ # FastAPI 백엔드
│ ├── app/
│ │ ├── api/ # API 라우터
│ │ │ ├── auth.py # 인증
│ │ │ ├── portfolio.py # 포트폴리오 관리
│ │ │ ├── rebalance.py # 리밸런싱 계산
│ │ │ ├── strategy.py # 퀀트 전략
│ │ │ ├── backtest.py # 백테스트
│ │ │ └── market.py # 시세 조회
│ │ ├── core/ # 핵심 설정
│ │ ├── models/ # SQLAlchemy 모델
│ │ ├── schemas/ # Pydantic 스키마
│ │ ├── services/ # 비즈니스 로직
│ │ │ ├── data_collector.py
│ │ │ ├── strategy_engine.py
│ │ │ └── backtest_engine.py
│ │ └── main.py
│ ├── jobs/ # 배치 작업
│ │ ├── scheduler.py
│ │ ├── collectors/
│ │ │ ├── base.py
│ │ │ ├── stock_collector.py
│ │ │ ├── sector_collector.py
│ │ │ ├── price_collector.py
│ │ │ ├── valuation_collector.py
│ │ │ ├── financial_collector.py
│ │ │ └── etf_collector.py
│ │ └── tasks.py
│ ├── requirements.txt
│ └── Dockerfile
├── frontend/ # Next.js 프론트엔드
│ ├── src/
│ │ ├── app/ # App Router (페이지)
│ │ ├── components/ # React 컴포넌트
│ │ └── lib/ # 유틸리티, API 클라이언트
│ ├── package.json
│ └── Dockerfile
├── docker-compose.yml
└── docs/
└── plans/
```
---
## 4. 데이터베이스 모델
### 4.1 퀀트 데이터 (배치 수집)
#### stocks (종목 마스터)
| 컬럼 | 타입 | 설명 |
|------|------|------|
| ticker | VARCHAR (PK) | 종목코드 |
| name | VARCHAR | 종목명 |
| market | VARCHAR | 시장구분 (KOSPI/KOSDAQ) |
| close_price | DECIMAL | 종가 |
| market_cap | BIGINT | 시가총액 |
| eps | DECIMAL | EPS |
| forward_eps | DECIMAL | 선행EPS |
| bps | DECIMAL | BPS |
| dividend_per_share | DECIMAL | 주당배당금 |
| stock_type | VARCHAR | 종목구분 (common/spac/preferred/reit) |
| base_date | DATE | 기준일 |
#### sectors (섹터 분류)
| 컬럼 | 타입 | 설명 |
|------|------|------|
| ticker | VARCHAR (PK) | 종목코드 |
| sector_code | VARCHAR | 섹터코드 (IDX_CD) |
| company_name | VARCHAR | 종목명 |
| sector_name | VARCHAR | 섹터명 |
| base_date | DATE | 기준일 |
#### valuations (밸류 지표)
| 컬럼 | 타입 | 설명 |
|------|------|------|
| ticker | VARCHAR (PK) | 종목코드 |
| base_date | DATE (PK) | 기준일 |
| per | DECIMAL | PER |
| pbr | DECIMAL | PBR |
| psr | DECIMAL | PSR |
| pcr | DECIMAL | PCR |
| dividend_yield | DECIMAL | 배당수익률 |
#### prices (가격 데이터)
| 컬럼 | 타입 | 설명 |
|------|------|------|
| ticker | VARCHAR (PK) | 종목코드 |
| date | DATE (PK) | 날짜 |
| open | DECIMAL | 시가 |
| high | DECIMAL | 고가 |
| low | DECIMAL | 저가 |
| close | DECIMAL | 종가 |
| volume | BIGINT | 거래량 |
#### financials (재무제표)
| 컬럼 | 타입 | 설명 |
|------|------|------|
| ticker | VARCHAR (PK) | 종목코드 |
| base_date | DATE (PK) | 기준일 |
| report_type | VARCHAR (PK) | 공시구분 (annual/quarterly) |
| account | VARCHAR (PK) | 계정명 |
| value | DECIMAL | 값 |
**account 값 매핑:**
- revenue, gross_profit, operating_income, net_income
- total_assets, total_equity, total_liabilities
- operating_cash_flow, depreciation, interest_expense
- income_tax, cash, current_assets, current_liabilities, non_current_assets
### 4.2 포트폴리오 관리
#### users
| 컬럼 | 타입 | 설명 |
|------|------|------|
| id | SERIAL (PK) | ID |
| username | VARCHAR | 사용자명 |
| email | VARCHAR | 이메일 |
| hashed_password | VARCHAR | 해시된 비밀번호 |
| created_at | TIMESTAMP | 생성일 |
#### portfolios
| 컬럼 | 타입 | 설명 |
|------|------|------|
| id | SERIAL (PK) | ID |
| user_id | INTEGER (FK) | 사용자 ID |
| name | VARCHAR | 포트폴리오명 |
| portfolio_type | VARCHAR | 유형 (pension/general) |
| created_at | TIMESTAMP | 생성일 |
| updated_at | TIMESTAMP | 수정일 |
#### targets (목표 비율)
| 컬럼 | 타입 | 설명 |
|------|------|------|
| portfolio_id | INTEGER (PK, FK) | 포트폴리오 ID |
| ticker | VARCHAR (PK) | 종목코드 |
| target_ratio | DECIMAL | 목표 비율 (%) |
#### holdings (보유 자산)
| 컬럼 | 타입 | 설명 |
|------|------|------|
| portfolio_id | INTEGER (PK, FK) | 포트폴리오 ID |
| ticker | VARCHAR (PK) | 종목코드 |
| quantity | INTEGER | 보유 수량 |
| avg_price | DECIMAL | 평균 매수가 |
#### transactions (거래 내역)
| 컬럼 | 타입 | 설명 |
|------|------|------|
| id | SERIAL (PK) | ID |
| portfolio_id | INTEGER (FK) | 포트폴리오 ID |
| ticker | VARCHAR | 종목코드 |
| tx_type | VARCHAR | 거래 유형 (buy/sell) |
| quantity | INTEGER | 수량 |
| price | DECIMAL | 가격 |
| executed_at | TIMESTAMP | 체결일시 |
| memo | TEXT | 메모 |
#### portfolio_snapshots
| 컬럼 | 타입 | 설명 |
|------|------|------|
| id | SERIAL (PK) | ID |
| portfolio_id | INTEGER (FK) | 포트폴리오 ID |
| total_value | DECIMAL | 총 평가금액 |
| snapshot_date | DATE | 스냅샷 날짜 |
#### snapshot_holdings
| 컬럼 | 타입 | 설명 |
|------|------|------|
| snapshot_id | INTEGER (PK, FK) | 스냅샷 ID |
| ticker | VARCHAR (PK) | 종목코드 |
| quantity | INTEGER | 보유 수량 |
| price | DECIMAL | 당시 가격 |
| value | DECIMAL | 평가 금액 |
| current_ratio | DECIMAL | 당시 비율 (%) |
### 4.3 ETF (퇴직연금용)
#### etfs
| 컬럼 | 타입 | 설명 |
|------|------|------|
| ticker | VARCHAR (PK) | 종목코드 |
| name | VARCHAR | ETF명 |
| asset_class | VARCHAR | 자산군 (equity/bond/gold/mixed) |
| market | VARCHAR | 시장 |
| expense_ratio | DECIMAL | 보수율 |
#### etf_prices
| 컬럼 | 타입 | 설명 |
|------|------|------|
| ticker | VARCHAR (PK) | 종목코드 |
| date | DATE (PK) | 날짜 |
| close | DECIMAL | 종가 |
| nav | DECIMAL | NAV |
| volume | BIGINT | 거래량 |
### 4.4 배치 작업 관리
#### job_logs
| 컬럼 | 타입 | 설명 |
|------|------|------|
| id | SERIAL (PK) | ID |
| job_name | VARCHAR | 작업명 |
| status | VARCHAR | 상태 (running/success/failed) |
| started_at | TIMESTAMP | 시작 시간 |
| finished_at | TIMESTAMP | 종료 시간 |
| records_count | INTEGER | 처리 건수 |
| error_msg | TEXT | 에러 메시지 |
---
## 5. API 엔드포인트
### 5.1 인증
| Method | Endpoint | 설명 |
|--------|----------|------|
| POST | /api/auth/login | 로그인 (JWT 발급) |
| POST | /api/auth/logout | 로그아웃 |
| GET | /api/auth/me | 현재 사용자 정보 |
### 5.2 포트폴리오
| Method | Endpoint | 설명 |
|--------|----------|------|
| GET | /api/portfolios | 포트폴리오 목록 |
| POST | /api/portfolios | 포트폴리오 생성 |
| GET | /api/portfolios/{id} | 포트폴리오 상세 |
| PUT | /api/portfolios/{id} | 포트폴리오 수정 |
| DELETE | /api/portfolios/{id} | 포트폴리오 삭제 |
| GET | /api/portfolios/{id}/targets | 목표 비율 조회 |
| PUT | /api/portfolios/{id}/targets | 목표 비율 설정 |
| GET | /api/portfolios/{id}/holdings | 보유 자산 조회 |
| PUT | /api/portfolios/{id}/holdings | 보유 자산 수정 |
| GET | /api/portfolios/{id}/transactions | 거래 내역 조회 |
| POST | /api/portfolios/{id}/transactions | 거래 기록 추가 |
| GET | /api/portfolios/{id}/snapshots | 스냅샷 목록 |
| POST | /api/portfolios/{id}/snapshots | 스냅샷 생성 |
### 5.3 리밸런싱
| Method | Endpoint | 설명 |
|--------|----------|------|
| GET | /api/portfolios/{id}/rebalance | 리밸런싱 계산 |
| POST | /api/portfolios/{id}/rebalance/simulate | 추가 입금 시뮬레이션 |
### 5.4 시세
| Method | Endpoint | 설명 |
|--------|----------|------|
| GET | /api/market/stocks/{ticker} | 종목 정보 |
| GET | /api/market/stocks/{ticker}/price | 현재가 (OpenAPI) |
| GET | /api/market/stocks/{ticker}/prices | 과거 시세 (DB) |
| GET | /api/market/etfs/{ticker} | ETF 정보 |
| GET | /api/market/etfs/{ticker}/price | ETF 현재가 |
| GET | /api/market/search?q= | 종목 검색 |
### 5.5 퀀트 전략
| Method | Endpoint | 설명 |
|--------|----------|------|
| POST | /api/strategy/multi-factor | 멀티 팩터 전략 |
| POST | /api/strategy/quality | 슈퍼 퀄리티 전략 |
| POST | /api/strategy/value-momentum | 슈퍼 밸류 모멘텀 전략 |
### 5.6 백테스트
| Method | Endpoint | 설명 |
|--------|----------|------|
| POST | /api/backtest | 백테스트 실행 |
### 5.7 데이터 수집 (관리자)
| Method | Endpoint | 설명 |
|--------|----------|------|
| POST | /api/admin/collect/stocks | 종목 마스터 수집 |
| POST | /api/admin/collect/sectors | 섹터 정보 수집 |
| POST | /api/admin/collect/prices | 가격 데이터 수집 |
| POST | /api/admin/collect/financials | 재무제표 수집 |
| POST | /api/admin/collect/valuations | 밸류 지표 수집 |
| GET | /api/admin/collect/status | 수집 작업 상태 |
---
## 6. 프론트엔드 페이지
| 경로 | 설명 |
|------|------|
| / | 대시보드 |
| /login | 로그인 |
| /portfolio | 포트폴리오 목록 |
| /portfolio/[id] | 포트폴리오 상세 |
| /portfolio/[id]/rebalance | 리밸런싱 계산 |
| /portfolio/[id]/history | 스냅샷/수익률 히스토리 |
| /portfolio/new | 새 포트폴리오 생성 |
| /strategy | 퀀트 전략 메인 |
| /strategy/multi-factor | 멀티 팩터 전략 |
| /strategy/quality | 슈퍼 퀄리티 전략 |
| /strategy/value-momentum | 슈퍼 밸류 모멘텀 전략 |
| /backtest | 백테스트 |
| /backtest/result/[id] | 백테스트 결과 |
| /market | 시세 조회 |
| /market/[ticker] | 종목 상세 |
| /admin/data | 데이터 수집 관리 |
---
## 7. 데이터 배치 수집
### 7.1 수집 대상 및 소스
| 데이터 | 소스 | 수집 주기 |
|--------|------|-----------|
| stocks | KRX (data.krx.co.kr) | 매일 18:00 |
| sectors | WISEindex | 매일 18:00 |
| prices | pykrx / KRX | 매일 18:00 |
| valuations | KRX | 매일 18:00 |
| financials | DART OpenAPI | 분기별 |
| etf_prices | pykrx | 매일 18:00 |
### 7.2 스케줄러 설정 (APScheduler)
```python
jobs:
- id: daily_stock_data
func: collect_stocks_and_sectors
trigger: cron, hour=18, minute=0, day_of_week=mon-fri
- id: daily_prices
func: collect_prices
trigger: cron, hour=18, minute=30, day_of_week=mon-fri
- id: daily_valuations
func: collect_valuations
trigger: cron, hour=19, minute=0, day_of_week=mon-fri
- id: quarterly_financials
func: collect_financials
trigger: cron, month=1,4,7,10, day=15
```
---
## 8. 퀀트 전략 엔진
### 8.1 팩터 계산
**밸류 팩터:**
- PER 역수 (1/PER)
- PBR 역수 (1/PBR)
- PSR 역수 (1/PSR)
- PCR 역수 (1/PCR)
- 배당수익률
**퀄리티 팩터:**
- ROE = 당기순이익 / 자본
- GP/A = 매출총이익 / 자산
- 영업현금흐름 / 자산
- 부채비율 역수
**모멘텀 팩터:**
- 12개월 수익률
- 6개월 수익률
- 최근 1개월 제외 11개월 수익률
**F-Score (9점 만점):**
- 수익성: ROA, CFO, ΔROA, Accrual (4점)
- 재무건전성: ΔLeverage, ΔLiquidity, Equity (3점)
- 운영효율성: ΔMargin, ΔTurnover (2점)
### 8.2 전략 실행 흐름
1. 유니버스 필터 (시장, 시가총액, 종목구분)
2. 팩터별 z-score 계산
3. 가중치 적용하여 종합 점수 산출
4. 순위 정렬 후 상위 N개 반환
### 8.3 백테스트 엔진
**입력:**
- strategy: 전략 종류 및 파라미터
- start_date, end_date: 테스트 기간
- rebalance_period: 리밸런싱 주기 (월별/분기별)
- initial_capital: 초기 자본
**출력:**
- total_return: 총 수익률
- cagr: 연평균 수익률
- mdd: 최대 낙폭
- sharpe_ratio: 샤프 비율
- holdings_history: 기간별 보유 종목
- equity_curve: 자산 추이
---
## 9. Docker 구성
### 9.1 docker-compose.yml
```yaml
version: '3.8'
services:
postgres:
image: postgres:15
environment:
POSTGRES_USER: galaxy
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: galaxy_po
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
backend:
build: ./backend
environment:
DATABASE_URL: postgresql://galaxy:${DB_PASSWORD}@postgres:5432/galaxy_po
KIS_APP_KEY: ${KIS_APP_KEY}
KIS_APP_SECRET: ${KIS_APP_SECRET}
JWT_SECRET: ${JWT_SECRET}
ports:
- "8000:8000"
depends_on:
- postgres
frontend:
build: ./frontend
environment:
NEXT_PUBLIC_API_URL: http://backend:8000
ports:
- "3000:3000"
depends_on:
- backend
volumes:
postgres_data:
```
### 9.2 Dockerfile (Backend)
```dockerfile
FROM python:3.14-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
```
### 9.3 Dockerfile (Frontend)
```dockerfile
FROM node:24-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
CMD ["npm", "start"]
```
### 9.4 환경 변수 (.env)
```
# Database
DB_PASSWORD=your_secure_password
# JWT
JWT_SECRET=your_jwt_secret_key
# 한국투자증권 OpenAPI
KIS_APP_KEY=your_kis_app_key
KIS_APP_SECRET=your_kis_app_secret
KIS_ACCOUNT_NO=your_account_number
# DART OpenAPI
DART_API_KEY=your_dart_api_key
```
---
## 10. 구현 순서
### Phase 1: 기반 구축
1. 프로젝트 초기화 (backend/frontend 구조)
2. Docker Compose 설정
3. PostgreSQL + DB 모델 정의
4. FastAPI 기본 구조 + 인증 (JWT)
5. Next.js 기본 구조 + 레이아웃
### Phase 2: 데이터 수집
6. 데이터 수집기 구현 (stocks, sectors, prices)
7. 배치 스케줄러 설정
8. 관리자 데이터 수집 UI
### Phase 3: 포트폴리오 관리
9. 포트폴리오 CRUD API
10. 목표 비율 / 보유 자산 관리
11. 거래 내역 기록
12. 리밸런싱 계산 로직
13. 포트폴리오 UI (대시보드, 상세, 리밸런싱)
### Phase 4: 퀀트 전략
14. 팩터 계산 로직 (value, quality, momentum)
15. 전략 엔진 (multi-factor, super-quality, value-momentum)
16. 전략 UI
### Phase 5: 백테스트
17. 백테스트 엔진
18. 백테스트 UI + 결과 시각화
### Phase 6: 마무리
19. 스냅샷 / 수익률 추적
20. ETF 시세 연동 (OpenAPI)
21. 테스트 / 버그 수정
22. 배포
---
## 11. 핵심 의존성
### backend/requirements.txt
```
fastapi
uvicorn
sqlalchemy
alembic
psycopg2-binary
pydantic
python-jose[cryptography]
passlib[bcrypt]
apscheduler
pykrx
requests
beautifulsoup4
pandas
numpy
```
### frontend/package.json (dependencies)
```json
{
"next": "^15",
"react": "^19",
"typescript": "^5",
"tailwindcss": "^4",
"recharts": "^2",
"axios": "^1",
"zustand": "^5"
}
```
---
**문서 버전:** 1.0
**작성일:** 2026-02-02