yongxiang9921/IPO
0
1import streamlit as st2import pandas as pd3import plotly.express as px4import time5from datetime import datetime6import db_manager # 引入我们的后端模块7 8# --- 1. 系统初始化 (System Init) ---9st.set_page_config(10 page_title="iPO Terminal - Asset Liquidation",11 page_icon="📉",12 layout="wide",13 initial_sidebar_state="expanded"14)15 16# 确保数据库已存在17db_manager.init_db()18 19# --- CSS 样式植入:金融极客风 ---20st.markdown("""21 <style>22 .stApp { background-color: #0E1117; color: #00FF41; }23 .stMetricValue { font-family: 'Courier New', monospace; font-weight: bold; color: #00FF41 !important; }24 /* 红色卖出按钮 */25 div.stButton > button {26 background-color: #FF4B4B; color: white; width: 100%;27 border-radius: 0px; border: 1px solid #FF0000;28 font-family: 'Courier New'; font-weight: bold; font-size: 20px;29 }30 div.stButton > button:hover { background-color: #FF0000; border-color: white; }31 </style>32 """, unsafe_allow_html=True)33 34# --- 2. 侧边栏:交易控制台 (Trading Floor) ---35with st.sidebar:36 st.title("💸 TRADING FLOOR")37 st.caption("Human Capital Liquidation System")38 st.markdown("---")39 40 # [新增] 薪资设置 - 用于计算收益 (折叠起来,保护隐私)41 with st.expander("⚙️ 财务参数 (Financial Params)"):42 monthly_salary = st.number_input("月薪 (Monthly Salary)", value=10000, step=1000,43 help="用于计算你的带薪拉屎收益 (EPS)")44 # 估算每分钟价值:月薪 / 21.75天 / 8小时 / 60分钟45 money_per_min = monthly_salary / 21.75 / 8 / 6046 st.caption(f"当前估值: ¥{money_per_min:.2f} / min")47 48 st.markdown("### 📝 委托单 (Order Entry)")49 50 # 1. 资产类型51 asset_options = [52 "牛市 : 完美的一条",53 "熊市 : 稀烂(腹泻",54 "流动性紧缩 : 便秘,拉不出来"55 "通货膨胀 : 只是放了很多屁,实际上没货"56 ]57 asset_type = st.selectbox("资产类别 (Asset Class)", options=asset_options)58 59 # 2. 交易参数60 col1, col2 = st.columns(2)61 with col1:62 volume = st.slider("成交量 (Vol)", 1, 10, 5,help="1=微量,10=清仓")63 with col2:64 volatility = st.slider("波动率 (Effort)", 1, 10, 3,help="用力程度,1=顺畅,10=拉不出来")65 66 duration = st.number_input("持仓时长 (Duration/Min)", min_value=1.0, value=10.0, step=0.5)67 68 # 计算本次预计收益69 estimated_profit = money_per_min * duration70 st.info(f"💰 预计资金回笼: ¥{estimated_profit:.2f}")71 72 st.markdown("---")73 74 # 3. 执行按钮75 if st.button("🔴 EXECUTE SELL (确认抛售)"):76 with st.spinner('正在连接直肠交易所...'):77 time.sleep(0.8) # 仪式感延迟78 79 # 调用后端写入数据库80 db_manager.execute_trade(81 asset_class=asset_type.split(" (")[0], # 只存英文名简写82 volume=volume,83 volatility=volatility,84 duration_min=duration,85 net_profit=round(estimated_profit, 2)86 )87 88 st.toast(f"✅ 交易成功!入账 ¥{estimated_profit:.2f}", icon="🤑")89 time.sleep(1) # 等待一秒让用户看清提示90 st.rerun() # 刷新页面,显示最新数据91 92# --- 3. 主界面:市场概览 (Market Overview) ---93 94st.title("📊 iPO (Initial Poop Offering) Dashboard")95st.markdown(f"**Status:** `MARKET OPEN` | **Trader:** `You` | **Date:** `{datetime.now().strftime('%Y-%m-%d')}`")96 97# 读取数据库数据98raw_data = db_manager.fetch_history()99df = pd.DataFrame(raw_data)100 101if df.empty:102 st.warning("⚠️ 市场休市中:暂无交易记录。请在左侧侧边栏发起你的第一次 IPO。")103else:104 # 转换时间格式,方便绘图105 df['timestamp'] = pd.to_datetime(df['timestamp'])106 107 # --- A. 顶部核心指标 (KPIs) ---108 col1, col2, col3, col4 = st.columns(4)109 110 total_profit = df['net_profit'].sum()111 total_duration = df['duration_min'].sum()112 avg_effort = df['volatility'].mean()113 last_trade_time = df['timestamp'].iloc[0]114 115 # 计算距离上一次的时间差116 time_diff = datetime.now() - last_trade_time117 hours_since = time_diff.total_seconds() / 3600118 119 with col1:120 st.metric("累计收益 (Total Earnings)", f"¥ {total_profit:,.2f}", help="也就是公司付钱请你拉屎的总金额")121 with col2:122 st.metric("总工时 (Total Hours)", f"{total_duration / 60:.1f} hrs", help="你在厕所度过的总时间")123 with col3:124 # 如果超过24小时没拉,变成红色警告125 sentiment = "Bearish (便秘风险)" if hours_since > 24 else "Bullish (通畅)"126 delta_color = "inverse" if hours_since > 24 else "normal"127 st.metric("上次交割 (Last Trade)", f"{hours_since:.1f} hrs ago", delta=sentiment, delta_color=delta_color)128 with col4:129 st.metric("平均压力 (Avg RSI)", f"{avg_effort:.1f}/10", help="平均括约肌努力程度")130 131 st.markdown("---")132 133 # --- B. 专业图表区 (Technical Analysis) ---134 c1, c2 = st.columns([2, 1])135 136 with c1:137 st.subheader("📈 收益走势 (Earnings Trend)")138 # 使用 Plotly 画更高级的面积图139 fig_trend = px.area(140 df,141 x='timestamp',142 y='net_profit',143 color='asset_class',144 title='Net Profit over Time by Asset Class',145 template="plotly_dark",146 color_discrete_sequence=px.colors.qualitative.Pastel147 )148 st.plotly_chart(fig_trend, use_container_width=True)149 150 with c2:151 st.subheader("🍰 资产分布 (Portfolio)")152 fig_pie = px.pie(153 df,154 names='asset_class',155 values='duration_min',156 hole=0.4,157 template="plotly_dark",158 color_discrete_sequence=px.colors.qualitative.Set3159 )160 fig_pie.update_layout(showlegend=False, margin=dict(t=0, b=0, l=0, r=0))161 st.plotly_chart(fig_pie, use_container_width=True)162 163 # --- C. 详细账本 (Ledger) ---164 with st.expander("📜 查看历史交割单 (Transaction History)", expanded=True):165 # 格式化一下显示,让它更好看166 display_df = df[['timestamp', 'asset_class', 'duration_min', 'net_profit', 'volatility']].copy()167 display_df.columns = ['Time', 'Asset Type', 'Duration (min)', 'Earnings (¥)', 'Effort (1-10)']168 169 st.dataframe(170 display_df.style.background_gradient(subset=['Earnings (¥)'], cmap='Greens'),171 use_container_width=True,172 hide_index=True173 )174 175# 底部免责声明176st.markdown("---")177st.caption(178 "Investment Advice: High volatility in the morning is expected. Please maintain adequate fiber intake to ensure market liquidity.")