petter2025's picture
Update core/calculators.py
115eb63 verified
raw
history blame
13.2 kB
"""
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