"""Tests for atm.report.""" from __future__ import annotations import pytest from atm.journal import TradeEntry from atm.report import iso_week, weekly_report WEEK = "2026-16" BASE_TS = "2026-04-14T10:00:00" def _trade( outcome: str, direction: str = "BUY", entry: float = 100.0, sl: float = 90.0, exit_: float | None = None, detected_ts: str | None = None, ts: str = BASE_TS, ) -> TradeEntry: return TradeEntry( ts=ts, direction=direction, symbol="US30", entry=entry, sl=sl, tp1=None, tp2=None, exit=exit_, outcome=outcome, detected_ts=detected_ts, notes="", ) def test_win_rate_and_pnl() -> None: """5 synthetic trades: tp1 +2R, tp2 +3R, sl -1.5R, manual +2R, open excluded.""" trades = [ # tp1: BUY, entry=100, sl=90, exit=120 → R = (120-100)/(100-90) = +2.0 _trade("tp1", exit_=120.0, detected_ts="2026-04-14T09:59:55"), # tp2: BUY, entry=100, sl=90, exit=130 → R = (130-100)/(100-90) = +3.0 _trade("tp2", exit_=130.0), # sl: BUY, entry=100, sl=90, exit=85 → R = (85-100)/(100-90) = -1.5 _trade("sl", exit_=85.0, detected_ts="2026-04-14T09:59:50"), # manual: SELL, entry=100, sl=110, exit=80 → R = (80-100)/(100-110) = +2.0 _trade("manual", direction="SELL", sl=110.0, exit_=80.0), # open: excluded from counts _trade("open"), ] report = weekly_report(trades, WEEK) assert report.week == WEEK assert report.n_trades == 4 assert report.n_wins == 2 assert report.n_losses == 2 assert report.win_rate == pytest.approx(0.5) assert report.pnl_r == pytest.approx(5.5) # slippage: trade[0]=5s, trade[2]=10s → avg=7.5s assert report.avg_slippage == pytest.approx(7.5) def test_iso_week() -> None: assert iso_week("2026-04-14T10:00:00") == "2026-16" assert iso_week("2026-01-01T00:00:00") == "2026-01" def test_empty_week() -> None: report = weekly_report([], WEEK) assert report.n_trades == 0 assert report.n_wins == 0 assert report.n_losses == 0 assert report.win_rate == 0.0 assert report.pnl_r == 0.0 assert report.avg_slippage is None