mcli-framework 7.12.2__py3-none-any.whl → 7.12.4__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 (216) hide show
  1. mcli/app/__init__.py +0 -2
  2. mcli/app/commands_cmd.py +30 -26
  3. mcli/app/completion_helpers.py +5 -5
  4. mcli/app/init_cmd.py +10 -10
  5. mcli/app/lock_cmd.py +29 -24
  6. mcli/app/main.py +2 -8
  7. mcli/app/model/model.py +5 -10
  8. mcli/app/store_cmd.py +8 -8
  9. mcli/app/video/__init__.py +0 -2
  10. mcli/app/video/video.py +1 -14
  11. mcli/chat/chat.py +90 -108
  12. mcli/chat/command_rag.py +0 -4
  13. mcli/chat/enhanced_chat.py +32 -41
  14. mcli/chat/system_controller.py +37 -37
  15. mcli/chat/system_integration.py +4 -5
  16. mcli/cli.py +2 -3
  17. mcli/lib/api/api.py +4 -9
  18. mcli/lib/api/daemon_client.py +19 -20
  19. mcli/lib/api/daemon_client_local.py +1 -3
  20. mcli/lib/api/daemon_decorator.py +6 -6
  21. mcli/lib/api/mcli_decorators.py +4 -8
  22. mcli/lib/auth/__init__.py +0 -1
  23. mcli/lib/auth/auth.py +4 -5
  24. mcli/lib/auth/mcli_manager.py +7 -12
  25. mcli/lib/auth/token_util.py +5 -5
  26. mcli/lib/config/__init__.py +29 -1
  27. mcli/lib/config/config.py +0 -1
  28. mcli/lib/custom_commands.py +1 -1
  29. mcli/lib/discovery/command_discovery.py +15 -15
  30. mcli/lib/erd/erd.py +7 -7
  31. mcli/lib/files/files.py +1 -1
  32. mcli/lib/fs/__init__.py +31 -1
  33. mcli/lib/fs/fs.py +12 -13
  34. mcli/lib/lib.py +0 -1
  35. mcli/lib/logger/logger.py +7 -10
  36. mcli/lib/performance/optimizer.py +25 -27
  37. mcli/lib/performance/rust_bridge.py +22 -27
  38. mcli/lib/performance/uvloop_config.py +0 -1
  39. mcli/lib/pickles/__init__.py +0 -1
  40. mcli/lib/pickles/pickles.py +0 -2
  41. mcli/lib/secrets/commands.py +0 -2
  42. mcli/lib/secrets/manager.py +0 -1
  43. mcli/lib/secrets/repl.py +2 -3
  44. mcli/lib/secrets/store.py +1 -2
  45. mcli/lib/services/data_pipeline.py +34 -34
  46. mcli/lib/services/lsh_client.py +38 -40
  47. mcli/lib/shell/shell.py +2 -2
  48. mcli/lib/toml/__init__.py +0 -1
  49. mcli/lib/ui/styling.py +0 -1
  50. mcli/lib/ui/visual_effects.py +33 -41
  51. mcli/lib/watcher/watcher.py +0 -1
  52. mcli/ml/__init__.py +1 -1
  53. mcli/ml/api/__init__.py +1 -1
  54. mcli/ml/api/app.py +8 -9
  55. mcli/ml/api/middleware.py +10 -10
  56. mcli/ml/api/routers/__init__.py +1 -1
  57. mcli/ml/api/routers/admin_router.py +3 -3
  58. mcli/ml/api/routers/auth_router.py +17 -18
  59. mcli/ml/api/routers/backtest_router.py +2 -2
  60. mcli/ml/api/routers/data_router.py +2 -2
  61. mcli/ml/api/routers/model_router.py +14 -15
  62. mcli/ml/api/routers/monitoring_router.py +2 -2
  63. mcli/ml/api/routers/portfolio_router.py +2 -2
  64. mcli/ml/api/routers/prediction_router.py +10 -9
  65. mcli/ml/api/routers/trade_router.py +2 -2
  66. mcli/ml/api/routers/websocket_router.py +6 -7
  67. mcli/ml/api/schemas.py +2 -2
  68. mcli/ml/auth/__init__.py +1 -1
  69. mcli/ml/auth/auth_manager.py +22 -23
  70. mcli/ml/auth/models.py +17 -17
  71. mcli/ml/auth/permissions.py +17 -17
  72. mcli/ml/backtesting/__init__.py +1 -1
  73. mcli/ml/backtesting/backtest_engine.py +31 -35
  74. mcli/ml/backtesting/performance_metrics.py +12 -14
  75. mcli/ml/backtesting/run.py +1 -2
  76. mcli/ml/cache.py +35 -36
  77. mcli/ml/cli/__init__.py +1 -1
  78. mcli/ml/cli/main.py +21 -24
  79. mcli/ml/config/__init__.py +1 -1
  80. mcli/ml/config/settings.py +28 -29
  81. mcli/ml/configs/__init__.py +1 -1
  82. mcli/ml/configs/dvc_config.py +14 -15
  83. mcli/ml/configs/mlflow_config.py +12 -13
  84. mcli/ml/configs/mlops_manager.py +19 -21
  85. mcli/ml/dashboard/__init__.py +4 -4
  86. mcli/ml/dashboard/app.py +20 -30
  87. mcli/ml/dashboard/app_supabase.py +16 -19
  88. mcli/ml/dashboard/app_training.py +11 -14
  89. mcli/ml/dashboard/cli.py +2 -2
  90. mcli/ml/dashboard/common.py +2 -3
  91. mcli/ml/dashboard/components/__init__.py +1 -1
  92. mcli/ml/dashboard/components/charts.py +13 -11
  93. mcli/ml/dashboard/components/metrics.py +7 -7
  94. mcli/ml/dashboard/components/tables.py +12 -9
  95. mcli/ml/dashboard/overview.py +2 -2
  96. mcli/ml/dashboard/pages/__init__.py +1 -1
  97. mcli/ml/dashboard/pages/cicd.py +15 -18
  98. mcli/ml/dashboard/pages/debug_dependencies.py +7 -7
  99. mcli/ml/dashboard/pages/monte_carlo_predictions.py +11 -18
  100. mcli/ml/dashboard/pages/predictions_enhanced.py +24 -32
  101. mcli/ml/dashboard/pages/scrapers_and_logs.py +22 -24
  102. mcli/ml/dashboard/pages/test_portfolio.py +3 -6
  103. mcli/ml/dashboard/pages/trading.py +16 -18
  104. mcli/ml/dashboard/pages/workflows.py +20 -30
  105. mcli/ml/dashboard/utils.py +9 -9
  106. mcli/ml/dashboard/warning_suppression.py +3 -3
  107. mcli/ml/data_ingestion/__init__.py +1 -1
  108. mcli/ml/data_ingestion/api_connectors.py +41 -46
  109. mcli/ml/data_ingestion/data_pipeline.py +36 -46
  110. mcli/ml/data_ingestion/stream_processor.py +43 -46
  111. mcli/ml/database/__init__.py +1 -1
  112. mcli/ml/database/migrations/env.py +2 -2
  113. mcli/ml/database/models.py +22 -24
  114. mcli/ml/database/session.py +14 -14
  115. mcli/ml/experimentation/__init__.py +1 -1
  116. mcli/ml/experimentation/ab_testing.py +45 -46
  117. mcli/ml/features/__init__.py +1 -1
  118. mcli/ml/features/ensemble_features.py +22 -27
  119. mcli/ml/features/recommendation_engine.py +30 -30
  120. mcli/ml/features/stock_features.py +29 -32
  121. mcli/ml/features/test_feature_engineering.py +10 -11
  122. mcli/ml/logging.py +4 -4
  123. mcli/ml/mlops/__init__.py +1 -1
  124. mcli/ml/mlops/data_versioning.py +29 -30
  125. mcli/ml/mlops/experiment_tracker.py +24 -24
  126. mcli/ml/mlops/model_serving.py +31 -34
  127. mcli/ml/mlops/pipeline_orchestrator.py +27 -35
  128. mcli/ml/models/__init__.py +5 -6
  129. mcli/ml/models/base_models.py +23 -23
  130. mcli/ml/models/ensemble_models.py +31 -31
  131. mcli/ml/models/recommendation_models.py +18 -19
  132. mcli/ml/models/test_models.py +14 -16
  133. mcli/ml/monitoring/__init__.py +1 -1
  134. mcli/ml/monitoring/drift_detection.py +32 -36
  135. mcli/ml/monitoring/metrics.py +2 -2
  136. mcli/ml/optimization/__init__.py +1 -1
  137. mcli/ml/optimization/optimize.py +1 -2
  138. mcli/ml/optimization/portfolio_optimizer.py +30 -32
  139. mcli/ml/predictions/__init__.py +1 -1
  140. mcli/ml/preprocessing/__init__.py +1 -1
  141. mcli/ml/preprocessing/data_cleaners.py +22 -23
  142. mcli/ml/preprocessing/feature_extractors.py +23 -26
  143. mcli/ml/preprocessing/ml_pipeline.py +23 -23
  144. mcli/ml/preprocessing/test_preprocessing.py +7 -8
  145. mcli/ml/scripts/populate_sample_data.py +0 -4
  146. mcli/ml/serving/serve.py +1 -2
  147. mcli/ml/tasks.py +17 -17
  148. mcli/ml/tests/test_integration.py +29 -30
  149. mcli/ml/tests/test_training_dashboard.py +21 -21
  150. mcli/ml/trading/__init__.py +1 -1
  151. mcli/ml/trading/migrations.py +5 -5
  152. mcli/ml/trading/models.py +21 -23
  153. mcli/ml/trading/paper_trading.py +16 -13
  154. mcli/ml/trading/risk_management.py +17 -18
  155. mcli/ml/trading/trading_service.py +25 -28
  156. mcli/ml/training/__init__.py +1 -1
  157. mcli/ml/training/train.py +0 -1
  158. mcli/public/oi/oi.py +1 -2
  159. mcli/self/completion_cmd.py +6 -10
  160. mcli/self/logs_cmd.py +19 -24
  161. mcli/self/migrate_cmd.py +22 -20
  162. mcli/self/redis_cmd.py +10 -11
  163. mcli/self/self_cmd.py +10 -18
  164. mcli/self/store_cmd.py +10 -12
  165. mcli/self/visual_cmd.py +9 -14
  166. mcli/self/zsh_cmd.py +2 -4
  167. mcli/workflow/daemon/async_command_database.py +23 -24
  168. mcli/workflow/daemon/async_process_manager.py +27 -29
  169. mcli/workflow/daemon/client.py +27 -33
  170. mcli/workflow/daemon/daemon.py +32 -36
  171. mcli/workflow/daemon/enhanced_daemon.py +24 -33
  172. mcli/workflow/daemon/process_cli.py +11 -12
  173. mcli/workflow/daemon/process_manager.py +23 -26
  174. mcli/workflow/daemon/test_daemon.py +4 -5
  175. mcli/workflow/dashboard/dashboard_cmd.py +0 -1
  176. mcli/workflow/doc_convert.py +15 -17
  177. mcli/workflow/gcloud/__init__.py +0 -1
  178. mcli/workflow/gcloud/gcloud.py +11 -8
  179. mcli/workflow/git_commit/ai_service.py +14 -15
  180. mcli/workflow/lsh_integration.py +9 -11
  181. mcli/workflow/model_service/client.py +26 -31
  182. mcli/workflow/model_service/download_and_run_efficient_models.py +10 -14
  183. mcli/workflow/model_service/lightweight_embedder.py +25 -35
  184. mcli/workflow/model_service/lightweight_model_server.py +26 -32
  185. mcli/workflow/model_service/lightweight_test.py +7 -10
  186. mcli/workflow/model_service/model_service.py +80 -91
  187. mcli/workflow/model_service/ollama_efficient_runner.py +14 -18
  188. mcli/workflow/model_service/openai_adapter.py +23 -23
  189. mcli/workflow/model_service/pdf_processor.py +21 -26
  190. mcli/workflow/model_service/test_efficient_runner.py +12 -16
  191. mcli/workflow/model_service/test_example.py +11 -13
  192. mcli/workflow/model_service/test_integration.py +3 -5
  193. mcli/workflow/model_service/test_new_features.py +7 -8
  194. mcli/workflow/notebook/converter.py +1 -1
  195. mcli/workflow/notebook/notebook_cmd.py +5 -6
  196. mcli/workflow/notebook/schema.py +0 -1
  197. mcli/workflow/notebook/validator.py +7 -3
  198. mcli/workflow/openai/openai.py +1 -2
  199. mcli/workflow/registry/registry.py +4 -1
  200. mcli/workflow/repo/repo.py +6 -7
  201. mcli/workflow/scheduler/cron_parser.py +16 -19
  202. mcli/workflow/scheduler/job.py +10 -10
  203. mcli/workflow/scheduler/monitor.py +15 -15
  204. mcli/workflow/scheduler/persistence.py +17 -18
  205. mcli/workflow/scheduler/scheduler.py +37 -38
  206. mcli/workflow/secrets/__init__.py +1 -1
  207. mcli/workflow/sync/test_cmd.py +0 -1
  208. mcli/workflow/wakatime/__init__.py +5 -9
  209. mcli/workflow/wakatime/wakatime.py +1 -2
  210. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/METADATA +1 -1
  211. mcli_framework-7.12.4.dist-info/RECORD +279 -0
  212. mcli_framework-7.12.2.dist-info/RECORD +0 -279
  213. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/WHEEL +0 -0
  214. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/entry_points.txt +0 -0
  215. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/licenses/LICENSE +0 -0
  216. {mcli_framework-7.12.2.dist-info → mcli_framework-7.12.4.dist-info}/top_level.txt +0 -0
@@ -1,10 +1,10 @@
1
- """Stock recommendation engine that combines all feature engineering components"""
1
+ """Stock recommendation engine that combines all feature engineering components."""
2
2
 
3
3
  import logging
4
- from dataclasses import asdict, dataclass
5
- from datetime import datetime, timedelta
4
+ from dataclasses import dataclass
5
+ from datetime import datetime
6
6
  from pathlib import Path
7
- from typing import Any, Dict, List, Optional, Tuple, Union
7
+ from typing import Dict, List, Optional, Tuple
8
8
 
9
9
  import joblib
10
10
  import numpy as np
@@ -31,7 +31,7 @@ logger = logging.getLogger(__name__)
31
31
 
32
32
  @dataclass
33
33
  class RecommendationConfig:
34
- """Configuration for stock recommendation engine"""
34
+ """Configuration for stock recommendation engine."""
35
35
 
36
36
  # Feature engineering components
37
37
  enable_technical_features: bool = True
@@ -73,7 +73,7 @@ class RecommendationConfig:
73
73
 
74
74
  @dataclass
75
75
  class RecommendationResult:
76
- """Result from stock recommendation engine"""
76
+ """Result from stock recommendation engine."""
77
77
 
78
78
  # Basic information
79
79
  ticker: str
@@ -105,7 +105,7 @@ class RecommendationResult:
105
105
 
106
106
 
107
107
  class StockRecommendationEngine:
108
- """Comprehensive stock recommendation engine"""
108
+ """Comprehensive stock recommendation engine."""
109
109
 
110
110
  def __init__(self, config: Optional[RecommendationConfig] = None):
111
111
  self.config = config or RecommendationConfig()
@@ -132,7 +132,7 @@ class StockRecommendationEngine:
132
132
  politician_metadata: Optional[pd.DataFrame] = None,
133
133
  market_data: Optional[Dict[str, pd.DataFrame]] = None,
134
134
  ) -> List[RecommendationResult]:
135
- """Generate stock recommendations based on politician trading data"""
135
+ """Generate stock recommendations based on politician trading data."""
136
136
 
137
137
  logger.info("Starting stock recommendation generation")
138
138
 
@@ -170,7 +170,7 @@ class StockRecommendationEngine:
170
170
  politician_metadata: Optional[pd.DataFrame],
171
171
  market_data: Optional[Dict[str, pd.DataFrame]],
172
172
  ) -> pd.DataFrame:
173
- """Extract all features for recommendation generation"""
173
+ """Extract all features for recommendation generation."""
174
174
 
175
175
  logger.info("Extracting comprehensive feature set")
176
176
  df = trading_data.copy()
@@ -204,7 +204,7 @@ class StockRecommendationEngine:
204
204
  def _add_technical_features(
205
205
  self, df: pd.DataFrame, stock_price_data: pd.DataFrame
206
206
  ) -> pd.DataFrame:
207
- """Add technical analysis features"""
207
+ """Add technical analysis features."""
208
208
  logger.info("Adding technical features")
209
209
 
210
210
  # Merge stock price data
@@ -254,7 +254,7 @@ class StockRecommendationEngine:
254
254
  def _add_political_features(
255
255
  self, df: pd.DataFrame, politician_metadata: Optional[pd.DataFrame]
256
256
  ) -> pd.DataFrame:
257
- """Add political influence features"""
257
+ """Add political influence features."""
258
258
  logger.info("Adding political features")
259
259
 
260
260
  # Political influence features
@@ -275,7 +275,7 @@ class StockRecommendationEngine:
275
275
  stock_price_data: pd.DataFrame,
276
276
  market_data: Optional[Dict[str, pd.DataFrame]],
277
277
  ) -> pd.DataFrame:
278
- """Add market regime features"""
278
+ """Add market regime features."""
279
279
  logger.info("Adding market regime features")
280
280
 
281
281
  # Add market regime features from stock price data
@@ -294,7 +294,7 @@ class StockRecommendationEngine:
294
294
  return df
295
295
 
296
296
  def _add_ensemble_features(self, df: pd.DataFrame) -> pd.DataFrame:
297
- """Add ensemble features"""
297
+ """Add ensemble features."""
298
298
  logger.info("Adding ensemble features")
299
299
 
300
300
  # Build ensemble features
@@ -309,7 +309,7 @@ class StockRecommendationEngine:
309
309
  return df
310
310
 
311
311
  def _add_interaction_features(self, df: pd.DataFrame) -> pd.DataFrame:
312
- """Add feature interactions"""
312
+ """Add feature interactions."""
313
313
  logger.info("Adding interaction features")
314
314
 
315
315
  # Get important feature pairs (mock implementation)
@@ -333,7 +333,7 @@ class StockRecommendationEngine:
333
333
  return df
334
334
 
335
335
  def _perform_feature_selection(self, df: pd.DataFrame) -> pd.DataFrame:
336
- """Perform feature selection"""
336
+ """Perform feature selection."""
337
337
  logger.info("Performing feature selection")
338
338
 
339
339
  # Create a synthetic target for feature selection if none exists
@@ -387,7 +387,7 @@ class StockRecommendationEngine:
387
387
  def _generate_stock_recommendation(
388
388
  self, stock_data: pd.DataFrame, ticker: str
389
389
  ) -> Optional[RecommendationResult]:
390
- """Generate recommendation for a specific stock"""
390
+ """Generate recommendation for a specific stock."""
391
391
 
392
392
  try:
393
393
  # Calculate component scores
@@ -460,7 +460,7 @@ class StockRecommendationEngine:
460
460
  return None
461
461
 
462
462
  def _calculate_technical_score(self, stock_data: pd.DataFrame) -> float:
463
- """Calculate technical analysis score"""
463
+ """Calculate technical analysis score."""
464
464
  try:
465
465
  technical_indicators = []
466
466
 
@@ -497,7 +497,7 @@ class StockRecommendationEngine:
497
497
  return 0.5
498
498
 
499
499
  def _calculate_political_score(self, stock_data: pd.DataFrame) -> float:
500
- """Calculate political influence score"""
500
+ """Calculate political influence score."""
501
501
  try:
502
502
  political_factors = []
503
503
 
@@ -528,7 +528,7 @@ class StockRecommendationEngine:
528
528
  return 0.5
529
529
 
530
530
  def _calculate_regime_score(self, stock_data: pd.DataFrame) -> float:
531
- """Calculate market regime score"""
531
+ """Calculate market regime score."""
532
532
  try:
533
533
  regime_factors = []
534
534
 
@@ -571,7 +571,7 @@ class StockRecommendationEngine:
571
571
  return 0.5
572
572
 
573
573
  def _calculate_ensemble_score(self, stock_data: pd.DataFrame) -> float:
574
- """Calculate ensemble model score"""
574
+ """Calculate ensemble model score."""
575
575
  try:
576
576
  # Use cluster-based scoring as proxy for ensemble
577
577
  ensemble_factors = []
@@ -596,7 +596,7 @@ class StockRecommendationEngine:
596
596
  return 0.5
597
597
 
598
598
  def _assess_risk_level(self, stock_data: pd.DataFrame) -> str:
599
- """Assess risk level for the stock"""
599
+ """Assess risk level for the stock."""
600
600
  try:
601
601
  risk_factors = []
602
602
 
@@ -629,11 +629,11 @@ class StockRecommendationEngine:
629
629
  return "medium"
630
630
 
631
631
  def _risk_to_numeric(self, risk_level: str) -> float:
632
- """Convert risk level to numeric value"""
632
+ """Convert risk level to numeric value."""
633
633
  return {"low": 0.2, "medium": 0.5, "high": 0.8}.get(risk_level, 0.5)
634
634
 
635
635
  def _calculate_confidence(self, stock_data: pd.DataFrame, final_score: float) -> float:
636
- """Calculate confidence in the recommendation"""
636
+ """Calculate confidence in the recommendation."""
637
637
  try:
638
638
  confidence_factors = []
639
639
 
@@ -658,7 +658,7 @@ class StockRecommendationEngine:
658
658
  def _generate_outlooks(
659
659
  self, stock_data: pd.DataFrame, final_score: float
660
660
  ) -> Tuple[str, str, str]:
661
- """Generate short, medium, and long-term outlooks"""
661
+ """Generate short, medium, and long-term outlooks."""
662
662
 
663
663
  def score_to_outlook(score):
664
664
  if score >= 0.7:
@@ -676,7 +676,7 @@ class StockRecommendationEngine:
676
676
  return short_term, medium_term, long_term
677
677
 
678
678
  def _get_key_features(self, stock_data: pd.DataFrame) -> Tuple[List[str], Dict[str, float]]:
679
- """Get key features and their importance"""
679
+ """Get key features and their importance."""
680
680
  try:
681
681
  # Get numerical features
682
682
  numerical_features = [
@@ -695,7 +695,7 @@ class StockRecommendationEngine:
695
695
  variance = stock_data[feature].var()
696
696
  importance = value * (1 + variance)
697
697
  feature_importance[feature] = importance
698
- except:
698
+ except Exception:
699
699
  feature_importance[feature] = 0
700
700
 
701
701
  # Sort by importance
@@ -715,7 +715,7 @@ class StockRecommendationEngine:
715
715
  def _generate_explanation(
716
716
  self, stock_data: pd.DataFrame, final_score: float, key_features: List[str]
717
717
  ) -> str:
718
- """Generate human-readable explanation for the recommendation"""
718
+ """Generate human-readable explanation for the recommendation."""
719
719
 
720
720
  try:
721
721
  if final_score >= 0.7:
@@ -746,7 +746,7 @@ class StockRecommendationEngine:
746
746
  return "Recommendation based on comprehensive analysis."
747
747
 
748
748
  def _generate_warnings(self, stock_data: pd.DataFrame, final_score: float) -> List[str]:
749
- """Generate warnings for the recommendation"""
749
+ """Generate warnings for the recommendation."""
750
750
 
751
751
  warnings = []
752
752
 
@@ -777,7 +777,7 @@ class StockRecommendationEngine:
777
777
  return warnings
778
778
 
779
779
  def save_model_artifacts(self, artifacts_dir: Path):
780
- """Save model artifacts and configurations"""
780
+ """Save model artifacts and configurations."""
781
781
  artifacts_dir.mkdir(parents=True, exist_ok=True)
782
782
 
783
783
  # Save configuration
@@ -792,7 +792,7 @@ class StockRecommendationEngine:
792
792
  logger.info(f"Saved model artifacts to {artifacts_dir}")
793
793
 
794
794
  def load_model_artifacts(self, artifacts_dir: Path):
795
- """Load model artifacts and configurations"""
795
+ """Load model artifacts and configurations."""
796
796
  try:
797
797
  # Load configuration
798
798
  config_path = artifacts_dir / "recommendation_config.joblib"
@@ -1,11 +1,8 @@
1
- """Stock-specific feature engineering for recommendation models"""
1
+ """Stock-specific feature engineering for recommendation models."""
2
2
 
3
3
  import logging
4
- import warnings
5
- from collections import defaultdict
6
4
  from dataclasses import dataclass
7
- from datetime import datetime, timedelta
8
- from typing import Any, Dict, List, Optional, Tuple, Union
5
+ from typing import Dict, List, Optional, Tuple
9
6
 
10
7
  import numpy as np
11
8
  import pandas as pd
@@ -15,7 +12,7 @@ logger = logging.getLogger(__name__)
15
12
 
16
13
  @dataclass
17
14
  class StockFeatureConfig:
18
- """Configuration for stock feature extraction"""
15
+ """Configuration for stock feature extraction."""
19
16
 
20
17
  # Technical indicator periods
21
18
  sma_periods: List[int] = None
@@ -50,13 +47,13 @@ class StockFeatureConfig:
50
47
 
51
48
 
52
49
  class StockRecommendationFeatures:
53
- """Core stock recommendation feature extractor"""
50
+ """Core stock recommendation feature extractor."""
54
51
 
55
52
  def __init__(self, config: Optional[StockFeatureConfig] = None):
56
53
  self.config = config or StockFeatureConfig()
57
54
 
58
55
  def extract_features(self, stock_data: pd.DataFrame) -> pd.DataFrame:
59
- """Extract stock recommendation features"""
56
+ """Extract stock recommendation features."""
60
57
  logger.info("Extracting stock recommendation features")
61
58
 
62
59
  df = stock_data.copy()
@@ -89,7 +86,7 @@ class StockRecommendationFeatures:
89
86
  return df
90
87
 
91
88
  def _extract_price_features(self, df: pd.DataFrame) -> pd.DataFrame:
92
- """Extract price-based features"""
89
+ """Extract price-based features."""
93
90
  # Basic price relationships
94
91
  df["hl_ratio"] = (df["high"] - df["low"]) / df["close"]
95
92
  df["oc_ratio"] = (df["open"] - df["close"]) / df["close"]
@@ -125,7 +122,7 @@ class StockRecommendationFeatures:
125
122
  return df
126
123
 
127
124
  def _extract_volume_features(self, df: pd.DataFrame) -> pd.DataFrame:
128
- """Extract volume-based features"""
125
+ """Extract volume-based features."""
129
126
  # Volume moving averages
130
127
  for period in self.config.volume_ma_periods:
131
128
  df[f"volume_ma_{period}"] = df["volume"].rolling(window=period).mean()
@@ -158,7 +155,7 @@ class StockRecommendationFeatures:
158
155
  return df
159
156
 
160
157
  def _extract_volatility_features(self, df: pd.DataFrame) -> pd.DataFrame:
161
- """Extract volatility-based features"""
158
+ """Extract volatility-based features."""
162
159
  # Calculate returns
163
160
  df["returns"] = df["close"].pct_change()
164
161
  df["log_returns"] = np.log(df["close"] / df["close"].shift(1))
@@ -197,7 +194,7 @@ class StockRecommendationFeatures:
197
194
  return df
198
195
 
199
196
  def _extract_momentum_features(self, df: pd.DataFrame) -> pd.DataFrame:
200
- """Extract momentum-based features"""
197
+ """Extract momentum-based features."""
201
198
  # RSI (Relative Strength Index)
202
199
  delta = df["close"].diff()
203
200
  gain = delta.where(delta > 0, 0).rolling(window=self.config.rsi_period).mean()
@@ -234,7 +231,7 @@ class StockRecommendationFeatures:
234
231
  return df
235
232
 
236
233
  def _extract_trend_features(self, df: pd.DataFrame) -> pd.DataFrame:
237
- """Extract trend-based features"""
234
+ """Extract trend-based features."""
238
235
  # Trend strength
239
236
  for window in [10, 20, 50]:
240
237
  # Linear regression slope
@@ -255,7 +252,7 @@ class StockRecommendationFeatures:
255
252
  ss_res = np.sum((prices - predicted) ** 2)
256
253
  ss_tot = np.sum((prices - np.mean(prices)) ** 2)
257
254
  return 1 - (ss_res / ss_tot) if ss_tot != 0 else 0
258
- except:
255
+ except Exception:
259
256
  return 0
260
257
 
261
258
  df[f"trend_strength_{window}"] = (
@@ -283,13 +280,13 @@ class StockRecommendationFeatures:
283
280
 
284
281
 
285
282
  class TechnicalIndicatorFeatures:
286
- """Advanced technical indicator features"""
283
+ """Advanced technical indicator features."""
287
284
 
288
285
  def __init__(self, config: Optional[StockFeatureConfig] = None):
289
286
  self.config = config or StockFeatureConfig()
290
287
 
291
288
  def extract_advanced_indicators(self, df: pd.DataFrame) -> pd.DataFrame:
292
- """Extract advanced technical indicators"""
289
+ """Extract advanced technical indicators."""
293
290
  df = df.copy()
294
291
 
295
292
  # Williams %R
@@ -315,13 +312,13 @@ class TechnicalIndicatorFeatures:
315
312
  return df
316
313
 
317
314
  def _williams_r(self, df: pd.DataFrame, period: int = 14) -> pd.Series:
318
- """Williams %R oscillator"""
315
+ """Williams %R oscillator."""
319
316
  highest_high = df["high"].rolling(window=period).max()
320
317
  lowest_low = df["low"].rolling(window=period).min()
321
318
  return -100 * (highest_high - df["close"]) / (highest_high - lowest_low)
322
319
 
323
320
  def _commodity_channel_index(self, df: pd.DataFrame, period: int = 20) -> pd.Series:
324
- """Commodity Channel Index"""
321
+ """Commodity Channel Index."""
325
322
  typical_price = (df["high"] + df["low"] + df["close"]) / 3
326
323
  sma_tp = typical_price.rolling(window=period).mean()
327
324
  mad = typical_price.rolling(window=period).apply(
@@ -330,7 +327,7 @@ class TechnicalIndicatorFeatures:
330
327
  return (typical_price - sma_tp) / (0.015 * mad)
331
328
 
332
329
  def _money_flow_index(self, df: pd.DataFrame, period: int = 14) -> pd.Series:
333
- """Money Flow Index"""
330
+ """Money Flow Index."""
334
331
  typical_price = (df["high"] + df["low"] + df["close"]) / 3
335
332
  money_flow = typical_price * df["volume"]
336
333
 
@@ -344,7 +341,7 @@ class TechnicalIndicatorFeatures:
344
341
  return mfi
345
342
 
346
343
  def _aroon_indicator(self, df: pd.DataFrame, period: int = 25) -> Tuple[pd.Series, pd.Series]:
347
- """Aroon Up and Aroon Down indicators"""
344
+ """Aroon Up and Aroon Down indicators."""
348
345
  aroon_up = (
349
346
  100 * (period - df["high"].rolling(window=period).apply(np.argmax, raw=False)) / period
350
347
  )
@@ -354,9 +351,9 @@ class TechnicalIndicatorFeatures:
354
351
  return aroon_up, aroon_down
355
352
 
356
353
  def _parabolic_sar(self, df: pd.DataFrame) -> pd.Series:
357
- """Parabolic SAR indicator (simplified version)"""
354
+ """Parabolic SAR indicator (simplified version)."""
358
355
  # Simplified PSAR implementation
359
- high = df["high"].values
356
+ df["high"].values
360
357
  low = df["low"].values
361
358
  close = df["close"].values
362
359
 
@@ -371,7 +368,7 @@ class TechnicalIndicatorFeatures:
371
368
  return pd.Series(psar, index=df.index)
372
369
 
373
370
  def _ichimoku_cloud(self, df: pd.DataFrame) -> pd.DataFrame:
374
- """Ichimoku Cloud components"""
371
+ """Ichimoku Cloud components."""
375
372
  # Tenkan-sen (Conversion Line)
376
373
  tenkan_high = df["high"].rolling(window=9).max()
377
374
  tenkan_low = df["low"].rolling(window=9).min()
@@ -408,13 +405,13 @@ class TechnicalIndicatorFeatures:
408
405
 
409
406
 
410
407
  class MarketRegimeFeatures:
411
- """Market regime detection features"""
408
+ """Market regime detection features."""
412
409
 
413
410
  def __init__(self, config: Optional[StockFeatureConfig] = None):
414
411
  self.config = config or StockFeatureConfig()
415
412
 
416
413
  def extract_regime_features(self, df: pd.DataFrame) -> pd.DataFrame:
417
- """Extract market regime features"""
414
+ """Extract market regime features."""
418
415
  df = df.copy()
419
416
 
420
417
  # Volatility regime
@@ -432,7 +429,7 @@ class MarketRegimeFeatures:
432
429
  return df
433
430
 
434
431
  def _volatility_regime(self, df: pd.DataFrame) -> pd.DataFrame:
435
- """Identify volatility regimes"""
432
+ """Identify volatility regimes."""
436
433
  returns = df["close"].pct_change()
437
434
  vol_20 = returns.rolling(window=20).std() * np.sqrt(252)
438
435
 
@@ -451,7 +448,7 @@ class MarketRegimeFeatures:
451
448
  return df
452
449
 
453
450
  def _trend_regime(self, df: pd.DataFrame) -> pd.DataFrame:
454
- """Identify trend regimes"""
451
+ """Identify trend regimes."""
455
452
  # Multiple timeframe trend analysis
456
453
  for window in [20, 50, 200]:
457
454
  sma = df["close"].rolling(window=window).mean()
@@ -475,7 +472,7 @@ class MarketRegimeFeatures:
475
472
  return df
476
473
 
477
474
  def _volume_regime(self, df: pd.DataFrame) -> pd.DataFrame:
478
- """Identify volume regimes"""
475
+ """Identify volume regimes."""
479
476
  volume_ma = df["volume"].rolling(window=20).mean()
480
477
  volume_ratio = df["volume"] / volume_ma
481
478
 
@@ -497,7 +494,7 @@ class MarketRegimeFeatures:
497
494
  return df
498
495
 
499
496
  def _market_stress_indicators(self, df: pd.DataFrame) -> pd.DataFrame:
500
- """Market stress and fear indicators"""
497
+ """Market stress and fear indicators."""
501
498
  returns = df["close"].pct_change()
502
499
 
503
500
  # Maximum drawdown
@@ -524,7 +521,7 @@ class MarketRegimeFeatures:
524
521
 
525
522
 
526
523
  class CrossAssetFeatures:
527
- """Cross-asset and correlation features"""
524
+ """Cross-asset and correlation features."""
528
525
 
529
526
  def __init__(self):
530
527
  pass
@@ -532,7 +529,7 @@ class CrossAssetFeatures:
532
529
  def extract_cross_asset_features(
533
530
  self, primary_df: pd.DataFrame, market_data: Dict[str, pd.DataFrame]
534
531
  ) -> pd.DataFrame:
535
- """Extract features based on relationships with other assets"""
532
+ """Extract features based on relationships with other assets."""
536
533
  df = primary_df.copy()
537
534
 
538
535
  # Correlation with market indices
@@ -554,7 +551,7 @@ class CrossAssetFeatures:
554
551
  covariance = np.cov(stock_ret, market_ret)[0][1]
555
552
  market_variance = np.var(market_ret)
556
553
  return covariance / market_variance if market_variance != 0 else 1.0
557
- except:
554
+ except Exception:
558
555
  return 1.0
559
556
 
560
557
  rolling_beta = pd.Series(index=df.index, dtype=float)
@@ -1,4 +1,4 @@
1
- """Test script for feature engineering system"""
1
+ """Test script for feature engineering system."""
2
2
 
3
3
  import os
4
4
  import sys
@@ -17,7 +17,7 @@ logger = logging.getLogger(__name__)
17
17
 
18
18
 
19
19
  def generate_mock_trading_data(n_records: int = 100) -> pd.DataFrame:
20
- """Generate mock politician trading data"""
20
+ """Generate mock politician trading data."""
21
21
  np.random.seed(42)
22
22
 
23
23
  politicians = ["Nancy Pelosi", "Mitch McConnell", "Chuck Schumer", "Kevin McCarthy"]
@@ -36,7 +36,7 @@ def generate_mock_trading_data(n_records: int = 100) -> pd.DataFrame:
36
36
  records = []
37
37
  start_date = datetime.now() - timedelta(days=365)
38
38
 
39
- for i in range(n_records):
39
+ for _i in range(n_records):
40
40
  days_ago = np.random.randint(0, 365)
41
41
  trade_date = start_date + timedelta(days=days_ago)
42
42
 
@@ -60,7 +60,7 @@ def generate_mock_trading_data(n_records: int = 100) -> pd.DataFrame:
60
60
 
61
61
 
62
62
  def generate_mock_stock_data(tickers: list, days: int = 365) -> pd.DataFrame:
63
- """Generate mock stock price data"""
63
+ """Generate mock stock price data."""
64
64
  np.random.seed(42)
65
65
 
66
66
  stock_data = []
@@ -99,7 +99,7 @@ def generate_mock_stock_data(tickers: list, days: int = 365) -> pd.DataFrame:
99
99
 
100
100
 
101
101
  def test_stock_features():
102
- """Test stock feature extraction"""
102
+ """Test stock feature extraction."""
103
103
  logger.info("Testing stock features...")
104
104
 
105
105
  from stock_features import StockRecommendationFeatures, TechnicalIndicatorFeatures
@@ -135,7 +135,7 @@ def test_stock_features():
135
135
 
136
136
 
137
137
  def test_political_features():
138
- """Test political feature extraction"""
138
+ """Test political feature extraction."""
139
139
  logger.info("Testing political features...")
140
140
 
141
141
  from political_features import PoliticalInfluenceFeatures
@@ -171,7 +171,7 @@ def test_political_features():
171
171
 
172
172
 
173
173
  def test_ensemble_features():
174
- """Test ensemble feature engineering"""
174
+ """Test ensemble feature engineering."""
175
175
  logger.info("Testing ensemble features...")
176
176
 
177
177
  from ensemble_features import EnsembleFeatureBuilder
@@ -207,7 +207,7 @@ def test_ensemble_features():
207
207
 
208
208
 
209
209
  def test_recommendation_engine():
210
- """Test the full recommendation engine"""
210
+ """Test the full recommendation engine."""
211
211
  logger.info("Testing recommendation engine...")
212
212
 
213
213
  from recommendation_engine import RecommendationConfig, StockRecommendationEngine
@@ -257,12 +257,11 @@ def test_recommendation_engine():
257
257
 
258
258
 
259
259
  def test_feature_integration():
260
- """Test integration of all feature components"""
260
+ """Test integration of all feature components."""
261
261
  logger.info("Testing feature integration...")
262
262
 
263
263
  from ensemble_features import EnsembleFeatureBuilder
264
264
  from political_features import PoliticalInfluenceFeatures
265
- from stock_features import StockRecommendationFeatures
266
265
 
267
266
  # Generate test data
268
267
  trading_data = generate_mock_trading_data(30)
@@ -304,7 +303,7 @@ def test_feature_integration():
304
303
 
305
304
 
306
305
  def main():
307
- """Run all feature engineering tests"""
306
+ """Run all feature engineering tests."""
308
307
  logger.info("Starting feature engineering tests...")
309
308
 
310
309
  try:
mcli/ml/logging.py CHANGED
@@ -1,4 +1,4 @@
1
- """Logging configuration for ML system"""
1
+ """Logging configuration for ML system."""
2
2
 
3
3
  import json
4
4
  import logging
@@ -11,7 +11,7 @@ from mcli.ml.config import settings
11
11
 
12
12
 
13
13
  class StructuredFormatter(logging.Formatter):
14
- """JSON structured logging formatter"""
14
+ """JSON structured logging formatter."""
15
15
 
16
16
  def format(self, record):
17
17
  log_obj = {
@@ -34,7 +34,7 @@ class StructuredFormatter(logging.Formatter):
34
34
 
35
35
 
36
36
  def setup_logging():
37
- """Configure logging for the application"""
37
+ """Configure logging for the application."""
38
38
 
39
39
  # Create logs directory
40
40
  log_dir = Path("logs")
@@ -76,5 +76,5 @@ def setup_logging():
76
76
 
77
77
 
78
78
  def get_logger(name: str) -> logging.Logger:
79
- """Get a logger instance"""
79
+ """Get a logger instance."""
80
80
  return logging.getLogger(name)
mcli/ml/mlops/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- """MLOps components for ML pipeline management"""
1
+ """MLOps components for ML pipeline management."""
2
2
 
3
3
  from .experiment_tracker import ExperimentRun, ExperimentTracker, MLflowConfig, ModelRegistry
4
4
  from .model_serving import ModelEndpoint, ModelServer, PredictionService