From 76f58386dc6da362405c40f96325556d8088ec48 Mon Sep 17 00:00:00 2001 From: DiTus Date: Thu, 30 Jul 2026 11:53:28 +0200 Subject: [PATCH] Fix spot balance Value column to show USD value instead of raw token amount --- dashboard.py | 105 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 6 deletions(-) diff --git a/dashboard.py b/dashboard.py index ef4f281..b13dafe 100644 --- a/dashboard.py +++ b/dashboard.py @@ -6,7 +6,7 @@ Provides DashboardRenderer for building rich terminal tables and layouts. from datetime import datetime, timezone try: - from rich.console import Console, Group + from rich.console import Console from rich.table import Table from rich.live import Live from rich.layout import Layout @@ -29,6 +29,7 @@ class DashboardRenderer: "market": True, "strategies": False, "indicators": True, + "balances": True, } def toggle_table(self, table_name, enabled=None): @@ -115,6 +116,9 @@ class DashboardRenderer: Text(direction, style=direction_style) ) + if coin == "SUI": + table.add_section() + if mid is not None: self.previous_prices[coin] = mid @@ -239,16 +243,105 @@ class DashboardRenderer: return table - def build_layout(self, watched_coins, prices, display_names, strategy_statuses, strategy_configs, indicators_status=None): - """Build the complete dashboard layout with vertically stacked tables.""" + def build_balances_table(self, account_data, prices=None): + """Build a combined balances and open positions table. + + Args: + account_data: dict with keys: + - spot_balances: list of {coin, total} + - positions: list of position dicts with position data + - account_value: float + - margin_used: float + - utilization: float + prices: dict mapping coin names to current mark prices + """ + if prices is None: + prices = {} + table = Table(show_header=True, header_style="bold cyan", title="Account Summary") + table.add_column("Type", justify="center", width=8) + table.add_column("Coin", justify="center", width=8) + table.add_column("Size", justify="right", width=12) + table.add_column("Value", justify="right", width=12) + + spot_balances = account_data.get('spot_balances', []) + for bal in spot_balances: + total = float(bal.get('total', 0)) + if total > 0: + coin = bal.get('coin', 'Unknown') + mark_price = float(prices.get(coin, 0)) + usd_value = total * mark_price + table.add_row( + Text("Spot", style="blue"), + coin, + f"{total:,.4f}", + f"${usd_value:,.2f}" + ) + + positions = account_data.get('positions', []) + for pos in positions: + position = pos.get('position', {}) + coin = position.get('coin', 'Unknown') + size = float(position.get('szi', 0)) + if size != 0: + position_value = float(position.get('positionValue', 0)) + side = "LONG" if size > 0 else "SHORT" + side_style = "green" if size > 0 else "red" + + table.add_row( + Text(f"P({side})", style=side_style), + coin, + f"{size:,.4f}", + f"${position_value:,.2f}" + ) + + if not spot_balances and not positions: + table.add_row("None", "-", "-", "-") + + account_value = account_data.get('account_value', 0) + margin_used = account_data.get('margin_used', 0) + utilization = account_data.get('utilization', 0) + +# table.add_section() + table.add_row( + Text("Acct", style="bold"), + "-", "-", + f"${account_value:,.2f}" + ) + table.add_row( + Text("Util", style="bold"), + "-", "-", + f"{utilization:.2f}%" + ) + + return table + + def build_layout(self, watched_coins, prices, display_names, strategy_statuses, strategy_configs, indicators_status=None, account_data=None): + """Build the complete dashboard layout in a 2x2 grid.""" + from rich.layout import Layout as RichLayout + tables = [] + if self.table_visibility.get("market", True): tables.append(self.build_market_table(watched_coins, prices, display_names)) if self.table_visibility.get("indicators", True): - tables.append(Padding(self.build_indicators_table(indicators_status), (2, 0, 0, 0))) + tables.append(Padding(self.build_indicators_table(indicators_status), (0, 0, 0, 2))) + if account_data is not None and self.table_visibility.get("balances", True): + tables.append(Padding(self.build_balances_table(account_data, prices), (0, 0, 0, 2))) if self.table_visibility.get("strategies", True): tables.append(self.build_strategy_table(strategy_statuses, strategy_configs)) if not tables: - return Layout() - return Layout(Group(*tables)) + return RichLayout() + + if len(tables) <= 2: + layout = RichLayout() + layout.split_row(*tables) + return layout + + top = RichLayout(ratio=1) + bottom = RichLayout(ratio=2) + top.split_row(*tables[:2]) + bottom.split_row(*tables[2:]) + layout = RichLayout() + layout.split_column(top, bottom) + return layout