diff --git a/tests/test_main.py b/tests/test_main.py index c2dbc6b..86e67d1 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -4,6 +4,7 @@ from datetime import UTC, date, datetime from unittest.mock import ANY, AsyncMock, MagicMock, patch import pytest +import src.main as main_module from src.config import Settings from src.context.layer import ContextLayer @@ -17,6 +18,7 @@ from src.main import ( KILL_SWITCH, _SESSION_RISK_LAST_BY_MARKET, _SESSION_RISK_OVERRIDES_BY_MARKET, + _SESSION_RISK_PROFILES_MAP, _STOPLOSS_REENTRY_COOLDOWN_UNTIL, _apply_staged_exit_override_for_hold, _compute_kr_atr_value, @@ -105,6 +107,8 @@ def _reset_kill_switch_state() -> None: _RUNTIME_EXIT_PEAKS.clear() _SESSION_RISK_LAST_BY_MARKET.clear() _SESSION_RISK_OVERRIDES_BY_MARKET.clear() + _SESSION_RISK_PROFILES_MAP.clear() + main_module._SESSION_RISK_PROFILES_RAW = "__reset__" _STOPLOSS_REENTRY_COOLDOWN_UNTIL.clear() yield KILL_SWITCH.clear_block() @@ -112,6 +116,8 @@ def _reset_kill_switch_state() -> None: _RUNTIME_EXIT_PEAKS.clear() _SESSION_RISK_LAST_BY_MARKET.clear() _SESSION_RISK_OVERRIDES_BY_MARKET.clear() + _SESSION_RISK_PROFILES_MAP.clear() + main_module._SESSION_RISK_PROFILES_RAW = "__reset__" _STOPLOSS_REENTRY_COOLDOWN_UNTIL.clear() @@ -234,6 +240,76 @@ def test_stoploss_cooldown_minutes_uses_session_override() -> None: assert value == 45 +def test_resolve_market_setting_ignores_profile_when_reload_disabled() -> None: + settings = Settings( + KIS_APP_KEY="k", + KIS_APP_SECRET="s", + KIS_ACCOUNT_NO="12345678-01", + GEMINI_API_KEY="g", + US_MIN_PRICE=5.0, + SESSION_RISK_RELOAD_ENABLED=False, + SESSION_RISK_PROFILES_JSON='{"US_PRE": {"US_MIN_PRICE": 9.5}}', + ) + market = MagicMock() + market.code = "US_NASDAQ" + + with patch("src.main.get_session_info", return_value=MagicMock(session_id="US_PRE")): + value = _resolve_market_setting( + market=market, + settings=settings, + key="US_MIN_PRICE", + default=5.0, + ) + + assert value == pytest.approx(5.0) + + +def test_resolve_market_setting_falls_back_on_invalid_profile_json() -> None: + settings = Settings( + KIS_APP_KEY="k", + KIS_APP_SECRET="s", + KIS_ACCOUNT_NO="12345678-01", + GEMINI_API_KEY="g", + US_MIN_PRICE=5.0, + SESSION_RISK_PROFILES_JSON="{invalid-json", + ) + market = MagicMock() + market.code = "US_NASDAQ" + + with patch("src.main.get_session_info", return_value=MagicMock(session_id="US_PRE")): + value = _resolve_market_setting( + market=market, + settings=settings, + key="US_MIN_PRICE", + default=5.0, + ) + + assert value == pytest.approx(5.0) + + +def test_resolve_market_setting_coerces_bool_string_override() -> None: + settings = Settings( + KIS_APP_KEY="k", + KIS_APP_SECRET="s", + KIS_ACCOUNT_NO="12345678-01", + GEMINI_API_KEY="g", + OVERNIGHT_EXCEPTION_ENABLED=True, + SESSION_RISK_PROFILES_JSON='{"US_AFTER": {"OVERNIGHT_EXCEPTION_ENABLED": "false"}}', + ) + market = MagicMock() + market.code = "US_NASDAQ" + + with patch("src.main.get_session_info", return_value=MagicMock(session_id="US_AFTER")): + value = _resolve_market_setting( + market=market, + settings=settings, + key="OVERNIGHT_EXCEPTION_ENABLED", + default=True, + ) + + assert value is False + + def test_estimate_pred_down_prob_from_rsi_uses_linear_mapping() -> None: assert _estimate_pred_down_prob_from_rsi(None) == 0.5 assert _estimate_pred_down_prob_from_rsi(0.0) == 0.0