diff --git a/README.md b/README.md new file mode 100644 index 0000000..6419b4b --- /dev/null +++ b/README.md @@ -0,0 +1,137 @@ +# stock-screener + +한국 주식 분석 플랫폼의 **정량 스크리닝 서비스**. 밸류에이션 지표를 기반으로 종목을 점수화하고 순위를 매겨 투자 후보를 선별합니다. + +## 기능 + +- **멀티 팩터 스크리닝**: PER, PBR, ROE 등 밸류에이션 지표 기반 점수화 +- **전략별 가중치**: Balanced / Value / Growth 전략에 따라 다른 가중치 적용 +- **섹터 내 상대 평가**: 동일 섹터 내에서 백분위 기반 순위 +- **시장 필터**: KOSPI / KOSDAQ / 전체 시장 선택 가능 +- **결과 조회 API**: 최신 결과 + run_id별 이력 조회 (종목명 JOIN) +- **비동기 워커**: Redis Streams 기반 작업 큐 소비 + +## API 엔드포인트 + +| 메서드 | 경로 | 설명 | +|--------|------|------| +| GET | `/health` | 서비스 상태 | +| GET | `/streams` | Redis Stream 큐 길이 | +| POST | `/screen` | 스크리닝 실행 트리거 | +| GET | `/results/latest` | 가장 최근 스크리닝 결과 | +| GET | `/results/{run_id}` | 특정 실행의 결과 | + +### POST /screen 파라미터 + +| 필드 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `strategy` | string | `balanced` | 스크리닝 전략 (`balanced`, `value`, `growth`) | +| `market` | string | `all` | 시장 필터 (`all`, `KOSPI`, `KOSDAQ`) | +| `top_n` | int | `50` | 상위 N개 종목 선별 | + +### 요청 예시 + +```bash +# 스크리닝 실행 +curl -X POST http://localhost:8004/screen \ + -H "Content-Type: application/json" \ + -d '{"strategy": "value", "market": "KOSPI", "top_n": 30}' + +# 최근 결과 조회 +curl http://localhost:8004/results/latest?limit=10 +``` + +### 응답 예시 + +```json +// GET /results/latest +{ + "run_id": "a1b2c3d4-...", + "strategy": "balanced", + "screened_at": "2024-12-20 15:30:00", + "results": [ + { + "stock_code": "005930", + "stock_name": "삼성전자", + "market": "KOSPI", + "sector": "전기전자", + "composite_score": 85.3, + "per_score": 12.5, + "pbr_score": 1.1, + "roe_score": 8.7, + "rank": 1, + "strategy": "balanced" + } + ] +} +``` + +## 스크리닝 로직 + +``` +1. PostgreSQL에서 최신 밸류에이션 데이터 로드 + (valuation + stock 테이블 JOIN) + │ + ▼ +2. 섹터별 그룹핑 + │ + ▼ +3. 각 지표에 대해 백분위 점수 계산 + - PER: 낮을수록 좋음 (역 백분위) + - PBR: 낮을수록 좋음 (역 백분위) + - ROE: 높을수록 좋음 + │ + ▼ +4. 전략별 가중치 적용 → composite_score + │ + ▼ +5. 전체 순위 매김 → 상위 N개 선별 +``` + +## 데이터 파이프라인 + +``` +POST /screen + │ + ▼ +queue:trigger-screen ──→ Worker (Screener) + │ + ▼ + queue:screened ──→ stock-catalyst +``` + +스크리닝 결과는 `queue:screened` 스트림에 발행되어 다음 단계(카탈리스트 탐지)로 전달됩니다. + +## 프로젝트 구조 + +``` +stock-screener/ +├── pyproject.toml +├── Dockerfile +├── .dockerignore +└── src/stock_screener/ + ├── __init__.py + ├── api.py # FastAPI 엔드포인트 (POST + GET) + ├── screener.py # Screener 엔진 (점수화, 순위) + └── worker.py # Redis Stream 소비자 + API 서버 실행 +``` + +## 환경변수 + +| 변수 | 설명 | 기본값 | +|------|------|--------| +| `REDIS_URL` | Redis 연결 URL | `redis://localhost:6379/0` | +| `POSTGRES_HOST` | PostgreSQL 호스트 | `localhost` | +| `POSTGRES_DB` | 데이터베이스명 | `stockdb` | + +## 로컬 실행 + +```bash +pip install -e ../stock-common && pip install -e . +python -m stock_screener.worker +``` + +## 의존성 + +- `stock-common` - 공유 라이브러리 +- Python >= 3.12