feat: Add trading plans page to Streamlit app with full CRUD functionality
This commit is contained in:
parent
8440171a08
commit
4730499ae2
@ -8,6 +8,11 @@ from trading.journal import (
|
|||||||
get_open_trades_summary, get_current_prices, generate_position_id,
|
get_open_trades_summary, get_current_prices, generate_position_id,
|
||||||
get_position_summary, get_latest_portfolio_value, update_portfolio_value
|
get_position_summary, get_latest_portfolio_value, update_portfolio_value
|
||||||
)
|
)
|
||||||
|
from trading.trading_plan import (
|
||||||
|
TradingPlan, PlanStatus, Timeframe, MarketFocus, TradeFrequency,
|
||||||
|
create_trading_plan_table, save_trading_plan, get_trading_plan,
|
||||||
|
get_all_trading_plans, update_trading_plan
|
||||||
|
)
|
||||||
from trading.position_calculator import PositionCalculator
|
from trading.position_calculator import PositionCalculator
|
||||||
from screener.scanner_controller import run_technical_scanner
|
from screener.scanner_controller import run_technical_scanner
|
||||||
from screener.canslim_controller import run_canslim_screener
|
from screener.canslim_controller import run_canslim_screener
|
||||||
@ -811,6 +816,193 @@ def strategy_guide_page():
|
|||||||
* Refine strategies
|
* Refine strategies
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
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("### Strategy Details")
|
||||||
|
st.write(f"**Timeframe:** {plan.timeframe.value}")
|
||||||
|
st.write(f"**Market:** {plan.market_focus.value}")
|
||||||
|
st.write(f"**Frequency:** {plan.trade_frequency.value}")
|
||||||
|
st.write(f"**Version:** {plan.strategy_version}")
|
||||||
|
|
||||||
|
st.markdown("### Risk Parameters")
|
||||||
|
st.write(f"**Stop Loss:** {plan.stop_loss}%")
|
||||||
|
st.write(f"**Profit Target:** {plan.profit_target}%")
|
||||||
|
st.write(f"**Risk/Trade:** {plan.total_risk_per_trade}%")
|
||||||
|
st.write(f"**Max Portfolio Risk:** {plan.max_portfolio_risk}%")
|
||||||
|
|
||||||
|
with col2:
|
||||||
|
st.markdown("### Performance")
|
||||||
|
if plan.win_rate:
|
||||||
|
st.write(f"**Win Rate:** {plan.win_rate}%")
|
||||||
|
if plan.average_return_per_trade:
|
||||||
|
st.write(f"**Avg Return:** {plan.average_return_per_trade}%")
|
||||||
|
if plan.profit_factor:
|
||||||
|
st.write(f"**Profit Factor:** {plan.profit_factor}")
|
||||||
|
|
||||||
|
st.markdown("### Trade Limits")
|
||||||
|
st.write(f"**Max Trades/Day:** {plan.max_trades_per_day}")
|
||||||
|
st.write(f"**Max Trades/Week:** {plan.max_trades_per_week}")
|
||||||
|
st.write(f"**Max Drawdown:** {plan.maximum_drawdown}%")
|
||||||
|
|
||||||
|
st.markdown("### Entry Criteria")
|
||||||
|
st.write(plan.entry_criteria)
|
||||||
|
|
||||||
|
st.markdown("### Exit Criteria")
|
||||||
|
st.write(plan.exit_criteria)
|
||||||
|
|
||||||
|
if plan.improvements_needed:
|
||||||
|
st.markdown("### Improvements Needed")
|
||||||
|
st.write(plan.improvements_needed)
|
||||||
|
else:
|
||||||
|
st.info("No trading plans found")
|
||||||
|
|
||||||
|
with add_tab:
|
||||||
|
st.subheader("Create New Trading Plan")
|
||||||
|
|
||||||
|
# Basic Info
|
||||||
|
col1, col2 = st.columns(2)
|
||||||
|
with col1:
|
||||||
|
plan_name = st.text_input("Plan Name")
|
||||||
|
status = st.selectbox("Status", [s.value for s in PlanStatus])
|
||||||
|
timeframe = st.selectbox("Timeframe", [t.value for t in Timeframe])
|
||||||
|
market_focus = st.selectbox("Market Focus", [m.value for m in MarketFocus])
|
||||||
|
|
||||||
|
with col2:
|
||||||
|
trade_frequency = st.selectbox("Trade Frequency", [f.value for f in TradeFrequency])
|
||||||
|
plan_author = st.text_input("Author")
|
||||||
|
strategy_version = st.number_input("Version", min_value=1, value=1)
|
||||||
|
|
||||||
|
# Risk Parameters
|
||||||
|
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)
|
||||||
|
profit_target = st.number_input("Profit Target %", min_value=0.1, value=21.0)
|
||||||
|
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)
|
||||||
|
total_risk_per_trade = st.number_input("Risk per Trade %", min_value=0.1, value=1.0)
|
||||||
|
max_portfolio_risk = st.number_input("Max Portfolio Risk %", min_value=0.1, value=5.0)
|
||||||
|
|
||||||
|
# Trade Rules
|
||||||
|
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)
|
||||||
|
max_trades_per_week = st.number_input("Max Trades per Week", min_value=1, value=15)
|
||||||
|
maximum_drawdown = st.number_input("Maximum Drawdown %", min_value=0.1, value=20.0)
|
||||||
|
|
||||||
|
# Strategy Details
|
||||||
|
st.subheader("Strategy Details")
|
||||||
|
entry_criteria = st.text_area("Entry Criteria")
|
||||||
|
exit_criteria = st.text_area("Exit Criteria")
|
||||||
|
entry_confirmation = st.text_area("Entry Confirmation")
|
||||||
|
market_conditions = st.text_area("Market Conditions")
|
||||||
|
indicators_used = st.text_area("Technical Indicators")
|
||||||
|
|
||||||
|
# Risk Management
|
||||||
|
st.subheader("Risk Management")
|
||||||
|
adjustments_for_drawdown = st.text_area("Drawdown Adjustments")
|
||||||
|
risk_controls = st.text_area("Risk Controls")
|
||||||
|
|
||||||
|
# Optional Fields
|
||||||
|
st.subheader("Additional Information")
|
||||||
|
col1, col2 = st.columns(2)
|
||||||
|
with col1:
|
||||||
|
sector_focus = st.text_input("Sector Focus (optional)")
|
||||||
|
fundamental_criteria = st.text_area("Fundamental Criteria (optional)")
|
||||||
|
|
||||||
|
with col2:
|
||||||
|
options_strategy_details = st.text_area("Options Strategy Details (optional)")
|
||||||
|
improvements_needed = st.text_area("Improvements Needed (optional)")
|
||||||
|
|
||||||
|
if st.button("Create Trading Plan"):
|
||||||
|
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.experimental_rerun()
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
|
||||||
|
if selected_plan_id:
|
||||||
|
plan = get_trading_plan(selected_plan_id)
|
||||||
|
if plan:
|
||||||
|
# Add similar form fields as in add_tab but with plan's current values
|
||||||
|
# This is a simplified version - you might want to add all fields
|
||||||
|
plan_name = st.text_input("Plan Name", value=plan.plan_name)
|
||||||
|
status = st.selectbox("Status",
|
||||||
|
[s.value for s in PlanStatus],
|
||||||
|
index=[s.value for s in PlanStatus].index(plan.status.value))
|
||||||
|
|
||||||
|
if st.button("Update Plan"):
|
||||||
|
try:
|
||||||
|
plan.plan_name = plan_name
|
||||||
|
plan.status = PlanStatus(status)
|
||||||
|
update_trading_plan(plan)
|
||||||
|
st.success("Plan updated successfully!")
|
||||||
|
st.experimental_rerun()
|
||||||
|
except Exception as e:
|
||||||
|
st.error(f"Error updating plan: {str(e)}")
|
||||||
|
else:
|
||||||
|
st.info("No plans available to edit")
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
st.set_page_config(page_title="Trading System", layout="wide")
|
st.set_page_config(page_title="Trading System", layout="wide")
|
||||||
init_session_state()
|
init_session_state()
|
||||||
@ -819,11 +1011,12 @@ def main():
|
|||||||
st.sidebar.title("Navigation")
|
st.sidebar.title("Navigation")
|
||||||
st.session_state.page = st.sidebar.radio(
|
st.session_state.page = st.sidebar.radio(
|
||||||
"Go to",
|
"Go to",
|
||||||
["Strategy Guide", "Trading Journal", "Technical Scanner", "CANSLIM Screener", "Trading System"]
|
["Strategy Guide", "Trading Journal", "Technical Scanner", "CANSLIM Screener", "Trading System", "Trading Plans"]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create necessary tables
|
# Create necessary tables
|
||||||
create_trades_table()
|
create_trades_table()
|
||||||
|
create_trading_plan_table()
|
||||||
|
|
||||||
# Display selected page
|
# Display selected page
|
||||||
if st.session_state.page == "Strategy Guide":
|
if st.session_state.page == "Strategy Guide":
|
||||||
@ -836,6 +1029,8 @@ def main():
|
|||||||
canslim_screener_page()
|
canslim_screener_page()
|
||||||
elif st.session_state.page == "Trading System":
|
elif st.session_state.page == "Trading System":
|
||||||
trading_system_page()
|
trading_system_page()
|
||||||
|
elif st.session_state.page == "Trading Plans":
|
||||||
|
trading_plan_page()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user