b572758682
## 동작 변경 이전: 알림 스레드가 사용자 dropdown 선택 1개 시간봉만 polling. 이후: [1m, 3m, 5m, 15m, 30m, 1h] 6개 시간봉을 매 cycle 마다 순회 polling. 같은 신호가 여러 시간봉에서 발화하면 각 시간봉별로 독립 알림 (dedup 도 interval 별로 분리). ## 상태 구조 변경 (alert_state.py) - last_alert : dict[(interval, key)] -> timestamp - last_fired_candle : dict[(interval, key)] -> candle_time - long_entry / short_entry : dict[interval] -> entry_record (TF 별로 진입 추적, 손절가 검증도 TF 별) ## 신호 정의는 변경 없음 OI 필터(oi_up / oi_up_2 / oi_down_2) 모두 원복 — 신호 정의는 의도된 대로 유지. "OI 하락 + 가격 하락 = 롱 청산" 케이스는 시스템 설계상 vol_short/strong_short 가 안 잡는 것이 정상 (별도 신호 추가 시 더 정밀한 분리 가능, 이번 변경에는 불포함). ## API 호출 부담 6 TF × ~4 endpoint per cycle = 24 calls / 30s = 48 calls/min. Binance futures 1200/min limit 대비 4% 사용 — 안전. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
37 lines
1.5 KiB
Python
37 lines
1.5 KiB
Python
"""
|
|
Streamlit 의 매 rerun 마다 메인 스크립트는 새 namespace 에서 재실행되어
|
|
모듈 최상단의 mutable state 가 모두 초기화된다 (`globals()` 가드도 우회됨).
|
|
|
|
이 파일은 별도 모듈로 단 한 번만 import 되므로 (Python 의 sys.modules 캐싱)
|
|
state 가 process lifetime 동안 보존된다. 알림 dedup, 진입 추적, 스레드
|
|
기동 가드 등 다중 rerun 환경에서 살아남아야 하는 모든 mutable 상태는
|
|
여기에 둔다.
|
|
|
|
알림 스레드는 multi-TF (1m/3m/5m/15m/30m/1h) 동시 모니터링 모드라
|
|
dedup 과 진입 추적은 모두 (interval, key) 또는 interval 별로 분리된다.
|
|
"""
|
|
import threading
|
|
|
|
# (interval, key) 별 마지막 알림 시각 (cooldown 용). default 0.
|
|
# 키가 없으면 dict.get 으로 0 fallback.
|
|
last_alert = {}
|
|
|
|
# (interval, key) 별 마지막으로 알림 보낸 candle open_time (per-candle dedup).
|
|
last_fired_candle = {}
|
|
|
|
# interval 별 진입 추적. value = entry_record dict 또는 None.
|
|
long_entry = {}
|
|
short_entry = {}
|
|
|
|
# forming candle 에서 발사된 알림은 캔들 마감 후 신호 재검증을 받는다.
|
|
# 마감 시점에 신호가 사라졌으면 [취소 알림] 을 보낸다.
|
|
# 항목 형식: {"interval", "direction", "candle_time", "msg", "sig_cols"}
|
|
pending_groups = []
|
|
|
|
alert_symbol = "BTCUSDT"
|
|
alert_interval = "5m" # UI 표시용; 알림 스레드는 multi-TF 모니터링이라 무시
|
|
alert_lock = threading.Lock()
|
|
alert_started = False
|
|
daily_report_started = False
|
|
last_report_date = None
|