from datetime import datetime, timezone from decimal import Decimal import unittest from kartsell_policy_contract import SellAction, SellInput, default_chain def base_input(**changes): values = dict( position_lot_id="lot-1", cycle_id="cycle-1", evidence_id="evidence-1", dataset_id="dataset-1", model_version="model-1", config_version="config-1", code_sha="sha-1", as_of=datetime(2026, 8, 1, 7, tzinfo=timezone.utc), published_at_cutoff=datetime(2026, 8, 1, 6, tzinfo=timezone.utc), current_portfolio_weight=Decimal("0.60"), strategic_core_floor_weight=Decimal("0.30"), ) values.update(changes) return SellInput(**values) class PolicyContractTests(unittest.TestCase): def test_hard_impairment_wins(self): result = default_chain().evaluate(base_input( hard_impairment_approved=True, capital_floor_breached=True, survival_sell_ratio_of_lot=Decimal("0.5"), gap_below_floor_atr=Decimal("2"), )) self.assertEqual("ALG-SELL-001", result.policy_id) self.assertEqual(SellAction.FULL_SELL, result.action) self.assertFalse(result.reentry_eligible) def test_gap_preserves_absolute_core_weight(self): result = default_chain().evaluate(base_input( strategic_core_floor_weight=Decimal("0.50"), gap_below_floor_atr=Decimal("2"), )) self.assertEqual("ALG-SELL-002", result.policy_id) self.assertEqual(Decimal("0.50000000"), result.target_portfolio_weight_after) def test_survival_can_cross_core(self): result = default_chain().evaluate(base_input( capital_floor_breached=True, survival_sell_ratio_of_lot=Decimal("0.50"), )) self.assertEqual("ALG-SELL-PORT-001", result.policy_id) self.assertEqual(Decimal("0.30000000"), result.target_portfolio_weight_after) def test_future_published_at_is_rejected(self): with self.assertRaises(ValueError): default_chain().evaluate(base_input( published_at_cutoff=datetime(2026, 8, 1, 8, tzinfo=timezone.utc) )) if __name__ == "__main__": unittest.main()