File size: 7,045 Bytes
944b8c3 cd4d01a 944b8c3 cd4d01a 8f44430 ec6a832 8f44430 ec6a832 8f44430 ec6a832 944b8c3 cd4d01a 944b8c3 f3a9a3f 944b8c3 d2c0c36 ec6a832 944b8c3 7ad65a9 cd4d01a d2c0c36 ec6a832 0c8cca8 ec6a832 d2c0c36 944b8c3 7ad65a9 d2c0c36 7ad65a9 d2c0c36 91ce90e 7ad65a9 d2c0c36 7ad65a9 d2c0c36 cd4d01a 7ad65a9 ec6a832 944b8c3 7ad65a9 944b8c3 7ad65a9 d2c0c36 2c321cc 8f44430 ec6a832 f3a9a3f 7ad65a9 d2c0c36 8f44430 d2c0c36 8f44430 7ad65a9 8f44430 7ad65a9 8f44430 d2c0c36 8f44430 7ad65a9 944b8c3 7ad65a9 d2c0c36 7ad65a9 d2c0c36 cd4d01a d2c0c36 7ad65a9 f3a9a3f 7ad65a9 d2c0c36 7ad65a9 cd4d01a 7ad65a9 cd4d01a 7ad65a9 ec6a832 7ad65a9 d2c0c36 7ad65a9 ec6a832 7ad65a9 cd4d01a 7ad65a9 d2c0c36 ec6a832 d2c0c36 7ad65a9 cd4d01a 7ad65a9 944b8c3 8f44430 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | """
NSE Portfolio Optimizer Pro - Main Entry Page
==============================================
"""
import streamlit as st
from datetime import datetime
import pandas as pd
# Import utilities for live data AND Theme
try:
from src.utils import get_nifty_data, render_header, get_theme_colors
except ImportError:
get_nifty_data = None
# Fallback dummies if import fails
def render_header(): pass
def get_theme_colors(): return {"card_bg": "#ffffff", "border": "#e2e8f0"}
# ============ PAGE CONFIGURATION ============
st.set_page_config(
page_title="NSE Portfolio Optimizer Pro",
page_icon="π",
layout="wide",
initial_sidebar_state="expanded",
menu_items={'About': 'NSE Portfolio Optimizer Pro v2.0'}
)
# ============ MAIN CONTENT ============
def main():
# 1. Render Header (with Toggle)
render_header()
# 2. Get Dynamic Colors from the Toggle State
colors = get_theme_colors()
# 3. Apply CSS dynamically based on the Toggle
st.markdown(f"""
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
:root {{ --primary: #2563eb; --font-main: 'Inter', sans-serif; }}
* {{ font-family: var(--font-main); }}
/* Metric Cards - controlled by Python variable, NOT system setting */
.stMetric {{
background: {colors['card_bg']} !important;
border: 1px solid {colors['border']} !important;
border-radius: 10px;
padding: 1rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.05);
}}
.badge-live {{
background-color: #dcfce7; color: #166534; padding: 2px 8px;
border-radius: 12px; font-size: 0.75rem; font-weight: 600;
border: 1px solid #bbf7d0;
}}
.badge-static {{
background-color: #f1f5f9; color: #475569; padding: 2px 8px;
border-radius: 12px; font-size: 0.75rem; font-weight: 600;
border: 1px solid #e2e8f0;
}}
</style>
""", unsafe_allow_html=True)
# ============ SESSION STATE ============
if 'user_preferences' not in st.session_state:
st.session_state.user_preferences = {
'risk_free_rate': 0.0654,
'default_years': 2,
'default_simulations': 1000,
'brokerage_rate': 0.0003,
'confidence_level': 0.95
}
if 'portfolio_history' not in st.session_state:
st.session_state.portfolio_history = []
if 'current_portfolio' not in st.session_state:
st.session_state.current_portfolio = None
st.title("π NSE Portfolio Optimizer Pro")
# --- TRANSPARENCY & ONBOARDING SECTION ---
with st.expander("π New here? Read about the data sources", expanded=False):
st.markdown("""
### π§ Data Transparency Statement
We believe in being 100% clear about where our numbers come from:
| Indicator | Source | Real-Time? | Why is it here? |
|-----------|--------|------------|-----------------|
| **NIFTY 50** | Yahoo Finance API | π’ **Yes (Delayed ~15m)** | Shows overall market health. |
| **Risk-Free Rate** | User Settings | π΄ **No (Fixed)** | Used as a benchmark. Defaults to India 10Y Bond Yield (6.54%). |
| **RBI Repo Rate** | Reference Value | π΄ **No (Fixed)** | Context only. Does not affect calculations. |
| **Stock Prices** | Yahoo Finance API | π’ **Yes (Delayed ~15m)** | Used for all portfolio optimization. |
""")
st.markdown("---")
# --- METRICS DASHBOARD ---
col1, col2, col3, col4 = st.columns(4)
# 1. Risk Free Rate (Static/Configurable)
with col1:
rf_rate = st.session_state.user_preferences['risk_free_rate'] * 100
st.metric(
"India Risk-Free Rate",
f"{rf_rate:.2f}%",
"Reference Setting",
help="βΉοΈ SOURCE: Your Settings.\n\nThis is the 'safe' return (like a FD or Bond) used to calculate Sharpe Ratio."
)
st.caption("π΄ Manual Setting")
# 2. RBI Repo Rate (Static)
with col2:
st.metric(
"RBI Repo Rate",
"5.25%",
"Neutral Stance",
help="βΉοΈ SOURCE: Fixed Reference.\n\nThis is the rate at which RBI lends money. Hardcoded context."
)
st.caption("π΄ Reference Only")
# 3. NIFTY 50 (Live)
with col3:
nifty_price = "Loading..."
nifty_delta = ""
is_live = False
if get_nifty_data:
df, _ = get_nifty_data()
if not df.empty:
current = df['Close'].iloc[-1]
prev = df['Close'].iloc[-2] if len(df) > 1 else current
change = current - prev
pct_change = (change / prev) * 100
nifty_price = f"{current:,.0f}"
nifty_delta = f"{change:+,.0f} ({pct_change:+.2f}%)"
is_live = True
st.metric(
"NIFTY 50",
nifty_price,
nifty_delta,
help="βΉοΈ SOURCE: Yahoo Finance (Live).\n\nThis shows the current level of the NIFTY 50 index."
)
if is_live:
st.caption(f"π’ Live Data ({datetime.now().strftime('%H:%M')})")
else:
st.caption("π΄ Data Unavailable")
# 4. Portfolios
with col4:
st.metric(
"Your Portfolios",
len(st.session_state.portfolio_history),
help="Number of portfolios you have created in this session."
)
st.caption("π΅ Session Data")
st.markdown("---")
# --- BEGINNER GUIDE ---
st.markdown("## π§ How to Start")
tab1, tab2 = st.tabs(["π Quick Start", "π‘ What do these terms mean?"])
with tab1:
col_new, col_exist = st.columns(2)
with col_new:
st.info("### 1. Create a New Portfolio\nGo here if you want to build a portfolio from scratch.")
if st.button("Go to New Portfolio β", use_container_width=True):
st.switch_page("pages/1_New_Portfolio.py")
with col_exist:
st.success("### 2. Optimize Existing\nGo here if you already own stocks and want to know how to rebalance them.")
if st.button("Go to Rebalance β", use_container_width=True):
st.switch_page("pages/2_Rebalance.py")
with tab2:
st.markdown("""
**Don't let the jargon scare you! Here is what matters:**
* **Sharpe Ratio:** Think of this as "Bang for your Buck." Higher is better.
* **Volatility:** The "Rollercoaster Factor." High volatility means the price jumps up and down a lot.
* **VaR (Value at Risk):** The "Worst Day" predictor.
""")
st.markdown("---")
st.caption("Β© 2025 NSE Portfolio Optimizer Pro | Data provided for educational purposes.")
if __name__ == "__main__":
main() |