fix(시세): LS spill-only·토큰 파일캐시·호가 snap_time 3초컷

- _feed_fallback 미러 OFF, LS cap/grace/hold RAM을 KIS·키움 spill과 정합
- LS 접근토큰 .ls_token_cache_*.json (재시작 재사용, revoke 루프 없음)
- 호가 RAM을 틱과 동일 LIVE_FEED_FALLBACK(snap_time)로 컷, 필터 max_age=0은 유지
- 익절 지정가 로그에 실제 호가 벤더(kis/kiwoom/ls 1·2·3차) 표기

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Your Name
2026-08-27 15:21:21 +09:00
parent ba2f9f0953
commit 5e44b86f8b
24 changed files with 1923 additions and 203 deletions

View File

@@ -1159,8 +1159,9 @@ class TradingOrchestrator:
self._ls_perm_ttl = float(get_env_int("PERM_SUB_UI_REFRESH_SEC", 15))
def _on_tick(code: str, payload: dict) -> None:
# 1) LS 전용 테이블 — 틱은 영구구독 enabled 만 (후보 틱 DB OFF)
if get_env_bool("LS_WS_TICK_SAVE", False) and self._ls_should_persist(code):
# 1) LS 전용 테이블 — 호가와 동일: 구독 중이면 적재 (영구만이 아님).
# 봉·VI 는 아래 _ls_should_persist(영구) 유지.
if get_env_bool("LS_WS_TICK_SAVE", False) and self._ls_is_subscribed(code):
self.db.insert_ls_ws_tick(
code=code,
ts=payload.get("ts"),
@@ -1289,7 +1290,7 @@ class TradingOrchestrator:
self.ls_ws_validator = None
def _ls_should_persist(self, code: str) -> bool:
"""LS DB 적재: 영구구독 enabled 코드만 (마스터와 무관, 행 기준)."""
"""LS 봉·VI DB: 영구구독 enabled 코드만 (마스터와 무관, 행 기준)."""
now = time.time()
ttl = float(getattr(self, "_ls_perm_ttl", 15.0) or 15.0)
if now - float(getattr(self, "_ls_perm_codes_ts", 0) or 0) >= ttl:
@@ -1302,10 +1303,8 @@ class TradingOrchestrator:
from permanent_subs import should_persist_ls
return should_persist_ls(code, getattr(self, "_ls_perm_codes", set()))
def _ls_should_persist_orderbook(self, code: str) -> bool:
"""LS 호가 DB: 구독 중인 종목 (영구∪폴백 유니버스). 틱/봉과 게이트 분리."""
if not get_env_bool("LS_WS_ORDERBOOK_SAVE", True):
return False
def _ls_is_subscribed(self, code: str) -> bool:
"""LS WS 구독 중인 (영구∪폴백 유니버스). 틱/호가 DB 공통 게이트."""
c = str(code or "").strip()
if not c:
return False
@@ -1318,6 +1317,12 @@ class TradingOrchestrator:
except Exception:
return False
def _ls_should_persist_orderbook(self, code: str) -> bool:
"""LS 호가 DB: SAVE ON 이고 구독 중. 봉/VI(영구)와 분리."""
if not get_env_bool("LS_WS_ORDERBOOK_SAVE", True):
return False
return self._ls_is_subscribed(code)
def _maybe_save_ls_orderbook_on_tick(self, code: str, payload: dict) -> None:
"""LS 체결 1건당 호가 RAM 스냅 1장 → ls_ws_orderbook (틱 동기).