fix: 인증 미들웨어 활성화, lifespan 예외처리, Docker 네트워크 바인딩 수정 및 문서 전면 개선

- hydra/main.py: auth_guard 미들웨어에 실제 API 키 검증 로직 추가
- hydra/main.py: lifespan 초기화 블록 try-except 감싸기, finally에서 ohlcv_store None 체크 추가
- Dockerfile: --host 127.0.0.1 → 0.0.0.0 (컨테이너 간 통신 가능하도록)
- hydra/config/settings.py: 기본 API 키 사용 시 경고 validator 추가
- README.md: 첫 사용자를 위한 상세 가이드로 전면 재작성
- docs/QUICKSTART_KO.md: 단계별 시작 가이드 개선
- docs/API_REFERENCE_KO.md: 전체 엔드포인트 응답 예시 및 파라미터 설명 추가

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
sinmb79
2026-03-30 16:02:04 +09:00
parent 92a692b63c
commit b4c775563c
6 changed files with 785 additions and 254 deletions

View File

@@ -18,4 +18,4 @@ RUN useradd -m hydra && chown -R hydra:hydra /app
USER hydra
EXPOSE 8000
CMD ["uvicorn", "hydra.main:app", "--host", "127.0.0.1", "--port", "8000"]
CMD ["uvicorn", "hydra.main:app", "--host", "0.0.0.0", "--port", "8000"]

382
README.md
View File

@@ -1,154 +1,267 @@
# HYDRA Engine
HYDRA Engine은 로컬 우선(Local-first) 철학으로 설계된 자동매매 엔진 프로젝트입니다.
데이터 수집, 지표 계산, 레짐 분류, 시그널 생성, 보조 데이터 수집, 백테스트, FastAPI API, Typer CLI를 하나의 저장소에서 관리합니다.
HYDRA Engine은 **로컬 우선(Local-first)** 철학으로 설계된 자동매매 엔진입니다.
데이터 수집 지표 계산 레짐 분류 시그널 생성 → 백테스트 → 실거래까지 하나의 저장소에서 관리합니다.
이 저장소는 "실거래 수익 보장"을 목표로 하지 않습니다. 먼저 안전하게 실행하고, 충분히 검증하고, 필요할 때만 확장하는 것을 목표로 합니다.
> **이 프로젝트는 교육·연구·실험용입니다.**
> 실거래 수익을 보장하지 않으며, 사용에 따른 모든 책임은 사용자 본인에게 있습니다.
> 반드시 [DISCLAIMER.md](DISCLAIMER.md)를 먼저 읽으세요.
## 1. 현재 포함된 기능
---
- FastAPI 기반 제어/API 서버
- Redis 기반 상태 공유
- OHLCV 수집기와 SQLite/TimescaleDB 저장소
- 지표 계산 엔진
- 레짐(Regime) 분류 엔진
- 전략 시그널 엔진
- 오더북 / 이벤트 / 감성 보조 데이터 수집
- 인메모리 백테스트 엔진
- Kill Switch, 주문 큐, 리스크 엔진, 설정 검증
- CLI 도구와 Docker Compose 프로필(lite / pro / expert)
## 목차
## 2. 이 프로젝트를 어떻게 이해하면 좋은가
1. [포함된 기능](#1-포함된-기능)
2. [사용 철학 — 어떻게 접근할 것인가](#2-사용-철학--어떻게-접근할-것인가)
3. [준비물 설치](#3-준비물-설치)
4. [처음 시작하기 (5단계)](#4-처음-시작하기-5단계)
5. [테스트 실행](#5-테스트-실행)
6. [Docker로 전체 파이프라인 실행](#6-docker로-전체-파이프라인-실행)
7. [API 사용법](#7-api-사용법)
8. [CLI 사용법](#8-cli-사용법)
9. [Docker 프로필 선택](#9-docker-프로필-선택)
10. [자주 발생하는 문제 (FAQ)](#10-자주-발생하는-문제-faq)
11. [문서](#11-문서)
12. [라이선스](#12-라이선스)
HYDRA는 한 번에 모든 기능을 다 켜는 프로젝트가 아닙니다.
---
1. 먼저 데이터를 수집합니다.
2. 지표와 레짐, 시그널을 계산합니다.
3. API나 CLI로 상태를 확인합니다.
4. 백테스트로 전략을 검증합니다.
5. 실거래는 마지막 단계에서 매우 조심스럽게 붙입니다.
## 1. 포함된 기능
현재 저장소에는 실거래로 연결되는 기반 코드가 일부 포함되어 있지만, 여러 CLI 명령은 아직 "예정" 상태의 placeholder를 포함합니다. 공개 배포용으로는 안전하게 시험, 학습, 백테스트, 데이터 파이프라인 검증부터 시작하는 것을 권장합니다.
| 모듈 | 설명 |
|------|------|
| FastAPI 서버 | REST API로 모든 기능 제어 |
| OHLCV 수집기 | 거래소에서 캔들 데이터 수집, SQLite/TimescaleDB 저장 |
| 지표 계산 엔진 | RSI, MACD, Bollinger Band 등 자동 계산 |
| 레짐 분류 엔진 | 시장 상태(추세/횡보/변동성) 분류 |
| 전략 시그널 엔진 | 매수/매도 시그널 생성 |
| 보조 데이터 수집 | 오더북, 이벤트 일정, 감성 점수 |
| 인메모리 백테스트 | 수집된 데이터로 전략 성과 검증 |
| Kill Switch | 긴급 전 포지션 청산 |
| 주문 큐 | 안전한 주문 처리 파이프라인 |
| 리스크 엔진 | 포지션 및 리스크 관리 |
| CLI 도구 | 터미널에서 모든 기능 제어 |
| Telegram 알림 | 주요 이벤트 실시간 알림 |
## 3. 빠른 시작
---
가장 쉬운 시작 방법은 아래 두 가지입니다.
## 2. 사용 철학 — 어떻게 접근할 것인가
- 로컬 Python 환경에서 테스트부터 실행
- Docker Compose Lite 프로필로 전체 파이프라인 기동
HYDRA는 **한 번에 모든 기능을 켜는 프로젝트가 아닙니다.**
### 3.1 요구 사항
```
1단계: 테스트 실행으로 코드 정상 확인
2단계: 데이터 수집 (거래소 API 키 없어도 공개 데이터 가능)
3단계: 지표·레짐·시그널 계산 확인
4단계: API/CLI로 상태 관찰
5단계: 백테스트로 전략 검증
6단계: (충분한 검증 후) 실거래 연결
```
- Python 3.11 이상
- Docker / Docker Compose
- Redis
- Git
처음 사용하는 분은 **1~4단계**부터 시작하는 것을 강력히 권장합니다.
### 3.2 저장소 준비
---
## 3. 준비물 설치
### 필수 소프트웨어
| 소프트웨어 | 버전 | 설치 링크 |
|-----------|------|----------|
| Python | 3.11 이상 | https://www.python.org/downloads/ |
| Git | 최신 | https://git-scm.com/ |
| Docker Desktop | 최신 | https://www.docker.com/products/docker-desktop |
> Docker Desktop을 설치하면 Docker와 Docker Compose가 함께 설치됩니다.
### 설치 확인
터미널(명령 프롬프트 / PowerShell / Terminal)에서 아래 명령을 실행해 버전을 확인합니다.
```bash
python --version # Python 3.11.x 이상이어야 함
git --version
docker --version
docker compose version
```
---
## 4. 처음 시작하기 (5단계)
### 4.1 저장소 다운로드
```bash
git clone https://github.com/sinmb79/Hydra-Engine.git
cd Hydra-Engine
```
### 4.2 Python 가상환경 생성 및 활성화
가상환경은 이 프로젝트 전용 Python 환경을 만들어 다른 프로젝트와 충돌하지 않게 합니다.
```bash
python -m venv .venv
```
Windows PowerShell:
**Windows (PowerShell):**
```powershell
.venv\Scripts\Activate.ps1
```
macOS / Linux:
> PowerShell에서 실행 오류가 발생하면 먼저 아래 명령을 실행하세요:
> ```powershell
> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
> ```
**macOS / Linux:**
```bash
source .venv/bin/activate
```
패키지 설치:
활성화되면 터미널 앞에 `(.venv)`가 표시됩니다.
### 4.3 패키지 설치
```bash
pip install -e .[dev]
```
### 3.3 환경 변수 설정
> 처음 설치 시 수분이 걸릴 수 있습니다.
`.env.example`를 복사해서 `.env`를 만드세요.
### 4.4 환경 변수 설정
`.env.example` 파일을 복사해 `.env`를 만듭니다.
**macOS / Linux:**
```bash
cp .env.example .env
```
Windows PowerShell:
**Windows (PowerShell):**
```powershell
Copy-Item .env.example .env
```
최소 필수 항목:
생성된 `.env` 파일을 텍스트 에디터로 열어 아래 항목을 수정합니다.
```env
HYDRA_API_KEY=change-me-to-a-random-secret
# 반드시 변경하세요 — 이 값이 API 접근 비밀번호입니다
HYDRA_API_KEY=여기에-랜덤-문자열-입력
# 프로필: lite(입문) / pro(중급) / expert(고급)
HYDRA_PROFILE=lite
# Redis 주소 (Docker 사용 시 기본값 유지)
REDIS_URL=redis://localhost:6379
```
`pro` 또는 `expert` 프로필에서는 `DB_PASSWORD`가 필요합니다.
> **HYDRA_API_KEY**는 API 호출 시 인증에 사용됩니다.
> 아무 문자열이나 사용할 수 있습니다. 예: `my-hydra-secret-2024`
## 4. 가장 먼저 해볼 것
### 4.1 테스트 실행
### 4.5 테스트 실행으로 정상 확인
```bash
pytest -q
```
정상이라면 전체 테스트가 통과해야 합니다.
모든 테스트가 통과하면 준비 완료입니다.
### 4.2 Lite 프로필로 실행
---
## 5. 테스트 실행
```bash
# 전체 테스트
pytest -q
# 특정 파일만
pytest tests/test_backtest_runner.py -v
# 상세 출력
pytest -v
```
---
## 6. Docker로 전체 파이프라인 실행
Docker Desktop이 실행 중인지 확인한 후 아래 명령을 실행합니다.
```bash
docker compose -f docker-compose.lite.yml up --build
```
서버 헬스체크:
> 첫 실행 시 이미지 빌드로 수분이 걸립니다.
### 실행 확인
새 터미널을 열고 헬스체크를 합니다.
```bash
curl http://127.0.0.1:8000/health
```
## 5. 주요 사용 흐름
아래와 같은 응답이 오면 정상입니다.
### 5.1 활성 시장 확인
```json
{"status": "ok"}
```
### 종료
```bash
curl -H "X-HYDRA-KEY: change-me-to-a-random-secret" \
# Ctrl+C 로 중지 후
docker compose -f docker-compose.lite.yml down
```
---
## 7. API 사용법
모든 API 호출은 `/health`를 제외하고 `X-HYDRA-KEY` 헤더를 포함해야 합니다.
```bash
curl -H "X-HYDRA-KEY: 여기에-API-키" http://127.0.0.1:8000/엔드포인트
```
### 7.1 헬스체크 (인증 불필요)
```bash
curl http://127.0.0.1:8000/health
```
### 7.2 활성 시장 확인
```bash
curl -H "X-HYDRA-KEY: my-hydra-secret-2024" \
http://127.0.0.1:8000/markets
```
### 5.2 수집 중인 심볼 확인
### 7.3 수집 중인 심볼 확인
```bash
curl -H "X-HYDRA-KEY: change-me-to-a-random-secret" \
curl -H "X-HYDRA-KEY: my-hydra-secret-2024" \
http://127.0.0.1:8000/data/symbols
```
### 5.3 캔들 조회
### 7.4 캔들(OHLCV) 데이터 조회
```bash
curl -G http://127.0.0.1:8000/data/candles \
-H "X-HYDRA-KEY: change-me-to-a-random-secret" \
-H "X-HYDRA-KEY: my-hydra-secret-2024" \
--data-urlencode "market=binance" \
--data-urlencode "symbol=BTC/USDT" \
--data-urlencode "timeframe=1h" \
--data-urlencode "limit=200"
--data-urlencode "limit=100"
```
### 5.4 백테스트 실행
### 7.5 백테스트 실행
```bash
curl -X POST http://127.0.0.1:8000/backtest/run \
-H "Content-Type: application/json" \
-H "X-HYDRA-KEY: change-me-to-a-random-secret" \
-H "X-HYDRA-KEY: my-hydra-secret-2024" \
-d '{
"market": "binance",
"symbol": "BTC/USDT",
@@ -161,63 +274,152 @@ curl -X POST http://127.0.0.1:8000/backtest/run \
}'
```
### 5.5 Kill Switch
> `since`와 `until`은 Unix timestamp (밀리초) 입니다.
> 위 예시는 2024년 1월 1일 ~ 2024년 2월 1일 구간입니다.
Kill Switch는 전 포지션 청산을 시도하는 고위험 명령입니다. 테스트 목적이 아니라면 함부로 사용하지 마세요.
CLI:
### 7.6 포지션 / 손익 확인
```bash
python -m hydra.cli.app kill
curl -H "X-HYDRA-KEY: my-hydra-secret-2024" http://127.0.0.1:8000/positions
curl -H "X-HYDRA-KEY: my-hydra-secret-2024" http://127.0.0.1:8000/pnl
```
API:
### 7.7 Kill Switch (주의: 전 포지션 청산)
```bash
curl -X POST "http://127.0.0.1:8000/killswitch?reason=manual_test" \
-H "X-HYDRA-KEY: change-me-to-a-random-secret"
-H "X-HYDRA-KEY: my-hydra-secret-2024"
```
## 6. CLI 예시
> Kill Switch는 실거래 중 긴급 상황에서만 사용하세요.
전체 API 목록은 [docs/API_REFERENCE_KO.md](docs/API_REFERENCE_KO.md)를 참고하세요.
---
## 8. CLI 사용법
```bash
# 도움말
python -m hydra.cli.app --help
# 초기 설정 마법사
python -m hydra.cli.app setup
# 현재 상태 확인
python -m hydra.cli.app status
# 시장 목록 확인
python -m hydra.cli.app market list-markets
# 시장 활성화 (paper = 모의거래)
python -m hydra.cli.app market enable binance --mode paper
python -m hydra.cli.app trade crypto binance BTC/USDT buy 0.01
# Kill Switch (긴급 청산)
python -m hydra.cli.app kill
```
주의:
> `trade`, `strategy`, `module` 명령 일부는 현재 개발 예정 상태입니다.
- `trade`, `strategy`, `module` 일부 명령은 아직 placeholder 메시지를 출력합니다.
- 공개 버전 기준으로는 데이터 수집, 관찰, 백테스트 중심으로 사용하는 것이 안전합니다.
---
## 7. Docker 프로필
## 9. Docker 프로필 선택
- `docker-compose.lite.yml`
- SQLite 사용
- 개인 PC / 테스트 / 입문용
- `docker-compose.pro.yml`
- TimescaleDB + Redis
- 중간 규모 수집/분석용
- `docker-compose.expert.yml`
- 고사양 장비 / 확장 시나리오용
| 프로필 | 파일 | 데이터베이스 | 권장 대상 |
|--------|------|------------|----------|
| **lite** | `docker-compose.lite.yml` | SQLite | 처음 시작하는 분, 개인 PC |
| **pro** | `docker-compose.pro.yml` | TimescaleDB + Redis | 중간 규모 수집·분석 |
| **expert** | `docker-compose.expert.yml` | 고사양 확장 구성 | 대용량 데이터, 고성능 서버 |
## 8. 문서
처음 사용자는 **lite**부터 시작하세요.
- 자세한 시작 가이드: [docs/QUICKSTART_KO.md](docs/QUICKSTART_KO.md)
- API 레퍼런스: [docs/API_REFERENCE_KO.md](docs/API_REFERENCE_KO.md)
- 법적 고지: [DISCLAIMER.md](DISCLAIMER.md)
```bash
# lite
docker compose -f docker-compose.lite.yml up --build
## 9. 안전 안내
# pro (DB_PASSWORD 설정 필요)
docker compose -f docker-compose.pro.yml up --build
- 이 저장소는 교육, 연구, 실험용입니다.
- 실거래 전에는 반드시 paper 모드와 백테스트로 먼저 검증하세요.
- `.env`, API 키, 계정 정보는 절대 Git에 올리지 마세요.
# expert
docker compose -f docker-compose.expert.yml up --build
```
---
## 10. 자주 발생하는 문제 (FAQ)
### Q: `pytest` 실행 시 ModuleNotFoundError가 발생해요
가상환경이 활성화되어 있는지 확인하세요.
```bash
# 가상환경 활성화 확인
# 터미널 앞에 (.venv)가 보여야 함
# 다시 설치
pip install -e .[dev]
```
### Q: Docker 실행 시 Redis 연결 오류가 발생해요
Docker Desktop이 실행 중인지 확인하세요. 그 다음 `.env` 파일의 `REDIS_URL`을 확인합니다.
Docker Compose 환경에서는 Redis가 컨테이너로 자동 실행되므로 기본값을 유지하세요.
```env
REDIS_URL=redis://redis:6379 # Docker Compose 내부
REDIS_URL=redis://localhost:6379 # 로컬 직접 실행
```
### Q: API 호출 시 403 오류가 발생해요
`X-HYDRA-KEY` 헤더가 `.env``HYDRA_API_KEY`와 일치하는지 확인하세요.
```bash
curl -H "X-HYDRA-KEY: 설정한-키-값" http://127.0.0.1:8000/markets
```
### Q: `HYDRA_API_KEY가 기본값` 경고가 뜨는데 괜찮나요?
로컬 테스트 목적이면 무시할 수 있지만, 외부에 서버를 노출할 경우 반드시 변경하세요.
`.env` 파일에서 `HYDRA_API_KEY=change-me`를 다른 값으로 바꾸면 경고가 사라집니다.
### Q: Windows에서 PowerShell 실행 정책 오류가 발생해요
```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```
### Q: Docker 빌드가 너무 느려요
처음 빌드는 수분이 걸립니다. 두 번째 실행부터는 캐시를 사용해 빠릅니다.
빌드 없이 실행하려면 `--build` 옵션을 제거하세요.
```bash
docker compose -f docker-compose.lite.yml up
```
---
## 11. 문서
| 문서 | 설명 |
|------|------|
| [docs/QUICKSTART_KO.md](docs/QUICKSTART_KO.md) | 10분 빠른 시작 가이드 |
| [docs/API_REFERENCE_KO.md](docs/API_REFERENCE_KO.md) | 전체 API 엔드포인트 레퍼런스 |
| [DISCLAIMER.md](DISCLAIMER.md) | 법적 고지 및 책임 한계 |
---
## 12. 안전 안내
- `.env` 파일과 API 키는 절대 Git에 올리지 마세요. (`.gitignore`에 이미 포함되어 있습니다)
- 실거래 전에는 반드시 paper 모드와 백테스트로 전략을 충분히 검증하세요.
- 기본적으로 로컬/사설 네트워크에서만 운용하는 것을 권장합니다.
- 거래소 API 키는 필요한 최소 권한만 부여하세요.
## 10. 라이선스
---
이 저장소는 [MIT License](LICENSE)를 따릅니다.
## 13. 라이선스
[MIT License](LICENSE)

View File

@@ -1,113 +1,271 @@
# HYDRA Engine API 레퍼런스
모든 보호된 엔드포인트는 아래 헤더를 요구합니다.
## 인증
`/health`를 제외한 모든 엔드포인트는 아래 헤더를 요구합니다.
```http
X-HYDRA-KEY: <HYDRA_API_KEY>
```
## 1. 헬스체크
`.env`에 설정한 `HYDRA_API_KEY` 값을 사용합니다.
### `GET /health`
**인증 실패 시 응답:**
```json
HTTP 403
{"detail": "Invalid or missing API key. Set X-HYDRA-KEY header."}
```
인증 없이 호출할 수 있습니다.
---
## 엔드포인트 목록
### 1. 헬스체크
#### `GET /health`
서버 상태를 확인합니다. **인증 불필요.**
```bash
curl http://127.0.0.1:8000/health
```
## 2. 시스템
**응답:**
```json
{"status": "ok"}
```
### `GET /status`
---
서버 프로필과 상태를 조회합니다.
### 2. 시스템
### `GET /modules`
#### `GET /status`
활성 모듈 상태를 조회합니다.
서버 프로필, 가동 시간 등 시스템 상태를 조회합니다.
## 3. 시장 관리
```bash
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/status
```
### `GET /markets`
#### `GET /modules`
현재 활성 시장 목록을 반환합니다.
각 모듈(수집기, 지표 엔진 등)의 활성 상태를 조회합니다.
### `POST /markets/{market_id}/enable`
```bash
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/modules
```
시장 활성화
---
예시:
### 3. 시장 관리
#### `GET /markets`
현재 설정된 시장 목록과 활성 상태를 반환합니다.
```bash
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/markets
```
**응답 예시:**
```json
[
{"market_id": "binance", "active": true, "mode": "paper"},
{"market_id": "upbit", "active": false, "mode": "paper"}
]
```
#### `POST /markets/{market_id}/enable`
시장을 활성화합니다.
```bash
curl -X POST \
-H "X-HYDRA-KEY: my-local-demo-key" \
-H "X-HYDRA-KEY: my-key" \
http://127.0.0.1:8000/markets/binance/enable
```
### `POST /markets/{market_id}/disable`
#### `POST /markets/{market_id}/disable`
시장 비활성화
시장 비활성화합니다.
## 4. 데이터
```bash
curl -X POST \
-H "X-HYDRA-KEY: my-key" \
http://127.0.0.1:8000/markets/binance/disable
```
### `GET /data/symbols`
---
### 4. 데이터
#### `GET /data/symbols`
수집 중이거나 저장된 시장/심볼/타임프레임 목록을 반환합니다.
### `GET /data/candles`
```bash
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/data/symbols
```
쿼리 파라미터:
**응답 예시:**
```json
[
{"market": "binance", "symbol": "BTC/USDT", "timeframe": "1h"},
{"market": "binance", "symbol": "ETH/USDT", "timeframe": "1h"}
]
```
- `market`
- `symbol`
- `timeframe`
- `limit` (기본 200, 최대 1000)
- `since` (선택)
#### `GET /data/candles`
예시:
OHLCV 캔들 데이터를 조회합니다.
**쿼리 파라미터:**
| 파라미터 | 필수 | 설명 | 예시 |
|---------|------|------|------|
| `market` | 필수 | 거래소 ID | `binance` |
| `symbol` | 필수 | 심볼 | `BTC/USDT` |
| `timeframe` | 필수 | 타임프레임 | `1h`, `4h`, `1d` |
| `limit` | 선택 | 캔들 수 (기본 200, 최대 1000) | `100` |
| `since` | 선택 | 시작 시간 (Unix ms) | `1704067200000` |
```bash
curl -G http://127.0.0.1:8000/data/candles \
-H "X-HYDRA-KEY: my-local-demo-key" \
-H "X-HYDRA-KEY: my-key" \
--data-urlencode "market=binance" \
--data-urlencode "symbol=BTC/USDT" \
--data-urlencode "timeframe=1h" \
--data-urlencode "limit=100"
```
## 5. 지표 / 레짐 / 시그널
### `GET /indicators`
### `GET /indicators/list`
### `GET /regime`
### `GET /regime/list`
### `GET /signal`
### `GET /signal/list`
이 엔드포인트들은 최신 계산 결과를 확인할 때 사용합니다.
## 6. 포지션 / 손익 / 리스크
### `GET /positions`
### `GET /pnl`
### `POST /pnl/reset-daily`
### `GET /risk`
### `POST /killswitch`
`POST /killswitch`는 매우 위험한 명령이므로 테스트 목적이 아니라면 호출하지 마세요.
예시:
```bash
curl -X POST "http://127.0.0.1:8000/killswitch?reason=manual_test" \
-H "X-HYDRA-KEY: my-local-demo-key"
**응답 예시:**
```json
[
{
"timestamp": 1704067200000,
"open": 42000.0,
"high": 42500.0,
"low": 41800.0,
"close": 42300.0,
"volume": 1234.56
}
]
```
## 7. 백테스트
---
### `POST /backtest/run`
### 5. 지표 / 레짐 / 시그널
요청 본문:
#### `GET /indicators`
가장 최근 계산된 지표 값을 반환합니다.
#### `GET /indicators/list`
계산 가능한 지표 목록을 반환합니다.
#### `GET /regime`
현재 시장 레짐(상태) 분류 결과를 반환합니다.
> 레짐 예시: `trending_up`, `trending_down`, `sideways`, `high_volatility`
#### `GET /regime/list`
레짐 히스토리 목록을 반환합니다.
#### `GET /signal`
가장 최근 전략 시그널을 반환합니다.
> 시그널 예시: `{"signal": "buy", "confidence": 0.72}`
#### `GET /signal/list`
시그널 히스토리 목록을 반환합니다.
```bash
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/indicators
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/regime
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/signal
```
---
### 6. 포지션 / 손익
#### `GET /positions`
현재 보유 포지션 목록을 반환합니다.
```bash
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/positions
```
**응답 예시:**
```json
[
{
"symbol": "BTC/USDT",
"side": "long",
"size": 0.01,
"entry_price": 42000.0,
"unrealized_pnl": 30.0
}
]
```
#### `GET /pnl`
누적 손익 정보를 반환합니다.
```bash
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/pnl
```
#### `POST /pnl/reset-daily`
일일 손익을 초기화합니다.
```bash
curl -X POST -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/pnl/reset-daily
```
---
### 7. 리스크 엔진
#### `GET /risk`
현재 리스크 상태(포지션 한도, 사용률 등)를 반환합니다.
```bash
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/risk
```
#### `POST /killswitch`
> **경고: 이 엔드포인트는 모든 포지션을 즉시 청산을 시도합니다. 신중하게 사용하세요.**
긴급 상황에서 전 포지션 청산을 트리거합니다.
```bash
curl -X POST "http://127.0.0.1:8000/killswitch?reason=emergency" \
-H "X-HYDRA-KEY: my-key"
```
**파라미터:**
- `reason` (선택): 청산 사유 메모 (로그에 기록됨)
---
### 8. 백테스트
#### `POST /backtest/run`
수집된 캔들 데이터를 기반으로 전략을 백테스트합니다.
**요청 본문:**
```json
{
@@ -122,33 +280,103 @@ curl -X POST "http://127.0.0.1:8000/killswitch?reason=manual_test" \
}
```
응답에는 아래 항목이 포함됩니다.
| 필드 | 필수 | 설명 |
|------|------|------|
| `market` | 필수 | 거래소 ID |
| `symbol` | 필수 | 심볼 |
| `timeframe` | 필수 | 타임프레임 |
| `since` | 필수 | 시작 시간 (Unix ms) |
| `until` | 필수 | 종료 시간 (Unix ms) |
| `initial_capital` | 선택 | 초기 자본 (기본 10000 USD) |
| `trade_amount_usd` | 선택 | 1회 거래 금액 (기본 100 USD) |
| `commission_pct` | 선택 | 수수료율 (기본 0.001 = 0.1%) |
- 시장 / 심볼 / 타임프레임
- 초기 자본 / 최종 자본
- 체결 트레이드 목록
- equity curve
- 성과 지표(`total_return_pct`, `total_trades`, `win_rate`, `max_drawdown_pct`, `sharpe_ratio`, `avg_pnl_usd`)
```bash
curl -X POST http://127.0.0.1:8000/backtest/run \
-H "Content-Type: application/json" \
-H "X-HYDRA-KEY: my-key" \
-d '{
"market": "binance",
"symbol": "BTC/USDT",
"timeframe": "1h",
"since": 1704067200000,
"until": 1706745600000,
"initial_capital": 10000,
"trade_amount_usd": 100,
"commission_pct": 0.001
}'
```
## 8. 보조 데이터
**응답 예시:**
```json
{
"market": "binance",
"symbol": "BTC/USDT",
"timeframe": "1h",
"initial_capital": 10000,
"final_capital": 10850.0,
"total_return_pct": 8.5,
"total_trades": 24,
"win_rate": 0.583,
"max_drawdown_pct": -4.2,
"sharpe_ratio": 1.35,
"avg_pnl_usd": 35.4,
"trades": [...],
"equity_curve": [...]
}
```
### `GET /orderbook`
### `GET /events`
### `GET /sentiment`
> **Unix timestamp 변환 팁:**
> - 2024-01-01 00:00:00 UTC → `1704067200000`
> - 2024-02-01 00:00:00 UTC → `1706745600000`
각 엔드포인트는 최근 오더북, 이벤트 일정, 감성 점수를 조회하는 데 사용합니다.
---
## 9. 인증 실패 시
### 9. 보조 데이터
- 잘못된 API 키: `403 Invalid API key`
- 내부 초기화 전 호출: `503 Store not initialized`
#### `GET /orderbook`
## 10. 권장 호출 순서
최근 수집된 오더북 스냅샷을 반환합니다.
1. `/health`
2. `/markets`
3. `/data/symbols`
4. `/data/candles`
5. `/backtest/run`
#### `GET /events`
실거래 관련 동작은 충분한 검증 이후에만 진행하세요.
수집된 크립토 이벤트 일정(상장, 하드포크 등)을 반환합니다.
#### `GET /sentiment`
감성 분석 점수를 반환합니다. (-1.0 = 매우 부정, +1.0 = 매우 긍정)
```bash
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/orderbook
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/events
curl -H "X-HYDRA-KEY: my-key" http://127.0.0.1:8000/sentiment
```
---
## 주요 HTTP 오류 코드
| 코드 | 의미 | 원인 |
|------|------|------|
| `403` | 인증 실패 | API 키 누락 또는 불일치 |
| `503` | 서비스 초기화 중 | 서버 기동 직후, 잠시 후 재시도 |
| `422` | 요청 형식 오류 | 필수 파라미터 누락 또는 타입 오류 |
| `500` | 서버 내부 오류 | 로그 확인 필요 |
---
## 권장 호출 순서
처음 사용할 때는 아래 순서로 호출해 각 단계가 정상인지 확인합니다.
```
1. GET /health → 서버 정상 확인
2. GET /markets → 시장 설정 확인
3. GET /data/symbols → 수집 데이터 확인
4. GET /data/candles → 캔들 데이터 조회
5. POST /backtest/run → 백테스트 실행
6. GET /positions → 포지션 확인
7. GET /pnl → 손익 확인
```
실거래 관련 동작은 충분한 검증(백테스트, paper 모드) 이후에만 진행하세요.

View File

@@ -1,116 +1,190 @@
# HYDRA Engine 빠른 시작 가이드
이 문서는 "처음 받은 사람이 10분 안에 테스트와 기본 실행까지 해보는 것"을 목표로 합니다.
**목표:** 이 문서를 따라하면 10~15분 안에 테스트 통과 및 서버 기동까지 완료할 수 있습니다.
## 1. 준비물
---
- Python 3.11 이상
- Git
- Docker / Docker Compose
## 2. 설치
## 1단계: 저장소 다운로드
```bash
git clone https://github.com/sinmb79/Hydra-Engine.git
cd Hydra-Engine
```
---
## 2단계: Python 가상환경 설정
```bash
python -m venv .venv
```
Windows PowerShell:
**Windows (PowerShell):**
```powershell
.venv\Scripts\Activate.ps1
```
패키지 설치:
**macOS / Linux:**
```bash
source .venv/bin/activate
```
터미널 앞에 `(.venv)` 가 표시되면 활성화 성공입니다.
```bash
pip install -e .[dev]
```
## 3. 환경 변수
---
## 3단계: 환경 변수 설정
**macOS / Linux:**
```bash
cp .env.example .env
```
최소 예시:
**Windows (PowerShell):**
```powershell
Copy-Item .env.example .env
```
`.env` 파일을 열고 `HYDRA_API_KEY` 를 변경합니다:
```env
HYDRA_API_KEY=my-local-demo-key
HYDRA_API_KEY=my-secret-key-2024
HYDRA_PROFILE=lite
REDIS_URL=redis://localhost:6379
```
## 4. 정상 동작 확인
> `HYDRA_API_KEY` 는 API 호출 시 사용하는 비밀번호입니다. 아무 문자열이나 가능합니다.
---
## 4단계: 테스트 실행
```bash
pytest -q
```
테스트가 모두 통과하면 기본 코드 상태 정상입니다.
전체 테스트가 통과하면 코드 상태 정상입니다.
## 5. Lite 프로필 실행
실패하는 테스트가 있으면:
- 가상환경이 활성화되어 있는지 확인
- `pip install -e .[dev]` 를 다시 실행
---
## 5단계: Docker로 서버 실행
Docker Desktop이 실행 중인지 먼저 확인합니다.
```bash
docker compose -f docker-compose.lite.yml up --build
```
다른 터미널에서 헬스체크:
터미널 창을 열고 헬스체크:
```bash
curl http://127.0.0.1:8000/health
```
## 6. 필수 API 예제
### 6.1 활성 시장 확인
```bash
curl -H "X-HYDRA-KEY: my-local-demo-key" http://127.0.0.1:8000/markets
```json
{"status": "ok"}
```
### 6.2 저장된 심볼 목록 확인
이 응답이 오면 서버가 정상 실행 중입니다.
---
## 6단계: 기본 API 호출 테스트
이후 모든 API 호출에는 `X-HYDRA-KEY` 헤더를 붙입니다.
### 시장 확인
```bash
curl -H "X-HYDRA-KEY: my-local-demo-key" http://127.0.0.1:8000/data/symbols
curl -H "X-HYDRA-KEY: my-secret-key-2024" \
http://127.0.0.1:8000/markets
```
### 6.3 백테스트 실행
### 저장된 심볼 목록
```bash
curl -H "X-HYDRA-KEY: my-secret-key-2024" \
http://127.0.0.1:8000/data/symbols
```
### 캔들 데이터 조회
```bash
curl -G http://127.0.0.1:8000/data/candles \
-H "X-HYDRA-KEY: my-secret-key-2024" \
--data-urlencode "market=binance" \
--data-urlencode "symbol=BTC/USDT" \
--data-urlencode "timeframe=1h" \
--data-urlencode "limit=50"
```
### 백테스트 실행
```bash
curl -X POST http://127.0.0.1:8000/backtest/run \
-H "Content-Type: application/json" \
-H "X-HYDRA-KEY: my-local-demo-key" \
-H "X-HYDRA-KEY: my-secret-key-2024" \
-d '{
"market": "binance",
"symbol": "BTC/USDT",
"timeframe": "1h",
"since": 1704067200000,
"until": 1706745600000
"until": 1706745600000,
"initial_capital": 10000,
"trade_amount_usd": 100,
"commission_pct": 0.001
}'
```
## 7. CLI 예제
---
```bash
python -m hydra.cli.app status
python -m hydra.cli.app market list-markets
python -m hydra.cli.app market enable binance --mode paper
python -m hydra.cli.app kill
## 7단계: 권장 사용 순서
```
테스트 통과 확인
시장 설정 확인 (GET /markets)
데이터 수집 상태 확인 (GET /data/symbols)
캔들 데이터 조회 (GET /data/candles)
백테스트 실행 (POST /backtest/run)
전략 성과 분석
(충분한 검증 후) 실거래 연결
```
## 8. 추천 사용 순서
---
1. 테스트 통과 확인
2. Lite 프로필 실행
3. 시장 설정 확인
4. 데이터 조회
5. 백테스트 실행
6. 전략/실거래 확장 여부 판단
## CLI 빠른 참조
## 9. 주의사항
```bash
python -m hydra.cli.app --help # 전체 도움말
python -m hydra.cli.app setup # 초기 설정 마법사
python -m hydra.cli.app status # 현재 상태
python -m hydra.cli.app market list-markets # 시장 목록
python -m hydra.cli.app market enable binance --mode paper # 모의거래 활성화
```
- 실거래 키를 넣기 전에 먼저 paper 모드로 확인하세요.
- API 키, 계정번호, 개인 설정은 `.env` 또는 로컬 전용 파일에만 저장하세요.
- FastAPI Swagger UI는 기본 비활성화 상태입니다. API 사용법은 `docs/API_REFERENCE_KO.md`를 참고하세요.
---
## 문제가 생겼을 때
| 증상 | 확인할 것 |
|------|----------|
| `ModuleNotFoundError` | 가상환경 활성화 여부, `pip install -e .[dev]` 재실행 |
| `403 Invalid API key` | `.env``HYDRA_API_KEY`와 헤더 값 일치 여부 |
| Redis 연결 오류 | Docker Desktop 실행 여부, `REDIS_URL` 설정 |
| 포트 8000 이미 사용 중 | 다른 프로세스 확인 후 종료 |
더 자세한 내용은 [README.md](../README.md) 의 FAQ 섹션을 참고하세요.

View File

@@ -1,4 +1,6 @@
import warnings
from functools import lru_cache
from pydantic import field_validator
from pydantic_settings import BaseSettings
@@ -13,6 +15,17 @@ class Settings(BaseSettings):
model_config = {"env_file": ".env", "env_file_encoding": "utf-8"}
@field_validator("hydra_api_key")
@classmethod
def api_key_must_not_be_default(cls, v: str) -> str:
if v == "change-me":
warnings.warn(
"[HYDRA] HYDRA_API_KEY가 기본값 'change-me'로 설정되어 있습니다. "
".env 파일에서 안전한 값으로 변경하세요.",
stacklevel=2,
)
return v
@lru_cache
def get_settings() -> Settings:

View File

@@ -48,53 +48,60 @@ async def lifespan(app: FastAPI):
configure_logging(settings.log_level)
logger.info("hydra_starting", profile=settings.hydra_profile)
r = redis_lib.Redis.from_url(settings.redis_url, decode_responses=True)
set_redis(r)
ohlcv_store = None
try:
r = redis_lib.Redis.from_url(settings.redis_url, decode_responses=True)
set_redis(r)
market_manager = MarketManager()
key_manager = KeyManager()
telegram = TelegramNotifier(settings.telegram_bot_token, settings.telegram_chat_id)
position_tracker = PositionTracker(r)
state_manager = StateManager(r)
risk_engine = RiskEngine(r, position_tracker)
pnl_tracker = PnlTracker(r)
ohlcv_store = create_store()
await ohlcv_store.init()
exchanges = create_exchanges(market_manager, key_manager)
market_manager = MarketManager()
key_manager = KeyManager()
telegram = TelegramNotifier(settings.telegram_bot_token, settings.telegram_chat_id)
position_tracker = PositionTracker(r)
state_manager = StateManager(r)
risk_engine = RiskEngine(r, position_tracker)
pnl_tracker = PnlTracker(r)
ohlcv_store = create_store()
await ohlcv_store.init()
exchanges = create_exchanges(market_manager, key_manager)
kill_switch = KillSwitch(
exchanges=exchanges,
position_tracker=position_tracker,
telegram=telegram,
redis_client=r,
)
order_queue = OrderQueue(
redis_client=r,
risk_engine=risk_engine,
position_tracker=position_tracker,
exchanges=exchanges,
)
graceful = GracefulManager(order_queue, position_tracker, r)
graceful.register_signals()
kill_switch = KillSwitch(
exchanges=exchanges,
position_tracker=position_tracker,
telegram=telegram,
redis_client=r,
)
order_queue = OrderQueue(
redis_client=r,
risk_engine=risk_engine,
position_tracker=position_tracker,
exchanges=exchanges,
)
graceful = GracefulManager(order_queue, position_tracker, r)
graceful.register_signals()
set_order_queue(order_queue)
set_position_tracker(position_tracker)
set_risk_deps(kill_switch, risk_engine)
set_market_manager(market_manager)
set_pnl_dependencies(pnl_tracker, position_tracker)
set_store(ohlcv_store)
set_redis_for_indicators(r)
set_redis_for_regime(r)
set_redis_for_signals(r)
set_redis_for_supplemental(r)
set_store_for_backtest(ohlcv_store)
set_order_queue(order_queue)
set_position_tracker(position_tracker)
set_risk_deps(kill_switch, risk_engine)
set_market_manager(market_manager)
set_pnl_dependencies(pnl_tracker, position_tracker)
set_store(ohlcv_store)
set_redis_for_indicators(r)
set_redis_for_regime(r)
set_redis_for_signals(r)
set_redis_for_supplemental(r)
set_store_for_backtest(ohlcv_store)
logger.info("hydra_started")
except Exception as exc:
logger.error("hydra_startup_failed", error=str(exc))
raise
logger.info("hydra_started")
try:
yield
finally:
logger.info("hydra_stopping")
await ohlcv_store.close()
if ohlcv_store is not None:
await ohlcv_store.close()
def create_app() -> FastAPI:
@@ -104,6 +111,13 @@ def create_app() -> FastAPI:
async def auth_guard(request: Request, call_next):
if request.url.path == "/health":
return await call_next(request)
from fastapi.responses import JSONResponse
api_key = request.headers.get("X-HYDRA-KEY", "")
if not api_key or api_key != get_settings().hydra_api_key:
return JSONResponse(
status_code=403,
content={"detail": "Invalid or missing API key. Set X-HYDRA-KEY header."},
)
return await call_next(request)
app.include_router(health.router)