From a8aea0349987d8f253f294e6955779e0705c2325 Mon Sep 17 00:00:00 2001 From: "Bobby (aider)" Date: Wed, 12 Feb 2025 17:10:23 -0800 Subject: [PATCH] feat: Refactor trading system page into separate module --- src/pages/trading/__init__.py | 1 + src/pages/trading/trading_system_page.py | 165 +++++++++++++++++++++++ src/streamlit_app.py | 157 --------------------- 3 files changed, 166 insertions(+), 157 deletions(-) create mode 100644 src/pages/trading/__init__.py diff --git a/src/pages/trading/__init__.py b/src/pages/trading/__init__.py new file mode 100644 index 0000000..dfa742b --- /dev/null +++ b/src/pages/trading/__init__.py @@ -0,0 +1 @@ +# Trading pages package diff --git a/src/pages/trading/trading_system_page.py b/src/pages/trading/trading_system_page.py index 6f8ab7b..837daaa 100644 --- a/src/pages/trading/trading_system_page.py +++ b/src/pages/trading/trading_system_page.py @@ -6,3 +6,168 @@ from trading.portfolio import Portfolio, Position from trading.position_calculator import PositionCalculator from pages.journal.trading_journal_page import format_datetime +import streamlit as st +import pandas as pd +from datetime import datetime +from trading.journal import get_latest_portfolio_value, update_portfolio_value, get_open_trades +from trading.portfolio import Portfolio, Position +from trading.position_calculator import PositionCalculator +from pages.journal.trading_journal_page import format_datetime + +def trading_system_page(): + st.header("Trading System") + + # Create tabs + calc_tab, portfolio_tab, value_tab = st.tabs(["Position Calculator", "Portfolio Management", "Portfolio Value"]) + + with calc_tab: + st.subheader("Position Calculator") + + # Get latest portfolio value for default account size + portfolio_data = get_latest_portfolio_value() + default_account_size = portfolio_data['total_value'] if portfolio_data else 100000.0 + + col1, col2 = st.columns(2) + with col1: + account_size = st.number_input("Account Size ($)", + min_value=0.0, + value=default_account_size, + step=1000.0) + risk_percentage = st.number_input("Risk Percentage (%)", + min_value=0.1, + max_value=100.0, + value=1.0, + step=0.1) + stop_loss_percentage = st.number_input("Stop Loss Percentage (%)", + min_value=0.1, + max_value=100.0, + value=7.0, + step=0.1) + + with col2: + entry_price = st.number_input("Entry Price ($)", min_value=0.01, step=0.01) + target_price = st.number_input("Target Price ($)", min_value=0.01, step=0.01) + + if st.button("Calculate Position"): + try: + calculator = PositionCalculator( + account_size=account_size, + risk_percentage=risk_percentage, + stop_loss_percentage=stop_loss_percentage + ) + + position = calculator.calculate_position_size(entry_price, target_price) + + col1, col2 = st.columns(2) + with col1: + st.metric("Number of Shares", f"{position['shares']:,}") + st.metric("Position Value", f"${position['position_value']:,.2f}") + st.metric("Risk Amount", f"${position['risk_amount']:,.2f}") + + with col2: + st.metric("Stop Loss Price", f"${position['stop_loss']:.2f}") + st.metric("Potential Loss", f"${position['potential_loss']:,.2f}") + if 'potential_profit' in position: + st.metric("Potential Profit", f"${position['potential_profit']:,.2f}") + st.metric("Risk/Reward Ratio", f"{position['risk_reward_ratio']:.2f}") + + except Exception as e: + st.error(f"Error calculating position: {str(e)}") + + with portfolio_tab: + st.subheader("Portfolio Management") + + # Initialize portfolio if not in session state + if 'portfolio' not in st.session_state: + st.session_state.portfolio = Portfolio() + + # Load existing open trades into portfolio + open_trades = get_open_trades() + for trade in open_trades: + position = Position( + symbol=trade['ticker'], + entry_date=trade['entry_date'], + entry_price=trade['entry_price'], + shares=trade['shares'], + stop_loss=trade['stop_loss'], + target_price=trade['target_price'] + ) + st.session_state.portfolio.add_position(position) + + # Add position form + with st.expander("Add New Position"): + col1, col2 = st.columns(2) + with col1: + symbol = st.text_input("Symbol").upper() + shares = st.number_input("Number of Shares", min_value=1, step=1) + entry_price = st.number_input("Entry Price ($)", min_value=0.01, step=0.01, key="port_entry_price") + + with col2: + target_price = st.number_input("Target Price ($)", min_value=0.01, step=0.01, key="port_target_price") + stop_loss = st.number_input("Stop Loss ($)", min_value=0.01, step=0.01) + + if st.button("Add Position"): + try: + position = Position( + symbol=symbol, + entry_date=datetime.now(), + entry_price=entry_price, + shares=shares, + stop_loss=stop_loss, + target_price=target_price + ) + st.session_state.portfolio.add_position(position) + st.success(f"Added position: {symbol}") + except Exception as e: + st.error(f"Error adding position: {str(e)}") + + # Display current portfolio + positions = st.session_state.portfolio.get_position_summary() + if positions: + st.subheader("Current Positions") + # Add a counter to make unique keys + for i, pos in enumerate(positions): + with st.expander(f"{pos['symbol']} Position - {format_datetime(pos['entry_date'])}"): + col1, col2 = st.columns(2) + with col1: + st.metric("Entry Price", f"${pos['entry_price']:.2f}") + st.metric("Shares", pos['shares']) + st.metric("Current Value", f"${pos['current_value']:.2f}") + + with col2: + st.metric("Stop Loss", f"${pos['stop_loss']:.2f}") + st.metric("Target", f"${pos['target_price']:.2f}") + st.metric("Risk/Reward", f"{pos['risk_reward_ratio']:.2f}") + + if st.button(f"Remove {pos['symbol']}", key=f"remove_{pos['symbol']}_{i}"): + st.session_state.portfolio.remove_position(pos['symbol']) + st.rerun() + else: + st.info("No positions in portfolio") + + with value_tab: + st.subheader("Portfolio Value Management") + + # Get latest portfolio value + portfolio_data = get_latest_portfolio_value() + + if portfolio_ + st.metric("Current Portfolio Value", f"${portfolio_data['total_value']:,.2f}") + st.metric("Cash Balance", f"${portfolio_data['cash_balance']:,.2f}") + st.text(f"Last Updated: {portfolio_data['date']}") + else: + st.info("No portfolio value data found") + + # Update portfolio value form + with st.expander("Update Portfolio Value"): + new_value = st.number_input("New Portfolio Value ($)", min_value=0.0, step=100.0) + new_cash = st.number_input("New Cash Balance ($)", min_value=0.0, step=100.0) + notes = st.text_area("Notes (optional)", key="portfolio_value_notes") + + if st.button("Update Values"): + try: + update_portfolio_value(new_value, new_cash, notes) + st.success("Portfolio value updated successfully!") + st.set_query_params(rerun=True) + except Exception as e: + st.error(f"Error updating portfolio value: {str(e)}") diff --git a/src/streamlit_app.py b/src/streamlit_app.py index 924d07e..2455dbd 100644 --- a/src/streamlit_app.py +++ b/src/streamlit_app.py @@ -35,163 +35,6 @@ def init_session_state(): -def trading_system_page(): - st.header("Trading System") - - # Create tabs - calc_tab, portfolio_tab, value_tab = st.tabs(["Position Calculator", "Portfolio Management", "Portfolio Value"]) - - with calc_tab: - st.subheader("Position Calculator") - - # Get latest portfolio value for default account size - portfolio_data = get_latest_portfolio_value() - default_account_size = portfolio_data['total_value'] if portfolio_data else 100000.0 - - col1, col2 = st.columns(2) - with col1: - account_size = st.number_input("Account Size ($)", - min_value=0.0, - value=default_account_size, - step=1000.0) - risk_percentage = st.number_input("Risk Percentage (%)", - min_value=0.1, - max_value=100.0, - value=1.0, - step=0.1) - stop_loss_percentage = st.number_input("Stop Loss Percentage (%)", - min_value=0.1, - max_value=100.0, - value=7.0, - step=0.1) - - with col2: - entry_price = st.number_input("Entry Price ($)", min_value=0.01, step=0.01) - target_price = st.number_input("Target Price ($)", min_value=0.01, step=0.01) - - if st.button("Calculate Position"): - try: - calculator = PositionCalculator( - account_size=account_size, - risk_percentage=risk_percentage, - stop_loss_percentage=stop_loss_percentage - ) - - position = calculator.calculate_position_size(entry_price, target_price) - - col1, col2 = st.columns(2) - with col1: - st.metric("Number of Shares", f"{position['shares']:,}") - st.metric("Position Value", f"${position['position_value']:,.2f}") - st.metric("Risk Amount", f"${position['risk_amount']:,.2f}") - - with col2: - st.metric("Stop Loss Price", f"${position['stop_loss']:.2f}") - st.metric("Potential Loss", f"${position['potential_loss']:,.2f}") - if 'potential_profit' in position: - st.metric("Potential Profit", f"${position['potential_profit']:,.2f}") - st.metric("Risk/Reward Ratio", f"{position['risk_reward_ratio']:.2f}") - - except Exception as e: - st.error(f"Error calculating position: {str(e)}") - - with portfolio_tab: - st.subheader("Portfolio Management") - - # Initialize portfolio if not in session state - if 'portfolio' not in st.session_state: - st.session_state.portfolio = Portfolio() - - # Load existing open trades into portfolio - open_trades = get_open_trades() - for trade in open_trades: - position = Position( - symbol=trade['ticker'], - entry_date=trade['entry_date'], - entry_price=trade['entry_price'], - shares=trade['shares'], - stop_loss=trade['stop_loss'], - target_price=trade['target_price'] - ) - st.session_state.portfolio.add_position(position) - - # Add position form - with st.expander("Add New Position"): - col1, col2 = st.columns(2) - with col1: - symbol = st.text_input("Symbol").upper() - shares = st.number_input("Number of Shares", min_value=1, step=1) - entry_price = st.number_input("Entry Price ($)", min_value=0.01, step=0.01, key="port_entry_price") - - with col2: - target_price = st.number_input("Target Price ($)", min_value=0.01, step=0.01, key="port_target_price") - stop_loss = st.number_input("Stop Loss ($)", min_value=0.01, step=0.01) - - if st.button("Add Position"): - try: - position = Position( - symbol=symbol, - entry_date=datetime.now(), - entry_price=entry_price, - shares=shares, - stop_loss=stop_loss, - target_price=target_price - ) - st.session_state.portfolio.add_position(position) - st.success(f"Added position: {symbol}") - except Exception as e: - st.error(f"Error adding position: {str(e)}") - - # Display current portfolio - positions = st.session_state.portfolio.get_position_summary() - if positions: - st.subheader("Current Positions") - # Add a counter to make unique keys - for i, pos in enumerate(positions): - with st.expander(f"{pos['symbol']} Position - {format_datetime(pos['entry_date'])}"): - col1, col2 = st.columns(2) - with col1: - st.metric("Entry Price", f"${pos['entry_price']:.2f}") - st.metric("Shares", pos['shares']) - st.metric("Current Value", f"${pos['current_value']:.2f}") - - with col2: - st.metric("Stop Loss", f"${pos['stop_loss']:.2f}") - st.metric("Target", f"${pos['target_price']:.2f}") - st.metric("Risk/Reward", f"{pos['risk_reward_ratio']:.2f}") - - if st.button(f"Remove {pos['symbol']}", key=f"remove_{pos['symbol']}_{i}"): - st.session_state.portfolio.remove_position(pos['symbol']) - st.rerun() - else: - st.info("No positions in portfolio") - - with value_tab: - st.subheader("Portfolio Value Management") - - # Get latest portfolio value - portfolio_data = get_latest_portfolio_value() - - if portfolio_data: - st.metric("Current Portfolio Value", f"${portfolio_data['total_value']:,.2f}") - st.metric("Cash Balance", f"${portfolio_data['cash_balance']:,.2f}") - st.text(f"Last Updated: {portfolio_data['date']}") - else: - st.info("No portfolio value data found") - - # Update portfolio value form - with st.expander("Update Portfolio Value"): - new_value = st.number_input("New Portfolio Value ($)", min_value=0.0, step=100.0) - new_cash = st.number_input("New Cash Balance ($)", min_value=0.0, step=100.0) - notes = st.text_area("Notes (optional)", key="portfolio_value_notes") - - if st.button("Update Values"): - try: - update_portfolio_value(new_value, new_cash, notes) - st.success("Portfolio value updated successfully!") - st.set_query_params(rerun=True) - except Exception as e: - st.error(f"Error updating portfolio value: {str(e)}") def trading_plan_page():