mcli-framework 7.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mcli-framework might be problematic. Click here for more details.

Files changed (186) hide show
  1. mcli/app/chat_cmd.py +42 -0
  2. mcli/app/commands_cmd.py +226 -0
  3. mcli/app/completion_cmd.py +216 -0
  4. mcli/app/completion_helpers.py +288 -0
  5. mcli/app/cron_test_cmd.py +697 -0
  6. mcli/app/logs_cmd.py +419 -0
  7. mcli/app/main.py +492 -0
  8. mcli/app/model/model.py +1060 -0
  9. mcli/app/model_cmd.py +227 -0
  10. mcli/app/redis_cmd.py +269 -0
  11. mcli/app/video/video.py +1114 -0
  12. mcli/app/visual_cmd.py +303 -0
  13. mcli/chat/chat.py +2409 -0
  14. mcli/chat/command_rag.py +514 -0
  15. mcli/chat/enhanced_chat.py +652 -0
  16. mcli/chat/system_controller.py +1010 -0
  17. mcli/chat/system_integration.py +1016 -0
  18. mcli/cli.py +25 -0
  19. mcli/config.toml +20 -0
  20. mcli/lib/api/api.py +586 -0
  21. mcli/lib/api/daemon_client.py +203 -0
  22. mcli/lib/api/daemon_client_local.py +44 -0
  23. mcli/lib/api/daemon_decorator.py +217 -0
  24. mcli/lib/api/mcli_decorators.py +1032 -0
  25. mcli/lib/auth/auth.py +85 -0
  26. mcli/lib/auth/aws_manager.py +85 -0
  27. mcli/lib/auth/azure_manager.py +91 -0
  28. mcli/lib/auth/credential_manager.py +192 -0
  29. mcli/lib/auth/gcp_manager.py +93 -0
  30. mcli/lib/auth/key_manager.py +117 -0
  31. mcli/lib/auth/mcli_manager.py +93 -0
  32. mcli/lib/auth/token_manager.py +75 -0
  33. mcli/lib/auth/token_util.py +1011 -0
  34. mcli/lib/config/config.py +47 -0
  35. mcli/lib/discovery/__init__.py +1 -0
  36. mcli/lib/discovery/command_discovery.py +274 -0
  37. mcli/lib/erd/erd.py +1345 -0
  38. mcli/lib/erd/generate_graph.py +453 -0
  39. mcli/lib/files/files.py +76 -0
  40. mcli/lib/fs/fs.py +109 -0
  41. mcli/lib/lib.py +29 -0
  42. mcli/lib/logger/logger.py +611 -0
  43. mcli/lib/performance/optimizer.py +409 -0
  44. mcli/lib/performance/rust_bridge.py +502 -0
  45. mcli/lib/performance/uvloop_config.py +154 -0
  46. mcli/lib/pickles/pickles.py +50 -0
  47. mcli/lib/search/cached_vectorizer.py +479 -0
  48. mcli/lib/services/data_pipeline.py +460 -0
  49. mcli/lib/services/lsh_client.py +441 -0
  50. mcli/lib/services/redis_service.py +387 -0
  51. mcli/lib/shell/shell.py +137 -0
  52. mcli/lib/toml/toml.py +33 -0
  53. mcli/lib/ui/styling.py +47 -0
  54. mcli/lib/ui/visual_effects.py +634 -0
  55. mcli/lib/watcher/watcher.py +185 -0
  56. mcli/ml/api/app.py +215 -0
  57. mcli/ml/api/middleware.py +224 -0
  58. mcli/ml/api/routers/admin_router.py +12 -0
  59. mcli/ml/api/routers/auth_router.py +244 -0
  60. mcli/ml/api/routers/backtest_router.py +12 -0
  61. mcli/ml/api/routers/data_router.py +12 -0
  62. mcli/ml/api/routers/model_router.py +302 -0
  63. mcli/ml/api/routers/monitoring_router.py +12 -0
  64. mcli/ml/api/routers/portfolio_router.py +12 -0
  65. mcli/ml/api/routers/prediction_router.py +267 -0
  66. mcli/ml/api/routers/trade_router.py +12 -0
  67. mcli/ml/api/routers/websocket_router.py +76 -0
  68. mcli/ml/api/schemas.py +64 -0
  69. mcli/ml/auth/auth_manager.py +425 -0
  70. mcli/ml/auth/models.py +154 -0
  71. mcli/ml/auth/permissions.py +302 -0
  72. mcli/ml/backtesting/backtest_engine.py +502 -0
  73. mcli/ml/backtesting/performance_metrics.py +393 -0
  74. mcli/ml/cache.py +400 -0
  75. mcli/ml/cli/main.py +398 -0
  76. mcli/ml/config/settings.py +394 -0
  77. mcli/ml/configs/dvc_config.py +230 -0
  78. mcli/ml/configs/mlflow_config.py +131 -0
  79. mcli/ml/configs/mlops_manager.py +293 -0
  80. mcli/ml/dashboard/app.py +532 -0
  81. mcli/ml/dashboard/app_integrated.py +738 -0
  82. mcli/ml/dashboard/app_supabase.py +560 -0
  83. mcli/ml/dashboard/app_training.py +615 -0
  84. mcli/ml/dashboard/cli.py +51 -0
  85. mcli/ml/data_ingestion/api_connectors.py +501 -0
  86. mcli/ml/data_ingestion/data_pipeline.py +567 -0
  87. mcli/ml/data_ingestion/stream_processor.py +512 -0
  88. mcli/ml/database/migrations/env.py +94 -0
  89. mcli/ml/database/models.py +667 -0
  90. mcli/ml/database/session.py +200 -0
  91. mcli/ml/experimentation/ab_testing.py +845 -0
  92. mcli/ml/features/ensemble_features.py +607 -0
  93. mcli/ml/features/political_features.py +676 -0
  94. mcli/ml/features/recommendation_engine.py +809 -0
  95. mcli/ml/features/stock_features.py +573 -0
  96. mcli/ml/features/test_feature_engineering.py +346 -0
  97. mcli/ml/logging.py +85 -0
  98. mcli/ml/mlops/data_versioning.py +518 -0
  99. mcli/ml/mlops/experiment_tracker.py +377 -0
  100. mcli/ml/mlops/model_serving.py +481 -0
  101. mcli/ml/mlops/pipeline_orchestrator.py +614 -0
  102. mcli/ml/models/base_models.py +324 -0
  103. mcli/ml/models/ensemble_models.py +675 -0
  104. mcli/ml/models/recommendation_models.py +474 -0
  105. mcli/ml/models/test_models.py +487 -0
  106. mcli/ml/monitoring/drift_detection.py +676 -0
  107. mcli/ml/monitoring/metrics.py +45 -0
  108. mcli/ml/optimization/portfolio_optimizer.py +834 -0
  109. mcli/ml/preprocessing/data_cleaners.py +451 -0
  110. mcli/ml/preprocessing/feature_extractors.py +491 -0
  111. mcli/ml/preprocessing/ml_pipeline.py +382 -0
  112. mcli/ml/preprocessing/politician_trading_preprocessor.py +569 -0
  113. mcli/ml/preprocessing/test_preprocessing.py +294 -0
  114. mcli/ml/scripts/populate_sample_data.py +200 -0
  115. mcli/ml/tasks.py +400 -0
  116. mcli/ml/tests/test_integration.py +429 -0
  117. mcli/ml/tests/test_training_dashboard.py +387 -0
  118. mcli/public/oi/oi.py +15 -0
  119. mcli/public/public.py +4 -0
  120. mcli/self/self_cmd.py +1246 -0
  121. mcli/workflow/daemon/api_daemon.py +800 -0
  122. mcli/workflow/daemon/async_command_database.py +681 -0
  123. mcli/workflow/daemon/async_process_manager.py +591 -0
  124. mcli/workflow/daemon/client.py +530 -0
  125. mcli/workflow/daemon/commands.py +1196 -0
  126. mcli/workflow/daemon/daemon.py +905 -0
  127. mcli/workflow/daemon/daemon_api.py +59 -0
  128. mcli/workflow/daemon/enhanced_daemon.py +571 -0
  129. mcli/workflow/daemon/process_cli.py +244 -0
  130. mcli/workflow/daemon/process_manager.py +439 -0
  131. mcli/workflow/daemon/test_daemon.py +275 -0
  132. mcli/workflow/dashboard/dashboard_cmd.py +113 -0
  133. mcli/workflow/docker/docker.py +0 -0
  134. mcli/workflow/file/file.py +100 -0
  135. mcli/workflow/gcloud/config.toml +21 -0
  136. mcli/workflow/gcloud/gcloud.py +58 -0
  137. mcli/workflow/git_commit/ai_service.py +328 -0
  138. mcli/workflow/git_commit/commands.py +430 -0
  139. mcli/workflow/lsh_integration.py +355 -0
  140. mcli/workflow/model_service/client.py +594 -0
  141. mcli/workflow/model_service/download_and_run_efficient_models.py +288 -0
  142. mcli/workflow/model_service/lightweight_embedder.py +397 -0
  143. mcli/workflow/model_service/lightweight_model_server.py +714 -0
  144. mcli/workflow/model_service/lightweight_test.py +241 -0
  145. mcli/workflow/model_service/model_service.py +1955 -0
  146. mcli/workflow/model_service/ollama_efficient_runner.py +425 -0
  147. mcli/workflow/model_service/pdf_processor.py +386 -0
  148. mcli/workflow/model_service/test_efficient_runner.py +234 -0
  149. mcli/workflow/model_service/test_example.py +315 -0
  150. mcli/workflow/model_service/test_integration.py +131 -0
  151. mcli/workflow/model_service/test_new_features.py +149 -0
  152. mcli/workflow/openai/openai.py +99 -0
  153. mcli/workflow/politician_trading/commands.py +1790 -0
  154. mcli/workflow/politician_trading/config.py +134 -0
  155. mcli/workflow/politician_trading/connectivity.py +490 -0
  156. mcli/workflow/politician_trading/data_sources.py +395 -0
  157. mcli/workflow/politician_trading/database.py +410 -0
  158. mcli/workflow/politician_trading/demo.py +248 -0
  159. mcli/workflow/politician_trading/models.py +165 -0
  160. mcli/workflow/politician_trading/monitoring.py +413 -0
  161. mcli/workflow/politician_trading/scrapers.py +966 -0
  162. mcli/workflow/politician_trading/scrapers_california.py +412 -0
  163. mcli/workflow/politician_trading/scrapers_eu.py +377 -0
  164. mcli/workflow/politician_trading/scrapers_uk.py +350 -0
  165. mcli/workflow/politician_trading/scrapers_us_states.py +438 -0
  166. mcli/workflow/politician_trading/supabase_functions.py +354 -0
  167. mcli/workflow/politician_trading/workflow.py +852 -0
  168. mcli/workflow/registry/registry.py +180 -0
  169. mcli/workflow/repo/repo.py +223 -0
  170. mcli/workflow/scheduler/commands.py +493 -0
  171. mcli/workflow/scheduler/cron_parser.py +238 -0
  172. mcli/workflow/scheduler/job.py +182 -0
  173. mcli/workflow/scheduler/monitor.py +139 -0
  174. mcli/workflow/scheduler/persistence.py +324 -0
  175. mcli/workflow/scheduler/scheduler.py +679 -0
  176. mcli/workflow/sync/sync_cmd.py +437 -0
  177. mcli/workflow/sync/test_cmd.py +314 -0
  178. mcli/workflow/videos/videos.py +242 -0
  179. mcli/workflow/wakatime/wakatime.py +11 -0
  180. mcli/workflow/workflow.py +37 -0
  181. mcli_framework-7.0.0.dist-info/METADATA +479 -0
  182. mcli_framework-7.0.0.dist-info/RECORD +186 -0
  183. mcli_framework-7.0.0.dist-info/WHEEL +5 -0
  184. mcli_framework-7.0.0.dist-info/entry_points.txt +7 -0
  185. mcli_framework-7.0.0.dist-info/licenses/LICENSE +21 -0
  186. mcli_framework-7.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,532 @@
1
+ """Streamlit dashboard for ML system monitoring"""
2
+
3
+ import streamlit as st
4
+ import pandas as pd
5
+ import plotly.express as px
6
+ import plotly.graph_objects as go
7
+ from plotly.subplots import make_subplots
8
+ import asyncio
9
+ import requests
10
+ import time
11
+ from datetime import datetime, timedelta
12
+ import numpy as np
13
+
14
+ from mcli.ml.database.session import SessionLocal
15
+ from mcli.ml.database.models import (
16
+ Model, Prediction, Portfolio, User, Trade,
17
+ StockData, BacktestResult, ModelStatus
18
+ )
19
+ from mcli.ml.cache import cache_manager
20
+ from mcli.ml.config import settings
21
+
22
+ # Page config
23
+ st.set_page_config(
24
+ page_title="MCLI ML Dashboard",
25
+ page_icon="📊",
26
+ layout="wide",
27
+ initial_sidebar_state="expanded"
28
+ )
29
+
30
+ # Custom CSS
31
+ st.markdown("""
32
+ <style>
33
+ .metric-card {
34
+ background-color: #f0f2f6;
35
+ padding: 1rem;
36
+ border-radius: 0.5rem;
37
+ border-left: 4px solid #1f77b4;
38
+ }
39
+ .alert-success {
40
+ background-color: #d4edda;
41
+ border: 1px solid #c3e6cb;
42
+ color: #155724;
43
+ padding: 0.75rem;
44
+ border-radius: 0.25rem;
45
+ }
46
+ .alert-warning {
47
+ background-color: #fff3cd;
48
+ border: 1px solid #ffeaa7;
49
+ color: #856404;
50
+ padding: 0.75rem;
51
+ border-radius: 0.25rem;
52
+ }
53
+ .alert-danger {
54
+ background-color: #f8d7da;
55
+ border: 1px solid #f5c6cb;
56
+ color: #721c24;
57
+ padding: 0.75rem;
58
+ border-radius: 0.25rem;
59
+ }
60
+ </style>
61
+ """, unsafe_allow_html=True)
62
+
63
+
64
+ @st.cache_data(ttl=30)
65
+ def get_system_metrics():
66
+ """Get real-time system metrics"""
67
+ db = SessionLocal()
68
+
69
+ try:
70
+ # Model metrics
71
+ total_models = db.query(Model).count()
72
+ deployed_models = db.query(Model).filter(Model.status == ModelStatus.DEPLOYED).count()
73
+ training_models = db.query(Model).filter(Model.status == ModelStatus.TRAINING).count()
74
+
75
+ # User metrics
76
+ total_users = db.query(User).count()
77
+ active_users = db.query(User).filter(
78
+ User.last_login_at >= datetime.utcnow() - timedelta(days=1)
79
+ ).count()
80
+
81
+ # Prediction metrics
82
+ predictions_today = db.query(Prediction).filter(
83
+ Prediction.prediction_date >= datetime.utcnow().date()
84
+ ).count()
85
+
86
+ # Portfolio metrics
87
+ active_portfolios = db.query(Portfolio).filter(Portfolio.is_active == True).count()
88
+
89
+ return {
90
+ 'total_models': total_models,
91
+ 'deployed_models': deployed_models,
92
+ 'training_models': training_models,
93
+ 'total_users': total_users,
94
+ 'active_users': active_users,
95
+ 'predictions_today': predictions_today,
96
+ 'active_portfolios': active_portfolios,
97
+ 'timestamp': datetime.utcnow()
98
+ }
99
+ finally:
100
+ db.close()
101
+
102
+
103
+ @st.cache_data(ttl=60)
104
+ def get_model_performance():
105
+ """Get model performance data"""
106
+ db = SessionLocal()
107
+
108
+ try:
109
+ models = db.query(Model).filter(Model.status == ModelStatus.DEPLOYED).all()
110
+
111
+ data = []
112
+ for model in models:
113
+ data.append({
114
+ 'name': model.name,
115
+ 'accuracy': model.test_accuracy or 0,
116
+ 'created_at': model.created_at,
117
+ 'last_updated': model.updated_at
118
+ })
119
+
120
+ return pd.DataFrame(data)
121
+ finally:
122
+ db.close()
123
+
124
+
125
+ @st.cache_data(ttl=30)
126
+ def get_recent_predictions():
127
+ """Get recent predictions"""
128
+ db = SessionLocal()
129
+
130
+ try:
131
+ predictions = db.query(Prediction).order_by(
132
+ Prediction.prediction_date.desc()
133
+ ).limit(100).all()
134
+
135
+ data = []
136
+ for pred in predictions:
137
+ data.append({
138
+ 'ticker': pred.ticker,
139
+ 'predicted_return': pred.predicted_return,
140
+ 'confidence': pred.confidence_score,
141
+ 'prediction_date': pred.prediction_date,
142
+ 'target_date': pred.target_date
143
+ })
144
+
145
+ return pd.DataFrame(data)
146
+ finally:
147
+ db.close()
148
+
149
+
150
+ @st.cache_data(ttl=60)
151
+ def get_portfolio_performance():
152
+ """Get portfolio performance data"""
153
+ db = SessionLocal()
154
+
155
+ try:
156
+ portfolios = db.query(Portfolio).filter(Portfolio.is_active == True).all()
157
+
158
+ data = []
159
+ for portfolio in portfolios:
160
+ data.append({
161
+ 'name': portfolio.name,
162
+ 'total_return': portfolio.total_return or 0,
163
+ 'sharpe_ratio': portfolio.sharpe_ratio or 0,
164
+ 'max_drawdown': portfolio.max_drawdown or 0,
165
+ 'current_value': portfolio.current_value or 0
166
+ })
167
+
168
+ return pd.DataFrame(data)
169
+ finally:
170
+ db.close()
171
+
172
+
173
+ def check_api_health():
174
+ """Check API health"""
175
+ try:
176
+ response = requests.get(f"http://localhost:{settings.api.port}/health", timeout=5)
177
+ return response.status_code == 200
178
+ except:
179
+ return False
180
+
181
+
182
+ def check_redis_health():
183
+ """Check Redis health"""
184
+ try:
185
+ cache_manager.initialize()
186
+ return cache_manager.redis_client.ping() if cache_manager.redis_client else False
187
+ except:
188
+ return False
189
+
190
+
191
+ def main():
192
+ """Main dashboard function"""
193
+
194
+ # Title and header
195
+ st.title("🤖 MCLI ML System Dashboard")
196
+ st.markdown("Real-time monitoring of ML models, predictions, and system health")
197
+
198
+ # Sidebar
199
+ st.sidebar.title("Navigation")
200
+ page = st.sidebar.selectbox(
201
+ "Choose a page",
202
+ ["Overview", "Models", "Predictions", "Portfolios", "System Health", "Live Monitoring"]
203
+ )
204
+
205
+ # Auto-refresh toggle
206
+ auto_refresh = st.sidebar.checkbox("Auto-refresh (30s)", value=True)
207
+ if auto_refresh:
208
+ time.sleep(30)
209
+ st.rerun()
210
+
211
+ # Manual refresh button
212
+ if st.sidebar.button("🔄 Refresh Now"):
213
+ st.cache_data.clear()
214
+ st.rerun()
215
+
216
+ # Main content based on selected page
217
+ if page == "Overview":
218
+ show_overview()
219
+ elif page == "Models":
220
+ show_models()
221
+ elif page == "Predictions":
222
+ show_predictions()
223
+ elif page == "Portfolios":
224
+ show_portfolios()
225
+ elif page == "System Health":
226
+ show_system_health()
227
+ elif page == "Live Monitoring":
228
+ show_live_monitoring()
229
+
230
+
231
+ def show_overview():
232
+ """Show overview dashboard"""
233
+ st.header("System Overview")
234
+
235
+ # Get metrics
236
+ metrics = get_system_metrics()
237
+
238
+ # Display key metrics
239
+ col1, col2, col3, col4 = st.columns(4)
240
+
241
+ with col1:
242
+ st.metric(
243
+ label="Deployed Models",
244
+ value=metrics['deployed_models'],
245
+ delta=f"{metrics['training_models']} training"
246
+ )
247
+
248
+ with col2:
249
+ st.metric(
250
+ label="Active Users",
251
+ value=metrics['active_users'],
252
+ delta=f"{metrics['total_users']} total"
253
+ )
254
+
255
+ with col3:
256
+ st.metric(
257
+ label="Predictions Today",
258
+ value=metrics['predictions_today']
259
+ )
260
+
261
+ with col4:
262
+ st.metric(
263
+ label="Active Portfolios",
264
+ value=metrics['active_portfolios']
265
+ )
266
+
267
+ # Charts
268
+ col1, col2 = st.columns(2)
269
+
270
+ with col1:
271
+ st.subheader("Model Performance")
272
+ model_data = get_model_performance()
273
+ if not model_data.empty:
274
+ fig = px.bar(
275
+ model_data,
276
+ x='name',
277
+ y='accuracy',
278
+ title="Model Accuracy Comparison"
279
+ )
280
+ st.plotly_chart(fig, use_container_width=True)
281
+ else:
282
+ st.info("No model performance data available")
283
+
284
+ with col2:
285
+ st.subheader("Recent Predictions")
286
+ pred_data = get_recent_predictions()
287
+ if not pred_data.empty:
288
+ # Show confidence distribution
289
+ fig = px.histogram(
290
+ pred_data,
291
+ x='confidence',
292
+ title="Prediction Confidence Distribution"
293
+ )
294
+ st.plotly_chart(fig, use_container_width=True)
295
+ else:
296
+ st.info("No recent predictions available")
297
+
298
+
299
+ def show_models():
300
+ """Show models dashboard"""
301
+ st.header("Model Management")
302
+
303
+ # Model performance table
304
+ model_data = get_model_performance()
305
+
306
+ if not model_data.empty:
307
+ st.subheader("Model Performance")
308
+ st.dataframe(model_data, use_container_width=True)
309
+
310
+ # Model accuracy chart
311
+ fig = px.line(
312
+ model_data,
313
+ x='created_at',
314
+ y='accuracy',
315
+ color='name',
316
+ title="Model Accuracy Over Time"
317
+ )
318
+ st.plotly_chart(fig, use_container_width=True)
319
+ else:
320
+ st.warning("No model data available")
321
+
322
+
323
+ def show_predictions():
324
+ """Show predictions dashboard"""
325
+ st.header("Predictions Analysis")
326
+
327
+ pred_data = get_recent_predictions()
328
+
329
+ if not pred_data.empty:
330
+ # Filters
331
+ col1, col2 = st.columns(2)
332
+ with col1:
333
+ selected_tickers = st.multiselect(
334
+ "Filter by Ticker",
335
+ options=pred_data['ticker'].unique(),
336
+ default=pred_data['ticker'].unique()[:5]
337
+ )
338
+
339
+ with col2:
340
+ confidence_threshold = st.slider(
341
+ "Minimum Confidence",
342
+ min_value=0.0,
343
+ max_value=1.0,
344
+ value=0.5,
345
+ step=0.1
346
+ )
347
+
348
+ # Filter data
349
+ filtered_data = pred_data[
350
+ (pred_data['ticker'].isin(selected_tickers)) &
351
+ (pred_data['confidence'] >= confidence_threshold)
352
+ ]
353
+
354
+ # Display filtered data
355
+ st.subheader("Filtered Predictions")
356
+ st.dataframe(filtered_data, use_container_width=True)
357
+
358
+ # Charts
359
+ col1, col2 = st.columns(2)
360
+
361
+ with col1:
362
+ fig = px.scatter(
363
+ filtered_data,
364
+ x='confidence',
365
+ y='predicted_return',
366
+ color='ticker',
367
+ title="Confidence vs Predicted Return"
368
+ )
369
+ st.plotly_chart(fig, use_container_width=True)
370
+
371
+ with col2:
372
+ # Group by ticker and show average return
373
+ avg_returns = filtered_data.groupby('ticker')['predicted_return'].mean().reset_index()
374
+ fig = px.bar(
375
+ avg_returns,
376
+ x='ticker',
377
+ y='predicted_return',
378
+ title="Average Predicted Return by Ticker"
379
+ )
380
+ st.plotly_chart(fig, use_container_width=True)
381
+
382
+ else:
383
+ st.warning("No prediction data available")
384
+
385
+
386
+ def show_portfolios():
387
+ """Show portfolios dashboard"""
388
+ st.header("Portfolio Performance")
389
+
390
+ portfolio_data = get_portfolio_performance()
391
+
392
+ if not portfolio_data.empty:
393
+ # Portfolio metrics
394
+ st.subheader("Portfolio Summary")
395
+ st.dataframe(portfolio_data, use_container_width=True)
396
+
397
+ # Performance charts
398
+ col1, col2 = st.columns(2)
399
+
400
+ with col1:
401
+ fig = px.bar(
402
+ portfolio_data,
403
+ x='name',
404
+ y='total_return',
405
+ title="Total Return by Portfolio"
406
+ )
407
+ st.plotly_chart(fig, use_container_width=True)
408
+
409
+ with col2:
410
+ fig = px.scatter(
411
+ portfolio_data,
412
+ x='sharpe_ratio',
413
+ y='total_return',
414
+ size='current_value',
415
+ hover_data=['name'],
416
+ title="Risk-Return Analysis"
417
+ )
418
+ st.plotly_chart(fig, use_container_width=True)
419
+
420
+ else:
421
+ st.warning("No portfolio data available")
422
+
423
+
424
+ def show_system_health():
425
+ """Show system health dashboard"""
426
+ st.header("System Health")
427
+
428
+ # Check various system components
429
+ api_healthy = check_api_health()
430
+ redis_healthy = check_redis_health()
431
+
432
+ col1, col2, col3 = st.columns(3)
433
+
434
+ with col1:
435
+ if api_healthy:
436
+ st.success("✅ API Server: Healthy")
437
+ else:
438
+ st.error("❌ API Server: Unhealthy")
439
+
440
+ with col2:
441
+ if redis_healthy:
442
+ st.success("✅ Redis Cache: Healthy")
443
+ else:
444
+ st.error("❌ Redis Cache: Unhealthy")
445
+
446
+ with col3:
447
+ # Database health (always assume healthy if we can query)
448
+ st.success("✅ Database: Healthy")
449
+
450
+ # System metrics over time (simulated)
451
+ st.subheader("System Metrics")
452
+
453
+ # Generate sample time series data
454
+ times = pd.date_range(start=datetime.now() - timedelta(hours=24), end=datetime.now(), freq='H')
455
+ cpu_usage = np.random.normal(45, 10, len(times))
456
+ memory_usage = np.random.normal(60, 15, len(times))
457
+
458
+ metrics_df = pd.DataFrame({
459
+ 'time': times,
460
+ 'cpu_usage': np.clip(cpu_usage, 0, 100),
461
+ 'memory_usage': np.clip(memory_usage, 0, 100)
462
+ })
463
+
464
+ fig = make_subplots(
465
+ rows=2, cols=1,
466
+ subplot_titles=('CPU Usage (%)', 'Memory Usage (%)')
467
+ )
468
+
469
+ fig.add_trace(
470
+ go.Scatter(x=metrics_df['time'], y=metrics_df['cpu_usage'], name='CPU'),
471
+ row=1, col=1
472
+ )
473
+
474
+ fig.add_trace(
475
+ go.Scatter(x=metrics_df['time'], y=metrics_df['memory_usage'], name='Memory'),
476
+ row=2, col=1
477
+ )
478
+
479
+ fig.update_layout(height=500, title_text="System Resource Usage (24h)")
480
+ st.plotly_chart(fig, use_container_width=True)
481
+
482
+
483
+ def show_live_monitoring():
484
+ """Show live monitoring with real-time updates"""
485
+ st.header("Live Monitoring")
486
+
487
+ # Real-time metrics placeholder
488
+ metrics_placeholder = st.empty()
489
+
490
+ # Live prediction feed
491
+ st.subheader("Live Prediction Feed")
492
+ prediction_placeholder = st.empty()
493
+
494
+ # Live model status
495
+ st.subheader("Model Status")
496
+ model_placeholder = st.empty()
497
+
498
+ # Auto-update every 5 seconds
499
+ if st.button("Start Live Monitoring"):
500
+ for i in range(60): # Run for 5 minutes
501
+ # Update metrics
502
+ metrics = get_system_metrics()
503
+ with metrics_placeholder.container():
504
+ col1, col2, col3 = st.columns(3)
505
+ with col1:
506
+ st.metric("Predictions/min", np.random.randint(5, 20))
507
+ with col2:
508
+ st.metric("Avg Confidence", f"{np.random.uniform(0.7, 0.9):.3f}")
509
+ with col3:
510
+ st.metric("Active Models", metrics['deployed_models'])
511
+
512
+ # Simulate new predictions
513
+ with prediction_placeholder.container():
514
+ new_preds = pd.DataFrame({
515
+ 'Ticker': np.random.choice(['AAPL', 'GOOGL', 'MSFT', 'TSLA'], 5),
516
+ 'Prediction': np.random.uniform(-0.05, 0.05, 5),
517
+ 'Confidence': np.random.uniform(0.6, 0.95, 5),
518
+ 'Time': [datetime.now() - timedelta(seconds=x*10) for x in range(5)]
519
+ })
520
+ st.dataframe(new_preds, use_container_width=True)
521
+
522
+ # Model status
523
+ with model_placeholder.container():
524
+ model_data = get_model_performance()
525
+ if not model_data.empty:
526
+ st.dataframe(model_data[['name', 'accuracy']], use_container_width=True)
527
+
528
+ time.sleep(5)
529
+
530
+
531
+ if __name__ == "__main__":
532
+ main()