auto: 일일 백업 2026-06-18 02:00
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -225,10 +225,33 @@ def _ind_key(code):
|
||||
config.RSI_PERIOD, config.TREND_SLOPE_DAYS)
|
||||
|
||||
|
||||
def _gather(extra_codes=None):
|
||||
LAST_QUOTES_PATH = config.STATE_DIR / 'last_quotes.json'
|
||||
|
||||
|
||||
def _save_last_quotes(quotes: dict) -> None:
|
||||
"""직전 스캔이 모은 시세 — judge_view(관심종목 탭)가 라이브 재호출 없이 같은 값을 재사용."""
|
||||
if not quotes: # 시세 수집 실패(빈 dict)면 직전 정상값 보존 — 덮어쓰지 않음
|
||||
return
|
||||
try:
|
||||
config.STATE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
LAST_QUOTES_PATH.write_text(json.dumps(quotes, ensure_ascii=False))
|
||||
except Exception as e:
|
||||
sys.stderr.write(f'[engine] last_quotes 저장 실패: {e}\n')
|
||||
|
||||
|
||||
def _load_last_quotes() -> dict | None:
|
||||
"""직전 스캔 시세. 없으면 None → 호출부가 라이브 폴백."""
|
||||
try:
|
||||
return json.loads(LAST_QUOTES_PATH.read_text())
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
|
||||
def _gather(extra_codes=None, quotes=None):
|
||||
"""파라미터 무관한 라이브 데이터 1회 수집 (메인·변이 공유). 종목·시세·시장매핑.
|
||||
|
||||
extra_codes: universe에 없지만 청산 판단을 위해 포함해야 할 보유 코드(수동 삭제된 보유분).
|
||||
quotes: 주어지면 라이브 시세 호출을 건너뛰고 그대로 사용 (judge_view 가 직전 스캔 시세 재사용).
|
||||
"""
|
||||
data.reset_book_memo() # 호가 공유 캐시 리셋 — 이번 스캔의 체결가를 전 선수가 공유
|
||||
_SCAN_CANDLES.clear()
|
||||
@@ -241,7 +264,8 @@ def _gather(extra_codes=None):
|
||||
uni = uni + [{'code': c, 'name': '', 'sources': ['held']}]
|
||||
codes.append(c)
|
||||
seen.add(c)
|
||||
quotes = data.batch_quotes(codes)
|
||||
if not quotes: # None(미지정) 또는 빈 dict(저장본 비었음)면 라이브 수집
|
||||
quotes = data.batch_quotes(codes)
|
||||
cmkt = universe.code_market_map()
|
||||
return uni, quotes, cmkt
|
||||
|
||||
@@ -399,7 +423,9 @@ def judge_view(vid: str) -> dict | None:
|
||||
pf = Portfolio.load(pp, tp)
|
||||
try:
|
||||
backtest.apply_params(params)
|
||||
uni, quotes, cmkt = _gather(set(pf.positions))
|
||||
# 직전 스캔이 저장한 시세 재사용 — 라이브 재호출 없이 보유종목 가격과 같은 시점으로 통일.
|
||||
# 스캔 이력이 아직 없으면(None) _gather 가 라이브 폴백.
|
||||
uni, quotes, cmkt = _gather(set(pf.positions), quotes=_load_last_quotes())
|
||||
return _run_scan(pf, uni, quotes, cmkt, now, execute=False)
|
||||
finally:
|
||||
backtest.apply_params(config.load_params()) # 전역 config 원복 (웹 데몬 잔류 방지)
|
||||
@@ -425,6 +451,7 @@ def scan(force: bool = False) -> dict:
|
||||
return {'skipped': True, 'reason': '장외/휴장', 'at': now.isoformat()}
|
||||
pf = Portfolio.load()
|
||||
uni, quotes, cmkt = _gather(set(pf.positions)) # 보유분은 universe에서 빠져도 청산 위해 포함
|
||||
_save_last_quotes(quotes)
|
||||
snap = _run_scan(pf, uni, quotes, cmkt, now)
|
||||
_attach_benchmark(snap, pf, now)
|
||||
config.STATE_DIR.mkdir(parents=True, exist_ok=True)
|
||||
@@ -448,6 +475,7 @@ def scan_all(force: bool = False) -> dict:
|
||||
for vpf in vpfs.values():
|
||||
held_union |= set(vpf.positions)
|
||||
uni, quotes, cmkt = _gather(held_union)
|
||||
_save_last_quotes(quotes)
|
||||
|
||||
# 기준 판단 (params.json) — 2026-06-10 기준전략 폐지: 매매 없이 판단만(last_scan = 화면·상태점용).
|
||||
# 실제 매매는 전부 변이들이 한다 (메인 계좌 동결).
|
||||
|
||||
Reference in New Issue
Block a user