You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

290 lines
6.6 KiB
Markdown

# Phase 1 아키텍처 및 저장소 구조 계획
## 1. 설계 원칙
이 프로젝트는 무료 데이터 기반의 미국 주식 이벤트 스윙 시스템입니다.
Phase 1의 핵심 원칙은 다음과 같습니다.
1. **원문(raw)을 절대 버리지 않는다.**
2. **운영 상태(PostgreSQL)와 연구용 시계열(DuckDB/Parquet)을 분리한다.**
3. **모든 adapter는 idempotent 해야 한다.**
4. **LLM은 규칙 기반 파서를 대체하지 않고 보강한다.**
5. **실패 시 no-trade/no-write가 기본값이다.**
6. **모든 서비스는 독립적으로 재실행 가능해야 한다.**
7. **표준화된 event/document identifier 없이는 downstream으로 보내지 않는다.**
## 2. 권장 저장소 구조
```text
repo/
apps/
collector/
sec_collector/
alpaca_collector/
fred_collector/
finra_collector/
parser/
filing_parser/
xbrl_parser/
event_parser/
feature_builder/
market_features/
event_features/
backtester/
live_trader/
libs/
adapters/
sec/
alpaca/
fred/
finra/
common/
config.py
logging.py
time_utils.py
ids.py
retries.py
file_store.py
db/
models.py
migrations/
schemas/
parser_event.schema.json
source_record.schema.json
llm/
prompts/
validator.py
cache.py
tests/
unit/
integration/
replay/
fixtures/
configs/
app.yaml
env.example
symbols.yaml
data/
raw/
staging/
parquet/
docs/
```
## 3. 실행 단위
초기에는 서비스별 독립 실행 파일로 둡니다.
- `python -m apps.collector.sec_collector.main`
- `python -m apps.collector.alpaca_collector.main`
- `python -m apps.parser.event_parser.main`
- `python -m apps.feature_builder.market_features.main`
초기에는 큐 시스템을 도입하지 않고, **명시적 스케줄 실행**을 사용합니다.
큐는 Phase 3 이후 필요 시 Redis/Celery 또는 경량 작업 큐를 검토합니다.
## 4. 저장 계층
### 4.1 Raw Zone
원문을 그대로 저장합니다.
경로 예시:
```text
data/raw/sec/2026-03-12/{cik}/{accession}/index.json
data/raw/sec/2026-03-12/{cik}/{accession}/filing.txt
data/raw/sec/2026-03-12/{cik}/{accession}/exhibit_99_1.html
data/raw/alpaca/bars/daily/2026-03-12/{symbol}.json
data/raw/fred/2026-03-12/{series_id}.json
data/raw/finra/2026-03-12/daily_short_sale_volume.txt
```
원칙:
- 원문은 수정하지 않습니다.
- 적재 시 수집 메타데이터를 sidecar JSON으로 함께 저장합니다.
- raw 저장 성공 전에는 structured write를 하지 않습니다.
### 4.2 Staging Zone
파싱 전 정규화 중간 결과를 저장합니다.
예:
- HTML → text 추출
- filing metadata
- extracted exhibit list
- temporary parsed items
### 4.3 Structured Zone
운영용 PostgreSQL + 연구용 Parquet로 저장합니다.
PostgreSQL:
- job 상태
- 문서 메타
- 이벤트 레코드
- parser 결과
- feature snapshot
- 주문/포지션 상태
Parquet/DuckDB:
- 바 시계열
- 대량 feature matrix
- 라벨링 데이터
- 실험/백테스트 산출물
## 5. 모듈 경계
### 5.1 Source Adapter
역할:
- 외부 원천에서 raw 데이터를 수집
- 최소 메타데이터 부착
- raw 저장
- source checksum 생성
금지:
- 전략 판단
- event scoring
- 트레이드 신호 생성
### 5.2 Normalizer
역할:
- raw를 내부 공통 포맷으로 정규화
- source-specific field를 canonical field로 변환
예:
- SEC accession → internal document_id
- Alpaca bar payload → canonical OHLCV schema
### 5.3 Parser
역할:
- 문서 기반 구조화
- 규칙 기반 이벤트 탐지
- 선택적으로 LLM 보강
### 5.4 Feature Builder
역할:
- 이벤트 특징 생성
- 시장 특징 생성
- 레짐 특징 생성
- attention 특징 생성(Phase 1에서는 인터페이스만)
### 5.5 Ranker
Phase 1에서는 실제 점수 산출보다 **입력 포맷 정의**까지만 합니다.
### 5.6 Execution Layer
Phase 1에서는 주문 실행을 하지 않고, **order_plan schema**만 정의합니다.
## 6. 공통 식별자 규칙
### 6.1 symbol_master_id
- 내부 고유 종목 식별자
- v1에서는 `ticker + venue + start_date` 조합 허용
### 6.2 document_id
형식:
```text
DOC::{source}::{issuer_id}::{event_date}::{accession_or_hash}
```
예:
```text
DOC::SEC::0000789019::2026-01-28::0001193125-26-027198
```
### 6.3 event_id
형식:
```text
EVT::{issuer_id}::{event_type}::{primary_document_id}
```
### 6.4 job_run_id
UUID 사용
## 7. 시간/달력 정책
- 내부 표준 타임존은 **UTC 저장 + US/Eastern 파생 컬럼**입니다.
- 거래일 계산은 반드시 거래소 달력을 사용합니다.
- raw 수집 시각, source published 시각, parsed event 시각을 구분합니다.
- `filed_at`, `accepted_at`, `collected_at`, `normalized_at`, `parsed_at` 필드를 각각 유지합니다.
## 8. 환경 변수 정책
필수 환경 변수 예시:
```text
APP_ENV=dev
POSTGRES_DSN=postgresql://...
DUCKDB_PATH=/app/data/parquet/research.duckdb
DATA_ROOT=/app/data
ALPACA_API_KEY=...
ALPACA_SECRET_KEY=...
FRED_API_KEY=...
OPENAI_API_KEY=...
LOG_LEVEL=INFO
SEC_USER_AGENT=project-name contact-email
```
원칙:
- 민감정보는 코드/문서에 하드코딩 금지
- `.env`는 로컬 전용, 배포에는 secret 주입 사용
- example 파일에는 placeholder만 포함
## 9. Docker Compose 기본 구성
서비스:
- `postgres`
- `app` (개발용 Python image)
- 필요 시 `adminer` 또는 경량 DB UI
초기에는 메시지 큐/오브젝트 스토리지는 넣지 않습니다.
## 10. 로그와 메트릭 정책
모든 서비스는 JSON log를 기본으로 합니다.
필수 필드:
- timestamp
- level
- service
- job_run_id
- source
- entity_id
- message
- error_class
- retry_count
메트릭 예시:
- source fetch count
- source fetch latency
- normalized record count
- parser success/fail count
- schema validation fail count
- duplicate skip count
## 11. 장애 처리 원칙
- raw 수집 실패 → structured write 금지
- schema validation 실패 → parser 결과 폐기, 원문은 유지
- DB write 실패 → retry 후 stop
- 외부 API rate limit → backoff
- 알 수 없는 필드 추가 → warning + raw 보존
## 12. Phase 1 수용 기준
- 로컬에서 `make bootstrap` 수준 명령으로 개발 환경 구축 가능
- sample SEC filing을 1회 수집 후 raw/staging/structured에 적재 가능
- sample Alpaca bar 데이터를 canonical schema로 변환 가능
- sample FRED/FINRA 데이터를 일자별로 적재 가능
- parser가 schema-valid JSON을 생성 가능
- 모든 경로가 재실행 시 중복 없이 안정 동작