Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import numpy as np | |
| import plotly.graph_objects as go | |
| import plotly.express as px | |
| # Import header | |
| from src.utils import render_header | |
| # ============ PAGE CONFIGURATION ============ | |
| st.set_page_config( | |
| page_title="Learn | NSE Optimizer", | |
| page_icon="๐", | |
| layout="wide" | |
| ) | |
| # ============ MAIN APP ============ | |
| def main(): | |
| render_header() | |
| st.title("๐ Interactive Learning Center") | |
| st.markdown("Master the art of portfolio optimization through interactive simulations and real-world examples.") | |
| tab1, tab2, tab3, tab4 = st.tabs([ | |
| "๐ Core Concepts", | |
| "๐งฎ Interactive Simulators", | |
| "๐ง Quiz Mode", | |
| "๐ Famous Portfolios" | |
| ]) | |
| # --- TAB 1: CORE CONCEPTS (Text + Visuals) --- | |
| with tab1: | |
| col1, col2 = st.columns([2, 1]) | |
| with col1: | |
| st.markdown("### 1. Modern Portfolio Theory (MPT)") | |
| st.info(""" | |
| **The Big Idea:** You don't have to pick the "best" stock. You need to pick the right *combination* of stocks. | |
| MPT proves that by combining assets that don't move together (low correlation), you can **reduce risk** without reducing expected returns. | |
| """) | |
| st.markdown("### 2. The Sharpe Ratio") | |
| st.warning(""" | |
| **Formula:** $(Return - Risk Free Rate) / Volatility$ | |
| Think of it as **"Return per unit of Stress"**. | |
| * If Portfolio A gives 15% return with huge daily swings (high stress)... | |
| * And Portfolio B gives 14% return with steady growth (low stress)... | |
| * **Portfolio B has a higher Sharpe Ratio** and is mathematically "better." | |
| """) | |
| with col2: | |
| st.markdown("### ๐ Key Glossary") | |
| st.markdown(""" | |
| | Term | Meaning | | |
| |------|---------| | |
| | **Volatility** | How wildly prices swing. High vol = High risk. | | |
| | **Drawdown** | The % drop from the peak. "How much can I lose?" | | |
| | **Beta** | Sensitivity to the market. Beta 1.5 moves 1.5x the market. | | |
| | **Alpha** | Returns earned *above* the market benchmark. | | |
| """) | |
| # --- TAB 2: SIMULATORS (Interactive) --- | |
| with tab2: | |
| st.subheader("๐ ๏ธ Financial Lab") | |
| sim_type = st.selectbox("Select Simulator", ["๐ The Cost of Volatility", "๐ฐ Power of Compounding"]) | |
| if sim_type == "๐ The Cost of Volatility": | |
| st.markdown("#### Why does consistency matter?") | |
| st.write("See how two portfolios with the **same average return** end up with different money due to volatility.") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.markdown("**๐ข Steady Portfolio**") | |
| st.write("Returns: +10%, +10%, +10%, +10%") | |
| steady = [100, 110, 121, 133.1, 146.41] | |
| st.line_chart(steady) | |
| st.metric("Final Value", "โน146.41") | |
| with col2: | |
| st.markdown("**๐ Volatile Portfolio**") | |
| st.write("Returns: +50%, -30%, +50%, -30%") | |
| # 100 -> 150 -> 105 -> 157.5 -> 110.25 | |
| volatile = [100, 150, 105, 157.5, 110.25] | |
| st.line_chart(volatile) | |
| st.metric("Final Value", "โน110.25", "-24% vs Steady") | |
| st.error("๐ก **Lesson:** Large losses destroy wealth faster than large gains build it. Avoiding big losses is key.") | |
| elif sim_type == "๐ฐ Power of Compounding": | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| initial = st.number_input("Initial Investment (โน)", value=100000) | |
| monthly = st.number_input("Monthly SIP (โน)", value=10000) | |
| with col2: | |
| rate = st.slider("Expected Annual Return (%)", 5, 25, 12) | |
| years = st.slider("Time Period (Years)", 5, 40, 20) | |
| # Calculate | |
| months = years * 12 | |
| monthly_rate = rate / 100 / 12 | |
| future_value = initial * (1 + monthly_rate)**months | |
| future_value += monthly * (((1 + monthly_rate)**months - 1) / monthly_rate) * (1 + monthly_rate) | |
| total_invested = initial + (monthly * months) | |
| wealth_gained = future_value - total_invested | |
| st.metric("Projected Wealth", f"โน{future_value:,.0f}", f"Invested: โน{total_invested:,.0f}") | |
| # Chart | |
| years_list = list(range(years + 1)) | |
| values = [] | |
| for y in years_list: | |
| m = y * 12 | |
| val = initial * (1 + monthly_rate)**m | |
| if m > 0: | |
| val += monthly * (((1 + monthly_rate)**m - 1) / monthly_rate) * (1 + monthly_rate) | |
| values.append(val) | |
| df_chart = pd.DataFrame({"Year": years_list, "Wealth": values}) | |
| st.area_chart(df_chart, x="Year", y="Wealth") | |
| # --- TAB 3: QUIZ --- | |
| with tab3: | |
| st.subheader("๐ง Test Your Knowledge") | |
| q1 = st.radio("1. What is the main goal of diversification?", | |
| ["To maximize returns at all costs", | |
| "To reduce risk without sacrificing expected returns", | |
| "To buy every stock in the market"]) | |
| if q1 == "To reduce risk without sacrificing expected returns": | |
| st.success("Correct! โ ") | |
| elif q1: | |
| st.error("Incorrect. Diversification is primarily about risk management.") | |
| st.markdown("---") | |
| q2 = st.radio("2. If a stock has a correlation of -1.0 with your portfolio, adding it will:", | |
| ["Increase portfolio risk", | |
| "Have no effect", | |
| "Significantly reduce portfolio risk"]) | |
| if q2 == "Significantly reduce portfolio risk": | |
| st.success("Correct! โ Negative correlation provides the best hedge.") | |
| elif q2: | |
| st.error("Incorrect. -1.0 means it moves in the exact opposite direction, cancelling out risk.") | |
| # --- TAB 4: FAMOUS PORTFOLIOS --- | |
| with tab4: | |
| st.subheader("๐ Famous Portfolio Strategies") | |
| strategies = { | |
| "60/40 Classic": {"Equity": 60, "Bonds": 40, "Gold": 0}, | |
| "All Weather (Ray Dalio)": {"Equity": 30, "Bonds": 55, "Gold": 15}, | |
| "Aggressive Growth": {"Equity": 90, "Bonds": 10, "Gold": 0}, | |
| "Permanent Portfolio": {"Equity": 25, "Bonds": 25, "Gold": 25, "Cash": 25} | |
| } | |
| selected_strat = st.selectbox("Choose a Strategy to Visualize", list(strategies.keys())) | |
| data = strategies[selected_strat] | |
| fig = px.pie( | |
| values=list(data.values()), | |
| names=list(data.keys()), | |
| title=f"{selected_strat} Allocation", | |
| hole=0.4 | |
| ) | |
| st.plotly_chart(fig, use_container_width=True) | |
| if selected_strat == "All Weather (Ray Dalio)": | |
| st.info("โน๏ธ **Why this works:** Designed to perform well in all economic environments (inflation, deflation, growth, recession) by heavily weighting bonds and commodities.") | |
| elif selected_strat == "60/40 Classic": | |
| st.info("โน๏ธ **Why this works:** The standard benchmark. Equities provide growth, Bonds provide stability and income.") | |
| if __name__ == "__main__": | |
| main() |