from __future__ import annotations import unittest from datetime import datetime import pandas as pd from dragon_strategy import DragonRuleEngine class TestDeepOversoldPendingPaths(unittest.TestCase): def _row(self, **kwargs) -> pd.Series: base = { "close": 100.0, "a1": -0.03, "b1": -0.05, "c1": 14.0, "kdj_buy": False, "kdj_sell": False, "ql_buy": False, "ql_sell": False, } base.update(kwargs) row = pd.Series(base) row.name = pd.Timestamp(datetime(2026, 1, 2)) return row def test_pending_confirmation_emits_confirmed_buy(self) -> None: engine = DragonRuleEngine() engine.context.pending_deep_oversold_subtype = "shallow_false_start" engine.context.pending_deep_oversold_origin_date = datetime(2026, 1, 1).date() engine.context.pending_deep_oversold_bars_waited = 1 engine.context.bridge_pending_deep_oversold_active = True row = self._row(ql_buy=True) action, reason = engine._pending_deep_oversold_decision(row) self.assertEqual(action, "BUY") self.assertEqual(reason, "deep_oversold_rebound_buy:confirmed_shallow_false_start") self.assertFalse(engine.context.bridge_pending_deep_oversold_active) def test_pending_is_cleared_on_sell_signal(self) -> None: engine = DragonRuleEngine() engine.context.pending_deep_oversold_subtype = "mixed_oversold" engine.context.pending_deep_oversold_origin_date = datetime(2026, 1, 1).date() engine.context.pending_deep_oversold_bars_waited = 1 engine.context.bridge_pending_deep_oversold_active = True row = self._row(kdj_sell=True) action, reason = engine._pending_deep_oversold_decision(row) self.assertEqual((action, reason), ("NONE", "")) self.assertFalse(engine.context.bridge_pending_deep_oversold_active) if __name__ == "__main__": unittest.main()