"""[R8] 빈 계좌 응답 후 swing 사이클 정지 시에도 stale fail-safe 가 작동해야 한다.""" from datetime import datetime, timedelta import pytest from app.core.config import settings from app.core import market_schedule as ms from app.services import mdd_manager as mm def _make(monkeypatch, now): monkeypatch.setattr(settings, "MDD_BLIND_BLOCK_ENTRY", True) monkeypatch.setattr(ms, "is_market_open", lambda *a, **k: True) monkeypatch.setattr(mm.MDDManager, "_now_kst_v2", staticmethod(lambda: now[0])) return mm.MDDManager() @pytest.mark.asyncio async def test_empty_account_then_stalled_blocks_entry(monkeypatch): t0 = datetime(2026, 10, 12, 10, 0, tzinfo=ms.KST) now = [t0] m = _make(monkeypatch, now) stale = mm._stale_sec_v2() assert stale > 0 await m.record_update_success(empty_account=True) now[0] = t0 + timedelta(seconds=stale - 1) assert await m.can_open_new_position() is True now[0] = t0 + timedelta(seconds=stale + 1) assert await m.can_open_new_position() is False @pytest.mark.asyncio async def test_empty_account_exempt_from_failure_counter(monkeypatch): t0 = datetime(2026, 10, 12, 10, 0, tzinfo=ms.KST) m = _make(monkeypatch, [t0]) await m.record_update_success(empty_account=True) m._update_failures = int(settings.MDD_BLIND_FAILURE_THRESHOLD) + 3 assert await m.can_open_new_position() is True