feat: Add weekly performance metrics to Portfolio Overview section

This commit is contained in:
Bobby (aider) 2025-02-13 12:27:35 -08:00
parent 201d48c302
commit 00d00fb06b

View File

@ -1,6 +1,6 @@
import streamlit as st
import plotly.graph_objects as go
from datetime import datetime
from datetime import datetime, timedelta
import pytz
from trading.journal import (
create_trades_table, get_open_trades, get_trade_history,
@ -9,6 +9,44 @@ from trading.journal import (
get_position_summary, get_latest_portfolio_value, update_portfolio_value
)
def calculate_weekly_metrics(trades) -> dict:
"""Calculate weekly performance metrics"""
now = datetime.now(pytz.timezone('US/Pacific'))
week_start = (now - timedelta(days=now.weekday())).replace(hour=0, minute=0, second=0, microsecond=0)
weekly_pl = 0
weekly_trades = []
for trade in trades:
# For sells/exits that happened this week
if (trade.get('direction') == 'sell' or trade.get('exit_price')) and \
trade.get('exit_date', trade.get('entry_date')) >= week_start:
price = float(trade.get('exit_price') or trade.get('entry_price'))
shares = float(trade['shares'])
position_id = trade['position_id']
# Find matching buy order
buy_trades = [t for t in trades
if t['position_id'] == position_id and
(t.get('direction', '').lower() != 'sell' and not t.get('exit_price'))]
if buy_trades:
# Calculate average entry price
total_cost = sum(float(t['entry_price']) * float(t['shares']) for t in buy_trades)
total_shares = sum(float(t['shares']) for t in buy_trades)
avg_entry_price = total_cost / total_shares if total_shares > 0 else 0
# Calculate trade P/L
trade_pl = (price - avg_entry_price) * shares
weekly_pl += trade_pl
weekly_trades.append(trade)
return {
'weekly_pl': weekly_pl,
'weekly_trade_count': len(weekly_trades)
}
def calculate_portfolio_metrics(position_value: float, current_value: float, total_portfolio_value: float) -> dict:
"""Calculate portfolio metrics for a position"""
allocation = (current_value / total_portfolio_value) * 100 if total_portfolio_value > 0 else 0
@ -178,14 +216,34 @@ def trading_journal_page():
total_portfolio_value = latest_portfolio['total_value'] if latest_portfolio else 0
cash_balance = latest_portfolio['cash_balance'] if latest_portfolio else 0
# Get trade history for weekly metrics
trade_history = get_trade_history()
weekly_metrics = calculate_weekly_metrics(trade_history) if trade_history else {'weekly_pl': 0, 'weekly_trade_count': 0}
# Portfolio overview section
st.subheader("Portfolio Overview")
col1, col2 = st.columns(2)
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Total Portfolio Value", f"${total_portfolio_value:,.2f}")
st.metric("Cash Balance", f"${cash_balance:,.2f}",
f"{(cash_balance/total_portfolio_value)*100:.1f}% of Portfolio" if total_portfolio_value > 0 else "")
with col2:
# Weekly metrics
weekly_pl_pct = (weekly_metrics['weekly_pl'] / total_portfolio_value * 100) if total_portfolio_value > 0 else 0
st.metric("Week P/L",
f"${weekly_metrics['weekly_pl']:,.2f}",
f"{weekly_pl_pct:.2f}% | {weekly_metrics['weekly_trade_count']} trades")
with col3:
# Overall P/L metrics (from trade history)
total_pl = sum(trade.get('position_pl', 0) for trade in trade_history) if trade_history else 0
total_pl_pct = (total_pl / total_portfolio_value * 100) if total_portfolio_value > 0 else 0
st.metric("Overall P/L",
f"${total_pl:,.2f}",
f"{total_pl_pct:.2f}% since inception")
total_paper_pl = 0
invested_value = 0