User caught this directly: it's already 2026-07-12 in Korea, but Run #2008's release was tagged quant_20260711.3.7150737 -- the wrong date. Confirmed: UTC was still 2026-07-11 16:2x when KST was already 2026-07-12 01:2x (9-hour offset). prepare-release.yml computed TODAY via `TZ=UTC date +%Y%m%d`, which is only "correct" if the team operates on UTC -- but this project's production server logs, deployment cadence, and team are all Korea Standard Time. Any release cut between midnight and 9am KST would silently tag itself with yesterday's date. Fixed by using `TZ=Asia/Seoul date +%Y%m%d` instead.
Core/Satellite Collector v4
은퇴자산용 코어/위성 후보 데이터 수집기입니다.
v4 기본 정책
- 파라미터 없이 실행
- 1차 유니버스: KOSPI 160개 + KOSDAQ 40개
- 최종 후보: 100개
- 최종 후보 내 KOSDAQ: 최대 20개
- 1차 탐색 총량은 v3와 동일한 200개로 유지하여 호출 수 증가를 막습니다.
KIS 사용 가이드
이 저장소의 데이터 팩터 수집 기본 코어는 KIS Open API입니다.
- 실제계좌:
KIS_APP_Key,KIS_APP_Secret - 모의계좌:
KIS_APP_Key_TEST,KIS_APP_Secret_TEST - API 유효성 확인은 모의계좌 환경변수로 수행하고, 데이터 수집은 실제계좌 환경변수로 수행
- 사용 범위: 조회형
quotations/ranking계열만 사용 - 금지 범위: 주문, 정정, 취소, 잔고조회는 사용하지 않음
- 폴백 순서:
KIS -> Naver Finance -> Yahoo Finance -> OpenDART -> Investing.com(best-effort)
CI 스케줄러는 GatherTradingData.json을 seed snapshot으로 사용하고, read-only API로 보강한 뒤 SQLite에 누적 저장합니다.
코드는 저장 백엔드를 backend contract로 분리해 두었고, 지금은 SQLite만 실행하지만 향후 PostgreSQL로 옮겨도 수집기 호출부를 크게 바꾸지 않도록 해 둔 상태입니다.
설치
npm install
node core_satellite_collector.js
OpenDART 공시까지 확인하려면:
$env:DART_API_KEY="발급받은키"
node core_satellite_collector.js
SQLite 기반 데이터 수집을 실행하려면:
$env:KIS_APP_Key="실제계좌키"
$env:KIS_APP_Secret="실제계좌시크릿"
python tools/run_kis_data_collection_v1.py --input-json GatherTradingData.json --sqlite-db src/quant_engine/kis_data_collection.db --output-json Temp/kis_data_collection_v1.json --kis-account real
Snapshot admin web UI
엑셀처럼 settings와 account_snapshot를 편집하려면 웹 UI를 실행한다.
python tools/run_snapshot_admin_server_v1.py --host 127.0.0.1 --port 8787 --db src/quant_engine/snapshot_admin.db --seed GatherTradingData.json
핫 리로드로 띄우려면 python tools/run_snapshot_admin_server_v1.py --reload --host 127.0.0.1 --port 8787 --db src/quant_engine/snapshot_admin.db --seed GatherTradingData.json 또는 npm run ops:snapshot-web-watch를 사용한다.
기본 흐름은 다음과 같다.
GatherTradingData.json또는 기존 SQLite DB를 seed로 적재- 웹 화면에서
settings와account_snapshot을 검토/편집 - 저장 시 SQLite에 반영
- 필요하면
/api/export로 JSON을 내려받아 CI 또는 검증에 사용 - 변경 이력, 승인, 잠금, undo는 웹 화면의
Approval & Locks영역에서 관리 - 변경 검토용 승인 패킷은
Export approval packet버튼으로Temp/snapshot_admin_approval_packet_v1.json에 저장한다.
웹 UI 스모크 검증은 아래 명령으로 실행한다.
python tools/validate_snapshot_admin_web_v1.py
### Calibration backlog
보정 백로그와 change ledger를 다시 만들려면 아래 명령을 사용한다.
```powershell
python tools/build_calibration_priority_v1.py
python tools/build_calibration_change_ledger_v4.py
python tools/build_calibration_review_report_v1.py
python tools/build_calibration_approval_list_v1.py
python tools/validate_calibration_change_ledger_v1.py
Gitea 스케줄러에서는 .gitea/workflows/calibration_backlog.yml이 weekday 자동 갱신을 수행한다.
운영 표준
릴리즈와 패키징의 기준 진입점은 아래를 사용합니다.
npm run ops:release
릴리즈 DAG의 엄격 판정이 필요하면 아래를 사용합니다.
npm run full-gate
패키지 생성은 아래를 사용합니다.
npm run prepare-upload-zip
ops:release는 릴리즈 DAG 전체를 실행하고, 일부 warn_only 검증은 PASS_WITH_WARNINGS로 기록합니다.
full-gate와 validate-engine-strict는 엄격 모드로 동일한 릴리즈 DAG를 재검증합니다.
추가 스크립트:
npm run ops:packagenpm run ops:validatenpm run ops:buildnpm run ops:snapshot-web-validatenpm run render-report-jsonnpm run validate-proposal-referencenpm run validate-gas-call-arity
GAS 반영 체크리스트
proposal_reference_json을 실제 하네스 출력으로 승격하려면 아래 순서를 따릅니다.
- Apps Script에 최신 gas_harness_rows.gs 반영
- Apps Script에서
runHarnessRefresh_()실행 - Google Sheets
harness_context시트에 아래 키 생성 확인proposal_reference_jsonproposal_reference_lock
- 로컬에서
npm run ops:prepare실행 npm run ops:release실행npm run full-gate실행- 최종 운영 전환 시
npm run prepare-upload-zip로 패키지 생성 여부를 확인
CI 전환 체크리스트
python tools/run_kis_data_collection_v1.py또는npm run ops:data-collect로 SQLite 수집을 먼저 검증src/quant_engine/kis_data_collection.db에collection_runs/collection_snapshots가 생성되는지 확인- Gitea 스케줄러가
GatherTradingData.json을 seed로 읽는지 확인 GatherTradingData.xlsx의존성을 제거한 후에도 수집이 유지되는지 확인- 이후 PostgreSQL 업그레이드 시 동일 row contract를 유지
CI / 배포 분리
.gitea/workflows/ci.yml은 검증 전용이다..gitea/workflows/deploy-prod.yml은 실배포 전용이다.- 공개 URL
http://178.104.200.7/quant/갱신은 deploy workflow 성공 여부로 판단한다.
운영 리포트 계약
운영 리포트는 .NET canonical renderer가 사람이 읽는 Temp/operational_report.md와 기계 검증용 Temp/operational_report.json을 함께 생성합니다.
운영 상태와 legacy 분리는 DOTNET_RENDERER_OPERATING_STATUS.md에서 확인합니다.
src/dotnet/QuantEngine.Tools/Program.cs가 canonical 생성 경로입니다.npm run render-report-json도 같은 .NET 경로를 호출합니다.operational_report.json이 canonical 계약입니다.operational_report.md는 표시용 렌더입니다.Temp/missing_data_inventory_v1.json은DATA_MISSING섹션 분리 인벤토리입니다.- JSON 스키마는
schemas/operational_report.schema.json을 사용합니다. - 계약 드리프트 검사는
npm run validate-operational-report-contract로 수행합니다. - 전체 게이트에는
render-report-json -> validate-report-json -> validate-report-quality -> validate-report-sync순서가 포함됩니다.
전환 기준:
validate-proposal-reference결과와ops:release결과를 함께 봅니다.prepare-upload-zip가PASS_WITH_WARNINGS를 출력하면 warn_only 검증 이슈가 남아 있는 상태입니다.