import streamlit as st import plotly.graph_objects as go import pandas as pd def render_portfolio(portfolio_manager, current_prices: dict, db): st.header("Portfolio Simulator") pv = portfolio_manager.get_portfolio_value(current_prices) cols = st.columns(5) cols[0].metric("Initial Capital", f"${portfolio_manager.initial_capital:.2f}") cols[1].metric("Current Value", f"${pv['total_value']:.2f}") pnl_delta = f"{pv['pnl_pct']:+.1f}%" cols[2].metric("Total P&L", f"${pv['total_pnl']:+.2f}", pnl_delta) cols[3].metric("Win Rate", f"{pv['win_rate']:.0f}%") cols[4].metric("Available Cash", f"${pv['cash']:.2f}") st.divider() col_left, col_right = st.columns([3, 2]) with col_left: st.subheader("Current Holdings") if portfolio_manager.positions: rows = [] for sym, pos in portfolio_manager.positions.items(): price = current_prices.get(sym, pos["entry_price"]) value = pos["quantity"] * price pnl = value - pos["invested_usd"] pnl_pct = (pnl / pos["invested_usd"] * 100) if pos["invested_usd"] > 0 else 0 rows.append({ "Coin": sym.replace("USDT", ""), "Invested": f"${pos['invested_usd']:.2f}", "Qty": f"{pos['quantity']:.6f}", "Entry": f"${pos['entry_price']:.4f}", "Current": f"${price:.4f}", "P&L": f"${pnl:+.2f} ({pnl_pct:+.1f}%)", }) st.dataframe(pd.DataFrame(rows), use_container_width=True, hide_index=True) else: st.info("No open positions") with col_right: st.subheader("Allocation") if portfolio_manager.positions: labels = [s.replace("USDT", "") for s in portfolio_manager.positions] values = [p["quantity"] * current_prices.get(s, p["entry_price"]) for s, p in portfolio_manager.positions.items()] labels.append("Cash") values.append(pv["cash"]) fig = go.Figure(data=[go.Pie(labels=labels, values=values, hole=0.4)]) fig.update_layout(template="plotly_dark", height=300, margin=dict(t=20, b=20)) st.plotly_chart(fig, use_container_width=True) else: st.info("100% Cash") st.divider() st.subheader("Trade History") if portfolio_manager.trades: trade_rows = [] for t in reversed(portfolio_manager.trades[-20:]): trade_rows.append({ "Time": t["timestamp"][:16], "Coin": t["coin"].replace("USDT", ""), "Side": t["side"], "Price": f"${t['price']:.4f}", "Amount": f"${t['amount_usd']:.2f}", "Reason": t["reason"], }) st.dataframe(pd.DataFrame(trade_rows), use_container_width=True, hide_index=True) else: st.info("No trades yet")