From b5e3fc0f4e18f5b3487383329557a8423a124f5b Mon Sep 17 00:00:00 2001 From: hyowons Date: Fri, 12 Jun 2026 09:09:42 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20VI=201h=20=EB=A7=A4=ED=95=91=20=EC=8B=A4?= =?UTF-8?q?=EC=A6=9D=20=EB=B0=98=EC=98=81=20=E2=80=94=20active=3D=ED=95=B4?= =?UTF-8?q?=EC=A0=9C=EC=8B=9C=EA=B0=81(1224)=20=EC=9C=A0=EB=AC=B4=EB=A1=9C?= =?UTF-8?q?=20=ED=8C=90=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2026-06-12 사이드카 날 VI 폭주(~1,000건) 실증 결과: - 9068은 발동/해제가 아니라 VI 종류(1=정적, 2=동적, 3=동적+정적) → 구 매핑은 동적 VI를 통째로 무시하고, 해제 이벤트도 active로 덮어썼음 - 발동 이벤트는 1224(해제시각)='000000', 해제 이벤트는 시각이 참 → active = release_time in ('','000000') 으로 교체, 1223 발동시각 추가 저장 - 1h는 구독 무관 시장 전역 broadcast임을 확인 (주석 기록) - 실증용 raw 로그 제거 (폭주 날 ~2,000줄 — 역할 완료) - 토스트: 발동시각 표시 추가, '000000'은 해제 표시 생략 - TTL 백스톱(_vi_expired 180s)은 해제 메시지 유실 대비로 유지 라이브 검증: 002780 동적 VI 발동(09:09:08) → active=True 정상 포착 Co-Authored-By: Claude Opus 4.8 (1M context) --- agents/stock/workspace/scripts/behive_web.py | 3 ++- agents/stock/workspace/scripts/realtime_hub.py | 17 ++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/agents/stock/workspace/scripts/behive_web.py b/agents/stock/workspace/scripts/behive_web.py index 78f471f..8e1e469 100644 --- a/agents/stock/workspace/scripts/behive_web.py +++ b/agents/stock/workspace/scripts/behive_web.py @@ -9464,7 +9464,8 @@ window.openPinModal = openPinModal; if(v.trigger_price) L.push('발동가: '+Number(v.trigger_price).toLocaleString()+'원'); if(v.trigger_pct!=null&&v.trigger_pct!==0) L.push('발동 등락률: '+(v.trigger_pct>=0?'+':'')+v.trigger_pct+'%'); if(v.count) L.push('당일 발동: '+v.count+'회'); - if(v.release_time) L.push('해제 예정: '+_fmtViTime(v.release_time)); + if(v.trigger_time&&v.trigger_time!=='000000') L.push('발동시각: '+_fmtViTime(v.trigger_time)); + if(v.release_time&&v.release_time!=='000000') L.push('해제: '+_fmtViTime(v.release_time)); head=L.join('\n')+'\n\n─────\n'; } var desc='⚡VI (변동성완화장치)\n\n주가가 짧은 시간에 급변하면 약 2분간\n단일가매매로 전환해 과열을 식히는 장치예요.\n\n• 동적VI: 직전 체결가 대비\n• 정적VI: 당일 기준가 대비\n(코스피200 3%·그 외 6% 등에서 발동)'; diff --git a/agents/stock/workspace/scripts/realtime_hub.py b/agents/stock/workspace/scripts/realtime_hub.py index 9e78e97..01a6352 100644 --- a/agents/stock/workspace/scripts/realtime_hub.py +++ b/agents/stock/workspace/scripts/realtime_hub.py @@ -349,19 +349,22 @@ class RealtimeHub: 'ts': datetime.now(KST).isoformat(), } elif typ == '1h': # VI 발동/해제 - # active 판정: 9068 VI발동구분. 해제시각(1224) 유무와 함께 실증 확인 예정(A단계). - # 실증 로그 — VI는 드물어 부담 없음. 2026-06-11 관찰: 발동 후 해제 1h가 안 오고 - # 1224(해제시각)가 발동시각과 동일 → 읽기 시점 TTL 만료(_vi_expired)로 방어 중. - print(f'[1h raw] {code} {vals}', file=sys.stderr, flush=True) + # 매핑 실증 완료 (2026-06-12 사이드카 날 VI 폭주 ~1,000건 관찰): + # - 9068 = VI 종류 (1=정적, 2=동적, 3=동적+정적) — 발동/해제 구분 아님 + # - 1223 = 발동시각, 1224 = 해제시각. 발동 이벤트는 1224='000000', 해제 이벤트는 시각이 참 + # - 1h는 구독 무관 시장 전역 broadcast (모든 종목 VI가 들어옴) + # 해제 메시지 유실 대비 백스톱으로 읽기 시점 TTL(_vi_expired)은 유지. kind_raw = (vals.get('9068') or '').strip() + release_t = (vals.get('1224') or '').strip() with self._lock: self._vi[code] = { - 'active': kind_raw not in ('', '0', '2'), # ⚠️ 매핑 실증 확인 필요 - 'vi_gubun': kind_raw, + 'active': release_t in ('', '000000'), # 해제시각 없음 = 발동 중 + 'vi_gubun': kind_raw, # VI 종류 (1정적/2동적/3동적+정적) 'apply_kind': (vals.get('1225') or '').strip(), # 정적/동적/동적+정적 'trigger_price': _abs_int(vals.get('1221')), 'trigger_pct': kc._to_float(vals.get('1489')), - 'release_time': (vals.get('1224') or '').strip(), + 'trigger_time': (vals.get('1223') or '').strip(), + 'release_time': release_t, 'direction': (vals.get('9069') or '').strip(), 'count': kc._to_int(vals.get('1490')), # 당일 VI 발동 횟수 'ts': datetime.now(KST).isoformat(),