You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Supabase 프로젝트 생성 — supabase.com에서 프로젝트 생성 후 URL/Key 확보
설치 및 실행
1. 환경 변수 설정
cp .env.example .env
.env 파일을 편집하여 실제 값을 입력:
# KIS OpenAPI 인증KIS_APP_KEY=발급받은_앱키KIS_APP_SECRET=발급받은_시크릿KIS_ACCOUNT_NO=계좌번호_8자리KIS_ACCOUNT_PRODUCT=01KIS_ENV=vts# vts(모의투자) 또는 real(실전)# SupabaseSUPABASE_URL=https://your-project.supabase.coSUPABASE_KEY=your-anon-key
2. 데이터베이스 초기화
Supabase SQL Editor에서 supabase/migrations/ 하위 마이그레이션 파일을 번호 순으로 모두 실행:
001_init.sql # 기본 테이블
003_trade_history_columns.sql # trade_history 컬럼 보강
004_strategy_config.sql # 전략 설정 영속화
005_system_config.sql # auto_start 등 시스템 설정
006_positions.sql # 포지션 영속화
007_parameter_recommendations.sql # AI 자문 이력
008_rename_momentum_breakout.sql # 전략명 정리
009_performance_cashflow.sql # 외부 입출금 + TWR
010_recompute_performance_fn.sql # daily_performance 일괄 재계산 RPC
011_register_donchian_swing.sql # 20일 신고가 스윙 전략 등록
012_recompute_prev_asset_fallback.sql # 분모 0 함정 차단
013_daily_log_reports.sql # 일일 로그 분석 리포트
014_system_logs_index.sql # system_logs 조회 인덱스
015_stock_master.sql # KIS CTPF1002R 캐시 (NXT 거래가능 사전 판별, 24h TTL)
016_recommendation_weights_review.sql # 자산배정 + 로직 자문 컬럼 (J4)
018_register_bull_flag_and_vcp.sql # 신규 전략 2종 등록 (bull_flag_breakout / vcp_breakout)
019_backtest_runs.sql # 외부 MCP 백테스트 실행 영속화 (Phase 2)
020_parameter_recommendations_backtest.sql # parameter_recommendations.backtest_summary JSONB (Phase 3)
021_weight_reasoning.sql # parameter_recommendations.weight_reasoning 별도 사유 (사이클 1)
022_market_regime_snapshots.sql # dkstock.cloud 매크로 일일 스냅샷 (사이클 2)
023_cash_usage_ratio_range.sql # cash_usage_ratio 범위 [0.5, 1.0] → [0.0, 1.0] 확장 (사이클 2)
024_vb_board_stop_loss_defaults.sql # VB 보드별 손절 디폴트 자동 복사 (사이클 3)
025_external_integration_toggles.sql # dkstock-regime / kis-mcp 외부 통합 DB-only 토글 (사이클 5)
026_kis_quote_accounts.sql # 보조 KIS 시세 수신 계좌 (사이클 7-A, 풀 슬롯 41 × (1 + N) 확장)
027_buy_block_mode.sql # 매수 가드 4 모드 (OFF/WARN/SOFT/HARD) + 4 임계값 (사이클 8)
028_auto_apply_status.sql # parameter_recommendations.status 에 'applied_auto' 분리 (사이클 23 P3, AI 자문 자동 적용)
029_trade_history_dedupe_unique.sql # (ticker, order_no, trade_type) 부분 UNIQUE 인덱스 (사이클 30, 042700 핑퐁 INSERT 영구 차단)
030_strategy_funnel_snapshots.sql # 조건검색 단계별 후보/탈락 종목 영구 추적 (사이클 34)
3. Docker Compose로 실행 (권장)
# 개발 환경 (hot-reload 지원)
docker compose up --build
# 프로덕션 환경
docker compose -f docker-compose.prod.yml up --build -d
다음 영업일 NXT 프리(08:00) 시가 + 30초 안정화 후 갭상승 +10% → 트레일링 스탑 -2% / 그 외 즉시 매도
전략 B: 변동성 돌파 (volatility_breakout)
구분
규칙
종목군
코스피+코스닥 전체, 시총/거래대금 필터, 노이즈 비율 기반 동적 K값
매매 가능 보드
MAIN only (09:00:05~15:20) — 사이클 26 (2026-05-20) KRX ONLY 정책. KRX 09:00 시가 + (전일 Range × k_value_krx_main, 기본 1.0). PRE_NXT/POST_NXT 매수 비활성 (보유 종목 손절/트레일링 매도는 보드 가드 무관 작동). k_value_nxt_pre/k_value_nxt_post 키는 DB/AI 자문 호환 보존만
매수
KRX 09:00 시가 + (전일 Range × K값) 돌파 순간, 할당 자금 10% 비중
손절
매수가 대비 -3%
청산
15:20 KRX 메인 일괄 청산 (OVERNIGHT 거부). 익일 청산 안전망: 15:20 청산이 누락된 비상 상황(시세 미수신/시장가 거부/재시작 race)에서만 다음 영업일 _execute_next_day_clear로 NXT 프리 청산 — WARNING 로그 노출
재매수
당일 매도 종목 재매수 차단
전략 C: 롱테일 변동성 돌파 (long_tail_volatility)
구분
규칙
종목군
변동성 돌파와 동일 + 연속상한가 종목 제외
매매 가능 보드
MAIN only (09:00:05~15:20) — 사이클 26 KRX ONLY. PRE_NXT/POST_NXT 매수 비활성. 상한가 모드 종목의 POST_NXT 시간대 손절 모니터링은 risk.on_tick 청산 평가가 보드 가드 무관 작동
어제 종가가 20일 신고가 돌파 + 60일 EMA 우상향 + 종가>EMA + 거래대금 ≥ 20일평균×1.5
매수
다음 영업일 09:05~09:30 시장가, 1종목당 1회. 시가 갭상승 +3%↑ 시 스킵 (추격 방지)
손절
매수가 대비 -7% 하드 손절
청산
ATR(14)×2 Chandelier 트레일링 (high_since_buy − ATR×2) — 시간 청산 없음
보유
멀티데이 (평균 5~15 영업일). DB positions 영속화로 일자 넘어 유지
종목명
KIS hts_kor_isnm 우선 + scanner.STATIC_TICKER_NAMES(KOSPI200/KOSDAQ150 인라인 코멘트 자동 파싱)로 fallback
전략 E: 눌림목 돌파 (bull_flag_breakout, 2026-05-15 추가)
구분
규칙
종목군
KRX 등락률 순위 → 시총 ≥ 500억 + 거래대금 ≥ 20억
매매 가능 보드
MAIN(09:05~13:00)
진입 조건
폴 자동 검출(직전 310영업일 누적 +20%↑, 음봉 비율 ≤ 30%) + 플래그 자동 검출(310영업일 횡보, 조정 폭 ≤ 폴 폭의 38.2%, 거래량 < 폴 평균의 60%) → 플래그 상단(flag_high) 돌파 + 당일 거래량 ≥ flag_avg_volume × 2
매수
종목당 1회 + 3영업일 쿨다운. 부분봉 가드(candles[0]==오늘이면 [1]부터)
손절
매수가 대비 -5% / 플래그 하단(flag_low) 이탈 → STOP_LOSS
청산
측정된 이동(flag_high + (pole_high - pole_start)) 도달 → 1차 절반 청산(_partial_exit 마킹, 1차 구현은 전량) → 잔여 high_since_buy − ATR×2 트레일링 / 5영업일 시간 청산 (캘린더일 +2 보정)
보유
단기 (평균 1~5 영업일)
전략 F: 변동성 수축 돌파 (vcp_breakout, 미네르비니식, 2026-05-15 추가)
구분
규칙
종목군
코스피200 + 코스닥150 → 시총 ≥ 1,000억 컷, 220일 일봉 fetch
매매 가능 보드
MAIN(09:05~14:30)
진입 조건
추세 필터(종가 > 50EMA > 150EMA > 200EMA + 200EMA 1개월(20영업일) 우상향) → 베이스 자동 검출(2575영업일, 깊이 ≤ 25%, 최대 30%) → pullback 점진 수축(swing high→low→high 검출, 24회, 직전 대비 폭 감소, 마지막 ≤ 8%) → 거래량 수축(마지막 5일 평균 < 베이스 직전 20일 평균 × 70%) → 베이스 상단(base_high) 돌파 + 당일 거래량 ≥ 20일 평균 × 1.5
매수
종목당 1회 + 7영업일 쿨다운
손절
매수가 대비 -7% / 베이스 하단(base_low) 이탈 → STOP_LOSS
청산
high_since_buy − ATR×2 트레일링 / 50일 EMA 이탈 → TRAILING_STOP. 시간·15:20 청산 없음 — 멀티데이 보유 (Position._MULTIDAY_STRATEGIES 멤버)
보유
멀티데이 (VCP 통상 2~6주)
프론트엔드 Settings 페이지에서 전략별 자금 비중 조절 가능. 대시보드 "조건검색 현황 → 20일 신고가 스윙" 탭에서 8단계 깔때기 통계 + 후보 종목 진입상태(보유 중 / 진입 대기 / 갭 스킵 / 장 시작 전 / 진입 시간 종료) 시각화. 신규 2 전략(bull_flag_breakout/vcp_breakout)은 초기 enabled=false, weight=0 등록 — Settings 에서 수동 활성화 권장 (백테스트/모의 검증 후)
매매 안전장치
항목
동작
종목코드 형식 비대칭
진입 단계는 6자리 숫자만(isdigit) — ETF·신주인수권·임시 코드 매수 차단. 사후처리(체결통보·잔고 sync)는 6자리 영숫자(isalnum) 허용 — 외부 경로로 들어와도 좀비 포지션 방지
매수가능 캐시
60초 TTL — KIS get_buyable() 호출을 매 틱 → 분당 1회로 축소
잔고부족 매수 락
900초 — is_insufficient_cash 응답 또는 max_buy_quantity≤0 시 다음 잔고 sync까지 매수 차단
매도 잔고부족 즉시 break
is_insufficient_quantity 응답 시 3회 재시도 생략 + 메모리·DB positions 정리
체결통보 race 가드
시장가 즉시체결 시 체결통보가 REST 응답보다 먼저 와도 _completed_orders set + 보정 INSERT로 PENDING 잔존 차단
진입 차단
VB/LTV _scan_universe의 거래량순위 후보 + scanner.scan_stocks 모두 ticker.isdigit() 검증
보드 가드
RiskManager.on_tick에서 매수 신호 평가 전 session_tracker.is_tradable(strategy_id, params)로 현재 활성 보드가 전략 tradable_boards에 포함됐는지 확인 — 비활성 보드에서는 신호 평가 자체 skip
매수 수량 1주 fallback (전략 잔여 자금 기준)
position_ratio × total_investment // current_price = 0이어도 전략 잔여 자금(= total_investment − 해당 전략 보유 buy_price×qty 합 − 해당 전략 pending_buy_amounts 합)이 1주 살 수 있으면 1주 매수. 4개 전략 모두 StrategyBase._fallback_one_share() 공통 헬퍼 호출. 기존 고정 total_investment 직접 비교 → 자금 90% 점유 후 추가 1주 매수로 전략 한도 초과하던 결함 차단(2026-05-11 P1)
NXT 거래가능 사전 판별 (Phase G)
KIS CTPF1002R 응답 cptt_trad_tr_psbl_yn=="Y" AND nxt_tr_stop_yn=="N"로 nxt_tradable 파생. stock_master 테이블(24h TTL)에 캐시. OrderEngine._strategy_exchange_async가 nxt_tradable=False면 NXT/SOR → KRX 강제 다운그레이드 + [nxt_downgrade] 로그. scheduler._execute_next_day_clear는 1순위 판별로 사용 → 시가 폴링/안정화 거치지 않고 즉시 보류(NXT 주문 시도 0). execute_sell이 NXT 시간대 매도 거부 받으면 stock_master.upsert_one(nxt_tradable=False) 사후 보강
NXT/KRX 통합 운영 (08:00~20:00)
KIS OpenAPI가 NXT(넥스트레이드 ATS) 주문/시세를 정식 지원함에 따라 KRX 메인장 외 NXT 프리/애프터 시간대까지 매매 가능. 사이클 26 (2026-05-20) — 매매 정책 KRX ONLY + 시세 채널 시간대별 전환: 신규 매수는 KRX 메인 09:00~15:20 단독, PRE_NXT/POST_NXT 는 보유 종목 매도(손절/트레일링)만. 보드 단순화 5→3 + 시세 채널 시간대별 분리 + 종목별 원자 전환.
항목
사용
시세 채널 (시간대별, 사이클 26)
H0STCNT0 (KRX 단독) + H0NXCNT0 (NXT 단독) — scanner.get_active_tick_tr_ids(now_t) 가 6 구간 분기: PRE_NXT 08:0008:59:09 {H0NXCNT0} / **KRX 사전 마진 08:59:1008:59:59 {H0NXCNT0, H0STCNT0}** / MAIN 09:0015:30 {H0STCNT0} / 종가 흡수 15:3015:39:09 {H0STCNT0} / NXT 사전 마진 15:39:10~15:39:59 {H0STCNT0, H0NXCNT0} / POST_NXT 15:40~19:59 {H0NXCNT0}. H0UNCNT0 (통합) TR_ID 는 하위 호환 보존만
통합 장운영정보
H0UNMKO0 / 대표 종목 005930 구독 (실전 한정). MKOP_CLS_CODE(110/112/121/129/130~159) 시장 전체 공통이라 1종목으로 보드 전환 수신. SessionTracker 가 시각 기반 tick + H0UNMKO0 코드 동시 사용
주문 라우팅
place_order(..., exchange=...) body 에 EXCG_ID_DVSN_CD (KRX/NXT/SOR). 모의(VTS) 는 KRX 만 허용 — SOR/NXT 는 실전 한정. 사이클 26 신규 매수는 전략 tradable_boards=("main",) 로 KRX 만 유효
src/engine/session.py::MarketBoard enum 활성 3 보드: pre_nxt (08:0009:00) / main (09:0015:40) / post_nxt (15:40~20:00). _BOARD_SCHEDULE 도 3 구간. krx_open/krx_after enum 값은 호환성 보존 (실제 스케줄 미사용). SessionTracker 30s 주기 tick + register_board_handler 콜백
전략별 매매 가능 보드
DEFAULT_TRADABLE_BOARDS — momentum: KRX_OPEN+MAIN (코드 enum 유지, 활성 보드는 MAIN) / volatility_breakout·long_tail_volatility: MAIN only (사이클 26 KRX ONLY) / donchian_swing·bull_flag_breakout·vcp_breakout: MAIN only
VB/LTV K값
k_value_krx_main (기본 1.0) — KRX 09:00 시가 기준 단독 사용. k_value_nxt_pre/k_value_nxt_post 키는 DB/AI 자문 응답 호환 보존만 (사이클 26 PRE_NXT 매수 제거)
종목 단위 원자 전환 (사이클 26)
TradingScheduler._atomic_board_transition(ticker, stale_tr_id, new_tr_id, ack_timeout_secs=2.0) — (1) unsubscribe (2) _subscriptions_acked 에서 (stale_tr_id, ticker) 제거 polling (timeout 2s) (3) new_tr_id 가 None 아니면 subscribe (4) 50ms sleep. _board_transition_loop(stale, new, tickers, priority_groups) — HIGH (positions / next_day_clear) 우선, 전체 순회, [board_transition_complete] INFO
사전 구독 마진 (사이클 26)
TIME_KRX_MAIN_OPEN_PRESUBSCRIBE=08:59:10 (KRX 채널 50초 사전 마진) / TIME_POST_NXT_OPEN_PRESUBSCRIBE=15:39:10 (NXT 채널 50초 사전 마진). 보유 + 익일청산 + 매수 후보 합집합 사전 구독 → 09:00 KRX 첫 체결 tick 즉시 수신 보장
익일 청산 시점
다음 영업일 NXT 프리 첫 거래(08:00 부근) + 30초 안정화 후 청산 (NEXT_DAY_STABILIZE_SECS=30). 대상: momentum, long_tail_volatility 상한가 모드, volatility_breakout 안전망
15:20 강제 청산
_force_clear_main_only — tradable_boards 에 POST_NXT 가 있는 전략은 보유 유지 (현재 해당 없음). 시간 가드 (2026-05-15 hotfix): 함수 진입 시 >=15:30 이면 즉시 skip + 익일 청산 안전망 위임
donchian 일중 시세 REST 폴링
_swing_rest_poll_loop — 09:30~15:20 KRX 메인 시간대 60s 주기로 _scanned_tickers ∪ positions ∪ pending_buys 합집합을 fetch_stock_detail 폴링 → scanner.ticker_prices 갱신 + ticker_last_tick touch + ticker_names 보강. 보유 종목만 RiskManager.on_tick 호출로 기존 트레일링/-7% 손절 평가 재사용. WS stale 시 ATR 트레일링 평가 끊김 차단 (2026-05-15 결함 B)
API 엔드포인트
Method
URL
설명
GET
/health
헬스 체크
POST
/api/trading/start
자동매매 시작
POST
/api/trading/stop
자동매매 정지
POST
/api/trading/restart
자동매매 재기동
POST
/api/trading/manual-sell
수동 매도 (시장가)
GET
/api/trading/status
현재 상태 조회
GET
/api/balance
잔고 조회 (예수금 + 보유종목, 종목별 NXT/KRX 거래시장 정보 join)
GET
/api/balance/buyable
매수 가능 금액 조회
GET
/api/history?page=&size=
거래 내역 (페이징)
GET
/api/history/pnl?page=&size=&strategy=&ticker=
매매손익 — 매수/매도 페어 1행 (포지션 0 사이클 단위 가중평균). 보유 중은 open 페어 (미실현 손익은 ticker_prices 현재가)
GET
/api/performance/summary
실적 요약 (TWR 누적 + 일평균 실현 수익률)
GET
/api/performance/daily
일별 실적 (실현손익 기반 + TWR 누적 + 외부 입출금)
POST
/api/performance/recompute
trade_history 기반 daily_performance 전체 소급 재계산 (멱등)
GET
/api/strategies
전략 목록 + 비중 + 상태 + 타겟가 + 스윙 scan_stats 깔때기
PUT
/api/strategies/weights
전략별 비중 수정 (매수금액 하한선 검증)
PUT
/api/strategies/{id}/params
전략 파라미터 수정
GET
/api/strategies/system/auto-start
자동 매매 설정 조회
PUT
/api/strategies/system/auto-start
자동 매매 설정 변경
GET
/api/strategies/system/cash-usage-ratio
매매 가용 자금 비율 조회 (J3, 2026-05-12)
PUT
/api/strategies/system/cash-usage-ratio
매매 가용 자금 비율 변경 (50~100% / 5% 단위, 다음 영업일 반영)
GET
/api/logs
시스템 로그 조회
GET
/api/recommendations
전략수정 AI자문 목록 (최근 30일)
GET
/api/recommendations/{id}
단일 자문 상세
POST
/api/recommendations/{id}/apply
선택한 키만 전략 파라미터에 적용. J4(2026-05-12) — body 옵션 apply_weight: bool=False. true 면 recommended_weight 가 strategy_config.weight 로 반영 (다음 영업일 _boot 부터). 자동 적용 없음, 운영자 명시 토글에서만
POST
/api/recommendations/{id}/reject
자문 전체 거절
GET
/api/log-reports?days=30
일일 로그 분석 리포트 목록
GET
/api/log-reports/{YYYY-MM-DD}
단일 영업일 리포트 상세
POST
/api/log-reports/run
수동 트리거 — 즉시 분석 실행 (영업일당 1건 UNIQUE)
GET
/api/realtime/subscriptions
WebSocket 구독 슬롯 진단 (total/acked/fresh_60s/stale_60s/limit/tickers/reconnect_count/ws_connected) + 사이클 35/37: sessions[*].tickers_detail (ticker/ticker_name/stale/last_tick/retries/last_resub/last_cntg_hour/today_volume). KIS inquire_ccnl 캐시(TTL 5분 + cap 20)로 KIS 실제 체결시각 동봉 — WS 구독 의심 진단용
POST
/api/realtime/resubscribe
stale(60s 미수신) TICK 구독 종목 즉시 일괄 재구독 (J2). 응답 {resubscribed, tickers}. F1 자동 재구독과 별개의 운영자 수동 트리거 (ScanMonitor 인라인 버튼). WebSocket 끊김 시 400
GET
/api/strategy-funnel?strategy_id=&target_date=
사이클 34: 전략별 조건검색 단계별 후보/탈락 종목 (survived_tickers cap 200 / excluded_sample cap 20)
GET
/api/strategy-funnel/recent?strategy_id=&days=7
최근 N영업일 추이
POST
/api/strategy-funnel/snapshot
수동 trigger — 각 전략 get_scan_stats() + get_scanned_tickers() 로 최종 단계 (step_no=99) 즉시 snapshot 생성
프로젝트 구조
auto_stock/
├── src/ # 백엔드 (FastAPI)
│ ├── main.py # 앱 엔트리포인트
│ ├── config.py # 환경 설정
│ ├── auth/ # KIS OAuth 인증
│ ├── api/ # KIS REST API 호출
│ ├── realtime/ # KIS WebSocket 실시간
│ ├── engine/ # 매매 엔진 (전략/주문/리스크/스케줄러)
│ ├── db/ # Supabase CRUD
│ ├── routes/ # FastAPI 라우트
│ └── models/ # Pydantic 데이터 모델
├── frontend/ # 프론트엔드 (React)
│ └── src/
│ ├── api/ # API 호출 함수
│ ├── components/ # UI 컴포넌트
│ ├── pages/ # 페이지
│ └── types/ # TypeScript 타입
├── supabase/migrations/ # DB 마이그레이션
├── docs/kis/ # KIS API 스펙 문서
├── .claude/ # Claude Code 하네스 (에이전트팀 + 스킬)
│ ├── agents/ # 7개 전문 에이전트 정의 (사이클 27, 2026-05-21)
│ └── skills/ # 9개 도메인 스킬
├── Dockerfile # 백엔드 Docker (dev/prod 멀티스테이지)
├── docker-compose.yml # 개발 환경 Docker Compose
├── docker-compose.prod.yml # 프로덕션 환경 Docker Compose
├── requirements.txt # Python 의존성
└── .env # 환경 변수 (git 미추적)
에이전트팀 (Claude Code 하네스)
이 프로젝트는 Claude Code의 서브에이전트 + 스킬 시스템을 활용한 다중 에이전트 협업 구조로 개발·운영된다. 사용자 요청 유형에 따라 오케스트레이터 스킬이 적합한 에이전트와 스킬을 자동 호출한다.
ssh -i ~/.ssh/auto-stock-key.pem ubuntu@<EC2_IP>cd~/auto_stock
git pull origin main
docker compose -f docker-compose.prod.yml up --build -d
주의: 로컬과 EC2에서 동시 실행 금지 — KIS API 동일 계정 동시 접속 시 충돌 발생
스케줄 — KRX/NXT 통합 운영 (08:00~20:00)
부팅 NXT 프리 KRX 메인 KRX 마감 → NXT 애프터 정산
─────────────┬────────┬─────────────────────┬──────────────────────┬────────────
07:45 07:50 07:55│08:00 09:00:05 09:30 15:20 15:30 19:50 20:00 20:10
│ │ │ │ │ │ │ │ │ │ │ │
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
자동 prepare WS 사전 익일청산 KRX 시가 모멘텀 KRX KRX 마감 NXT 애프터 정산
시작 토큰 연결 구독 (NXT 08:00 확정+VB/ 스캔+ 메인 → NXT 애프터 매수중단 +DB
포지션 돌파 +30초 안정) LTV MAIN 매매 매수 전환 (구독 유지)+AI자문 적재
복구 종목 + VB/LTV 매매 진입 시작 중단 POST_NXT 매매 (OpenAI)
PRE_NXT +KRX 활성 (VB/LTV) 일일
매매 시작 메인 로그
강제 분석
청산
(POST_NXT
미활성
전략만)
시각
동작
07:45
자동 매매 시작 (AUTO_START 활성 시, 주말+공휴일 자동 건너뜀 — KIS chk-holiday API)
07:50
_boot() — 토큰 사전 순차 발급 (사이클 20: 메인+보조 N 분당 1개 한도 직렬화) → DB 포지션 복구 → KIS 잔고 교차 검증 → 미체결 복구 → stock_master eager 갱신 (보유+익일청산) → 매크로 fetch + market_regime_snapshots INSERT → cash_usage_ratio 자동 조정 → 전략 prepare
07:55
사전 구독 — 돌파(VB/LTV) + 스윙(donchian) 스캔 종목 + 보유 포지션. WebSocket 연결 + 체결통보 + (실전) H0UNMKO0 구독. 유니버스 비어있으면 prepare 재실행
08:00
NXT 프리 진입 — 익일 청산 백그라운드 (NEXT_DAY_STABILIZE_SECS=30s 안정화 후 NXT 시가 청산). 사이클 26: VB/LTV PRE_NXT 매수 제거됨 (tradable_boards=("main",)) — _confirm_breakout_open_prices(board="pre_nxt") 호출 안 함
08:59:10
사이클 26 신규 — KRX 채널 사전 구독 마진 (50초): _board_transition_loop("H0NXCNT0", "H0STCNT0", 보유+익일청산) 종목별 원자 전환 + 매수 후보 신규 KRX subscribe. 09:00 KRX 첫 체결 tick 즉시 수신 보장
09:00:05
KRX 메인 시가 확정 — _confirm_breakout_open_prices(board="main") VB/LTV target_price 계산 (KRX 09:00 시가 + 전일Range × k_value_krx_main). 직후 _drain_pending_next_day_clear() — 08:00 보류 종목 KRX 시장가 일괄 청산
09:05~09:30
donchian 스윙 진입창 — 시장가 1주문/종목, 갭 +3%↑ 스킵
09:30
모멘텀(상한가) 종목 스캔 시작, 매수 감시. 5분 주기 _scan_loop 시작 — 모멘텀+돌파+스윙+보유 합집합 시세 재구독
15:20
KRX 메인 신규 매수 중단 + 강제 청산 (_force_clear_main_only) — VB 전체 + LTV 상한가 미도달 청산. 시간 가드(2026-05-15 hotfix): >=15:30 진입 시 skip + 익일 청산 안전망 위임
15:30
KRX 메인 마감 (15:30~15:39:59 종가 흡수 마진 — MAIN 보드 유지). 사이클 26: _confirm_breakout_open_prices(board="post_nxt") 호출 제거 (VB/LTV tradable_boards 에 post_nxt 없음 → 시가 확정 대상 없음)
15:39:10
사이클 26 신규 — NXT 채널 사전 구독 마진 (50초): _board_transition_loop("H0STCNT0", "H0NXCNT0", 보유+익일청산) 종목별 원자 전환 + 매수 후보 KRX unsubscribe