import streamlit as st from db.db_connection import create_client from trading.trading_plan import ( delete_trading_plan, TradingPlan, PlanStatus, Timeframe, MarketFocus, TradeFrequency, save_trading_plan, get_trading_plan, get_all_trading_plans, update_trading_plan, get_plan_trades, link_trades_to_plan, calculate_plan_metrics, unlink_trades_from_plan ) def trading_plan_page(): st.header("Trading Plans") # Create tabs for different plan operations list_tab, add_tab, edit_tab = st.tabs(["View Plans", "Add Plan", "Edit Plan"]) with list_tab: st.subheader("Trading Plans") plans = get_all_trading_plans() if plans: for plan in plans: with st.expander(f"{plan.plan_name} ({plan.status.value})"): col1, col2 = st.columns(2) with col1: st.markdown("### Basic Information") st.write(f"**Plan Name:** {plan.plan_name}") st.write(f"**Status:** {plan.status.value}") st.write(f"**Author:** {plan.plan_author}") st.write(f"**Version:** {plan.strategy_version}") st.write(f"**Created:** {plan.created_at}") st.write(f"**Updated:** {plan.updated_at}") st.markdown("### Market Details") st.write(f"**Timeframe:** {plan.timeframe.value}") st.write(f"**Market:** {plan.market_focus.value}") st.write(f"**Frequency:** {plan.trade_frequency.value}") if plan.sector_focus: st.write(f"**Sector Focus:** {plan.sector_focus}") with col2: st.markdown("### Risk Parameters") st.write(f"**Stop Loss:** {plan.stop_loss}%") st.write(f"**Profit Target:** {plan.profit_target}%") st.write(f"**Risk/Reward Ratio:** {plan.risk_reward_ratio}") st.write(f"**Position Size:** {plan.position_sizing}%") st.write(f"**Risk per Trade:** {plan.total_risk_per_trade}%") st.write(f"**Max Portfolio Risk:** {plan.max_portfolio_risk}%") st.write(f"**Max Drawdown:** {plan.maximum_drawdown}%") st.write(f"**Max Trades/Day:** {plan.max_trades_per_day}") st.write(f"**Max Trades/Week:** {plan.max_trades_per_week}") st.markdown("### Performance Metrics") if any([plan.win_rate, plan.average_return_per_trade, plan.profit_factor]): col3, col4 = st.columns(2) with col3: if plan.win_rate: st.write(f"**Win Rate:** {plan.win_rate}%") if plan.average_return_per_trade: st.write(f"**Avg Return/Trade:** {plan.average_return_per_trade}%") with col4: if plan.profit_factor: st.write(f"**Profit Factor:** {plan.profit_factor}") st.markdown("### Linked Trades") plan_trades = get_plan_trades(plan.id) if plan_trades: total_pl = 0 winning_trades = 0 total_trades = len(plan_trades) st.markdown("#### Trade Statistics") col1, col2 = st.columns(2) with col1: st.write(f"**Total Trades:** {total_trades}") st.write(f"**Winning Trades:** {winning_trades}") if total_trades > 0: st.write(f"**Win Rate:** {(winning_trades/total_trades)*100:.2f}%") with col2: st.write(f"**Total P/L:** ${total_pl:.2f}") if total_trades > 0: st.write(f"**Average P/L per Trade:** ${total_pl/total_trades:.2f}") st.markdown("#### Individual Trades") for trade in plan_trades: st.markdown("---") cols = st.columns(3) with cols[0]: st.write(f"**{trade['ticker']} - {trade['entry_date']}**") st.write(f"**Direction:** {trade['direction']}") if trade['strategy']: st.write(f"**Strategy:** {trade['strategy']}") with cols[1]: st.write(f"**Entry:** ${trade['entry_price']:.2f}") st.write(f"**Shares:** {trade['shares']}") with cols[2]: if trade['exit_price']: pl = (trade['exit_price'] - trade['entry_price']) * trade['shares'] total_pl += pl if pl > 0: winning_trades += 1 st.write(f"**Exit:** ${trade['exit_price']:.2f}") st.write(f"**P/L:** ${pl:.2f}") st.write(f"**Exit Date:** {trade['exit_date']}") else: st.write("**Status:** Open") else: st.info("No trades linked to this plan") st.markdown("### Strategy Details") st.write("**Entry Criteria:**") st.write(plan.entry_criteria) st.write("**Exit Criteria:**") st.write(plan.exit_criteria) st.write("**Entry Confirmation:**") st.write(plan.entry_confirmation) st.write("**Market Conditions:**") st.write(plan.market_conditions) st.write("**Technical Indicators:**") st.write(plan.indicators_used) st.markdown("### Risk Management") st.write("**Drawdown Adjustments:**") st.write(plan.adjustments_for_drawdown) st.write("**Risk Controls:**") st.write(plan.risk_controls) if plan.fundamental_criteria: st.markdown("### Fundamental Analysis") st.write(plan.fundamental_criteria) if plan.options_strategy_details: st.markdown("### Options Strategy") st.write(plan.options_strategy_details) if plan.improvements_needed: st.markdown("### Areas for Improvement") st.write(plan.improvements_needed) if plan.trade_review_notes: st.markdown("### Trade Review Notes") st.write(plan.trade_review_notes) if plan.future_testing_ideas: st.markdown("### Future Testing Ideas") st.write(plan.future_testing_ideas) if plan.historical_backtest_results: st.markdown("### Historical Backtest Results") st.write(plan.historical_backtest_results) if plan.real_trade_performance: st.markdown("### Real Trading Performance") st.write(plan.real_trade_performance) else: st.info("No trading plans found") with add_tab: st.subheader("Create New Trading Plan") col1, col2 = st.columns(2) with col1: plan_name = st.text_input("Plan Name", key="add_plan_name") status = st.selectbox("Status", [s.value for s in PlanStatus], key="add_status") timeframe = st.selectbox("Timeframe", [t.value for t in Timeframe], key="add_timeframe") market_focus = st.selectbox("Market Focus", [m.value for m in MarketFocus], key="add_market_focus") with col2: trade_frequency = st.selectbox("Trade Frequency", [f.value for f in TradeFrequency], key="add_trade_frequency") plan_author = st.text_input("Author", key="add_plan_author") strategy_version = st.number_input("Version", min_value=1, value=1, key="add_strategy_version") st.subheader("Risk Parameters") col1, col2 = st.columns(2) with col1: stop_loss = st.number_input("Stop Loss %", min_value=0.1, value=7.0, key="add_stop_loss") profit_target = st.number_input("Profit Target %", min_value=0.1, value=21.0, key="add_profit_target") risk_reward_ratio = profit_target / stop_loss if stop_loss > 0 else 0 st.write(f"Risk:Reward Ratio: {risk_reward_ratio:.2f}") with col2: position_sizing = st.number_input("Position Size %", min_value=0.1, value=5.0, key="add_position_sizing") total_risk_per_trade = st.number_input("Risk per Trade %", min_value=0.1, value=1.0, key="add_total_risk_per_trade") max_portfolio_risk = st.number_input("Max Portfolio Risk %", min_value=0.1, value=5.0, key="add_max_portfolio_risk") st.subheader("Trade Rules") col1, col2 = st.columns(2) with col1: max_trades_per_day = st.number_input("Max Trades per Day", min_value=1, value=3, key="add_max_trades_per_day") max_trades_per_week = st.number_input("Max Trades per Week", min_value=1, value=15, key="add_max_trades_per_week") maximum_drawdown = st.number_input("Maximum Drawdown %", min_value=0.1, value=20.0, key="add_maximum_drawdown") st.subheader("Strategy Details") entry_criteria = st.text_area("Entry Criteria", key="add_entry_criteria") exit_criteria = st.text_area("Exit Criteria", key="add_exit_criteria") entry_confirmation = st.text_area("Entry Confirmation", key="add_entry_confirmation") market_conditions = st.text_area("Market Conditions", key="add_market_conditions") indicators_used = st.text_area("Technical Indicators", key="add_indicators_used") st.subheader("Risk Management") adjustments_for_drawdown = st.text_area("Drawdown Adjustments", key="add_adjustments_for_drawdown") risk_controls = st.text_area("Risk Controls", key="add_risk_controls") st.subheader("Additional Information") col1, col2 = st.columns(2) with col1: sector_focus = st.text_input("Sector Focus (optional)", key="add_sector_focus") fundamental_criteria = st.text_area("Fundamental Criteria (optional)", key="add_fundamental_criteria") with col2: options_strategy_details = st.text_area("Options Strategy Details (optional)", key="add_options_strategy_details") improvements_needed = st.text_area("Improvements Needed (optional)", key="add_improvements_needed") if st.button("Create Trading Plan", key="create_plan_button"): try: plan = TradingPlan( plan_name=plan_name, status=PlanStatus(status), timeframe=Timeframe(timeframe), market_focus=MarketFocus(market_focus), trade_frequency=TradeFrequency(trade_frequency), entry_criteria=entry_criteria, exit_criteria=exit_criteria, stop_loss=stop_loss, profit_target=profit_target, risk_reward_ratio=risk_reward_ratio, entry_confirmation=entry_confirmation, position_sizing=position_sizing, maximum_drawdown=maximum_drawdown, max_trades_per_day=max_trades_per_day, max_trades_per_week=max_trades_per_week, total_risk_per_trade=total_risk_per_trade, max_portfolio_risk=max_portfolio_risk, adjustments_for_drawdown=adjustments_for_drawdown, risk_controls=risk_controls, market_conditions=market_conditions, indicators_used=indicators_used, plan_author=plan_author, strategy_version=strategy_version, sector_focus=sector_focus, fundamental_criteria=fundamental_criteria, options_strategy_details=options_strategy_details, improvements_needed=improvements_needed ) save_trading_plan(plan) st.success("Trading plan created successfully!") st.query_params.update(rerun=True) except Exception as e: st.error(f"Error creating trading plan: {str(e)}") with edit_tab: st.subheader("Edit Trading Plan") plans = get_all_trading_plans() if plans: selected_plan_id = st.selectbox( "Select Plan to Edit", options=[plan.id for plan in plans], format_func=lambda x: next(p.plan_name for p in plans if p.id == x), key="edit_plan_select" ) if selected_plan_id: plan = get_trading_plan(selected_plan_id) if plan: col1, col2 = st.columns(2) with col1: plan_name = st.text_input("Plan Name", value=plan.plan_name, key="edit_plan_name") status = st.selectbox("Status", [s.value for s in PlanStatus], index=[s.value for s in PlanStatus].index(plan.status.value), key="edit_status") timeframe = st.selectbox("Timeframe", [t.value for t in Timeframe], index=[t.value for t in Timeframe].index(plan.timeframe.value), key="edit_timeframe") market_focus = st.selectbox("Market Focus", [m.value for m in MarketFocus], index=[m.value for m in MarketFocus].index(plan.market_focus.value), key="edit_market_focus") with col2: trade_frequency = st.selectbox("Trade Frequency", [f.value for f in TradeFrequency], index=[f.value for f in TradeFrequency].index(plan.trade_frequency.value), key="edit_trade_frequency") plan_author = st.text_input("Author", value=plan.plan_author, key="edit_plan_author") strategy_version = st.number_input("Version", min_value=1, value=plan.strategy_version, key="edit_strategy_version") st.subheader("Risk Parameters") col1, col2 = st.columns(2) with col1: stop_loss = st.number_input("Stop Loss %", min_value=0.1, value=plan.stop_loss, key="edit_stop_loss") profit_target = st.number_input("Profit Target %", min_value=0.1, value=plan.profit_target, key="edit_profit_target") risk_reward_ratio = profit_target / stop_loss if stop_loss > 0 else 0 st.write(f"Risk:Reward Ratio: {risk_reward_ratio:.2f}") with col2: position_sizing = st.number_input("Position Size %", min_value=0.1, value=plan.position_sizing, key="edit_position_sizing") total_risk_per_trade = st.number_input("Risk per Trade %", min_value=0.1, value=plan.total_risk_per_trade, key="edit_total_risk_per_trade") max_portfolio_risk = st.number_input("Max Portfolio Risk %", min_value=0.1, value=plan.max_portfolio_risk, key="edit_max_portfolio_risk") st.subheader("Trade Rules") col1, col2 = st.columns(2) with col1: max_trades_per_day = st.number_input("Max Trades per Day", min_value=1, value=plan.max_trades_per_day, key="edit_max_trades_per_day") max_trades_per_week = st.number_input("Max Trades per Week", min_value=1, value=plan.max_trades_per_week, key="edit_max_trades_per_week") maximum_drawdown = st.number_input("Maximum Drawdown %", min_value=0.1, value=plan.maximum_drawdown, key="edit_maximum_drawdown") st.subheader("Strategy Details") entry_criteria = st.text_area("Entry Criteria", value=plan.entry_criteria, key="edit_entry_criteria") exit_criteria = st.text_area("Exit Criteria", value=plan.exit_criteria, key="edit_exit_criteria") entry_confirmation = st.text_area("Entry Confirmation", value=plan.entry_confirmation, key="edit_entry_confirmation") market_conditions = st.text_area("Market Conditions", value=plan.market_conditions, key="edit_market_conditions") indicators_used = st.text_area("Technical Indicators", value=plan.indicators_used, key="edit_indicators_used") st.subheader("Risk Management") adjustments_for_drawdown = st.text_area("Drawdown Adjustments", value=plan.adjustments_for_drawdown, key="edit_adjustments_for_drawdown") risk_controls = st.text_area("Risk Controls", value=plan.risk_controls, key="edit_risk_controls") st.subheader("Additional Information") col1, col2 = st.columns(2) with col1: sector_focus = st.text_input("Sector Focus (optional)", value=plan.sector_focus, key="edit_sector_focus") fundamental_criteria = st.text_area("Fundamental Criteria (optional)", value=plan.fundamental_criteria, key="edit_fundamental_criteria") with col2: options_strategy_details = st.text_area("Options Strategy Details (optional)", value=plan.options_strategy_details, key="edit_options_strategy_details") improvements_needed = st.text_area("Improvements Needed (optional)", value=plan.improvements_needed, key="edit_improvements_needed") if st.button("Update Plan", key="update_plan_button"): try: plan.plan_name = plan_name plan.status = PlanStatus(status) plan.timeframe = Timeframe(timeframe) plan.market_focus = MarketFocus(market_focus) plan.trade_frequency = TradeFrequency(trade_frequency) plan.plan_author = plan_author plan.strategy_version = strategy_version plan.stop_loss = stop_loss plan.profit_target = profit_target plan.position_sizing = position_sizing plan.total_risk_per_trade = total_risk_per_trade plan.max_portfolio_risk = max_portfolio_risk plan.max_trades_per_day = max_trades_per_day plan.max_trades_per_week = max_trades_per_week plan.maximum_drawdown = maximum_drawdown plan.entry_criteria = entry_criteria plan.exit_criteria = exit_criteria plan.entry_confirmation = entry_confirmation plan.market_conditions = market_conditions plan.indicators_used = indicators_used plan.adjustments_for_drawdown = adjustments_for_drawdown plan.risk_controls = risk_controls plan.sector_focus = sector_focus plan.fundamental_criteria = fundamental_criteria plan.options_strategy_details = options_strategy_details plan.improvements_needed = improvements_needed update_trading_plan(plan) st.success("Plan updated successfully!") st.query_params.update(rerun=True) except Exception as e: st.error(f"Error updating plan: {str(e)}") if st.button("Delete Plan", key="delete_plan_button"): try: delete_trading_plan(plan.id) st.success("Plan deleted successfully!") st.query_params.update(rerun=True) except Exception as e: st.error(f"Error deleting plan: {str(e)}") st.subheader("Trade Management") plan_trades = get_plan_trades(plan.id) if plan_trades: st.write("Current Trades:") for trade in plan_trades: with st.expander(f"{trade['ticker']} - {trade['entry_date']}"): col1, col2 = st.columns(2) with col1: st.write(f"Entry: ${trade['entry_price']:.2f}") st.write(f"Shares: {trade['shares']}") with col2: if trade['exit_price']: pl = (trade['exit_price'] - trade['entry_price']) * trade['shares'] st.write(f"Exit: ${trade['exit_price']:.2f}") st.write(f"P/L: ${pl:.2f}") if st.button("Unlink Trade", key=f"unlink_trade_{trade['id']}"): try: query = """ ALTER TABLE stock_db.trades UPDATE plan_id = NULL WHERE id = %(trade_id)s """ with create_client() as client: client.command(query, {'trade_id': trade['id']}) metrics = calculate_plan_metrics(plan.id) plan.win_rate = metrics['win_rate'] plan.average_return_per_trade = metrics['average_return'] plan.profit_factor = metrics['profit_factor'] update_trading_plan(plan) st.success(f"Trade unlinked successfully!") st.query_params.update(rerun=True) except Exception as e: st.error(f"Error unlinking trade: {str(e)}") if st.button("Unlink All Trades", key=f"unlink_all_trades_{plan.id}"): try: if unlink_trades_from_plan(plan.id): plan.win_rate = None plan.average_return_per_trade = None plan.profit_factor = None update_trading_plan(plan) st.success("All trades unlinked successfully!") st.query_params.update(rerun=True) else: st.error("Error unlinking trades") except Exception as e: st.error(f"Error unlinking trades: {str(e)}") with create_client() as client: query = """ SELECT id, ticker, entry_date, entry_price, shares, exit_price, exit_date, direction, strategy, CASE WHEN exit_price IS NOT NULL THEN (exit_price - entry_price) * shares ELSE NULL END as profit_loss FROM stock_db.trades WHERE plan_id IS NULL ORDER BY entry_date DESC """ result = client.query(query) available_trades = [dict(zip( ['id', 'ticker', 'entry_date', 'entry_price', 'shares', 'exit_price', 'exit_date', 'direction', 'strategy', 'profit_loss'], row )) for row in result.result_rows] if available_trades: st.write("Link Existing Trades:") selected_trades = st.multiselect( "Select trades to link to this plan", options=[t['id'] for t in available_trades], format_func=lambda x: next( f"{t['ticker']} - {t['entry_date']} - ${t['entry_price']:.2f} " f"({t['direction']}) - {t['strategy']} " f"{'[Closed]' if t['exit_price'] else '[Open]'} " f"{'P/L: $' + format(t['profit_loss'], '.2f') if t['profit_loss'] is not None else ''}" for t in available_trades if t['id'] == x ), key=f"link_trades_{plan.id}" ) if selected_trades and st.button("Link Selected Trades", key=f"link_trades_button_{plan.id}"): if link_trades_to_plan(plan.id, selected_trades): st.success("Trades linked successfully!") metrics = calculate_plan_metrics(plan.id) plan.win_rate = metrics['win_rate'] plan.average_return_per_trade = metrics['average_return'] plan.profit_factor = metrics['profit_factor'] update_trading_plan(plan) st.query_params.update(rerun=True) else: st.error("Error linking trades") else: st.info("No plans available to edit")