Coverage for src / monte_neo / visualization / trades.py: 52%

40 statements  

« prev     ^ index     » next       coverage.py v7.13.1, created at 2026-01-28 16:27 +0200

1"""Trade visualization module.""" 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING 

6 

7from rich.console import Console 

8from rich.table import Table 

9 

10if TYPE_CHECKING: 

11 pass 

12 

13console = Console() 

14 

15 

16class TradeVisualizer: 

17 """Visualize trade results.""" 

18 

19 def show_trades_table( 

20 self, 

21 trades: list, 

22 limit: int = 20, 

23 ) -> None: 

24 """Display trades in a table. 

25 

26 Args: 

27 trades: List of TradeResult objects. 

28 limit: Maximum trades to show. 

29 """ 

30 table = Table( 

31 title=f"Trades (showing {min(limit, len(trades))} of {len(trades)})" 

32 ) 

33 

34 table.add_column("#", style="dim") 

35 table.add_column("Entry", style="cyan") 

36 table.add_column("Exit", style="cyan") 

37 table.add_column("Direction", style="blue") 

38 table.add_column("Entry Price", style="white") 

39 table.add_column("Exit Price", style="white") 

40 table.add_column("P&L %", style="green") 

41 

42 for i, trade in enumerate(trades[:limit]): 

43 pnl_style = "green" if trade.pnl_pct > 0 else "red" 

44 direction = "LONG" if trade.direction == 1 else "SHORT" 

45 

46 table.add_row( 

47 str(i + 1), 

48 str(trade.entry_idx), 

49 str(trade.exit_idx), 

50 direction, 

51 f"{trade.entry_price:.2f}", 

52 f"{trade.exit_price:.2f}", 

53 f"[{pnl_style}]{trade.pnl_pct * 100:.2f}%[/]", 

54 ) 

55 

56 console.print(table) 

57 

58 def show_trade_summary(self, trades: list) -> None: 

59 """Show trade summary statistics. 

60 

61 Args: 

62 trades: List of TradeResult objects. 

63 """ 

64 if not trades: 

65 console.print("[yellow]No trades to display[/]") 

66 return 

67 

68 winners = [t for t in trades if t.pnl > 0] 

69 losers = [t for t in trades if t.pnl < 0] 

70 

71 table = Table(title="Trade Summary") 

72 table.add_column("Stat", style="cyan") 

73 table.add_column("Value", style="green") 

74 

75 table.add_row("Total Trades", str(len(trades))) 

76 table.add_row("Winners", str(len(winners))) 

77 table.add_row("Losers", str(len(losers))) 

78 table.add_row("Win Rate", f"{len(winners) / len(trades) * 100:.1f}%") 

79 

80 if winners: 

81 avg_win = sum(t.pnl_pct for t in winners) / len(winners) 

82 table.add_row("Avg Win", f"{avg_win * 100:.2f}%") 

83 

84 if losers: 

85 avg_loss = sum(t.pnl_pct for t in losers) / len(losers) 

86 table.add_row("Avg Loss", f"{avg_loss * 100:.2f}%") 

87 

88 console.print(table)