""" kis_trader/engine/range_break_env_keys.py — 박스권 돌파(RANGE_BREAK) env 키 단일 정의 """ from __future__ import annotations from typing import Any, Dict RANGE_BREAK_CONFIG_KEYS = frozenset({ "RANGE_BREAK_BOX_LOOKBACK_MIN", "RANGE_BREAK_BOX_MAX_WIDTH_PCT", "RANGE_BREAK_BOX_MIN_WIDTH_PCT", "RANGE_BREAK_SETUP_VOL_MAX_MULT", "RANGE_BREAK_SETUP_BEAR_BARS_MIN", "RANGE_BREAK_VOL_MULT", "RANGE_BREAK_VOL_WIN", "RANGE_BREAK_BREAK_MARGIN_PCT", "RANGE_BREAK_BODY_MIN_PCT", "RANGE_BREAK_TIME_START", "RANGE_BREAK_TIME_END_HM", "RANGE_BREAK_STOP_LOSS_PCT", "RANGE_BREAK_TAKE_PROFIT_PCT", "RANGE_BREAK_TRAIL_PCT", "RANGE_BREAK_TRAIL_ARM_PCT", "RANGE_BREAK_SHOULDER_MIN_HIGH_PCT", "RANGE_BREAK_SHOULDER_CUT_PCT", "RANGE_BREAK_MAX_HOLD_BARS", "RANGE_BREAK_MAX_DAILY", "RANGE_BREAK_COOLDOWN_SEC", "RANGE_BREAK_MAX_DAILY_CHG", "RANGE_BREAK_MIN_PRICE", "RANGE_BREAK_HIGH_CHASE_THR", "RANGE_BREAK_USE_HIGH_CHASE_FILTER", "RANGE_BREAK_MAX_LOSS_PER_TRADE_KRW", "RANGE_BREAK_SLOT_MONEY", "RANGE_BREAK_MAX_STOCKS", "RANGE_BREAK_TOTAL_BUDGET_KRW", "RANGE_BREAK_MAX_BUY_AMOUNT", "RANGE_BREAK_LIVE_BACKTEST_ALIGN", "RANGE_BREAK_LIVE_SIGNAL_LOOKBACK_BARS", "RANGE_BREAK_FORCE_EOD_EXIT", "STRATEGY_RANGE_BREAK_ENABLED", "RANGE_BREAK_UNIVERSE_SOURCE", "RANK_RANGE_BREAK_SORT", "RANK_RANGE_BREAK_LIMIT", "CONDITION_RANGE_BREAK_NAME", "CONDITION_RANGE_BREAK_SEQ", "RANGE_BREAK_CAND_LIMIT", "KIS_RANGE_BREAK_MM_CHANNEL", }) def _row_val(row: Dict[str, Any], key: str, default: Any = None) -> Any: v = row.get(key) if v not in (None, "", "None"): return v return default def range_break_env_float(row: Dict[str, Any], key: str, default: float) -> float: v = _row_val(row, key) if v is None: return float(default) try: return float(v) except (TypeError, ValueError): return float(default) def range_break_env_int(row: Dict[str, Any], key: str, default: int) -> int: v = _row_val(row, key) if v is None: return int(default) try: return int(float(v)) except (TypeError, ValueError): return int(default) def range_break_env_bool(row: Dict[str, Any], key: str, default: bool) -> bool: v = _row_val(row, key) if v is None: return default s = str(v).strip().lower() if s in ("1", "true", "t", "y", "yes", "on"): return True if s in ("0", "false", "f", "n", "no", "off", ""): return False return default