# Milestone: Scheduled Market Data Refresh ## 위치 - Roadmap: `agent-roadmap/ROADMAP.md` - Phase: `agent-roadmap/phase/backtest-loop/PHASE.md` ## 목표 원격 서버에서 선택 universe의 market data import를 수동 scenario 실행에만 의존하지 않고 주기적으로 실행한다. 스케줄 tick은 provider 호출, DB upsert, freshness/gap 확인, backtest input readiness까지 headless 산출물로 남겨 운영자가 현재 데이터 상태를 확인할 수 있게 한다. ## 상태 [진행중] ## 승격 조건 - 없음 ## 구현 잠금 - 상태: 해제 - SDD: 필요 - SDD 문서: `agent-roadmap/sdd/backtest-loop/scheduled-market-data-refresh/SDD.md` - SDD 사유: 원격 scheduler가 외부 provider 호출, DB write, retry/idempotency, config/env, field smoke에 영향을 준다. - 잠금 해제 조건: 아래 체크리스트 - [x] SDD 잠금이 해제되어 있다. - [x] SDD 사용자 리뷰가 없거나 승인/해결되었다. - [x] Acceptance Scenario가 Milestone 기능 Task와 연결되어 있다. - [x] Evidence Map이 plan의 `Spec Targets`와 완료 시 `Spec Completion`으로 검증 가능하게 연결되어 있다. - 결정 필요: 없음 - 결정 반영: - D01: scheduler는 `services/worker` 내장 loop가 1차 실행 주체다. - OS/systemd는 worker process supervision만 맡고, external cron은 사용하지 않는다. - worker scheduler는 설정된 한도 안에서 병렬 수집을 지원해야 한다. ## 범위 - 원격 worker/API runtime 위에서 실행할 scheduled market data refresh 경계. 일정 판단과 상태 관리는 worker 내부에 둔다. - named universe별 provider, selector, timeframe, cadence, timezone, backfill window, parallelism limit 설정 - 스케줄 tick마다 `import_daily_bars` 또는 후속 import action을 실행하고 DB upsert idempotency를 유지하는 흐름 - tick 안에서 여러 수집 작업을 설정된 한도 안에서 병렬 실행하는 흐름 - provider 지연, 결측, gap, duplicate 상태를 freshness/readiness 결과로 남기는 확인 표면 - remote runner에서 migration, runtime startup, scheduler tick, freshness query, backtest input selector를 검증하는 headless smoke ## 기능 ### Epic: [schedule] Scheduled refresh orchestration 원격 서버에서 선택 universe import를 주기 실행하고, 재시작/중복 실행에도 DB 상태가 안정적으로 유지되게 한다. - [x] [schedule-config] named universe별 provider, selector, timeframe, cadence, timezone, backfill window, parallelism limit를 선언하고 validate/dry-run에서 지원하지 않는 provider/timeframe 조합을 거부한다. 검증: schedule config validate가 next window와 rejected combination을 text/JSONL로 출력한다. - [x] [scheduled-runner] 원격 worker runtime에서 내장 scheduler tick이 market data import job을 실행하고, 병렬 수집과 재시작 또는 tick 중복에도 같은 bar key를 중복 저장하지 않는다. 검증: worker scheduler tick 2회 실행 후 병렬 item별 result와 `bars` key 중복 없는 freshness/readiness 출력이 남는다. - [x] [retry-backfill] provider 지연, 결측, gap 결과에 따라 retry와 backfill window를 계산하고 실패를 stale/error 상태로 남긴다. 검증: fixture 또는 local smoke에서 missing/gap/provider delay 케이스가 stable text/JSONL로 구분된다. ### Epic: [handoff] Headless readiness handoff 스케줄 결과를 운영자가 화면 없이 확인하고, backtest selector가 주기 적재 데이터를 사용할 수 있게 한다. - [ ] [refresh-status] last_success, last_error, next_run, imported bar count, missing/gap/duplicate/provider_delay 상태를 CLI/JSONL로 확인할 수 있게 한다. 검증: status scenario가 success, stale, error 케이스를 구분한다. - [ ] [backtest-readiness] scheduler가 적재한 데이터에서 backtest input selector와 result scenario가 실행될 수 있음을 원격 smoke로 검증한다. 검증: remote runner에서 scheduler tick 이후 backtest matrix 또는 result summary scenario가 exit code `0`을 기록한다. ## 완료 리뷰 - 상태: 없음 - 요청일: 없음 - 완료 근거: 없음 - 리뷰 필요: - [ ] 사용자가 완료 결과를 확인했다 - [ ] archive 이동을 승인했다 - 리뷰 코멘트: 없음 ## 범위 제외 - Flutter 운영 화면 구현 - 새 strategy 판단 로직 또는 투자 의사결정 알고리즘 설계 - paper/live order routing과 실거래 adapter 변경 - 월봉/분봉 provider import와 backtest engine 지원 확장 전체. 현재 scheduler는 지원되는 import/backtest timeframe을 주기 실행 대상으로 삼고, 월봉/분봉 확대는 `Backtest Multi-Timeframe Coverage`에서 다룬다. - 외부 provider credential 값이나 개인 secret 문서화 ## 작업 컨텍스트 - 관련 경로: `services/worker/`, `services/api/`, `apps/cli/`, `packages/contracts/`, `packages/domain/`, `deployments/local/`, `agent-test/local/` - 표준선(선택): 운영 기능은 먼저 화면 없이 CLI, YAML scenario, JSONL/text output, fixture, remote smoke로 검증한다. - 표준선(선택): scheduled import는 provider 호출과 DB upsert를 idempotent하게 유지하고, 동일 tick 재실행이 중복 row를 만들지 않아야 한다. - 표준선(선택): scheduler config에는 secret 값을 넣지 않고, 원격 runtime env/SOPS 주입 경계를 따른다. - 선행 작업: Backtest Data Collection Infrastructure, Backtest Scenario Automation, Backtest Multi-Timeframe Coverage - 후속 작업: Data Quality Monitoring 후보 - 결정: scheduler는 `services/worker` 내장 loop가 1차 실행 주체다. OS/systemd는 worker process supervision만 맡고 external cron은 사용하지 않는다. worker scheduler는 설정된 한도 안에서 병렬 수집을 지원해야 한다.