mcli-framework 7.2.0__py3-none-any.whl → 7.4.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.
- mcli/__init__.py +160 -0
- mcli/__main__.py +14 -0
- mcli/app/__init__.py +23 -0
- mcli/app/commands_cmd.py +741 -0
- mcli/app/model/__init__.py +0 -0
- mcli/app/video/__init__.py +5 -0
- mcli/chat/__init__.py +34 -0
- mcli/lib/__init__.py +0 -0
- mcli/lib/api/__init__.py +0 -0
- mcli/lib/auth/__init__.py +1 -0
- mcli/lib/config/__init__.py +1 -0
- mcli/lib/erd/__init__.py +25 -0
- mcli/lib/files/__init__.py +0 -0
- mcli/lib/fs/__init__.py +1 -0
- mcli/lib/logger/__init__.py +3 -0
- mcli/lib/performance/__init__.py +17 -0
- mcli/lib/pickles/__init__.py +1 -0
- mcli/lib/shell/__init__.py +0 -0
- mcli/lib/toml/__init__.py +1 -0
- mcli/lib/watcher/__init__.py +0 -0
- mcli/ml/__init__.py +16 -0
- mcli/ml/api/__init__.py +30 -0
- mcli/ml/api/routers/__init__.py +27 -0
- mcli/ml/api/schemas.py +2 -2
- mcli/ml/auth/__init__.py +45 -0
- mcli/ml/auth/models.py +2 -2
- mcli/ml/backtesting/__init__.py +39 -0
- mcli/ml/cli/__init__.py +5 -0
- mcli/ml/cli/main.py +1 -1
- mcli/ml/config/__init__.py +33 -0
- mcli/ml/configs/__init__.py +16 -0
- mcli/ml/dashboard/__init__.py +12 -0
- mcli/ml/dashboard/app_integrated.py +296 -30
- mcli/ml/dashboard/app_training.py +1 -1
- mcli/ml/dashboard/components/__init__.py +7 -0
- mcli/ml/dashboard/pages/__init__.py +6 -0
- mcli/ml/dashboard/pages/cicd.py +1 -1
- mcli/ml/dashboard/pages/debug_dependencies.py +364 -0
- mcli/ml/dashboard/pages/gravity_viz.py +565 -0
- mcli/ml/dashboard/pages/monte_carlo_predictions.py +555 -0
- mcli/ml/dashboard/pages/overview.py +378 -0
- mcli/ml/dashboard/pages/predictions_enhanced.py +20 -6
- mcli/ml/dashboard/pages/scrapers_and_logs.py +22 -6
- mcli/ml/dashboard/pages/test_portfolio.py +423 -0
- mcli/ml/dashboard/pages/trading.py +768 -0
- mcli/ml/dashboard/streamlit_extras_utils.py +297 -0
- mcli/ml/dashboard/utils.py +161 -0
- mcli/ml/dashboard/warning_suppression.py +34 -0
- mcli/ml/data_ingestion/__init__.py +39 -0
- mcli/ml/database/__init__.py +47 -0
- mcli/ml/database/session.py +169 -16
- mcli/ml/experimentation/__init__.py +29 -0
- mcli/ml/features/__init__.py +39 -0
- mcli/ml/mlops/__init__.py +33 -0
- mcli/ml/models/__init__.py +94 -0
- mcli/ml/monitoring/__init__.py +25 -0
- mcli/ml/optimization/__init__.py +27 -0
- mcli/ml/predictions/__init__.py +5 -0
- mcli/ml/predictions/monte_carlo.py +428 -0
- mcli/ml/preprocessing/__init__.py +28 -0
- mcli/ml/scripts/__init__.py +1 -0
- mcli/ml/trading/__init__.py +66 -0
- mcli/ml/trading/alpaca_client.py +417 -0
- mcli/ml/trading/migrations.py +164 -0
- mcli/ml/trading/models.py +418 -0
- mcli/ml/trading/paper_trading.py +326 -0
- mcli/ml/trading/risk_management.py +370 -0
- mcli/ml/trading/trading_service.py +480 -0
- mcli/ml/training/__init__.py +10 -0
- mcli/mygroup/__init__.py +3 -0
- mcli/public/__init__.py +1 -0
- mcli/public/commands/__init__.py +2 -0
- mcli/self/__init__.py +3 -0
- mcli/self/self_cmd.py +514 -15
- mcli/workflow/__init__.py +0 -0
- mcli/workflow/daemon/__init__.py +15 -0
- mcli/workflow/daemon/daemon.py +21 -3
- mcli/workflow/dashboard/__init__.py +5 -0
- mcli/workflow/docker/__init__.py +0 -0
- mcli/workflow/file/__init__.py +0 -0
- mcli/workflow/gcloud/__init__.py +1 -0
- mcli/workflow/git_commit/__init__.py +0 -0
- mcli/workflow/interview/__init__.py +0 -0
- mcli/workflow/politician_trading/__init__.py +4 -0
- mcli/workflow/registry/__init__.py +0 -0
- mcli/workflow/repo/__init__.py +0 -0
- mcli/workflow/scheduler/__init__.py +25 -0
- mcli/workflow/search/__init__.py +0 -0
- mcli/workflow/sync/__init__.py +5 -0
- mcli/workflow/videos/__init__.py +1 -0
- mcli/workflow/wakatime/__init__.py +80 -0
- {mcli_framework-7.2.0.dist-info → mcli_framework-7.4.0.dist-info}/METADATA +4 -1
- {mcli_framework-7.2.0.dist-info → mcli_framework-7.4.0.dist-info}/RECORD +97 -18
- {mcli_framework-7.2.0.dist-info → mcli_framework-7.4.0.dist-info}/WHEEL +0 -0
- {mcli_framework-7.2.0.dist-info → mcli_framework-7.4.0.dist-info}/entry_points.txt +0 -0
- {mcli_framework-7.2.0.dist-info → mcli_framework-7.4.0.dist-info}/licenses/LICENSE +0 -0
- {mcli_framework-7.2.0.dist-info → mcli_framework-7.4.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
"""Monte Carlo Simulation Dashboard for Politician Trading Predictions
|
|
2
|
+
|
|
3
|
+
Inspired by best practices from:
|
|
4
|
+
- mesmith027/streamlit_webapps (Monte Carlo techniques)
|
|
5
|
+
- jumitti/tfinder (UI/UX patterns)
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from datetime import datetime, timedelta
|
|
10
|
+
from typing import Optional
|
|
11
|
+
|
|
12
|
+
import pandas as pd
|
|
13
|
+
import plotly.graph_objects as go
|
|
14
|
+
import streamlit as st
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
# Try to import Monte Carlo simulator
|
|
19
|
+
HAS_MONTE_CARLO = True
|
|
20
|
+
try:
|
|
21
|
+
from mcli.ml.predictions.monte_carlo import (
|
|
22
|
+
MonteCarloTradingSimulator,
|
|
23
|
+
simulate_politician_trade_impact,
|
|
24
|
+
)
|
|
25
|
+
except ImportError:
|
|
26
|
+
HAS_MONTE_CARLO = False
|
|
27
|
+
MonteCarloTradingSimulator = None
|
|
28
|
+
|
|
29
|
+
# Try to import streamlit-extras
|
|
30
|
+
try:
|
|
31
|
+
from mcli.ml.dashboard.streamlit_extras_utils import (
|
|
32
|
+
section_header,
|
|
33
|
+
enhanced_metrics,
|
|
34
|
+
vertical_space,
|
|
35
|
+
)
|
|
36
|
+
HAS_EXTRAS = True
|
|
37
|
+
except ImportError:
|
|
38
|
+
HAS_EXTRAS = False
|
|
39
|
+
section_header = lambda *args, **kwargs: st.header(args[0])
|
|
40
|
+
enhanced_metrics = None
|
|
41
|
+
vertical_space = lambda x: st.write("")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def show_monte_carlo_predictions():
|
|
45
|
+
"""Main Monte Carlo predictions page"""
|
|
46
|
+
|
|
47
|
+
# Page header with custom styling
|
|
48
|
+
st.markdown(
|
|
49
|
+
"""
|
|
50
|
+
<style>
|
|
51
|
+
.main-header {
|
|
52
|
+
font-size: 2.5rem;
|
|
53
|
+
font-weight: bold;
|
|
54
|
+
color: #749BC2;
|
|
55
|
+
text-align: center;
|
|
56
|
+
padding: 1rem 0;
|
|
57
|
+
}
|
|
58
|
+
.sub-header {
|
|
59
|
+
font-size: 1.2rem;
|
|
60
|
+
color: #4A6FA5;
|
|
61
|
+
text-align: center;
|
|
62
|
+
margin-bottom: 2rem;
|
|
63
|
+
}
|
|
64
|
+
</style>
|
|
65
|
+
""",
|
|
66
|
+
unsafe_allow_html=True,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
st.markdown(
|
|
70
|
+
'<div class="main-header">🎲 Monte Carlo Trading Simulator</div>',
|
|
71
|
+
unsafe_allow_html=True,
|
|
72
|
+
)
|
|
73
|
+
st.markdown(
|
|
74
|
+
'<div class="sub-header">Simulate potential outcomes of politician trades using Monte Carlo methods</div>',
|
|
75
|
+
unsafe_allow_html=True,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
if not HAS_MONTE_CARLO:
|
|
79
|
+
st.error("⚠️ Monte Carlo simulator not available. Please ensure all dependencies are installed.")
|
|
80
|
+
st.info(
|
|
81
|
+
"""
|
|
82
|
+
**Required:**
|
|
83
|
+
- numpy
|
|
84
|
+
- pandas
|
|
85
|
+
- plotly
|
|
86
|
+
|
|
87
|
+
Install with: `pip install numpy pandas plotly`
|
|
88
|
+
"""
|
|
89
|
+
)
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
# Sidebar configuration
|
|
93
|
+
with st.sidebar:
|
|
94
|
+
st.markdown("## ⚙️ Simulation Settings")
|
|
95
|
+
|
|
96
|
+
st.markdown("---")
|
|
97
|
+
st.markdown("### 📊 Parameters")
|
|
98
|
+
|
|
99
|
+
num_simulations = st.slider(
|
|
100
|
+
"Number of Simulations",
|
|
101
|
+
min_value=100,
|
|
102
|
+
max_value=10000,
|
|
103
|
+
value=1000,
|
|
104
|
+
step=100,
|
|
105
|
+
help="More simulations = better accuracy but slower performance",
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
days_forward = st.slider(
|
|
109
|
+
"Days to Simulate",
|
|
110
|
+
min_value=30,
|
|
111
|
+
max_value=365,
|
|
112
|
+
value=90,
|
|
113
|
+
step=30,
|
|
114
|
+
help="How far into the future to project",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
confidence_level = st.select_slider(
|
|
118
|
+
"Confidence Level",
|
|
119
|
+
options=[0.90, 0.95, 0.99],
|
|
120
|
+
value=0.95,
|
|
121
|
+
format_func=lambda x: f"{x*100:.0f}%",
|
|
122
|
+
help="Confidence interval for predictions",
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
st.markdown("---")
|
|
126
|
+
st.markdown("### 📈 Display Options")
|
|
127
|
+
|
|
128
|
+
num_paths_display = st.slider(
|
|
129
|
+
"Paths to Display",
|
|
130
|
+
min_value=10,
|
|
131
|
+
max_value=500,
|
|
132
|
+
value=100,
|
|
133
|
+
step=10,
|
|
134
|
+
help="Number of individual simulation paths to show on chart",
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
show_percentiles = st.checkbox(
|
|
138
|
+
"Show Confidence Bands",
|
|
139
|
+
value=True,
|
|
140
|
+
help="Display 50% and 90% confidence bands",
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
st.markdown("---")
|
|
144
|
+
st.markdown("### ℹ️ About")
|
|
145
|
+
st.info(
|
|
146
|
+
"""
|
|
147
|
+
**Monte Carlo Simulation** uses random sampling to model
|
|
148
|
+
possible future price movements based on historical volatility
|
|
149
|
+
and returns.
|
|
150
|
+
|
|
151
|
+
**Key Concepts:**
|
|
152
|
+
- Uses Geometric Brownian Motion (GBM)
|
|
153
|
+
- Assumes log-normal price distribution
|
|
154
|
+
- Estimates drift (μ) and volatility (σ) from historical data
|
|
155
|
+
"""
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
# Main content area with tabs
|
|
159
|
+
tab1, tab2, tab3, tab4 = st.tabs([
|
|
160
|
+
"🎯 Quick Simulation",
|
|
161
|
+
"📊 Advanced Analysis",
|
|
162
|
+
"📚 Learn More",
|
|
163
|
+
"⚙️ Custom Parameters"
|
|
164
|
+
])
|
|
165
|
+
|
|
166
|
+
with tab1:
|
|
167
|
+
show_quick_simulation(
|
|
168
|
+
num_simulations, days_forward, num_paths_display,
|
|
169
|
+
show_percentiles, confidence_level
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
with tab2:
|
|
173
|
+
show_advanced_analysis(num_simulations, days_forward, confidence_level)
|
|
174
|
+
|
|
175
|
+
with tab3:
|
|
176
|
+
show_educational_content()
|
|
177
|
+
|
|
178
|
+
with tab4:
|
|
179
|
+
show_custom_parameters(num_simulations, days_forward)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def show_quick_simulation(
|
|
183
|
+
num_simulations: int,
|
|
184
|
+
days_forward: int,
|
|
185
|
+
num_paths_display: int,
|
|
186
|
+
show_percentiles: bool,
|
|
187
|
+
confidence_level: float,
|
|
188
|
+
):
|
|
189
|
+
"""Quick simulation interface"""
|
|
190
|
+
|
|
191
|
+
section_header(
|
|
192
|
+
"🚀 Quick Start Simulation",
|
|
193
|
+
"Enter stock details and get instant Monte Carlo predictions",
|
|
194
|
+
divider="blue"
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
# Input form
|
|
198
|
+
with st.form("quick_sim_form"):
|
|
199
|
+
col1, col2 = st.columns(2)
|
|
200
|
+
|
|
201
|
+
with col1:
|
|
202
|
+
stock_symbol = st.text_input(
|
|
203
|
+
"Stock Symbol",
|
|
204
|
+
value="AAPL",
|
|
205
|
+
placeholder="e.g., AAPL, TSLA, MSFT",
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
current_price = st.number_input(
|
|
209
|
+
"Current Price ($)",
|
|
210
|
+
min_value=0.01,
|
|
211
|
+
value=150.00,
|
|
212
|
+
step=0.01,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
with col2:
|
|
216
|
+
politician_name = st.text_input(
|
|
217
|
+
"Politician Name",
|
|
218
|
+
value="Nancy Pelosi",
|
|
219
|
+
placeholder="e.g., Nancy Pelosi",
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
transaction_amount = st.number_input(
|
|
223
|
+
"Transaction Amount ($)",
|
|
224
|
+
min_value=1000,
|
|
225
|
+
value=100000,
|
|
226
|
+
step=1000,
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
# Historical parameters
|
|
230
|
+
col3, col4 = st.columns(2)
|
|
231
|
+
|
|
232
|
+
with col3:
|
|
233
|
+
annual_return = st.number_input(
|
|
234
|
+
"Expected Annual Return (%)",
|
|
235
|
+
min_value=-50.0,
|
|
236
|
+
max_value=100.0,
|
|
237
|
+
value=12.0,
|
|
238
|
+
step=0.5,
|
|
239
|
+
help="Historical average annual return",
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
with col4:
|
|
243
|
+
annual_volatility = st.number_input(
|
|
244
|
+
"Annual Volatility (%)",
|
|
245
|
+
min_value=1.0,
|
|
246
|
+
max_value=100.0,
|
|
247
|
+
value=25.0,
|
|
248
|
+
step=1.0,
|
|
249
|
+
help="Historical standard deviation of returns",
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
submitted = st.form_submit_button(
|
|
253
|
+
"🎲 Run Simulation",
|
|
254
|
+
type="primary",
|
|
255
|
+
use_container_width=True,
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
if submitted:
|
|
259
|
+
run_simulation(
|
|
260
|
+
stock_symbol=stock_symbol,
|
|
261
|
+
politician_name=politician_name,
|
|
262
|
+
current_price=current_price,
|
|
263
|
+
transaction_amount=transaction_amount,
|
|
264
|
+
drift=annual_return / 100,
|
|
265
|
+
volatility=annual_volatility / 100,
|
|
266
|
+
num_simulations=num_simulations,
|
|
267
|
+
days_forward=days_forward,
|
|
268
|
+
num_paths_display=num_paths_display,
|
|
269
|
+
show_percentiles=show_percentiles,
|
|
270
|
+
confidence_level=confidence_level,
|
|
271
|
+
)
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def run_simulation(
|
|
275
|
+
stock_symbol: str,
|
|
276
|
+
politician_name: str,
|
|
277
|
+
current_price: float,
|
|
278
|
+
transaction_amount: float,
|
|
279
|
+
drift: float,
|
|
280
|
+
volatility: float,
|
|
281
|
+
num_simulations: int,
|
|
282
|
+
days_forward: int,
|
|
283
|
+
num_paths_display: int,
|
|
284
|
+
show_percentiles: bool,
|
|
285
|
+
confidence_level: float,
|
|
286
|
+
):
|
|
287
|
+
"""Execute Monte Carlo simulation and display results"""
|
|
288
|
+
|
|
289
|
+
with st.spinner(f"Running {num_simulations:,} simulations..."):
|
|
290
|
+
# Initialize simulator
|
|
291
|
+
simulator = MonteCarloTradingSimulator(
|
|
292
|
+
initial_price=current_price,
|
|
293
|
+
days_to_simulate=days_forward,
|
|
294
|
+
num_simulations=num_simulations,
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
# Run simulation
|
|
298
|
+
simulator.simulate_price_paths(drift, volatility)
|
|
299
|
+
|
|
300
|
+
# Calculate statistics
|
|
301
|
+
stats = simulator.calculate_statistics()
|
|
302
|
+
|
|
303
|
+
vertical_space(2)
|
|
304
|
+
|
|
305
|
+
# Display results header
|
|
306
|
+
section_header(
|
|
307
|
+
f"📈 Simulation Results: {stock_symbol}",
|
|
308
|
+
f"{politician_name} • {num_simulations:,} simulations • {days_forward} days",
|
|
309
|
+
divider="green"
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
# Key metrics
|
|
313
|
+
if HAS_EXTRAS and enhanced_metrics:
|
|
314
|
+
enhanced_metrics([
|
|
315
|
+
{
|
|
316
|
+
"label": "Expected Price",
|
|
317
|
+
"value": f"${stats['expected_final_price']:.2f}",
|
|
318
|
+
"delta": f"{stats['expected_return']:.1f}%"
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"label": "Probability of Profit",
|
|
322
|
+
"value": f"{stats['probability_profit']:.1f}%",
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"label": "Value at Risk (95%)",
|
|
326
|
+
"value": f"{stats['value_at_risk_95']:.1f}%",
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
"label": "Best Case (95th %ile)",
|
|
330
|
+
"value": f"${stats['percentile_95']:.2f}",
|
|
331
|
+
"delta": f"+{((stats['percentile_95']/current_price - 1) * 100):.1f}%"
|
|
332
|
+
},
|
|
333
|
+
])
|
|
334
|
+
else:
|
|
335
|
+
col1, col2, col3, col4 = st.columns(4)
|
|
336
|
+
with col1:
|
|
337
|
+
st.metric("Expected Price", f"${stats['expected_final_price']:.2f}",
|
|
338
|
+
f"{stats['expected_return']:.1f}%")
|
|
339
|
+
with col2:
|
|
340
|
+
st.metric("Profit Probability", f"{stats['probability_profit']:.1f}%")
|
|
341
|
+
with col3:
|
|
342
|
+
st.metric("VaR (95%)", f"{stats['value_at_risk_95']:.1f}%")
|
|
343
|
+
with col4:
|
|
344
|
+
st.metric("Best Case", f"${stats['percentile_95']:.2f}")
|
|
345
|
+
|
|
346
|
+
vertical_space(2)
|
|
347
|
+
|
|
348
|
+
# Price path visualization
|
|
349
|
+
st.subheader("📊 Simulated Price Paths")
|
|
350
|
+
|
|
351
|
+
path_fig = simulator.create_path_visualization(
|
|
352
|
+
num_paths_to_plot=num_paths_display,
|
|
353
|
+
show_percentiles=show_percentiles
|
|
354
|
+
)
|
|
355
|
+
st.plotly_chart(path_fig, config={"displayModeBar": True}, use_container_width=True)
|
|
356
|
+
|
|
357
|
+
vertical_space(1)
|
|
358
|
+
|
|
359
|
+
# Distribution visualization
|
|
360
|
+
st.subheader("📉 Price & Return Distributions")
|
|
361
|
+
dist_fig = simulator.create_distribution_visualization()
|
|
362
|
+
st.plotly_chart(dist_fig, config={"displayModeBar": True}, use_container_width=True)
|
|
363
|
+
|
|
364
|
+
vertical_space(2)
|
|
365
|
+
|
|
366
|
+
# Detailed statistics
|
|
367
|
+
with st.expander("📊 Detailed Statistics", expanded=False):
|
|
368
|
+
col1, col2 = st.columns(2)
|
|
369
|
+
|
|
370
|
+
with col1:
|
|
371
|
+
st.markdown("**Price Statistics**")
|
|
372
|
+
st.markdown(f"- Current Price: ${current_price:.2f}")
|
|
373
|
+
st.markdown(f"- Expected Final: ${stats['expected_final_price']:.2f}")
|
|
374
|
+
st.markdown(f"- Median Final: ${stats['median_final_price']:.2f}")
|
|
375
|
+
st.markdown(f"- Standard Dev: ${stats['std_final_price']:.2f}")
|
|
376
|
+
st.markdown(f"- Min Price: ${stats['min_final_price']:.2f}")
|
|
377
|
+
st.markdown(f"- Max Price: ${stats['max_final_price']:.2f}")
|
|
378
|
+
|
|
379
|
+
with col2:
|
|
380
|
+
st.markdown("**Return Statistics**")
|
|
381
|
+
st.markdown(f"- Expected Return: {stats['expected_return']:.2f}%")
|
|
382
|
+
st.markdown(f"- Median Return: {stats['median_return']:.2f}%")
|
|
383
|
+
st.markdown(f"- Std Dev Return: {stats['std_return']:.2f}%")
|
|
384
|
+
st.markdown(f"- 5th Percentile: {stats['value_at_risk_95']:.2f}%")
|
|
385
|
+
st.markdown(f"- 95th Percentile: {((stats['percentile_95']/current_price - 1)*100):.2f}%")
|
|
386
|
+
|
|
387
|
+
# Confidence intervals
|
|
388
|
+
confidence_intervals = simulator.calculate_confidence_intervals([confidence_level])
|
|
389
|
+
lower, upper = confidence_intervals[confidence_level]
|
|
390
|
+
|
|
391
|
+
st.info(
|
|
392
|
+
f"**{confidence_level*100:.0f}% Confidence Interval:** "
|
|
393
|
+
f"${lower:.2f} - ${upper:.2f} "
|
|
394
|
+
f"({((lower/current_price - 1)*100):.1f}% to {((upper/current_price - 1)*100):.1f}%)"
|
|
395
|
+
)
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def show_advanced_analysis(num_simulations: int, days_forward: int, confidence_level: float):
|
|
399
|
+
"""Advanced analysis with historical data integration"""
|
|
400
|
+
|
|
401
|
+
section_header(
|
|
402
|
+
"🔬 Advanced Analysis",
|
|
403
|
+
"Use historical price data for more accurate simulations",
|
|
404
|
+
divider="violet"
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
st.info(
|
|
408
|
+
"""
|
|
409
|
+
**Coming Soon:**
|
|
410
|
+
- Integration with real-time market data APIs
|
|
411
|
+
- Historical politician trade correlation analysis
|
|
412
|
+
- Portfolio optimization using Monte Carlo
|
|
413
|
+
- Multi-stock scenario analysis
|
|
414
|
+
"""
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
def show_educational_content():
|
|
419
|
+
"""Educational content about Monte Carlo methods"""
|
|
420
|
+
|
|
421
|
+
section_header(
|
|
422
|
+
"📚 Understanding Monte Carlo Simulation",
|
|
423
|
+
"Learn how probabilistic modeling predicts trading outcomes",
|
|
424
|
+
divider="orange"
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
st.markdown("""
|
|
428
|
+
## What is Monte Carlo Simulation?
|
|
429
|
+
|
|
430
|
+
Monte Carlo simulation is a computational technique that uses random sampling
|
|
431
|
+
to estimate possible outcomes of an uncertain event.
|
|
432
|
+
|
|
433
|
+
### How It Works for Stock Predictions
|
|
434
|
+
|
|
435
|
+
1. **Estimate Parameters**
|
|
436
|
+
- Calculate historical drift (μ): average return
|
|
437
|
+
- Calculate volatility (σ): standard deviation of returns
|
|
438
|
+
|
|
439
|
+
2. **Generate Random Paths**
|
|
440
|
+
- Use Geometric Brownian Motion (GBM)
|
|
441
|
+
- Formula: S(t+dt) = S(t) × exp((μ - σ²/2)dt + σ√dt × Z)
|
|
442
|
+
- Where Z is a random normal variable
|
|
443
|
+
|
|
444
|
+
3. **Analyze Results**
|
|
445
|
+
- Run thousands of simulations
|
|
446
|
+
- Calculate statistics on final prices
|
|
447
|
+
- Estimate probability distributions
|
|
448
|
+
|
|
449
|
+
### Key Advantages
|
|
450
|
+
|
|
451
|
+
- **Probabilistic**: Shows range of possible outcomes, not just one prediction
|
|
452
|
+
- **Visual**: Easy to understand probability distributions
|
|
453
|
+
- **Flexible**: Can incorporate different assumptions and scenarios
|
|
454
|
+
- **Risk Assessment**: Calculates Value at Risk (VaR) and confidence intervals
|
|
455
|
+
|
|
456
|
+
### Limitations
|
|
457
|
+
|
|
458
|
+
- Assumes log-normal distribution (may not capture extreme events)
|
|
459
|
+
- Based on historical data (past performance ≠ future results)
|
|
460
|
+
- Doesn't account for market structure changes
|
|
461
|
+
- Ignores transaction costs and liquidity constraints
|
|
462
|
+
|
|
463
|
+
### For Politician Trading Analysis
|
|
464
|
+
|
|
465
|
+
Monte Carlo is particularly useful for:
|
|
466
|
+
- **Following trades**: Estimate expected returns from mimicking politician trades
|
|
467
|
+
- **Risk management**: Understand downside risk before entering positions
|
|
468
|
+
- **Position sizing**: Determine appropriate investment amounts
|
|
469
|
+
- **Timing analysis**: Compare different holding periods
|
|
470
|
+
""")
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
def show_custom_parameters(num_simulations: int, days_forward: int):
|
|
474
|
+
"""Custom parameter configuration"""
|
|
475
|
+
|
|
476
|
+
section_header(
|
|
477
|
+
"⚙️ Custom Parameters",
|
|
478
|
+
"Advanced configuration for power users",
|
|
479
|
+
divider="gray"
|
|
480
|
+
)
|
|
481
|
+
|
|
482
|
+
st.warning(
|
|
483
|
+
"⚠️ **Advanced Users Only** - Modifying these parameters requires "
|
|
484
|
+
"understanding of financial mathematics and Monte Carlo methods."
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
with st.form("custom_params_form"):
|
|
488
|
+
st.markdown("### Geometric Brownian Motion Parameters")
|
|
489
|
+
|
|
490
|
+
col1, col2 = st.columns(2)
|
|
491
|
+
|
|
492
|
+
with col1:
|
|
493
|
+
custom_drift = st.number_input(
|
|
494
|
+
"Drift (μ) - Annual",
|
|
495
|
+
min_value=-1.0,
|
|
496
|
+
max_value=1.0,
|
|
497
|
+
value=0.10,
|
|
498
|
+
step=0.01,
|
|
499
|
+
format="%.4f",
|
|
500
|
+
help="Expected return rate (e.g., 0.10 = 10% per year)",
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
custom_volatility = st.number_input(
|
|
504
|
+
"Volatility (σ) - Annual",
|
|
505
|
+
min_value=0.01,
|
|
506
|
+
max_value=2.0,
|
|
507
|
+
value=0.25,
|
|
508
|
+
step=0.01,
|
|
509
|
+
format="%.4f",
|
|
510
|
+
help="Standard deviation of returns (e.g., 0.25 = 25% volatility)",
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
with col2:
|
|
514
|
+
random_seed = st.number_input(
|
|
515
|
+
"Random Seed",
|
|
516
|
+
min_value=0,
|
|
517
|
+
max_value=999999,
|
|
518
|
+
value=42,
|
|
519
|
+
help="For reproducible results",
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
use_seed = st.checkbox("Use Random Seed", value=False)
|
|
523
|
+
|
|
524
|
+
st.markdown("### Time Parameters")
|
|
525
|
+
|
|
526
|
+
col3, col4 = st.columns(2)
|
|
527
|
+
|
|
528
|
+
with col3:
|
|
529
|
+
trading_days_per_year = st.number_input(
|
|
530
|
+
"Trading Days/Year",
|
|
531
|
+
min_value=200,
|
|
532
|
+
max_value=365,
|
|
533
|
+
value=252,
|
|
534
|
+
help="Standard is 252 for US markets",
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
with col4:
|
|
538
|
+
time_step = st.selectbox(
|
|
539
|
+
"Time Step",
|
|
540
|
+
["Daily", "Weekly", "Monthly"],
|
|
541
|
+
help="Granularity of simulation",
|
|
542
|
+
)
|
|
543
|
+
|
|
544
|
+
submitted = st.form_submit_button("Run Custom Simulation", type="primary")
|
|
545
|
+
|
|
546
|
+
if submitted:
|
|
547
|
+
st.success(
|
|
548
|
+
f"Custom simulation configured with μ={custom_drift:.4f}, "
|
|
549
|
+
f"σ={custom_volatility:.4f}"
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
# Module-level execution
|
|
554
|
+
if __name__ == "__main__":
|
|
555
|
+
show_monte_carlo_predictions()
|