P1 데이터 자산화

의존: 없음 (선행 페이즈). 베이스 브랜치 main.

[WEALTH-P1-01] daily_prices 스키마 + DailyPrice 도메인

작업 내용 (설계 의도)

수년치 일봉 OHLCV를 시계열로 영속화하는 기반을 만든다. DailyPrice를 Rich Domain Entity로 두고, (symbol, trade_date) unique로 멱등 적재를 보장한다. 룩어헤드 방지 불변식(미래 날짜 거부)을 Entity에 캡슐화한다.

롤백: 마이그레이션 실패 시 역방향 DDL로 daily_prices 테이블 제거.

다이어그램

클래스 의존

flowchart LR
    Entity[DailyPrice] --> Repo[PriceHistoryRepository]
    Repo -.->|implements| Impl[PriceHistoryRepositoryImpl]
    Impl --> Table[(daily_prices)]

테스트 케이스

  • 동일 (symbol, trade_date) 재적재 시 멱등하게 upsert된다.
  • close > high 또는 low > close인 일봉은 생성 시 거부된다.
  • 미래 날짜(trade_date > 오늘) 일봉은 거부된다.
  • TestContainers MySQL에 저장 후 (symbol, 기간)으로 오름차순 조회된다.

[WEALTH-P1-02] 과거 일봉 백필 Gateway + UseCase

작업 내용 (설계 의도)

외부 소스(토스/증권사)에서 종목별 과거 N년 일봉을 수집하는 PriceBackfillGateway(domain interface)와 BackfillPriceHistoryUseCase를 만든다. 소스가 제공하는 최대 기간을 페이지네이션으로 끌어와 daily_prices에 적재한다. 부분 실패(일부 종목)는 허용하고 로그로 남긴다.

롤백: 백필은 멱등하므로 재실행으로 복구. 잘못 적재 시 기간 기준 delete.

다이어그램

처리 흐름

sequenceDiagram
    participant UC as BackfillPriceHistoryUseCase
    participant Gw as PriceBackfillGateway
    participant Repo as PriceHistoryRepository
    UC->>Gw: fetchDailyCandles(symbol, years)
    Gw-->>UC: 과거 일봉 리스트
    UC->>Repo: saveAll(dailyPrices)

테스트 케이스

  • 3년치 일봉을 수집해 daily_prices에 적재한다.
  • 외부 소스가 5xx를 반환하면 PriceBackfillException을 던진다.
  • 일부 종목 수집 실패 시 나머지 종목은 정상 적재된다(부분 실패 허용).
  • 동일 종목 재백필 시 중복 없이 멱등 처리된다.

[WEALTH-P1-03] 수급·재무 시계열 연계 (선택)

작업 내용 (설계 의도)

기존 marketflow(네이버 수급)·OpenDART(재무) 소스를 daily_prices와 같은 시점 기준으로 시계열 정렬해 백테스트 입력으로 합칠 수 있게 한다. 신규 수집이 아니라 기존 적재분의 시계열 조인 관점 정리다.

테스트 케이스

  • 특정 종목·날짜로 OHLCV·수급·재무가 같은 trade_date 기준으로 조회된다.
  • 수급·재무가 없는 날짜는 가격만 반환된다(부분 결측 허용).