"""Multi-leg non-double-book accounting invariant tests for PINK → DITAv2.""" from __future__ import annotations from datetime import datetime, timezone import unittest from prod.clean_arch.dita_v2 import ( ExecutionKernel, InMemoryControlPlane, InMemoryZincPlane, KernelCommandType, KernelIntent, MockVenueAdapter, MockVenueScenario, TradeSide, TradeStage, ) class TestAccountingInvariants(unittest.TestCase): """Verify single-application of capital deltas across multi-leg exits.""" def setUp(self): self.control = InMemoryControlPlane() self.venue = MockVenueAdapter( MockVenueScenario( reject_entries=False, reject_exits=False, partial_fill_ratio=0.5, cancel_reject=False, ) ) self.kernel = ExecutionKernel( max_slots=1, control_plane=self.control, venue=self.venue, zinc_plane=InMemoryZincPlane(), ) def _enter(self) -> None: intent = KernelIntent( timestamp=datetime.now(timezone.utc), intent_id="acct-entry-001", trade_id="acct-trade-001", slot_id=0, asset="BTCUSDT", side=TradeSide.SHORT, action=KernelCommandType.ENTER, reference_price=65000.0, target_size=0.01, leverage=2.0, reason="acct_test_entry", exit_leg_ratios=(0.5, 1.0), ) self.kernel.process_intent(intent) def _exit(self) -> None: intent = KernelIntent( timestamp=datetime.now(timezone.utc), intent_id="acct-exit-001", trade_id="acct-trade-001", slot_id=0, asset="BTCUSDT", side=TradeSide.SHORT, action=KernelCommandType.EXIT, reference_price=64500.0, target_size=0.005, leverage=2.0, reason="acct_test_exit", exit_leg_ratios=(0.5, 1.0), ) self.kernel.process_intent(intent) def test_capital_unchanged_after_entry(self): capital_before = self.kernel.account.snapshot.capital self._enter() capital_after = self.kernel.account.snapshot.capital self.assertEqual(capital_after, capital_before, "Entry should not change capital (no realized PnL)") def test_full_cycle_does_not_crash(self): """Run a full entry→partial exit lifecycle without errors.""" self._enter() slot_before = self.kernel.slot(0) self.assertTrue(slot_before.is_open(), "Slot should be open after entry") self._exit() # After partial exit, slot may still be open or closed depending on mock behavior slot_after = self.kernel.slot(0) self.assertIsNotNone(slot_after, "Slot should still exist after partial exit") if __name__ == "__main__": unittest.main()