auto: 일일 백업 2026-06-28 02:00
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -672,9 +672,13 @@ def _fetch_quotes_batch(entries: list[dict]) -> list[dict]:
|
|||||||
if not miss_codes:
|
if not miss_codes:
|
||||||
return cards
|
return cards
|
||||||
|
|
||||||
|
nxt_probe_codes = list(miss_codes)
|
||||||
|
nxt_probe_indices = list(miss_indices)
|
||||||
|
|
||||||
# WS 허브 연결 시 — 미스 종목 시세를 허브 메모리(0B 실시간, KRX+NXT 통합)에서 우선 충당.
|
# WS 허브 연결 시 — 미스 종목 시세를 허브 메모리(0B 실시간, KRX+NXT 통합)에서 우선 충당.
|
||||||
# 서버가 동일 렌더러로 OHLC·마크를 그대로 그린다 (마크는 허브 exchange 필드로 판정).
|
# 서버가 동일 렌더러로 OHLC를 그린다. 단, NXT 거래가능 초록점은 허브 exchange가 아니라
|
||||||
# 허브에 없는(아직 미체결) 종목만 ka10095 폴백으로 남긴다. 캐시엔 안 넣음 — 매 페치 라이브 허브 사용.
|
# 아래 ka10095 NX 단독 응답 가능 여부로만 판정한다.
|
||||||
|
# 허브에 없는(아직 미체결) 종목만 ka10095 AL 폴백으로 남긴다. 캐시엔 안 넣음 — 매 페치 라이브 허브 사용.
|
||||||
hub = _RT_HUB
|
hub = _RT_HUB
|
||||||
if hub is not None and hub.is_connected():
|
if hub is not None and hub.is_connected():
|
||||||
hub_q = hub.get_quotes(miss_codes)
|
hub_q = hub.get_quotes(miss_codes)
|
||||||
@@ -694,30 +698,32 @@ def _fetch_quotes_batch(entries: list[dict]) -> list[dict]:
|
|||||||
out['open'] = q.get('open') or None
|
out['open'] = q.get('open') or None
|
||||||
out['high'] = q.get('high') or None
|
out['high'] = q.get('high') or None
|
||||||
out['low'] = q.get('low') or None
|
out['low'] = q.get('low') or None
|
||||||
is_nxt = (q.get('exchange') or '').upper() == 'NXT'
|
out['_krx_price'] = price
|
||||||
out['_krx_price'] = 0 if is_nxt else price
|
out['_nxt_price'] = 0
|
||||||
out['_nxt_price'] = price if is_nxt else 0
|
|
||||||
miss_codes, miss_indices = rest_codes, rest_indices
|
miss_codes, miss_indices = rest_codes, rest_indices
|
||||||
if not miss_codes:
|
|
||||||
return cards
|
|
||||||
|
|
||||||
|
batch: dict[str, dict] = {}
|
||||||
|
if miss_codes:
|
||||||
try:
|
try:
|
||||||
batch = kc.get_watchlist_quotes(miss_codes)
|
batch = kc.get_watchlist_quotes(miss_codes)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
sys.stderr.write(f'ka10095 batch 실패, ka10001 fallback: {ex}\n')
|
sys.stderr.write(f'ka10095 batch 실패, ka10001 fallback: {ex}\n')
|
||||||
for idx in miss_indices:
|
for idx in miss_indices:
|
||||||
cards[idx] = _fetch_quote(entries[idx])
|
cards[idx] = _fetch_quote(entries[idx])
|
||||||
return cards
|
|
||||||
|
|
||||||
# NXT 비교용 batch — 마크(KRX/NXT) 판정에 사용. 실패해도 fallback X (마크만 KRX로 처리).
|
# NXT 비교용 batch — 마크(KRX/NXT) 판정에 사용. 실패해도 fallback X (마크만 KRX로 처리).
|
||||||
# get_watchlist_quotes는 NXT 단독 suffix를 'NX'로 받는다. 'NXT'는 suffix 없이 KRX/기본값으로
|
# get_watchlist_quotes는 NXT 단독 suffix를 'NX'로 받는다. 'NXT'는 suffix 없이 KRX/기본값으로
|
||||||
# 떨어져 NXT 미거래 종목도 거래 가능처럼 보이므로 쓰면 안 된다.
|
# 떨어져 NXT 미거래 종목도 거래 가능처럼 보이므로 쓰면 안 된다.
|
||||||
nxt_batch: dict[str, dict] = {}
|
nxt_batch: dict[str, dict] = {}
|
||||||
try:
|
try:
|
||||||
nxt_batch = kc.get_watchlist_quotes(miss_codes, exchange='NX')
|
nxt_batch = kc.get_watchlist_quotes(nxt_probe_codes, exchange='NX')
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
sys.stderr.write(f'ka10095 NXT batch 실패 (마크 판정용): {ex}\n')
|
sys.stderr.write(f'ka10095 NXT batch 실패 (마크 판정용): {ex}\n')
|
||||||
|
|
||||||
|
for idx, code in zip(nxt_probe_indices, nxt_probe_codes):
|
||||||
|
nxt_q = nxt_batch.get(code) if nxt_batch else None
|
||||||
|
cards[idx]['_nxt_price'] = (nxt_q or {}).get('price', 0) if nxt_q else 0
|
||||||
|
|
||||||
for idx, code in zip(miss_indices, miss_codes):
|
for idx, code in zip(miss_indices, miss_codes):
|
||||||
q = batch.get(code)
|
q = batch.get(code)
|
||||||
out = cards[idx]
|
out = cards[idx]
|
||||||
@@ -735,8 +741,7 @@ def _fetch_quotes_batch(entries: list[dict]) -> list[dict]:
|
|||||||
else:
|
else:
|
||||||
out['quote_error'] = '가격 0'
|
out['quote_error'] = '가격 0'
|
||||||
# 마크 판정: NXT batch 가격 vs 기본 batch 가격 비교.
|
# 마크 판정: NXT batch 가격 vs 기본 batch 가격 비교.
|
||||||
nxt_q = nxt_batch.get(code) if nxt_batch else None
|
nxt_price = out.get('_nxt_price', 0) or 0
|
||||||
nxt_price = (nxt_q or {}).get('price', 0) if nxt_q else 0
|
|
||||||
out['_krx_price'] = price
|
out['_krx_price'] = price
|
||||||
out['_nxt_price'] = nxt_price
|
out['_nxt_price'] = nxt_price
|
||||||
snap = {
|
snap = {
|
||||||
@@ -6158,7 +6163,7 @@ def _render_watchlist_panel(cards: list[dict]) -> tuple[str, int]:
|
|||||||
sections.append(f'<div class="section-label">보유중<span class="count">{len(held)}</span></div>')
|
sections.append(f'<div class="section-label">보유중<span class="count">{len(held)}</span></div>')
|
||||||
sections.append('\n'.join(_render_row(c) for c in held))
|
sections.append('\n'.join(_render_row(c) for c in held))
|
||||||
if watching:
|
if watching:
|
||||||
sections.append(f'<div class="section-label">매수전<span class="count">{len(watching)}</span></div>')
|
sections.append(f'<div class="section-label">감시<span class="count">{len(watching)}</span></div>')
|
||||||
sections.append('\n'.join(_render_row(c) for c in watching))
|
sections.append('\n'.join(_render_row(c) for c in watching))
|
||||||
if trash:
|
if trash:
|
||||||
sections.append(f'<div class="section-label trash-label">삭제예정<span class="count">{len(trash)}</span></div>')
|
sections.append(f'<div class="section-label trash-label">삭제예정<span class="count">{len(trash)}</span></div>')
|
||||||
|
|||||||
Reference in New Issue
Block a user