Files
openclaw/agents/stock/workspace/memory/2026-09-14-krx-aftermarket.md
T
hyowons 3e62670b24 auto: 일일 백업 2026-09-09 02:00
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-09 02:00:03 +09:00

12 KiB
Raw Blame History

KRX 애프터마켓 개설 · NXT 제도개선 (시행 2026-09-14)

상태: 조사·기록만 완료. 코드 변경 0건. 관리자님 지시(2026-09-08): "내용만 확인해놔. 14일 이후에 키움 API가 어떻게 변경되는지 확인하고 작업하자." → §4 키움 API 확인이 모든 구현의 선행 조건이다. 확인 전에 §5 좌표를 손대지 말 것.

출처: 대신증권 공지 「KRX 애프터마켓 개설 및 NXT 제도개선 안내」 (2026-09-08 13:56 게시) https://money2.daishin.com/E5/MBoard/PType_Basic/Mobile_Notice/DM_Basic_Read.aspx?seq=18257&page=1&p=4124&v=3090&m=3817


1. 공지 확정 사실

KRX 시간표

구분 변경 전 변경 후
장개시전 시간외 종가 08:30~08:40 현행 유지
정규장 09:00~15:30 현행 유지
장종료후 시간외 종가 15:40~16:00 현행 유지
장종료후 시간외 단일가 16:00~18:00 폐지
KRX 애프터마켓 없음 16:00~20:00 신설

애프터마켓 매매 규칙

  • 체결: 접속매매 (최초/최종 단일가 없음). VI 발동 시에만 단일가 전환
  • ※ NXT 애프터마켓 개장 전 10분간(15:30~15:40)은 단일가매매 적용
  • 제출가능 호가: 지정가 · 최우선지정가 · 최유리지정가 (IOC/FOK 허용) → 시장가 없음, 스톱지정가 없음
  • 대상: 유가증권·코스닥의 주권/외국주권/DR/리츠/선박투자회사/투자회사/SOC
  • 제외종목 9종: 30분 단위매매 · 거래정지 · 당일 정규장 미거래 · 투자경고 · 투자위험 · 이상급등 · 관리 · 초저유동 · 투자주의환기 · 투자유의
  • 기존 시간외단일가에서 거래되던 ETF/ETN 거래불가
  • 시세: 애프터마켓의 고가/저가/실시간 체결가 산출. 익일 기준가 참조가격은 정규장 종가

정규장 미체결 주문 — 자동 소멸 시점 (명문화됨)

구분 KRX NXT
자동 증거금 해지 정규장 종료 후 15:35~ 애프터마켓 종료 후 20:05~
미체결 주문 애프터마켓에서 재주문 필요 (미이전) 애프터마켓까지 주문 유지
예시 09:00 주문 → 15:30 미체결 → 15:35~ 증거금 해지 → 16:00 이후 재주문 08:00 주문 → 20:00까지 미체결 → 20:00 이후 증거금 해지

NXT 제도개선

정적VI 도입 + 동적/정적VI 발동 시 단일가매매(2분) 전환

동적VI 정적VI
참조가격 직전 체결가격 직전 단일가매매 가격 (없으면 기준가격)
발동요건 코스피200 ±3% / 기타 ±6% ±10%
발동효과 단일가매매 전환(2분) 〃
제출가능호가 지정가, 스톱지정가호가(메인마켓) 〃
적용대상 모든 접속매매 체결 / 마켓별 최초가격 배제 모든 접속·단일가매매 체결(VI단일가 제외) / 마켓별 최초가격에도 적용
  • 거래정지 후 재개 시 단일가매매: CB(시장) NXT 30분 중단 + 단일가 30초 (KRX 20분 + 10분) / 중요내용공시(종목) NXT 40분 정지 + 단일가 30초 (KRX 30분 + 10분)
  • GTP(Good till Premarket) 전용호가 도입 — 프리마켓 제출 호가 전체에 적용 가능, 미체결잔량은 프리마켓 종료(08:50) 일괄 취소
  • 프리마켓 상·하한가 주문가능 — 2026-08-12부터 한시 적용됐던 NXT 프리마켓 상·하한가 주문제한 해제
  • 대주거래 09:00~20:00 확대 (KRX/NXT 동일) — 우리는 대주거래 미사용, 영향 없음

외부 교차 확인 (뉴스): 애프터마켓 16:0020:00 · 15:4016:00 시간외종가 유지 · ETF·ETN 거래불가 · 공식 종가는 15:30 정규장 종가 · 사이드카 없음·VI 있음.


2. 현재 코드가 믿고 있는 시간 모델

시간 경계는 scripts/orders/limits.json L37-49가 단일 진실 공급원이고 guards.py엔 시간 리터럴이 0개다(orders/__init__.py:22-24 설계 규칙).

guards.session_at() (guards.py:78-89) 세션 5종 + determine_routing() (guards.py:143-161):

세션 구간 suffix dmst_stex_tp
NXT_PRE 08:00:00–09:00:00 _NX NXT
(틈) 09:00:00–09:00:30 — ValueError
KRX_NXT 09:00:30–15:20:00 _AL / '' SOR / KRX
KRX_CLOSE 15:20:00–15:30:00 '' KRX
NXT_AFTER 15:30:00–20:00:00 _NX NXT
CLOSED 그 외 — ValueError

⚠️ 핵심: KRX 시간외 시장(종가·단일가)이 모델에 아예 없다. 15:30 이후는 전부 NXT로 취급한다. KRX 애프터마켓 신설이 정확히 이 가정을 깬다.

⚠️ 자산웹 phase는 별개의 하드코딩이다(behive_web.py:788-808) — 09:00~15:30=regular, 08:00~20:00=nxt, 그 외 closed. 프리(08:0009:00)와 애프터(15:3020:00)를 같은 nxt 값으로 구분하지 못한다.


3. 영향 분석 (2026-09-08 실측)

① 거래 가능해지는데 자산웹이 막는 종목 — 가장 실질적

ETF/ETN은 state/stock_codes.json 기준 1,063/1,064가 nxt_enable=False. 애프터마켓에서도 ETF/ETN은 거래불가이므로 현행 차단이 결과적으로 정당하다.

문제는 NXT 미상장 일반주. 전체 4,300종목 중 nxt_enable=False가 3,693개, ETF/ETN을 뺀 약 2,630개가 9/14부터 KRX 애프터마켓에서 거래 가능해진다.

ETF/ETN (차단 유지 정당) NXT 미상장 일반주 (신규 거래가능) NXT 상장
보유 37 12 15 10
관심 57 12 20 25
감시 45 0 32 13

보유분 해당 15종목: LG씨엔에스 · SK이터닉스 · 삼성전자우 · 파두 · 아난티 · 제닉스로보틱스 · 마키나락스 · 노루페인트 · 베뉴지 · 서부T&D · 진흥기업 · 피앤씨테크 · RF머트리얼즈 · WON 두산그룹포커스 · WON 초대형IB&금융지주

차단 경로: _market_phase_state()가 16:00~20:00을 nxt로 판정 → /api/quote_book이 nxt_enable=False 회신(behive_web.py:14687-14717) → 클라이언트가 📵 NXT 거래불가 라벨 + cls='closed'(behive_web.py:12853) → refreshSubmitGate()가 state.phaseCanTrade===false로 매수/매도 버튼 disable(behive_web.py:12928-12935).

② 감시 공백

감시 현재 커버 애프터마켓(16:00~20:00)
trailing_monitor 08:00–19:59 (plist 720엔트리) ✅ 이미 커버
surge_monitor 09:00–15:35 (MARKET_CLOSE=(15,35) L91, plist 396엔트리) ❌ 급등락·VI 알림 0건
watchlist_monitor 10:00/12:00/14:00 3회 (MARKET_CLOSE=(15,45) L48) ❌
sim-scan 09:00–15:30 (plist 196엔트리) ❌

③ 부수 영향 지점

  • surge_monitor.get_limit_map() 하루 1콜 캐시(L306-320) — 애프터마켓 가격제한폭이 정규장과 다르면 16:00 이후 upl_pric/lst_pric이 틀린 값이 된다. 공지·뉴스에 제한폭 언급이 없어 미확정(§4-4).
  • trailing_monitor.py:142 실측 전제 재검증 필요 — "스톱주문은 장 마감 후 체결 없이 소멸한다(15:3018:21 사이)". 그 관측 구간이었던 시간외단일가(16:0018:00)가 폐지되고, 공지가 소멸 시점을 KRX 15:35~ / NXT 20:05~로 명문화했다. 재실측 없이는 _notify_gone_batch의 "장 마감 취소 추정" 문구가 틀린 시각에 나간다.
  • 시장가 차단은 유지가 맞다 — validate_market_order_session()(guards.py:195-205)이 NXT_PRE/NXT_AFTER에서 MARKET을 거부한다. 애프터마켓 호가유형에도 시장가가 없어 근거가 오히려 늘어난다.
  • ⚠️ STOP_LIMIT은 세션 제약이 전무하다. 애프터마켓엔 스톱지정가가 없고 NXT 메인마켓엔 있으므로, 라우팅을 KRX로 바꾸는 순간 트레일링·스톱 발주가 깨진다.
  • 09:00:00–09:00:30 틈은 CLOSED → determine_routing이 ValueError. 기존 하자이며 이번 변경과 무관하나 같이 손볼 후보.
  • 시간 가드가 두 계통으로 갈려 있다 — limits.json 기반은 trailing_monitor 단독이고, surge_monitor·watchlist_monitor·behive_web·stock_analysis는 각자 하드코딩. 제도 변경마다 파일별로 손봐야 한다. 통합하면 이후엔 JSON 편집 + plist 재생성 2단계로 줄어든다.

4. 키움 API 확인 체크리스트 — 다음 작업의 선행 조건

로컬 ~/.openclaw/docs/키움 REST API 문서.pdf는 2026-05-07 검증본으로 이번 제도 변경 이전판이고, 키움 OpenAPI 포털에서 관련 공지를 찾지 못했다. ⚠️ CLAUDE.md 규칙("suffix 패턴 추측 금지 — 2026-05-07 ka10004 사고")에 따라 아래 값을 지어내지 않는다.

  1. dmst_stex_tp 값 — 현재 매핑 _EXCHANGE_BY_SUFFIX = {'_AL':'SOR', '_NX':'NXT', '':'KRX'}(kiwoom_order.py:36-41). 애프터마켓 주문이 KRX로 그냥 나가는지, SOR가 자동 라우팅하는지, 신규 값이 생기는지.
  2. trde_tp 값 — 현재 '0' 지정가 / '3' 시장가 / '28' 스톱지정가(kiwoom_order.py:31-34). 애프터마켓 전용 호가유형(최우선지정가·최유리지정가·IOC·FOK) 코드가 추가되는지.
  3. 애프터마켓 참여 가능 여부 플래그 — ka10099 nxtEnable은 NXT 상장 여부만 준다. 제외종목 9종류를 판별할 필드가 새로 생기는지, 아니면 order_warning·state 텍스트로 근사해야 하는지.
  4. 애프터마켓 가격제한폭 — ka10001/ka10095의 upl_pric/lst_pric이 16:00 이후에도 정규장 기준값인지 애프터 전용 값인지. surge_monitor 상·하한가 트리거 정확도가 여기 걸려 있다.
  5. VI 필드 — NXT 정적VI 도입으로 실시간 1h broadcast 페이로드가 확장되는지. surge_monitor가 vi.active를 그대로 신뢰한다(L373-377).
  6. 호가·시세 TR의 애프터마켓 구분 — ka10004 응답에 세션 구분 필드가 생기는지. 현재 자산웹은 시간외/애프터 구분 필드를 전혀 쓰지 않는다.
  7. 미체결 조회(ka10075) 동작 — KRX 주문이 15:35 증거금 해지 후 목록에서 즉시 빠지는지. trailing_monitor 생존 판정이 이 응답에 전적으로 의존한다.

확인 방법: 9/14(월) 장에서 ① 키움 REST API 포털·공지 재확인 ② 16:00 이후 ka10095·ka10001 응답 실측(조회 전용, 안전) ③ 필요시 NXT 미상장 보유주 1주로 애프터마켓 실주문 검증.


5. 확인 후 손댈 좌표 (미리 특정)

§4 확인 전엔 손대지 않는다.

대상 파일:라인 성격
세션 정의 scripts/orders/limits.json:37-49 애프터마켓 경계 추가
세션 판정 scripts/orders/guards.py:78-89 (session_at) 세션 1종 추가
라우팅 scripts/orders/guards.py:143-161 (determine_routing) 애프터 세션 라우팅
시장가 게이트 scripts/orders/guards.py:195-205 애프터 세션 추가(거부 유지)
거래소 코드 scripts/orders/kiwoom_order.py:36-41 §4-1 결과 반영
자산웹 phase scripts/behive_web.py:788-808, :812(_PHASE_BOUNDARIES_MIN) phase 분리 + 16:00 경계
phase 라벨·게이트 scripts/behive_web.py:12845-12874, :12928-12935 📵 NXT 거래불가 조건 재정의
호가 거래소 선택 scripts/behive_web.py:14687-14717 애프터 세션 분기
급등락 감시 scripts/surge_monitor.py:90-91, :306-320 + plist 396→약 660엔트리 시간 확대 + 제한폭 캐시
워치리스트 감시 scripts/watchlist_monitor.py:47-48 + plist 시간 확대
트레일링 문구·전제 scripts/trailing_monitor.py:142, :487 소멸 시점 재실측 반영
시세 조회 거래소 scripts/trailing_monitor.py:446 ('NX' if sess in ('NXT_PRE','NXT_AFTER') else 'AL') 세션명 추가 시 동반 수정 필수
경계 테스트 scripts/orders/tests/test_guards.py:45-72 12케이스 갱신 필수
정책 문서 scripts/orders/__init__.py:38-42, memory/orders_module.md:38,41-42 "08:00–20:00 NXT" 서술 정정

⚠️ 20:00 종료가 유지되므로 guards.after_trading_day(= nxt_after_end)와 그 소비자(orders/trailing.py:692 is_arm_expired), trailing-monitor plist(720엔트리), briefing 20:10/20:30·trade-journal 21:00 트리거는 무변경 가능.