"""Contracts of the live pipeline: price panel refresh, session gating, order sizing, and how results are reported.""" import unittest from datetime import datetime, timezone import numpy as np import pandas as pd import bridge import data_manager import trader from main import backtest def _panel(rows: dict[str, list], start: str = "2026-09-14") -> pd.DataFrame: idx = pd.bdate_range(start, periods=len(next(iter(rows.values())))) return pd.DataFrame(rows, index=idx, dtype=float) class PanelRefreshTests(unittest.TestCase): def test_refresh_overwrites_stale_window_and_keeps_missing_bars_raw(self): stored = _panel({"AAA": [10, 11, 11, 11, 12], "BBB": [5, 5, 5, 5, 5]}) window_start = stored.index[2] fresh = pd.DataFrame( {"AAA": [11.5, np.nan, 12.2]}, index=stored.index[2:], ) merged = data_manager._merge_refresh(stored, fresh, window_start) self.assertEqual(merged.loc[stored.index[2], "AAA"], 11.5) self.assertTrue(np.isnan(merged.loc[stored.index[3], "AAA"])) self.assertEqual(merged.loc[stored.index[4], "AAA"], 12.2) # Tickers not in the refresh keep their stored values. self.assertEqual(merged.loc[stored.index[3], "BBB"], 5) def test_refresh_rescales_history_after_split_adjustment(self): stored = _panel({"AAA": [100, 102, 104, 106, 108, 110, 112]}) window_start = stored.index[2] # Yahoo now reports the whole window divided by 2 (2:1 split adjusted). fresh = stored.loc[window_start:, ["AAA"]] / 2 merged = data_manager._merge_refresh(stored, fresh, window_start) returns = merged["AAA"].pct_change().dropna() self.assertTrue((returns > 0).all(), returns) self.assertAlmostEqual(merged["AAA"].iloc[0], 50.0) def test_newest_row_printed_by_few_tickers_is_dropped(self): panel = _panel({ "A": [1, 1, 1, np.nan], "B": [1, 1, 1, np.nan], "C": [1, 1, 1, np.nan], "D": [1, 1, 1, 2], }) self.assertNotIn(panel.index[-1], data_manager._drop_sparse_rows(panel).index) def test_rows_printed_by_a_minority_of_tickers_are_dropped(self): panel = _panel({ "SPY": [1, 1, np.nan, 1, 1], "UPRO": [1, 1, np.nan, 1, 1], "GLD": [1, 1, np.nan, 1, 1], "7200.HK": [1, 1, 1, 1, 1], }) cleaned = data_manager._drop_sparse_rows(panel) self.assertNotIn(panel.index[2], cleaned.index) self.assertEqual(len(cleaned), 4) class SessionAndOrderTests(unittest.TestCase): def test_todays_bar_is_not_a_close_until_the_session_settles(self): raw = _panel({"SPY": [1, 1, 1]}, start="2026-09-22") today = raw.index[-1] intraday = datetime(2026, 9, 24, 17, 0, tzinfo=timezone.utc) # 13:00 New York settled = datetime(2026, 9, 24, 20, 30, tzinfo=timezone.utc) # 16:30 New York self.assertNotIn(today, trader.completed_sessions(raw, "us", "SPY", now=intraday)) self.assertIn(today, trader.completed_sessions(raw, "us", "SPY", now=settled)) def test_days_without_a_benchmark_print_are_not_sessions(self): raw = _panel({"SPY": [1, np.nan, 1], "7200.HK": [1, 1, 1]}, start="2026-09-02") later = datetime(2026, 10, 1, tzinfo=timezone.utc) sessions = trader.completed_sessions(raw, "etfs", "SPY", now=later) self.assertNotIn(raw.index[1], sessions) def test_a_share_orders_use_board_lots_and_exit_odd_lots(self): trades = trader.compute_trades( holdings={"600000.SS": 150}, cash=100_000.0, target_weights={"600519.SS": 0.5}, prices={"600519.SS": 170.0, "600000.SS": 10.0}, min_trade_value=50, integer_shares=True, lot_size=100, ) by_ticker = {t["ticker"]: t["shares_delta"] for t in trades} self.assertEqual(by_ticker["600519.SS"] % 100, 0) self.assertEqual(by_ticker["600000.SS"], -150) def test_tickers_without_a_fresh_price_are_not_traded(self): trades = trader.compute_trades( holdings={"UPRO": 10}, cash=5_000.0, target_weights={"TQQQ": 1.0}, prices={"UPRO": 150.0, "TQQQ": 80.0}, frozen={"UPRO"}, ) self.assertEqual([t["ticker"] for t in trades], ["TQQQ"]) class ReportingTests(unittest.TestCase): def test_periodic_returns_include_the_first_day_of_each_period(self): idx = pd.to_datetime(["2026-01-30", "2026-02-02", "2026-02-27", "2026-03-02"]) equity = pd.Series([100.0, 110.0, 110.0, 121.0], index=idx) monthly, yearly = bridge.compute_periodic_returns(equity) self.assertAlmostEqual(monthly["2026-02"], 0.10) self.assertAlmostEqual(monthly["2026-03"], 0.10) self.assertAlmostEqual(yearly["2026"], 0.21) def test_injected_cash_is_not_reported_as_performance(self): idx = pd.bdate_range("2024-01-02", periods=400) equity = pd.Series(10_000 * 1.0003 ** np.arange(400), index=idx) schedule = {"amount": 5_000, "frequency": "yearly_months", "months": [2, 8], "startYear": 1} plain = bridge._build_strategy_result("x", equity, [], None, 10_000) injected = bridge._build_strategy_result("x", equity, [], schedule, 10_000) self.assertAlmostEqual(injected["metrics"]["totalReturn"], plain["metrics"]["totalReturn"]) flows = injected["capitalFlows"] self.assertEqual(flows["invested"], 10_000 + 5_000 * len(injected["injections"])) self.assertAlmostEqual(flows["profit"], flows["finalValue"] - flows["invested"], places=2) def test_ruined_portfolio_stays_at_zero(self): class TwiceLevered: def generate_signals(self, data): return pd.DataFrame(2.0, index=data.index, columns=data.columns) prices = pd.DataFrame({"X": [10.0, 10.0, 4.0, 5.0]}, index=pd.bdate_range("2026-01-01", periods=4)) equity = backtest(TwiceLevered(), prices, initial_capital=100) self.assertTrue((equity.iloc[2:] == 0).all(), equity) if __name__ == "__main__": unittest.main()