Files
The-Ouroboros/docs/plans/2026-03-04-issue-409-kr-session-exchange-routing-design.md

4.3 KiB

Issue #409 Design - KR Session-Aware Exchange Routing

Context

  • Issue: #409 (bug: KR 세션별 거래소 미분리 - 스크리닝/주문/이중상장 우선순위 미처리)
  • Related runtime observation targets: #318, #325
  • Date: 2026-03-04
  • Confirmed approach: Option 2 (routing module introduction)

Goals

  1. Ensure domestic screening uses session-specific exchange market code.
  2. Ensure domestic order submission explicitly sets exchange routing code.
  3. Add dual-listing routing priority logic (spread/liquidity aware) with safe fallback.
  4. Keep existing behavior stable for non-KR flows and existing risk/order policy guards.
  5. Enable runtime observability for #409 while monitoring #318/#325 in parallel.

Non-Goals

  • Replacing current session classification model.
  • Introducing new market sessions or changing session boundaries.
  • Refactoring overseas order flow.

Architecture

New Component

  • Add KRExchangeRouter (new module, e.g. src/broker/kr_exchange_router.py).
  • Responsibility split:
    • classify_session_id: session classification only.
    • KRExchangeRouter: final domestic exchange selection (KRX/NXT) for ranking and order.
    • KISBroker: inject resolved routing values into request params/body.

Integration Points

  • KISBroker.fetch_market_rankings
    • Session-aware market division code:
      • KRX_REG -> J
      • NXT_PRE, NXT_AFTER -> NX
  • KISBroker.send_order
    • Explicit EXCG_ID_DVSN_CD is always set.
  • SmartVolatilityScanner._scan_domestic
    • Ensure domestic ranking API path resolves exchange consistently with current session.

Data Flow

  1. Scanner path:
    • Determine session_id.
    • resolve_for_ranking(session_id).
    • Inject J or NX into ranking API params.
  2. Order path:
    • Pass session_id into order path.
    • resolve_for_order(stock_code, session_id).
    • Single listing: session default exchange.
    • Dual listing: select by spread/liquidity heuristic when data is available.
    • Data unavailable/error: fallback to session default.
    • Send order with explicit EXCG_ID_DVSN_CD.
  3. Observability:
    • Log session_id, resolved_exchange, routing_reason.

Dual-Listing Routing Priority

  • Preferred decision source: spread/liquidity comparison.
  • Deterministic fallback: session-default exchange.
  • Proposed reasons in logs:
    • session_default
    • dual_listing_spread
    • dual_listing_liquidity
    • fallback_data_unavailable

Error Handling

  • Router does not block order path when auxiliary data is unavailable.
  • Fail-open strategy for routing selection (fallback to session default) while preserving existing API/network error semantics.
  • send_order exchange field omission is forbidden by design after this change.

Testing Strategy

Unit

  • Router mapping by session (KRX_REG, NXT_PRE, NXT_AFTER).
  • Dual-listing routing priority and fallback.
  • Broker order body includes EXCG_ID_DVSN_CD.
  • Ranking params use session-aware market code.

Integration/Regression

  • smart_scanner domestic calls align with session exchange.
  • Existing order policy tests remain green.
  • Re-run regression sets covering #318/#325 related paths.

Runtime Observation (24h)

  • Restart program from working branch build.
  • Run runtime monitor for up to 24h.
  • Verify and track:
    • #409: session-aware routing evidence in logs.
    • #318: ATR dynamic stop evidence.
    • #325: ATR/pred_down_prob injection evidence.
  • If anomalies are detected during monitoring, create separate issue tickets with evidence and links.

Acceptance Criteria

  1. No domestic ranking call uses hardcoded KRX-only behavior across NXT sessions.
  2. No domestic order is sent without EXCG_ID_DVSN_CD.
  3. Dual-listing path has explicit priority logic and deterministic fallback.
  4. Tests pass for new and affected paths.
  5. Runtime monitor evidence is collected for #409, #318, #325; anomalies are ticketed.

Risks and Mitigations

  • Risk: Increased routing complexity introduces regressions.
    • Mitigation: isolate router, high-coverage unit tests, preserve existing interfaces where possible.
  • Risk: Runtime events for #318/#325 may not naturally occur in 24h.
    • Mitigation: mark as NOT_OBSERVED and keep issue state based on evidence policy; do not force-close without proof.

Planned Next Step

  • Invoke writing-plans workflow and produce implementation plan before code changes.