""" Enhanced ROI calculators and business logic with Monte Carlo simulation """ from typing import Dict, List, Any, Tuple import numpy as np import logging from dataclasses import dataclass from enum import Enum from config.settings import settings logger = logging.getLogger(__name__) class ROIConfidence(Enum): """Confidence levels for ROI predictions""" HIGH = "High" MEDIUM = "Medium" LOW = "Low" @dataclass class ROIScenarioResult: """Result of a single ROI scenario calculation""" scenario_name: str annual_impact: float enterprise_cost: float savings: float roi_multiplier: float roi_percentage: float payback_months: float confidence: ROIConfidence def to_dict(self) -> Dict[str, Any]: """Convert to dictionary""" return { "scenario_name": self.scenario_name, "annual_impact": f"${self.annual_impact:,.0f}", "enterprise_cost": f"${self.enterprise_cost:,.0f}", "savings": f"${self.savings:,.0f}", "roi_multiplier": f"{self.roi_multiplier:.1f}×", "roi_percentage": f"{self.roi_percentage:.0f}%", "payback_months": f"{self.payback_months:.1f}", "confidence": self.confidence.value } class EnhancedROICalculator: """Investor-grade ROI calculator with Monte Carlo simulation""" def __init__(self): self.engineer_hourly_rate = settings.engineer_hourly_rate self.engineer_annual_cost = settings.engineer_annual_cost self.default_savings_rate = settings.default_savings_rate def calculate_comprehensive_roi(self, monthly_incidents: int, avg_impact: float, team_size: int) -> Dict[str, Any]: """ Calculate multi-scenario ROI analysis with Monte Carlo simulation Args: monthly_incidents: Average incidents per month avg_impact: Average revenue impact per incident team_size: Number of engineers Returns: Comprehensive ROI analysis """ logger.info(f"Calculating ROI: incidents={monthly_incidents}, " f"impact=${avg_impact:,}, team={team_size}") # Base scenario (realistic) base = self._calculate_with_monte_carlo( monthly_incidents, avg_impact, team_size, savings_rate_mean=0.82, savings_rate_std=0.05, efficiency_mean=0.85, efficiency_std=0.03 ) # Best case (aggressive adoption) best = self._calculate_with_monte_carlo( monthly_incidents, avg_impact, team_size, savings_rate_mean=0.92, savings_rate_std=0.03, efficiency_mean=0.92, efficiency_std=0.02 ) # Worst case (conservative) worst = self._calculate_with_monte_carlo( monthly_incidents, avg_impact, team_size, savings_rate_mean=0.72, savings_rate_std=0.07, efficiency_mean=0.78, efficiency_std=0.05 ) # Generate recommendation recommendation = self._get_recommendation(base.mean_roi) # Calculate industry comparison comparison = self._get_industry_comparison(base.mean_roi) return { "summary": { "your_annual_impact": f"${base.mean_annual_impact:,.0f}", "potential_savings": f"${base.mean_savings:,.0f}", "enterprise_cost": f"${base.enterprise_cost:,.0f}", "roi_multiplier": f"{base.mean_roi:.1f}×", "payback_months": f"{base.mean_payback:.1f}", "annual_roi_percentage": f"{base.mean_roi_percentage:.0f}%", "monte_carlo_simulations": 1000, "confidence_interval": f"{base.roi_ci[0]:.1f}× - {base.roi_ci[1]:.1f}×" }, "scenarios": { "base_case": { "roi": f"{base.mean_roi:.1f}×", "payback": f"{base.mean_payback:.1f} months", "confidence": base.confidence.value, "ci_low": f"{base.roi_ci[0]:.1f}×", "ci_high": f"{base.roi_ci[1]:.1f}×" }, "best_case": { "roi": f"{best.mean_roi:.1f}×", "payback": f"{best.mean_payback:.1f} months", "confidence": best.confidence.value, "ci_low": f"{best.roi_ci[0]:.1f}×", "ci_high": f"{best.roi_ci[1]:.1f}×" }, "worst_case": { "roi": f"{worst.mean_roi:.1f}×", "payback": f"{worst.mean_payback:.1f} months", "confidence": worst.confidence.value, "ci_low": f"{worst.roi_ci[0]:.1f}×", "ci_high": f"{worst.roi_ci[1]:.1f}×" } }, "comparison": comparison, "recommendation": recommendation, "monte_carlo_stats": { "base_roi_std": f"{base.roi_std:.2f}", "best_roi_std": f"{best.roi_std:.2f}", "worst_roi_std": f"{worst.roi_std:.2f}" } } def _calculate_with_monte_carlo(self, monthly_incidents: int, avg_impact: float, team_size: int, savings_rate_mean: float, savings_rate_std: float, efficiency_mean: float, efficiency_std: float) -> 'MonteCarloResult': """ Run Monte Carlo simulation for ROI calculation Returns: MonteCarloResult with statistics """ np.random.seed(42) # For reproducible results n_simulations = 1000 # Generate random samples with normal distribution savings_rates = np.random.normal( savings_rate_mean, savings_rate_std, n_simulations ) efficiencies = np.random.normal( efficiency_mean, efficiency_std, n_simulations ) # Clip to reasonable bounds savings_rates = np.clip(savings_rates, 0.5, 0.95) efficiencies = np.clip(efficiencies, 0.5, 0.95) # Calculate for each simulation annual_impacts = monthly_incidents * 12 * avg_impact enterprise_costs = team_size * self.engineer_annual_cost savings_list = [] roi_list = [] roi_percentage_list = [] payback_list = [] for i in range(n_simulations): savings = annual_impacts * savings_rates[i] * efficiencies[i] roi = savings / enterprise_costs if enterprise_costs > 0 else 0 roi_percentage = (roi - 1) * 100 payback = (enterprise_costs / (savings / 12)) if savings > 0 else 0 savings_list.append(savings) roi_list.append(roi) roi_percentage_list.append(roi_percentage) payback_list.append(payback) # Convert to numpy arrays for statistics savings_arr = np.array(savings_list) roi_arr = np.array(roi_list) roi_percentage_arr = np.array(roi_percentage_list) payback_arr = np.array(payback_list) # Calculate statistics mean_savings = np.mean(savings_arr) mean_roi = np.mean(roi_arr) mean_roi_percentage = np.mean(roi_percentage_arr) mean_payback = np.mean(payback_arr) roi_std = np.std(roi_arr) roi_ci = ( np.percentile(roi_arr, 25), np.percentile(roi_arr, 75) ) # Determine confidence level if roi_std / mean_roi < 0.1: # Low relative standard deviation confidence = ROIConfidence.HIGH elif roi_std / mean_roi < 0.2: confidence = ROIConfidence.MEDIUM else: confidence = ROIConfidence.LOW return MonteCarloResult( mean_annual_impact=annual_impacts, enterprise_cost=enterprise_costs, mean_savings=mean_savings, mean_roi=mean_roi, mean_roi_percentage=mean_roi_percentage, mean_payback=mean_payback, roi_std=roi_std, roi_ci=roi_ci, confidence=confidence, n_simulations=n_simulations ) def _get_recommendation(self, roi_multiplier: float) -> Dict[str, str]: """Get recommendation based on ROI""" if roi_multiplier >= 5.0: return { "action": "🚀 Deploy ARF Enterprise", "reason": "Exceptional ROI (>5×) with quick payback", "timeline": "30-day implementation", "expected_value": ">$1M annual savings", "priority": "High", "next_steps": [ "Schedule enterprise demo", "Request custom ROI analysis", "Start 30-day trial" ] } elif roi_multiplier >= 3.0: return { "action": "✅ Implement ARF Enterprise", "reason": "Strong ROI (3-5×) with operational benefits", "timeline": "60-day phased rollout", "expected_value": ">$500K annual savings", "priority": "Medium", "next_steps": [ "Evaluate OSS edition", "Run pilot with 2-3 services", "Measure initial impact" ] } elif roi_multiplier >= 2.0: return { "action": "📊 Evaluate ARF Enterprise", "reason": "Positive ROI (2-3×) with learning benefits", "timeline": "90-day evaluation", "expected_value": ">$250K annual savings", "priority": "Medium-Low", "next_steps": [ "Start with OSS edition", "Document baseline metrics", "Identify pilot use cases" ] } else: return { "action": "🆓 Start with ARF OSS", "reason": "Validate value before Enterprise investment", "timeline": "14-day evaluation", "expected_value": "Operational insights + clear upgrade path", "priority": "Low", "next_steps": [ "Install OSS edition", "Analyze 2-3 incident scenarios", "Document potential improvements" ] } def _get_percentile(self, roi_multiplier: float) -> int: """Calculate percentile vs industry benchmarks""" benchmarks = [ (10.0, 5), # Top 5% at 10× ROI (8.0, 10), # Top 10% at 8× ROI (5.0, 25), # Top 25% at 5× ROI (3.0, 50), # Top 50% at 3× ROI (2.0, 75), # Top 75% at 2× ROI (1.0, 90) # Top 90% at 1× ROI ] for threshold, percentile in benchmarks: if roi_multiplier >= threshold: return percentile return 95 # Bottom 5% def _get_industry_comparison(self, roi_multiplier: float) -> Dict[str, str]: """Get industry comparison metrics""" percentile = self._get_percentile(roi_multiplier) return { "industry_average": "5.2× ROI", "top_performers": "8.7× ROI", "your_position": f"Top {percentile}%", "benchmark_analysis": "Above industry average" if roi_multiplier >= 5.2 else "Below industry average", "improvement_potential": f"{max(0, 8.7 - roi_multiplier):.1f}× additional ROI possible" } def calculate_simple_roi(self, monthly_incidents: int, avg_impact: float, team_size: int) -> Dict[str, Any]: """ Simple ROI calculation without Monte Carlo For backward compatibility """ result = self._calculate_with_monte_carlo( monthly_incidents, avg_impact, team_size, savings_rate_mean=self.default_savings_rate, savings_rate_std=0.05, efficiency_mean=0.85, efficiency_std=0.03 ) return { "annual_impact": result.mean_annual_impact, "enterprise_cost": result.enterprise_cost, "savings": result.mean_savings, "roi_multiplier": result.mean_roi, "roi_percentage": result.mean_roi_percentage, "payback_months": result.mean_payback } @dataclass class MonteCarloResult: """Result of Monte Carlo simulation""" mean_annual_impact: float enterprise_cost: float mean_savings: float mean_roi: float mean_roi_percentage: float mean_payback: float roi_std: float roi_ci: Tuple[float, float] confidence: ROIConfidence n_simulations: int