updating the AI Suggestions yab

This commit is contained in:
Pascal BIBEHE 2025-06-04 03:20:33 +02:00
parent f7cf624721
commit 27ef418f84

View File

@ -1659,45 +1659,28 @@ def remove_ticker(ticker_to_remove: str) -> None:
# Display current tickers in the main space
if st.session_state.etf_allocations:
st.subheader("Selected ETFs")
st.markdown("""
<style>
.ticker-container {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-bottom: 20px;
}
.ticker-item {
display: inline-flex;
align-items: center;
color: #2ecc71;
font-size: 1.1em;
font-weight: 500;
}
.ticker-close {
margin-left: 2px;
cursor: pointer;
font-size: 1.1em;
opacity: 0.7;
}
.ticker-close:hover {
opacity: 1;
}
</style>
""", unsafe_allow_html=True)
# Create a container for tickers
ticker_container = st.container()
with ticker_container:
# Display each ticker with a close button
for etf in st.session_state.etf_allocations:
col1, col2 = st.columns([0.05, 0.95]) # Adjusted column ratio
with col1:
# Create four columns for the tables with smaller widths
col1, col2, col3, col4 = st.columns([1, 1, 1, 1])
# Split the ETFs into four groups
etf_groups = [[] for _ in range(4)]
for i, etf in enumerate(st.session_state.etf_allocations):
group_index = i % 4
etf_groups[group_index].append(etf)
# Display each group in its own column
for i, (col, etf_group) in enumerate(zip([col1, col2, col3, col4], etf_groups)):
with col:
for etf in etf_group:
st.markdown(f"""
<div style="display: flex; align-items: center; gap: 2px; margin-bottom: -15px;">
<span style="color: #2ecc71; font-weight: 500;">{etf['ticker']}</span>
</div>
""", unsafe_allow_html=True)
if st.button("×", key=f"remove_{etf['ticker']}",
help=f"Remove {etf['ticker']} from portfolio"):
remove_ticker(etf['ticker'])
with col2:
st.markdown(f"<div class='ticker-item'>{etf['ticker']}</div>", unsafe_allow_html=True)
# Debug information
logger.info("=== Session State Debug ===")
@ -1829,7 +1812,15 @@ with st.sidebar:
# Create a container for ETF input
with st.container():
# Input field for ETF ticker only
# Input field for ETF ticker with improved visibility
st.markdown("""
<style>
.stTextInput input {
color: #2ecc71 !important;
font-weight: 500 !important;
}
</style>
""", unsafe_allow_html=True)
new_ticker = st.text_input("ETF Ticker", help="Enter a valid ETF ticker (e.g., SCHD)")
# Add button to add ETF
@ -2872,29 +2863,68 @@ if st.session_state.simulation_run and st.session_state.df_data is not None:
investment_horizon=investment_horizon
)
# Get AI suggestions
# Get AI suggestions for different strategies
with st.spinner("Analyzing ETFs and generating portfolio suggestions..."):
try:
portfolio = selection_service.select_etfs(goal)
# Strategy 1: Balanced Growth
balanced_goal = InvestmentGoal(
capital_target=capital_target,
income_target=income_target if income_target > 0 else None,
risk_tolerance=RiskTolerance.MODERATE,
investment_horizon=investment_horizon
)
balanced_portfolio = selection_service.select_etfs(balanced_goal)
if portfolio:
# Display portfolio suggestions
st.success("Portfolio suggestions generated successfully!")
# Strategy 2: Income Focus
income_goal = InvestmentGoal(
capital_target=capital_target,
income_target=income_target * 1.2 if income_target > 0 else capital_target * 0.05, # 20% higher income target
risk_tolerance=RiskTolerance.CONSERVATIVE,
investment_horizon=investment_horizon
)
income_portfolio = selection_service.select_etfs(income_goal)
# Create a DataFrame for better display
portfolio_df = pd.DataFrame(portfolio)
# Strategy 3: Growth Focus
growth_goal = InvestmentGoal(
capital_target=capital_target,
income_target=income_target * 0.8 if income_target > 0 else None, # 20% lower income target
risk_tolerance=RiskTolerance.AGGRESSIVE,
investment_horizon=investment_horizon
)
growth_portfolio = selection_service.select_etfs(growth_goal)
# Strategy 4: Risk-Adjusted
risk_adjusted_goal = InvestmentGoal(
capital_target=capital_target,
income_target=income_target if income_target > 0 else None,
risk_tolerance=RiskTolerance[risk_tolerance.upper()],
investment_horizon=investment_horizon
)
risk_adjusted_portfolio = selection_service.select_etfs(risk_adjusted_goal)
# Create tabs for each strategy
strategy_tabs = st.tabs([
"🔄 Balanced Growth",
"💰 Income Focus",
"📈 Growth Focus",
"⚖️ Risk-Adjusted"
])
# Display Balanced Growth Strategy
with strategy_tabs[0]:
st.write("### Balanced Growth Strategy")
st.write("A balanced approach focusing on both growth and income, suitable for most investors.")
if balanced_portfolio:
portfolio_df = pd.DataFrame(balanced_portfolio)
portfolio_df['Allocation (%)'] = portfolio_df['allocation'] * 100
portfolio_df['Amount ($)'] = portfolio_df['amount']
# Display portfolio summary
st.write("### Portfolio Summary")
st.dataframe(
portfolio_df[['ticker', 'name', 'Allocation (%)', 'Amount ($)']],
hide_index=True
)
# Display detailed metrics
st.write("### Detailed Metrics")
# Display metrics
metrics_df = pd.DataFrame([
{
'Ticker': etf['ticker'],
@ -2905,21 +2935,148 @@ if st.session_state.simulation_run and st.session_state.df_data is not None:
'Sharpe Ratio': etf['metrics']['sharpe_ratio'],
'Dividend Yield (%)': etf['metrics']['dividend_yield'] * 100
}
for etf in portfolio
for etf in balanced_portfolio
])
st.dataframe(metrics_df, hide_index=True)
# Display portfolio allocation chart
st.write("### Portfolio Allocation")
fig = px.pie(
portfolio_df,
values='Allocation (%)',
names='ticker',
title='Portfolio Allocation by ETF'
)
st.plotly_chart(fig)
else:
st.error("No portfolio suggestions could be generated. Please try different parameters.")
st.error("Could not generate balanced growth portfolio.")
# Display Income Focus Strategy
with strategy_tabs[1]:
st.write("### Income Focus Strategy")
st.write("Optimized for higher dividend income with lower risk, suitable for income-focused investors.")
if income_portfolio:
portfolio_df = pd.DataFrame(income_portfolio)
portfolio_df['Allocation (%)'] = portfolio_df['allocation'] * 100
portfolio_df['Amount ($)'] = portfolio_df['amount']
st.dataframe(
portfolio_df[['ticker', 'name', 'Allocation (%)', 'Amount ($)']],
hide_index=True
)
# Display metrics
metrics_df = pd.DataFrame([
{
'Ticker': etf['ticker'],
'Expense Ratio (%)': etf['metrics']['expense_ratio'] * 100,
'AUM ($B)': etf['metrics']['aum'] / 1e9,
'Volatility (%)': etf['metrics']['volatility'] * 100,
'Max Drawdown (%)': etf['metrics']['max_drawdown'] * 100,
'Sharpe Ratio': etf['metrics']['sharpe_ratio'],
'Dividend Yield (%)': etf['metrics']['dividend_yield'] * 100
}
for etf in income_portfolio
])
st.dataframe(metrics_df, hide_index=True)
else:
st.error("Could not generate income focus portfolio.")
# Display Growth Focus Strategy
with strategy_tabs[2]:
st.write("### Growth Focus Strategy")
st.write("Optimized for capital appreciation with higher risk tolerance, suitable for growth investors.")
if growth_portfolio:
portfolio_df = pd.DataFrame(growth_portfolio)
portfolio_df['Allocation (%)'] = portfolio_df['allocation'] * 100
portfolio_df['Amount ($)'] = portfolio_df['amount']
st.dataframe(
portfolio_df[['ticker', 'name', 'Allocation (%)', 'Amount ($)']],
hide_index=True
)
# Display metrics
metrics_df = pd.DataFrame([
{
'Ticker': etf['ticker'],
'Expense Ratio (%)': etf['metrics']['expense_ratio'] * 100,
'AUM ($B)': etf['metrics']['aum'] / 1e9,
'Volatility (%)': etf['metrics']['volatility'] * 100,
'Max Drawdown (%)': etf['metrics']['max_drawdown'] * 100,
'Sharpe Ratio': etf['metrics']['sharpe_ratio'],
'Dividend Yield (%)': etf['metrics']['dividend_yield'] * 100
}
for etf in growth_portfolio
])
st.dataframe(metrics_df, hide_index=True)
else:
st.error("Could not generate growth focus portfolio.")
# Display Risk-Adjusted Strategy
with strategy_tabs[3]:
st.write("### Risk-Adjusted Strategy")
st.write(f"Optimized for your specific risk tolerance ({risk_tolerance}), balancing growth and income.")
if risk_adjusted_portfolio:
portfolio_df = pd.DataFrame(risk_adjusted_portfolio)
portfolio_df['Allocation (%)'] = portfolio_df['allocation'] * 100
portfolio_df['Amount ($)'] = portfolio_df['amount']
st.dataframe(
portfolio_df[['ticker', 'name', 'Allocation (%)', 'Amount ($)']],
hide_index=True
)
# Display metrics
metrics_df = pd.DataFrame([
{
'Ticker': etf['ticker'],
'Expense Ratio (%)': etf['metrics']['expense_ratio'] * 100,
'AUM ($B)': etf['metrics']['aum'] / 1e9,
'Volatility (%)': etf['metrics']['volatility'] * 100,
'Max Drawdown (%)': etf['metrics']['max_drawdown'] * 100,
'Sharpe Ratio': etf['metrics']['sharpe_ratio'],
'Dividend Yield (%)': etf['metrics']['dividend_yield'] * 100
}
for etf in risk_adjusted_portfolio
])
st.dataframe(metrics_df, hide_index=True)
else:
st.error("Could not generate risk-adjusted portfolio.")
# Add buttons to apply each strategy
st.write("### Apply Strategy")
col1, col2, col3, col4 = st.columns(4)
with col1:
if st.button("Apply Balanced Growth", key="apply_balanced"):
if balanced_portfolio:
st.session_state.etf_allocations = [
{"ticker": etf['ticker'], "allocation": etf['allocation'] * 100}
for etf in balanced_portfolio
]
st.success("Applied Balanced Growth strategy!")
st.rerun()
with col2:
if st.button("Apply Income Focus", key="apply_income"):
if income_portfolio:
st.session_state.etf_allocations = [
{"ticker": etf['ticker'], "allocation": etf['allocation'] * 100}
for etf in income_portfolio
]
st.success("Applied Income Focus strategy!")
st.rerun()
with col3:
if st.button("Apply Growth Focus", key="apply_growth"):
if growth_portfolio:
st.session_state.etf_allocations = [
{"ticker": etf['ticker'], "allocation": etf['allocation'] * 100}
for etf in growth_portfolio
]
st.success("Applied Growth Focus strategy!")
st.rerun()
with col4:
if st.button("Apply Risk-Adjusted", key="apply_risk_adjusted"):
if risk_adjusted_portfolio:
st.session_state.etf_allocations = [
{"ticker": etf['ticker'], "allocation": etf['allocation'] * 100}
for etf in risk_adjusted_portfolio
]
st.success("Applied Risk-Adjusted strategy!")
st.rerun()
except ValueError as e:
st.error(str(e))