# 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을 생성 가능 - 모든 경로가 재실행 시 중복 없이 안정 동작