from copy import deepcopy from cashflow_model import FinancialModel, ForecastScenario from engine.forecast import ForecastService class ScenarioError(Exception): pass DEFAULT_SCENARIOS = { "baseline": ForecastScenario( name="baseline", income_multiplier=1.0, expense_multiplier=1.0, growth_multiplier=1.0, description="Базовый сценарий без изменений", ), "optimistic": ForecastScenario( name="optimistic", income_multiplier=1.15, expense_multiplier=0.95, growth_multiplier=1.2, description="Оптимистичный: доход +15%, расход -5%, рост активов +20%", ), "pessimistic": ForecastScenario( name="pessimistic", income_multiplier=0.85, expense_multiplier=1.1, growth_multiplier=0.8, description="Пессимистичный: доход -15%, расход +10%, рост активов -20%", ), } class ScenarioService: def __init__(self, model: FinancialModel): self.model = deepcopy(model) def apply(self, scenario: ForecastScenario, months: int = 12) -> dict: model = deepcopy(self.model) for t in model.transactions: if t.amount > 0: t.amount *= scenario.income_multiplier else: t.amount *= scenario.expense_multiplier for r in model.recurring: if r.category == "income": r.amount *= scenario.income_multiplier else: r.amount *= scenario.expense_multiplier for a in model.assets: a.growth_rate *= scenario.growth_multiplier service = ForecastService(model) result = service.summary(months) result["scenario"] = scenario.name result["scenario_description"] = scenario.description return result def compare(self, months: int = 12) -> dict: results = {} for name, scenario in DEFAULT_SCENARIOS.items(): results[name] = self.apply(scenario, months) return results def what_if( self, income_mult: float = 1.0, expense_mult: float = 1.0, growth_mult: float = 1.0, months: int = 12, ) -> dict: scenario = ForecastScenario( name="what-if", income_multiplier=income_mult, expense_multiplier=expense_mult, growth_multiplier=growth_mult, description=( f"What-if: income x{income_mult}, " f"expense x{expense_mult}, growth x{growth_mult}" ), ) return self.apply(scenario, months)