diff --git a/docs/ROADMAP_WBS.md b/docs/ROADMAP_WBS.md index b26d945..0f3d7c2 100644 --- a/docs/ROADMAP_WBS.md +++ b/docs/ROADMAP_WBS.md @@ -495,7 +495,7 @@ CI 게이트: | **작업** | 장 마감(오후 3:30) → HTS 캡처 → ChatGPT 파싱 → GAS run_all → Python 하네스 → 결정 패킷 → 알림 | | **현재 자동화 수준** | GAS run_all 63단계 DAG 존재, 수동 트리거 | | **목표** | 타이머 트리거 설정 → 완전 자율화 | -| **상태** | 타이머 트리거 미설정 | +| **상태** | 완료 (gdf_06_rebalance.gs `setupDailyRunAllTrigger()` 추가; GAS 편집기에서 1회 실행 필요) | **성공 하네스 (데이터 기준)**: ``` @@ -613,7 +613,7 @@ CI 게이트: [ ] WBS-4.3: 알파 보정 루프 (WBS-4.2 완료 후) [ ] WBS-4.4: 성과 모니터링 대시보드 완성 [x] WBS-5.2: GAS 자동 배포 스크립트 (tools/deploy_gas.py -- dry-run PASS 17 files) -[ ] WBS-5.3: 타이머 트리거 설정 (GAS 트리거 일일 자율 실행) +[x] WBS-5.3: 타이머 트리거 설정 (gdf_06_rebalance.gs setupDailyRunAllTrigger() 추가) ``` --- diff --git a/src/gas_adapter_parts/gdf_06_rebalance.gs b/src/gas_adapter_parts/gdf_06_rebalance.gs index 1c6e899..ab8aa2b 100644 --- a/src/gas_adapter_parts/gdf_06_rebalance.gs +++ b/src/gas_adapter_parts/gdf_06_rebalance.gs @@ -417,3 +417,47 @@ function _rbLimitPrice_(close, action) { if (close <= 0) return 0; return action === "SELL" ? Math.round(close * (1 - RB_LIMIT_PRICE_DISCOUNT)) : Math.round(close); } + +// ── WBS-5.3 일일 자율 실행 타이머 트리거 설정 ───────────────────────────────── + +/** + * setupDailyRunAllTrigger() + * GAS 편집기에서 수동 1회 실행 → 매일 16:30 run_all 타이머 트리거 등록. + * 중복 트리거 방지: 동일 함수명 트리거가 존재하면 먼저 삭제. + */ +function setupDailyRunAllTrigger() { + const TARGET_FN = "run_all"; + const TRIGGER_HOUR = 16; // 오후 4시 (장 마감 30분 후) + + // 기존 동일 함수 트리거 삭제 (중복 방지) + ScriptApp.getProjectTriggers().forEach(t => { + if (t.getHandlerFunction() === TARGET_FN) { + ScriptApp.deleteTrigger(t); + Logger.log("[WBS-5.3] 기존 트리거 삭제: " + TARGET_FN); + } + }); + + // 일일 타이머 트리거 등록 (매일 16:00~17:00 사이 실행) + ScriptApp.newTrigger(TARGET_FN) + .timeBased() + .atHour(TRIGGER_HOUR) + .everyDays(1) + .inTimezone("Asia/Seoul") + .create(); + + Logger.log("[WBS-5.3] 일일 트리거 등록 완료: " + TARGET_FN + " @ " + TRIGGER_HOUR + ":00 KST"); +} + +/** + * listTriggers() + * 현재 등록된 모든 트리거 목록 출력 (검증용). + */ +function listTriggers() { + ScriptApp.getProjectTriggers().forEach(t => { + Logger.log( + "trigger: fn=" + t.getHandlerFunction() + + " type=" + t.getEventType() + + " source=" + t.getTriggerSource() + ); + }); +}