Fix spot balance Value column to show USD value instead of raw token amount
This commit is contained in:
105
dashboard.py
105
dashboard.py
@ -6,7 +6,7 @@ Provides DashboardRenderer for building rich terminal tables and layouts.
|
|||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from rich.console import Console, Group
|
from rich.console import Console
|
||||||
from rich.table import Table
|
from rich.table import Table
|
||||||
from rich.live import Live
|
from rich.live import Live
|
||||||
from rich.layout import Layout
|
from rich.layout import Layout
|
||||||
@ -29,6 +29,7 @@ class DashboardRenderer:
|
|||||||
"market": True,
|
"market": True,
|
||||||
"strategies": False,
|
"strategies": False,
|
||||||
"indicators": True,
|
"indicators": True,
|
||||||
|
"balances": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
def toggle_table(self, table_name, enabled=None):
|
def toggle_table(self, table_name, enabled=None):
|
||||||
@ -115,6 +116,9 @@ class DashboardRenderer:
|
|||||||
Text(direction, style=direction_style)
|
Text(direction, style=direction_style)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if coin == "SUI":
|
||||||
|
table.add_section()
|
||||||
|
|
||||||
if mid is not None:
|
if mid is not None:
|
||||||
self.previous_prices[coin] = mid
|
self.previous_prices[coin] = mid
|
||||||
|
|
||||||
@ -239,16 +243,105 @@ class DashboardRenderer:
|
|||||||
|
|
||||||
return table
|
return table
|
||||||
|
|
||||||
def build_layout(self, watched_coins, prices, display_names, strategy_statuses, strategy_configs, indicators_status=None):
|
def build_balances_table(self, account_data, prices=None):
|
||||||
"""Build the complete dashboard layout with vertically stacked tables."""
|
"""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 = []
|
tables = []
|
||||||
|
|
||||||
if self.table_visibility.get("market", True):
|
if self.table_visibility.get("market", True):
|
||||||
tables.append(self.build_market_table(watched_coins, prices, display_names))
|
tables.append(self.build_market_table(watched_coins, prices, display_names))
|
||||||
if self.table_visibility.get("indicators", True):
|
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):
|
if self.table_visibility.get("strategies", True):
|
||||||
tables.append(self.build_strategy_table(strategy_statuses, strategy_configs))
|
tables.append(self.build_strategy_table(strategy_statuses, strategy_configs))
|
||||||
|
|
||||||
if not tables:
|
if not tables:
|
||||||
return Layout()
|
return RichLayout()
|
||||||
return Layout(Group(*tables))
|
|
||||||
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user