refactor: Enhance trade history display with performance metrics and detailed trade information
This commit is contained in:
parent
b1b22ac026
commit
47b58faddd
@ -9,6 +9,39 @@ from trading.journal import (
|
||||
get_position_summary, get_latest_portfolio_value, update_portfolio_value
|
||||
)
|
||||
|
||||
def calculate_position_performance(trades):
|
||||
"""Calculate performance metrics for a group of trades"""
|
||||
total_bought = 0
|
||||
total_cost = 0
|
||||
total_sold = 0
|
||||
total_proceeds = 0
|
||||
|
||||
for trade in trades:
|
||||
if trade['direction'] == 'buy':
|
||||
shares = float(trade['shares'])
|
||||
price = float(trade['entry_price'])
|
||||
total_bought += shares
|
||||
total_cost += shares * price
|
||||
elif trade['direction'] == 'sell':
|
||||
shares = float(trade['shares'])
|
||||
price = float(trade['entry_price']) # For sells, entry_price is the exit price
|
||||
total_sold += shares
|
||||
total_proceeds += shares * price
|
||||
|
||||
avg_entry = total_cost / total_bought if total_bought > 0 else 0
|
||||
avg_exit = total_proceeds / total_sold if total_sold > 0 else 0
|
||||
realized_pl = total_proceeds - (total_sold / total_bought * total_cost) if total_bought > 0 else 0
|
||||
remaining_shares = total_bought - total_sold
|
||||
|
||||
return {
|
||||
'total_bought': total_bought,
|
||||
'total_sold': total_sold,
|
||||
'avg_entry': avg_entry,
|
||||
'avg_exit': avg_exit,
|
||||
'realized_pl': realized_pl,
|
||||
'remaining_shares': remaining_shares
|
||||
}
|
||||
|
||||
def format_datetime(dt):
|
||||
"""Format datetime for display"""
|
||||
if dt:
|
||||
@ -310,45 +343,59 @@ def trading_journal_page():
|
||||
trades.sort(key=lambda x: (x['entry_date'], 0 if x.get('direction') == 'buy' else 1))
|
||||
first_trade = trades[0]
|
||||
|
||||
# Calculate position performance
|
||||
performance = calculate_position_performance(trades)
|
||||
|
||||
with st.expander(f"{first_trade['ticker']} - Position {position_id}"):
|
||||
# Show position summary
|
||||
col1, col2, col3 = st.columns(3)
|
||||
with col1:
|
||||
st.metric("Total Shares Bought", f"{int(performance['total_bought']):,}")
|
||||
st.metric("Avg Entry", f"${performance['avg_entry']:.2f}")
|
||||
with col2:
|
||||
st.metric("Total Shares Sold", f"{int(performance['total_sold']):,}")
|
||||
st.metric("Avg Exit", f"${performance['avg_exit']:.2f}")
|
||||
with col3:
|
||||
st.metric("Remaining Shares", f"{int(performance['remaining_shares']):,}")
|
||||
st.metric("Realized P/L",
|
||||
f"${performance['realized_pl']:.2f}",
|
||||
f"{(performance['realized_pl'] / (performance['total_sold'] * performance['avg_entry']) * 100):.2f}%" if performance['total_sold'] > 0 else None)
|
||||
|
||||
st.markdown("---")
|
||||
|
||||
# Show buy trades
|
||||
st.subheader("Buy Orders")
|
||||
for trade in trades:
|
||||
st.markdown(f"**{format_datetime(trade['entry_date'])}**")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
try:
|
||||
if trade['direction'] == 'sell':
|
||||
# For sells, use entry_price as the exit price
|
||||
exit_price = float(trade['entry_price'])
|
||||
st.metric("Exit Price", f"${exit_price:.2f}")
|
||||
# Update the trade's exit_price and exit_date
|
||||
trade['exit_price'] = exit_price
|
||||
trade['exit_date'] = trade['entry_date']
|
||||
else:
|
||||
entry_price = float(trade['entry_price'])
|
||||
st.metric("Entry Price", f"${entry_price:.2f}")
|
||||
except (ValueError, TypeError):
|
||||
price_label = "Exit Price" if trade['direction'] == 'sell' else "Entry Price"
|
||||
st.metric(price_label, "N/A")
|
||||
st.metric("Shares", trade['shares'])
|
||||
direction = trade.get('direction', 'buy')
|
||||
if isinstance(direction, str):
|
||||
st.metric("Type", direction.capitalize())
|
||||
else:
|
||||
st.metric("Type", "Buy") # Default value if direction is not a string
|
||||
|
||||
with col2:
|
||||
if trade['direction'] == 'buy':
|
||||
if trade['direction'] == 'buy':
|
||||
col1, col2, col3 = st.columns(3)
|
||||
with col1:
|
||||
st.text(f"Date: {format_datetime(trade['entry_date'])}")
|
||||
st.text(f"Shares: {trade['shares']}")
|
||||
with col2:
|
||||
st.text(f"Price: ${float(trade['entry_price']):.2f}")
|
||||
st.text(f"Order: {trade['order_type']}")
|
||||
with col3:
|
||||
if trade.get('target_price'):
|
||||
st.metric("Target", f"${trade['target_price']:.2f}")
|
||||
st.text(f"Target: ${float(trade['target_price']):.2f}")
|
||||
if trade.get('stop_loss'):
|
||||
st.metric("Stop Loss", f"${trade['stop_loss']:.2f}")
|
||||
|
||||
if trade.get('strategy'):
|
||||
st.text(f"Strategy: {trade['strategy']}")
|
||||
if trade.get('notes'):
|
||||
st.text(f"Notes: {trade['notes']}")
|
||||
|
||||
st.markdown("---")
|
||||
st.text(f"Stop: ${float(trade['stop_loss']):.2f}")
|
||||
if trade.get('entry_reason'):
|
||||
st.text(f"Reason: {trade['entry_reason']}")
|
||||
st.markdown("---")
|
||||
|
||||
# Show sell trades
|
||||
st.subheader("Sell Orders")
|
||||
for trade in trades:
|
||||
if trade['direction'] == 'sell':
|
||||
col1, col2 = st.columns(2)
|
||||
with col1:
|
||||
st.text(f"Date: {format_datetime(trade['entry_date'])}")
|
||||
st.text(f"Shares: {trade['shares']}")
|
||||
with col2:
|
||||
st.text(f"Price: ${float(trade['entry_price']):.2f}")
|
||||
st.text(f"Order: {trade['order_type']}")
|
||||
if trade.get('exit_reason'):
|
||||
st.text(f"Reason: {trade['exit_reason']}")
|
||||
st.markdown("---")
|
||||
else:
|
||||
st.info("No trade history found")
|
||||
|
||||
Loading…
Reference in New Issue
Block a user