""" WLD(월드코인) 실시간 모니터 — BB·일목·04 매칭 규칙 알림 (자동 매매 없음). """ from __future__ import annotations from datetime import datetime import time from config import COIN_NAME, MONITOR_ALERT_COOLDOWN_MIN, MONITOR_LOOP_SLEEP_SEC, SYMBOL from deepcoin.matching.live_eval import evaluate_live_rules from deepcoin.matching.load_rules import load_monitor_rules from deepcoin.ops.alert_message import build_rule_alert_message from deepcoin.ops.monitor import Monitor class MonitorCoin(Monitor): """WLD 시장 상태·매칭 규칙 주기 출력.""" def __init__(self, cooldown_file: str | None = None, *, check_rules: bool = True) -> None: """ Args: cooldown_file: 매매 쿨다운 JSON 경로. check_rules: True면 04 active_rules 평가·알림. """ super().__init__(cooldown_file=cooldown_file) self.check_rules = check_rules self._last_alert_unix: dict[str, float] = {} def monitor_wld(self) -> None: """전 봉 BB·일목·추세 및 규칙 발화를 출력합니다.""" from deepcoin.data.ops_sync import ensure_ops_candles ensure_ops_candles() print( "[{}] {} ({})".format( datetime.now().strftime("%Y-%m-%d %H:%M:%S"), COIN_NAME, SYMBOL, ) ) self.process_wld_market_status(SYMBOL) if self.check_rules: self._check_matched_rules() def _check_matched_rules(self) -> None: """04 monitor_rules 최신 봉 평가 후 쿨다운 내 중복 알림 방지.""" rules = load_monitor_rules() if not rules: print(" [04 규칙] monitor_rules 없음 — scripts/04_match_rules.py 실행") return try: fired = evaluate_live_rules(rules) except Exception as exc: print(f" [04 규칙] 평가 오류: {exc}") return if not fired: print(f" [04 규칙] 발화 없음 (감시 {len(rules)}개)") return balances: dict | None = None try: balances = self.load_balances_dict() except Exception: balances = None cooldown_sec = MONITOR_ALERT_COOLDOWN_MIN * 60 now = time.time() for hit in fired: rid = hit["rule_id"] preview = build_rule_alert_message(hit, balances).replace("\n", " | ") print(f" [04] {preview}") last = self._last_alert_unix.get(rid, 0.0) if now - last < cooldown_sec: print(f" [04] 쿨다운 skip {rid} ({MONITOR_ALERT_COOLDOWN_MIN}분)") continue self._last_alert_unix[rid] = now self._send_coin_msg(build_rule_alert_message(hit, balances)) def run_schedule(self) -> None: """MONITOR_LOOP_SLEEP_SEC 간격으로 상태를 출력합니다.""" rules = load_monitor_rules() names = ", ".join(r["rule_id"] for r in rules) or "(없음)" print( f"05 모니터 시작 · 감시 {len(rules)}개 ({names}) · " f"주기 {MONITOR_LOOP_SLEEP_SEC}초 · 알림쿨다운 {MONITOR_ALERT_COOLDOWN_MIN}분" ) while True: self.monitor_wld() time.sleep(MONITOR_LOOP_SLEEP_SEC) if __name__ == "__main__": MonitorCoin(cooldown_file=None).run_schedule()