mcli-framework 7.1.1__py3-none-any.whl → 7.1.3__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/app/completion_cmd.py +59 -49
- mcli/app/completion_helpers.py +60 -138
- mcli/app/logs_cmd.py +6 -2
- mcli/app/main.py +17 -14
- mcli/app/model_cmd.py +19 -4
- mcli/chat/chat.py +3 -2
- mcli/lib/search/cached_vectorizer.py +1 -0
- mcli/lib/services/data_pipeline.py +12 -5
- mcli/lib/services/lsh_client.py +68 -57
- mcli/ml/api/app.py +28 -36
- mcli/ml/api/middleware.py +8 -16
- mcli/ml/api/routers/admin_router.py +3 -1
- mcli/ml/api/routers/auth_router.py +32 -56
- mcli/ml/api/routers/backtest_router.py +3 -1
- mcli/ml/api/routers/data_router.py +3 -1
- mcli/ml/api/routers/model_router.py +35 -74
- mcli/ml/api/routers/monitoring_router.py +3 -1
- mcli/ml/api/routers/portfolio_router.py +3 -1
- mcli/ml/api/routers/prediction_router.py +60 -65
- mcli/ml/api/routers/trade_router.py +6 -2
- mcli/ml/api/routers/websocket_router.py +12 -9
- mcli/ml/api/schemas.py +10 -2
- mcli/ml/auth/auth_manager.py +49 -114
- mcli/ml/auth/models.py +30 -15
- mcli/ml/auth/permissions.py +12 -19
- mcli/ml/backtesting/backtest_engine.py +134 -108
- mcli/ml/backtesting/performance_metrics.py +142 -108
- mcli/ml/cache.py +12 -18
- mcli/ml/cli/main.py +37 -23
- mcli/ml/config/settings.py +29 -12
- mcli/ml/dashboard/app.py +122 -130
- mcli/ml/dashboard/app_integrated.py +955 -154
- mcli/ml/dashboard/app_supabase.py +176 -108
- mcli/ml/dashboard/app_training.py +212 -206
- mcli/ml/dashboard/cli.py +14 -5
- mcli/ml/data_ingestion/api_connectors.py +51 -81
- mcli/ml/data_ingestion/data_pipeline.py +127 -125
- mcli/ml/data_ingestion/stream_processor.py +72 -80
- mcli/ml/database/migrations/env.py +3 -2
- mcli/ml/database/models.py +112 -79
- mcli/ml/database/session.py +6 -5
- mcli/ml/experimentation/ab_testing.py +149 -99
- mcli/ml/features/ensemble_features.py +9 -8
- mcli/ml/features/political_features.py +6 -5
- mcli/ml/features/recommendation_engine.py +15 -14
- mcli/ml/features/stock_features.py +7 -6
- mcli/ml/features/test_feature_engineering.py +8 -7
- mcli/ml/logging.py +10 -15
- mcli/ml/mlops/data_versioning.py +57 -64
- mcli/ml/mlops/experiment_tracker.py +49 -41
- mcli/ml/mlops/model_serving.py +59 -62
- mcli/ml/mlops/pipeline_orchestrator.py +203 -149
- mcli/ml/models/base_models.py +8 -7
- mcli/ml/models/ensemble_models.py +6 -5
- mcli/ml/models/recommendation_models.py +7 -6
- mcli/ml/models/test_models.py +18 -14
- mcli/ml/monitoring/drift_detection.py +95 -74
- mcli/ml/monitoring/metrics.py +10 -22
- mcli/ml/optimization/portfolio_optimizer.py +172 -132
- mcli/ml/predictions/prediction_engine.py +62 -50
- mcli/ml/preprocessing/data_cleaners.py +6 -5
- mcli/ml/preprocessing/feature_extractors.py +7 -6
- mcli/ml/preprocessing/ml_pipeline.py +3 -2
- mcli/ml/preprocessing/politician_trading_preprocessor.py +11 -10
- mcli/ml/preprocessing/test_preprocessing.py +4 -4
- mcli/ml/scripts/populate_sample_data.py +36 -16
- mcli/ml/tasks.py +82 -83
- mcli/ml/tests/test_integration.py +86 -76
- mcli/ml/tests/test_training_dashboard.py +169 -142
- mcli/mygroup/test_cmd.py +2 -1
- mcli/self/self_cmd.py +31 -16
- mcli/self/test_cmd.py +2 -1
- mcli/workflow/dashboard/dashboard_cmd.py +13 -6
- mcli/workflow/lsh_integration.py +46 -58
- mcli/workflow/politician_trading/commands.py +576 -427
- mcli/workflow/politician_trading/config.py +7 -7
- mcli/workflow/politician_trading/connectivity.py +35 -33
- mcli/workflow/politician_trading/data_sources.py +72 -71
- mcli/workflow/politician_trading/database.py +18 -16
- mcli/workflow/politician_trading/demo.py +4 -3
- mcli/workflow/politician_trading/models.py +5 -5
- mcli/workflow/politician_trading/monitoring.py +13 -13
- mcli/workflow/politician_trading/scrapers.py +332 -224
- mcli/workflow/politician_trading/scrapers_california.py +116 -94
- mcli/workflow/politician_trading/scrapers_eu.py +70 -71
- mcli/workflow/politician_trading/scrapers_uk.py +118 -90
- mcli/workflow/politician_trading/scrapers_us_states.py +125 -92
- mcli/workflow/politician_trading/workflow.py +98 -71
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.3.dist-info}/METADATA +1 -1
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.3.dist-info}/RECORD +94 -94
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.3.dist-info}/WHEEL +0 -0
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.3.dist-info}/entry_points.txt +0 -0
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.3.dist-info}/licenses/LICENSE +0 -0
- {mcli_framework-7.1.1.dist-info → mcli_framework-7.1.3.dist-info}/top_level.txt +0 -0
|
@@ -3,11 +3,12 @@ Prediction Engine for Politician Trading Analysis
|
|
|
3
3
|
Generates stock predictions based on politician trading disclosures
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
import numpy as np
|
|
6
|
+
from collections import defaultdict
|
|
8
7
|
from datetime import datetime, timedelta
|
|
9
8
|
from typing import Dict, List, Optional, Tuple
|
|
10
|
-
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
import pandas as pd
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
class PoliticianTradingPredictor:
|
|
@@ -33,16 +34,16 @@ class PoliticianTradingPredictor:
|
|
|
33
34
|
return pd.DataFrame()
|
|
34
35
|
|
|
35
36
|
# Ensure required columns exist
|
|
36
|
-
required_cols = [
|
|
37
|
-
if not all(col in disclosures.columns for col in [
|
|
37
|
+
required_cols = ["ticker_symbol", "transaction_type", "amount"]
|
|
38
|
+
if not all(col in disclosures.columns for col in ["ticker_symbol"]):
|
|
38
39
|
return pd.DataFrame()
|
|
39
40
|
|
|
40
41
|
# Filter recent trades
|
|
41
|
-
if
|
|
42
|
+
if "disclosure_date" in disclosures.columns:
|
|
42
43
|
try:
|
|
43
|
-
disclosures[
|
|
44
|
+
disclosures["disclosure_date"] = pd.to_datetime(disclosures["disclosure_date"])
|
|
44
45
|
cutoff_date = datetime.now() - timedelta(days=self.recent_days)
|
|
45
|
-
recent_disclosures = disclosures[disclosures[
|
|
46
|
+
recent_disclosures = disclosures[disclosures["disclosure_date"] >= cutoff_date]
|
|
46
47
|
except:
|
|
47
48
|
recent_disclosures = disclosures
|
|
48
49
|
else:
|
|
@@ -54,20 +55,32 @@ class PoliticianTradingPredictor:
|
|
|
54
55
|
# Analyze trading patterns by ticker
|
|
55
56
|
predictions = []
|
|
56
57
|
|
|
57
|
-
for ticker in recent_disclosures[
|
|
58
|
-
if pd.isna(ticker) or ticker ==
|
|
58
|
+
for ticker in recent_disclosures["ticker_symbol"].unique():
|
|
59
|
+
if pd.isna(ticker) or ticker == "":
|
|
59
60
|
continue
|
|
60
61
|
|
|
61
|
-
ticker_trades = recent_disclosures[recent_disclosures[
|
|
62
|
+
ticker_trades = recent_disclosures[recent_disclosures["ticker_symbol"] == ticker]
|
|
62
63
|
|
|
63
64
|
# Calculate trading metrics
|
|
64
65
|
buy_count = 0
|
|
65
66
|
sell_count = 0
|
|
66
67
|
total_amount = 0
|
|
67
68
|
|
|
68
|
-
if
|
|
69
|
-
buy_count = len(
|
|
70
|
-
|
|
69
|
+
if "transaction_type" in ticker_trades.columns:
|
|
70
|
+
buy_count = len(
|
|
71
|
+
ticker_trades[
|
|
72
|
+
ticker_trades["transaction_type"].str.contains(
|
|
73
|
+
"purchase|buy", case=False, na=False
|
|
74
|
+
)
|
|
75
|
+
]
|
|
76
|
+
)
|
|
77
|
+
sell_count = len(
|
|
78
|
+
ticker_trades[
|
|
79
|
+
ticker_trades["transaction_type"].str.contains(
|
|
80
|
+
"sale|sell", case=False, na=False
|
|
81
|
+
)
|
|
82
|
+
]
|
|
83
|
+
)
|
|
71
84
|
|
|
72
85
|
total_trades = buy_count + sell_count
|
|
73
86
|
|
|
@@ -75,10 +88,10 @@ class PoliticianTradingPredictor:
|
|
|
75
88
|
continue
|
|
76
89
|
|
|
77
90
|
# Calculate amount if available
|
|
78
|
-
if
|
|
91
|
+
if "amount" in ticker_trades.columns:
|
|
79
92
|
try:
|
|
80
93
|
# Try to extract numeric values from amount
|
|
81
|
-
amounts = ticker_trades[
|
|
94
|
+
amounts = ticker_trades["amount"].astype(str)
|
|
82
95
|
# This is a simplified extraction - adjust based on actual data format
|
|
83
96
|
total_amount = len(ticker_trades) * 50000 # Rough estimate
|
|
84
97
|
except:
|
|
@@ -92,11 +105,11 @@ class PoliticianTradingPredictor:
|
|
|
92
105
|
sell_count=sell_count,
|
|
93
106
|
total_trades=total_trades,
|
|
94
107
|
total_amount=total_amount,
|
|
95
|
-
ticker_trades=ticker_trades
|
|
108
|
+
ticker_trades=ticker_trades,
|
|
96
109
|
)
|
|
97
110
|
|
|
98
111
|
if prediction:
|
|
99
|
-
prediction[
|
|
112
|
+
prediction["ticker"] = ticker
|
|
100
113
|
predictions.append(prediction)
|
|
101
114
|
|
|
102
115
|
if not predictions:
|
|
@@ -104,7 +117,7 @@ class PoliticianTradingPredictor:
|
|
|
104
117
|
|
|
105
118
|
# Convert to DataFrame and sort by confidence
|
|
106
119
|
pred_df = pd.DataFrame(predictions)
|
|
107
|
-
pred_df = pred_df.sort_values(
|
|
120
|
+
pred_df = pred_df.sort_values("confidence", ascending=False)
|
|
108
121
|
|
|
109
122
|
return pred_df.head(50) # Return top 50 predictions
|
|
110
123
|
|
|
@@ -114,7 +127,7 @@ class PoliticianTradingPredictor:
|
|
|
114
127
|
sell_count: int,
|
|
115
128
|
total_trades: int,
|
|
116
129
|
total_amount: float,
|
|
117
|
-
ticker_trades: pd.DataFrame
|
|
130
|
+
ticker_trades: pd.DataFrame,
|
|
118
131
|
) -> Optional[Dict]:
|
|
119
132
|
"""
|
|
120
133
|
Calculate prediction metrics for a single ticker
|
|
@@ -128,23 +141,23 @@ class PoliticianTradingPredictor:
|
|
|
128
141
|
|
|
129
142
|
# Determine recommendation based on trading pattern
|
|
130
143
|
if buy_ratio > 0.7:
|
|
131
|
-
recommendation =
|
|
144
|
+
recommendation = "BUY"
|
|
132
145
|
predicted_return = np.random.uniform(0.02, 0.15) # Positive return for buy signal
|
|
133
146
|
risk_score = 0.3 + (np.random.random() * 0.3) # Lower risk for strong buy
|
|
134
147
|
elif sell_ratio > 0.7:
|
|
135
|
-
recommendation =
|
|
148
|
+
recommendation = "SELL"
|
|
136
149
|
predicted_return = np.random.uniform(-0.10, -0.02) # Negative return for sell signal
|
|
137
150
|
risk_score = 0.6 + (np.random.random() * 0.3) # Higher risk for sell
|
|
138
151
|
elif buy_ratio > sell_ratio:
|
|
139
|
-
recommendation =
|
|
152
|
+
recommendation = "BUY"
|
|
140
153
|
predicted_return = np.random.uniform(0.01, 0.08)
|
|
141
154
|
risk_score = 0.4 + (np.random.random() * 0.3)
|
|
142
155
|
elif sell_ratio > buy_ratio:
|
|
143
|
-
recommendation =
|
|
156
|
+
recommendation = "SELL"
|
|
144
157
|
predicted_return = np.random.uniform(-0.05, -0.01)
|
|
145
158
|
risk_score = 0.5 + (np.random.random() * 0.3)
|
|
146
159
|
else:
|
|
147
|
-
recommendation =
|
|
160
|
+
recommendation = "HOLD"
|
|
148
161
|
predicted_return = np.random.uniform(-0.02, 0.02)
|
|
149
162
|
risk_score = 0.4 + (np.random.random() * 0.4)
|
|
150
163
|
|
|
@@ -158,33 +171,29 @@ class PoliticianTradingPredictor:
|
|
|
158
171
|
|
|
159
172
|
# Recency score
|
|
160
173
|
recency_score = 0.5
|
|
161
|
-
if
|
|
174
|
+
if "disclosure_date" in ticker_trades.columns:
|
|
162
175
|
try:
|
|
163
|
-
most_recent = ticker_trades[
|
|
176
|
+
most_recent = ticker_trades["disclosure_date"].max()
|
|
164
177
|
days_ago = (datetime.now() - most_recent).days
|
|
165
178
|
recency_score = max(0.3, 1.0 - (days_ago / self.recent_days))
|
|
166
179
|
except:
|
|
167
180
|
pass
|
|
168
181
|
|
|
169
182
|
# Combined confidence (weighted average)
|
|
170
|
-
confidence =
|
|
171
|
-
trade_count_score * 0.3 +
|
|
172
|
-
consistency_score * 0.4 +
|
|
173
|
-
recency_score * 0.3
|
|
174
|
-
)
|
|
183
|
+
confidence = trade_count_score * 0.3 + consistency_score * 0.4 + recency_score * 0.3
|
|
175
184
|
|
|
176
185
|
# Add some variance
|
|
177
186
|
confidence = min(0.95, max(0.50, confidence + np.random.uniform(-0.05, 0.05)))
|
|
178
187
|
|
|
179
188
|
return {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
189
|
+
"predicted_return": predicted_return,
|
|
190
|
+
"confidence": confidence,
|
|
191
|
+
"risk_score": risk_score,
|
|
192
|
+
"recommendation": recommendation,
|
|
193
|
+
"trade_count": total_trades,
|
|
194
|
+
"buy_count": buy_count,
|
|
195
|
+
"sell_count": sell_count,
|
|
196
|
+
"signal_strength": consistency_score,
|
|
188
197
|
}
|
|
189
198
|
|
|
190
199
|
def get_top_picks(self, predictions: pd.DataFrame, n: int = 10) -> pd.DataFrame:
|
|
@@ -194,30 +203,33 @@ class PoliticianTradingPredictor:
|
|
|
194
203
|
|
|
195
204
|
# Score = confidence * abs(predicted_return)
|
|
196
205
|
predictions = predictions.copy()
|
|
197
|
-
predictions[
|
|
206
|
+
predictions["score"] = predictions["confidence"] * predictions["predicted_return"].abs()
|
|
198
207
|
|
|
199
|
-
return predictions.nlargest(n,
|
|
208
|
+
return predictions.nlargest(n, "score")
|
|
200
209
|
|
|
201
|
-
def get_buy_recommendations(
|
|
210
|
+
def get_buy_recommendations(
|
|
211
|
+
self, predictions: pd.DataFrame, min_confidence: float = 0.6
|
|
212
|
+
) -> pd.DataFrame:
|
|
202
213
|
"""Get buy recommendations above confidence threshold"""
|
|
203
214
|
if predictions.empty:
|
|
204
215
|
return pd.DataFrame()
|
|
205
216
|
|
|
206
217
|
buys = predictions[
|
|
207
|
-
(predictions[
|
|
208
|
-
(predictions['confidence'] >= min_confidence)
|
|
218
|
+
(predictions["recommendation"] == "BUY") & (predictions["confidence"] >= min_confidence)
|
|
209
219
|
]
|
|
210
220
|
|
|
211
|
-
return buys.sort_values(
|
|
221
|
+
return buys.sort_values("predicted_return", ascending=False)
|
|
212
222
|
|
|
213
|
-
def get_sell_recommendations(
|
|
223
|
+
def get_sell_recommendations(
|
|
224
|
+
self, predictions: pd.DataFrame, min_confidence: float = 0.6
|
|
225
|
+
) -> pd.DataFrame:
|
|
214
226
|
"""Get sell recommendations above confidence threshold"""
|
|
215
227
|
if predictions.empty:
|
|
216
228
|
return pd.DataFrame()
|
|
217
229
|
|
|
218
230
|
sells = predictions[
|
|
219
|
-
(predictions[
|
|
220
|
-
(predictions[
|
|
231
|
+
(predictions["recommendation"] == "SELL")
|
|
232
|
+
& (predictions["confidence"] >= min_confidence)
|
|
221
233
|
]
|
|
222
234
|
|
|
223
|
-
return sells.sort_values(
|
|
235
|
+
return sells.sort_values("predicted_return", ascending=True)
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"""Data cleaning utilities for ML preprocessing"""
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import logging
|
|
4
|
+
import re
|
|
5
|
+
from dataclasses import dataclass
|
|
5
6
|
from datetime import datetime, timedelta
|
|
6
7
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
7
|
-
|
|
8
|
-
import
|
|
9
|
-
import
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
import pandas as pd
|
|
10
11
|
|
|
11
12
|
logger = logging.getLogger(__name__)
|
|
12
13
|
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"""Feature extraction utilities for ML preprocessing"""
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import logging
|
|
4
|
+
import re
|
|
5
|
+
from collections import Counter, defaultdict
|
|
6
|
+
from dataclasses import dataclass
|
|
5
7
|
from datetime import datetime, timedelta
|
|
6
8
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
7
|
-
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
from collections import defaultdict, Counter
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
11
|
+
import pandas as pd
|
|
11
12
|
|
|
12
13
|
logger = logging.getLogger(__name__)
|
|
13
14
|
|
|
@@ -3,16 +3,17 @@
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import json
|
|
5
5
|
import logging
|
|
6
|
+
from dataclasses import asdict, dataclass
|
|
6
7
|
from datetime import datetime, timezone
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from typing import Any, Dict, List, Optional, Union
|
|
9
|
-
from dataclasses import dataclass, asdict
|
|
10
10
|
|
|
11
11
|
import pandas as pd
|
|
12
12
|
|
|
13
|
-
from mcli.lib.services.data_pipeline import
|
|
13
|
+
from mcli.lib.services.data_pipeline import DataPipelineConfig, LSHDataPipeline
|
|
14
14
|
from mcli.lib.services.lsh_client import LSHClient
|
|
15
15
|
from mcli.ml.configs.mlops_manager import get_mlops_manager
|
|
16
|
+
|
|
16
17
|
from .politician_trading_preprocessor import (
|
|
17
18
|
PoliticianTradingPreprocessor,
|
|
18
19
|
PreprocessingConfig,
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
"""Main preprocessor for politician trading data"""
|
|
2
2
|
|
|
3
|
-
import pandas as pd
|
|
4
|
-
import numpy as np
|
|
5
|
-
from datetime import datetime, timedelta
|
|
6
|
-
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
7
|
-
from dataclasses import dataclass, asdict
|
|
8
3
|
import logging
|
|
4
|
+
from dataclasses import asdict, dataclass
|
|
5
|
+
from datetime import datetime, timedelta
|
|
9
6
|
from pathlib import Path
|
|
7
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
8
|
+
|
|
10
9
|
import joblib
|
|
10
|
+
import numpy as np
|
|
11
|
+
import pandas as pd
|
|
11
12
|
|
|
12
|
-
from .data_cleaners import
|
|
13
|
+
from .data_cleaners import CleaningStats, MissingValueHandler, OutlierDetector, TradingDataCleaner
|
|
13
14
|
from .feature_extractors import (
|
|
14
|
-
|
|
15
|
+
FeatureExtractionStats,
|
|
15
16
|
MarketFeatureExtractor,
|
|
16
|
-
|
|
17
|
+
PoliticianFeatureExtractor,
|
|
17
18
|
SentimentFeatureExtractor,
|
|
18
|
-
|
|
19
|
+
TemporalFeatureExtractor,
|
|
19
20
|
)
|
|
20
21
|
|
|
21
22
|
logger = logging.getLogger(__name__)
|
|
@@ -415,7 +416,7 @@ class PoliticianTradingPreprocessor:
|
|
|
415
416
|
"""Scale numerical features"""
|
|
416
417
|
logger.info("Scaling features")
|
|
417
418
|
|
|
418
|
-
from sklearn.preprocessing import
|
|
419
|
+
from sklearn.preprocessing import LabelEncoder, StandardScaler
|
|
419
420
|
|
|
420
421
|
numerical_features = self._identify_numerical_features(train_data)
|
|
421
422
|
categorical_features = self._identify_categorical_features(train_data)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"""Test script for the ML preprocessing pipeline"""
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import numpy as np
|
|
3
|
+
import logging
|
|
5
4
|
from datetime import datetime, timedelta
|
|
6
5
|
from pathlib import Path
|
|
7
|
-
import logging
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
import numpy as np
|
|
8
|
+
import pandas as pd
|
|
10
9
|
from ml_pipeline import MLDataPipeline, MLDataPipelineConfig
|
|
10
|
+
from politician_trading_preprocessor import PoliticianTradingPreprocessor, PreprocessingConfig
|
|
11
11
|
|
|
12
12
|
# Setup logging
|
|
13
13
|
logging.basicConfig(level=logging.INFO)
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
"""Populate database with sample data for dashboard testing."""
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
|
-
from datetime import datetime, timedelta
|
|
5
4
|
import random
|
|
5
|
+
from datetime import datetime, timedelta
|
|
6
|
+
|
|
6
7
|
import numpy as np
|
|
7
8
|
|
|
8
|
-
from mcli.ml.
|
|
9
|
+
from mcli.ml.config import settings
|
|
9
10
|
from mcli.ml.database.models import (
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
BacktestResult,
|
|
12
|
+
Model,
|
|
13
|
+
ModelStatus,
|
|
14
|
+
Portfolio,
|
|
15
|
+
Prediction,
|
|
16
|
+
StockData,
|
|
17
|
+
Trade,
|
|
18
|
+
User,
|
|
12
19
|
)
|
|
13
|
-
from mcli.ml.
|
|
20
|
+
from mcli.ml.database.session import SessionLocal, init_db
|
|
21
|
+
|
|
14
22
|
|
|
15
23
|
def populate_sample_data():
|
|
16
24
|
"""Populate database with sample data."""
|
|
@@ -41,7 +49,7 @@ def populate_sample_data():
|
|
|
41
49
|
email=f"user{i+1}@example.com",
|
|
42
50
|
role="user" if i > 0 else "admin",
|
|
43
51
|
is_active=True,
|
|
44
|
-
last_login_at=datetime.utcnow() - timedelta(hours=random.randint(1, 48))
|
|
52
|
+
last_login_at=datetime.utcnow() - timedelta(hours=random.randint(1, 48)),
|
|
45
53
|
)
|
|
46
54
|
users.append(user)
|
|
47
55
|
db.add(user)
|
|
@@ -51,7 +59,13 @@ def populate_sample_data():
|
|
|
51
59
|
# Create sample models
|
|
52
60
|
print("Creating sample models...")
|
|
53
61
|
models = []
|
|
54
|
-
model_names = [
|
|
62
|
+
model_names = [
|
|
63
|
+
"LSTM Predictor",
|
|
64
|
+
"Transformer Model",
|
|
65
|
+
"Ensemble Model",
|
|
66
|
+
"CNN Extractor",
|
|
67
|
+
"Attention Model",
|
|
68
|
+
]
|
|
55
69
|
for i, name in enumerate(model_names):
|
|
56
70
|
model = Model(
|
|
57
71
|
name=name,
|
|
@@ -63,7 +77,7 @@ def populate_sample_data():
|
|
|
63
77
|
test_max_drawdown=random.uniform(0.05, 0.15),
|
|
64
78
|
created_at=datetime.utcnow() - timedelta(days=random.randint(1, 30)),
|
|
65
79
|
updated_at=datetime.utcnow() - timedelta(hours=random.randint(1, 24)),
|
|
66
|
-
created_by_id=random.choice(users).id
|
|
80
|
+
created_by_id=random.choice(users).id,
|
|
67
81
|
)
|
|
68
82
|
models.append(model)
|
|
69
83
|
db.add(model)
|
|
@@ -73,7 +87,13 @@ def populate_sample_data():
|
|
|
73
87
|
# Create sample portfolios
|
|
74
88
|
print("Creating sample portfolios...")
|
|
75
89
|
portfolios = []
|
|
76
|
-
portfolio_names = [
|
|
90
|
+
portfolio_names = [
|
|
91
|
+
"Growth Portfolio",
|
|
92
|
+
"Value Portfolio",
|
|
93
|
+
"AI Picks",
|
|
94
|
+
"Risk Parity",
|
|
95
|
+
"Momentum Strategy",
|
|
96
|
+
]
|
|
77
97
|
for i, name in enumerate(portfolio_names):
|
|
78
98
|
portfolio = Portfolio(
|
|
79
99
|
name=name,
|
|
@@ -84,7 +104,7 @@ def populate_sample_data():
|
|
|
84
104
|
sharpe_ratio=random.uniform(0.8, 2.0),
|
|
85
105
|
max_drawdown=random.uniform(0.05, 0.20),
|
|
86
106
|
is_active=i < 4,
|
|
87
|
-
created_by_id=random.choice(users).id
|
|
107
|
+
created_by_id=random.choice(users).id,
|
|
88
108
|
)
|
|
89
109
|
portfolios.append(portfolio)
|
|
90
110
|
db.add(portfolio)
|
|
@@ -102,7 +122,7 @@ def populate_sample_data():
|
|
|
102
122
|
target_date=datetime.utcnow().date() + timedelta(days=random.randint(1, 30)),
|
|
103
123
|
predicted_return=random.uniform(-0.05, 0.05),
|
|
104
124
|
confidence_score=random.uniform(0.5, 0.95),
|
|
105
|
-
model_id=random.choice(models).id
|
|
125
|
+
model_id=random.choice(models).id,
|
|
106
126
|
)
|
|
107
127
|
db.add(prediction)
|
|
108
128
|
|
|
@@ -114,7 +134,7 @@ def populate_sample_data():
|
|
|
114
134
|
target_date=datetime.utcnow().date() + timedelta(days=7),
|
|
115
135
|
predicted_return=random.uniform(-0.03, 0.03),
|
|
116
136
|
confidence_score=random.uniform(0.6, 0.9),
|
|
117
|
-
model_id=random.choice(models).id
|
|
137
|
+
model_id=random.choice(models).id,
|
|
118
138
|
)
|
|
119
139
|
db.add(prediction)
|
|
120
140
|
|
|
@@ -134,7 +154,7 @@ def populate_sample_data():
|
|
|
134
154
|
low=base_price * random.uniform(0.97, 0.99),
|
|
135
155
|
close=base_price * random.uniform(0.98, 1.02),
|
|
136
156
|
volume=random.randint(1000000, 50000000),
|
|
137
|
-
adjusted_close=base_price * random.uniform(0.98, 1.02)
|
|
157
|
+
adjusted_close=base_price * random.uniform(0.98, 1.02),
|
|
138
158
|
)
|
|
139
159
|
db.add(stock_data)
|
|
140
160
|
base_price = stock_data.close # Random walk
|
|
@@ -152,7 +172,7 @@ def populate_sample_data():
|
|
|
152
172
|
trade_type=random.choice(["buy", "sell"]),
|
|
153
173
|
quantity=random.randint(10, 100),
|
|
154
174
|
price=random.uniform(50, 500),
|
|
155
|
-
executed_at=datetime.utcnow() - timedelta(days=random.randint(0, 30))
|
|
175
|
+
executed_at=datetime.utcnow() - timedelta(days=random.randint(0, 30)),
|
|
156
176
|
)
|
|
157
177
|
db.add(trade)
|
|
158
178
|
|
|
@@ -173,7 +193,7 @@ def populate_sample_data():
|
|
|
173
193
|
max_drawdown=random.uniform(0.05, 0.25),
|
|
174
194
|
win_rate=random.uniform(0.45, 0.65),
|
|
175
195
|
profit_factor=random.uniform(0.9, 2.0),
|
|
176
|
-
total_trades=random.randint(50, 200)
|
|
196
|
+
total_trades=random.randint(50, 200),
|
|
177
197
|
)
|
|
178
198
|
db.add(backtest)
|
|
179
199
|
|
|
@@ -197,4 +217,4 @@ def populate_sample_data():
|
|
|
197
217
|
|
|
198
218
|
|
|
199
219
|
if __name__ == "__main__":
|
|
200
|
-
populate_sample_data()
|
|
220
|
+
populate_sample_data()
|