import unittest from trade_exchange_stats_lib import ( aggregate_bilateral_stats, commission_usdt_from_fill, filter_position_lifecycle_fills, merge_commission_prefer_income, quote_turnover_usdt_from_fill, ) class TradeExchangeStatsTests(unittest.TestCase): def test_turnover_from_cost(self): t = {"cost": 1000.0, "price": 50, "amount": 20} self.assertEqual(quote_turnover_usdt_from_fill(t), 1000.0) def test_commission_from_fee(self): t = {"fee": {"cost": -0.42, "currency": "USDT"}} self.assertEqual(commission_usdt_from_fill(t), 0.42) def test_bilateral_aggregate(self): fills = [ {"side": "buy", "cost": 500, "fee": {"cost": -0.2, "currency": "USDT"}, "timestamp": 1000}, {"side": "sell", "cost": 520, "fee": {"cost": -0.21, "currency": "USDT"}, "timestamp": 2000}, ] stats = aggregate_bilateral_stats(fills) self.assertIsNotNone(stats) self.assertEqual(stats["exchange_turnover_usdt"], 1020.0) self.assertEqual(stats["exchange_commission_usdt"], 0.41) def test_filter_long_lifecycle(self): base = 1_700_000_000_000 trades = [ {"side": "buy", "timestamp": base, "cost": 100}, {"side": "sell", "timestamp": base + 60_000, "cost": 110}, {"side": "buy", "timestamp": base + 120_000, "cost": 999}, ] got = filter_position_lifecycle_fills( trades, "long", base - 1000, base + 90_000, close_buffer_ms=0 ) self.assertEqual(len(got), 2) def test_prefer_income_commission(self): self.assertEqual(merge_commission_prefer_income(0.3, 0.45), 0.45) if __name__ == "__main__": unittest.main()