feat(tests): 신규 키움 웹소켓 조건검색 및 실시간 조건검색 테스트 추가

변경 사항
----
- _test_kiwoom_condition_list.py: 키움 웹소켓 조건검색 '목록조회' 기능을 단독으로 테스트하는 스크립트 추가
- _test_kiwoom_condition_realtime.py: 'momentum' 조건식을 실시간으로 등록하고 초기 매칭 종목 리스트 및 실시간 편입/이탈을 수신하는 테스트 스크립트 추가
- _verify_columnar_bitid.py, _verify_shared_e2e_breakout.py, _verify_shared_e2e.py: 공유 메모리 및 dict 간의 데이터 일관성을 검증하는 테스트 추가

영향
----
- 신규 테스트 스크립트 추가로 키움 웹소켓 API의 기능 검증 및 안정성을 높임
- 기존 기능에 대한 영향 없음

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-06 01:27:00 +09:00
parent d8ba01afa4
commit 61c72a8a4c
171 changed files with 176914 additions and 7329 deletions

View File

@@ -58,10 +58,13 @@ class WSPriceValidator:
kis_ws, # kis_ws.KISWebSocketPriceCache 인스턴스
kiwoom_ws, # kiwoom_ws.KiwoomWebSocketPriceCache 인스턴스
db, # database.TradeDB
sync_kiwoom_to_kis: bool = True,
):
self.kis_ws = kis_ws
self.kiwoom_ws = kiwoom_ws
self.db = db
# WS_SUBSCRIBE_KIS_MINIMAL 시 키움 구독은 WSManager 가 전담 → 여기서 REMOVE 금지
self._sync_kiwoom_to_kis = bool(sync_kiwoom_to_kis)
self._thread: Optional[threading.Thread] = None
self._running = False
@@ -102,6 +105,13 @@ class WSPriceValidator:
except AttributeError:
return set()
def _kiwoom_subscribed(self) -> Set[str]:
try:
with self.kiwoom_ws._sub_lock: # type: ignore[attr-defined]
return set(self.kiwoom_ws._subscribed) # type: ignore[attr-defined]
except AttributeError:
return set()
def _sync_kiwoom_subscriptions(self, target: Set[str]) -> None:
"""키움 WS 구독 = KIS WS 구독 으로 맞춤."""
try:
@@ -131,12 +141,16 @@ class WSPriceValidator:
def _tick(self) -> None:
"""1회 비교."""
codes = self._kis_subscribed()
if not codes:
return
# 키움 WS 구독 동기화 (구독 안 된 종목은 데이터 없으니 의미 없음)
self._sync_kiwoom_subscriptions(codes)
kis_codes = self._kis_subscribed()
if self._sync_kiwoom_to_kis:
if not kis_codes:
return
self._sync_kiwoom_subscriptions(kis_codes)
codes = kis_codes
else:
codes = kis_codes | self._kiwoom_subscribed()
if not codes:
return
# 키움 WS 연결되어 있어야 의미 있음. 미연결이면 한쪽만 기록.
kiwoom_ready = self.kiwoom_ws.is_connected()