初始提交
This commit is contained in:
+210
@@ -0,0 +1,210 @@
|
||||
import streamlit as st
|
||||
from datetime import datetime
|
||||
from typing import Dict, List
|
||||
|
||||
from monitor_db import monitor_db
|
||||
from monitor_service import monitor_service
|
||||
from notification_service import notification_service
|
||||
|
||||
def display_monitor_panel():
|
||||
"""显示监测面板"""
|
||||
|
||||
st.markdown("## 📊 实时监测面板")
|
||||
|
||||
# 监测服务控制
|
||||
col1, col2, col3 = st.columns([1, 1, 1])
|
||||
|
||||
with col1:
|
||||
if st.button("▶️ 启动监测服务", type="primary"):
|
||||
monitor_service.start_monitoring()
|
||||
|
||||
with col2:
|
||||
if st.button("⏹️ 停止监测服务"):
|
||||
monitor_service.stop_monitoring()
|
||||
|
||||
with col3:
|
||||
if st.button("🔄 手动更新所有"):
|
||||
stocks = monitor_service.get_stocks_needing_update()
|
||||
for stock in stocks:
|
||||
monitor_service.manual_update_stock(stock['id'])
|
||||
st.success(f"✅ 已手动更新 {len(stocks)} 只股票")
|
||||
|
||||
# 显示通知
|
||||
display_notifications()
|
||||
|
||||
# 显示监测股票
|
||||
display_monitored_stocks()
|
||||
|
||||
def display_notifications():
|
||||
"""显示通知"""
|
||||
notifications = notification_service.get_streamlit_notifications()
|
||||
|
||||
if notifications:
|
||||
st.markdown("### 🔔 最新提醒")
|
||||
|
||||
for notification in notifications[-5:]: # 只显示最近5条
|
||||
notification_type = notification['type']
|
||||
color_map = {
|
||||
'entry': '🟢',
|
||||
'take_profit': '🟡',
|
||||
'stop_loss': '🔴'
|
||||
}
|
||||
icon = color_map.get(notification_type, '🔵')
|
||||
|
||||
st.info(f"{icon} **{notification['symbol']}** - {notification['message']}")
|
||||
|
||||
if st.button("清空提醒"):
|
||||
notification_service.clear_streamlit_notifications()
|
||||
st.rerun()
|
||||
|
||||
def display_monitored_stocks():
|
||||
"""显示监测股票卡片"""
|
||||
stocks = monitor_db.get_monitored_stocks()
|
||||
|
||||
if not stocks:
|
||||
st.info("📋 暂无监测股票,请在分析完成后点击'加入监测'按钮添加")
|
||||
return
|
||||
|
||||
st.markdown(f"### 📈 监测中 ({len(stocks)} 只)")
|
||||
|
||||
# 每行显示3个卡片
|
||||
cols = st.columns(3)
|
||||
|
||||
for i, stock in enumerate(stocks):
|
||||
col_idx = i % 3
|
||||
with cols[col_idx]:
|
||||
display_stock_card(stock)
|
||||
|
||||
def display_stock_card(stock: Dict):
|
||||
"""显示单个股票监测卡片"""
|
||||
|
||||
with st.container():
|
||||
st.markdown(f"### {stock['symbol']} - {stock['name']}")
|
||||
|
||||
# 评级和状态
|
||||
col1, col2 = st.columns([1, 1])
|
||||
with col1:
|
||||
rating_color = {
|
||||
'买入': '🟢',
|
||||
'持有': '🟡',
|
||||
'卖出': '🔴'
|
||||
}
|
||||
st.metric("评级", f"{rating_color.get(stock['rating'], '⚪')} {stock['rating']}")
|
||||
|
||||
with col2:
|
||||
if stock['current_price'] and stock['current_price'] != 'N/A':
|
||||
st.metric("当前价格", f"¥{stock['current_price']}")
|
||||
else:
|
||||
st.metric("当前价格", "等待更新")
|
||||
|
||||
# 关键价位
|
||||
entry_range = stock['entry_range']
|
||||
st.info(f"**进场区间**: ¥{entry_range['min']} - ¥{entry_range['max']}")
|
||||
|
||||
if stock['take_profit']:
|
||||
st.success(f"**止盈位**: ¥{stock['take_profit']}")
|
||||
|
||||
if stock['stop_loss']:
|
||||
st.error(f"**止损位**: ¥{stock['stop_loss']}")
|
||||
|
||||
# 最后更新时间
|
||||
if stock['last_checked']:
|
||||
last_checked = datetime.fromisoformat(stock['last_checked'])
|
||||
st.caption(f"最后更新: {last_checked.strftime('%m-%d %H:%M')}")
|
||||
|
||||
# 操作按钮
|
||||
col1, col2 = st.columns([1, 1])
|
||||
with col1:
|
||||
if st.button("🔄 更新", key=f"update_{stock['id']}"):
|
||||
if monitor_service.manual_update_stock(stock['id']):
|
||||
st.success("✅ 更新成功")
|
||||
else:
|
||||
st.error("❌ 更新失败")
|
||||
|
||||
with col2:
|
||||
if st.button("🗑️ 移除", key=f"remove_{stock['id']}"):
|
||||
monitor_db.remove_monitored_stock(stock['id'])
|
||||
st.success("✅ 已移除监测")
|
||||
st.rerun()
|
||||
|
||||
def add_to_monitor_dialog(stock_info: Dict, analysis_result: Dict):
|
||||
"""显示添加到监测的对话框"""
|
||||
|
||||
st.markdown("---")
|
||||
st.markdown("## 📈 添加到实时监测")
|
||||
|
||||
# 从分析结果中提取关键数据
|
||||
final_decision = analysis_result.get('final_decision', {})
|
||||
rating = final_decision.get('rating', '持有')
|
||||
reasoning = final_decision.get('reasoning', '')
|
||||
|
||||
# 生成唯一的session标识符
|
||||
import uuid
|
||||
import time
|
||||
session_id = f"{stock_info.get('symbol', 'unknown')}_{int(time.time())}_{uuid.uuid4().hex[:6]}"
|
||||
|
||||
# 解析关键价位(从分析结果中提取或手动输入)
|
||||
col1, col2 = st.columns([1, 1])
|
||||
|
||||
with col1:
|
||||
# 进场区间
|
||||
st.subheader("🎯 进场区间")
|
||||
entry_min = st.number_input("最低进场价", value=0.0, key=f"entry_min_{session_id}")
|
||||
entry_max = st.number_input("最高进场价", value=0.0, key=f"entry_max_{session_id}")
|
||||
|
||||
if entry_min > 0 and entry_max > 0 and entry_max > entry_min:
|
||||
entry_range = {"min": entry_min, "max": entry_max}
|
||||
else:
|
||||
st.warning("请输入有效的进场区间")
|
||||
entry_range = None
|
||||
|
||||
with col2:
|
||||
# 止盈止损
|
||||
st.subheader("⚖️ 风险控制")
|
||||
take_profit = st.number_input("止盈价位", value=0.0, key=f"take_profit_{session_id}")
|
||||
stop_loss = st.number_input("止损价位", value=0.0, key=f"stop_loss_{session_id}")
|
||||
|
||||
if take_profit > 0:
|
||||
st.success(f"止盈位: ¥{take_profit}")
|
||||
if stop_loss > 0:
|
||||
st.error(f"止损位: ¥{stop_loss}")
|
||||
|
||||
# 监测设置
|
||||
st.subheader("⏰ 监测设置")
|
||||
check_interval = st.slider("监测间隔(分钟)", 5, 120, 30, key=f"check_interval_{session_id}")
|
||||
notification_enabled = st.checkbox("启用提醒", value=True, key=f"notification_enabled_{session_id}")
|
||||
|
||||
# 添加按钮
|
||||
if st.button("✅ 确认加入监测", type="primary", key=f"add_monitor_{session_id}"):
|
||||
if entry_range:
|
||||
# 添加到监测数据库
|
||||
stock_id = monitor_db.add_monitored_stock(
|
||||
symbol=stock_info.get('symbol'),
|
||||
name=stock_info.get('name'),
|
||||
rating=rating,
|
||||
entry_range=entry_range,
|
||||
take_profit=take_profit if take_profit > 0 else None,
|
||||
stop_loss=stop_loss if stop_loss > 0 else None,
|
||||
check_interval=check_interval
|
||||
)
|
||||
|
||||
st.success(f"✅ 已成功将 {stock_info.get('symbol')} 加入实时监测")
|
||||
st.balloons()
|
||||
|
||||
# 立即更新一次价格
|
||||
monitor_service.manual_update_stock(stock_id)
|
||||
else:
|
||||
st.error("❌ 请设置有效的进场区间")
|
||||
|
||||
def get_monitor_summary() -> Dict:
|
||||
"""获取监测摘要信息"""
|
||||
stocks = monitor_db.get_monitored_stocks()
|
||||
|
||||
summary = {
|
||||
'total_stocks': len(stocks),
|
||||
'stocks_needing_update': len(monitor_service.get_stocks_needing_update()),
|
||||
'pending_notifications': len(monitor_db.get_pending_notifications()),
|
||||
'active_monitoring': monitor_service.running
|
||||
}
|
||||
|
||||
return summary
|
||||
Reference in New Issue
Block a user