auto: 일일 백업 2026-09-09 02:00
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
# 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:00~20:00 · 15:40~16: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:00~09:00)와 애프터(15:30~20: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:30~18:21 사이)". 그 관측 구간이었던 시간외단일가(16:00~18: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 트리거는 **무변경 가능**.
|
||||
Reference in New Issue
Block a user