feat: Refactor trading system page into separate module
This commit is contained in:
parent
2fcf238f6b
commit
a8aea03499
1
src/pages/trading/__init__.py
Normal file
1
src/pages/trading/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Trading pages package
|
||||||
@ -6,3 +6,168 @@ from trading.portfolio import Portfolio, Position
|
|||||||
from trading.position_calculator import PositionCalculator
|
from trading.position_calculator import PositionCalculator
|
||||||
from pages.journal.trading_journal_page import format_datetime
|
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)}")
|
||||||
|
|||||||
@ -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():
|
def trading_plan_page():
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user