summaryrefslogtreecommitdiff
path: root/backend/tests/test_dcf_advanced.py
diff options
context:
space:
mode:
Diffstat (limited to 'backend/tests/test_dcf_advanced.py')
-rw-r--r--backend/tests/test_dcf_advanced.py148
1 files changed, 148 insertions, 0 deletions
diff --git a/backend/tests/test_dcf_advanced.py b/backend/tests/test_dcf_advanced.py
new file mode 100644
index 0000000..20f6921
--- /dev/null
+++ b/backend/tests/test_dcf_advanced.py
@@ -0,0 +1,148 @@
+import pytest
+
+from app.services.data_service import _run_dcf_explicit_build
+
+
+_APPROX = pytest.approx
+
+
+def test_run_dcf_explicit_build_two_year_reference_scenario() -> None:
+ # Given
+ base_revenue = 1_000.0
+
+ # When
+ result = _run_dcf_explicit_build(
+ base_revenue=base_revenue,
+ revenue_growth=[0.10, 0.05],
+ ebitda_margin=[0.30, 0.32],
+ dna_pct_revenue=[0.05, 0.05],
+ capex_pct_revenue=[0.07, 0.07],
+ nwc_chg_pct_delta_rev=[0.02, 0.02],
+ tax_rate=[0.25, 0.25],
+ wacc=0.10,
+ terminal_growth=0.03,
+ shares_outstanding=100.0,
+ total_debt=50.0,
+ cash=10.0,
+ preferred_equity=5.0,
+ minority_interest=3.0,
+ projection_years=2,
+ )
+
+ # Then
+ assert result["available"] is True
+ assert result["base_fcf"] == _APPROX(184.25)
+ assert result["fcf_pv_sum"] == _APPROX(357.42928814344134)
+ assert result["terminal_value_pv"] == _APPROX(2_674.37743224556)
+ assert result["enterprise_value"] == _APPROX(3_031.8067203890014)
+ assert result["net_debt"] == 40.0
+ assert result["equity_value"] == _APPROX(2_983.8067203890014)
+ assert result["intrinsic_value_per_share"] == _APPROX(29.838067203890013)
+ assert result["wacc"] == 0.10
+ assert result["terminal_growth"] == 0.03
+ assert result["projection_years"] == 2
+
+
+def test_run_dcf_explicit_build_terminal_growth_at_wacc_returns_error() -> None:
+ # Given / When
+ result = _run_dcf_explicit_build(
+ base_revenue=1_000.0,
+ revenue_growth=[0.05],
+ ebitda_margin=[0.30],
+ dna_pct_revenue=[0.05],
+ capex_pct_revenue=[0.07],
+ nwc_chg_pct_delta_rev=[0.02],
+ tax_rate=[0.25],
+ wacc=0.10,
+ terminal_growth=0.10,
+ shares_outstanding=100.0,
+ total_debt=0.0,
+ cash=0.0,
+ preferred_equity=0.0,
+ minority_interest=0.0,
+ projection_years=1,
+ )
+
+ # Then
+ assert result["available"] is True
+ assert "Terminal growth" in result["error"]
+ assert "intrinsic_value_per_share" not in result
+
+
+def test_run_dcf_explicit_build_zero_wacc_returns_error() -> None:
+ # Given / When
+ result = _run_dcf_explicit_build(
+ base_revenue=1_000.0,
+ revenue_growth=[0.05],
+ ebitda_margin=[0.30],
+ dna_pct_revenue=[0.05],
+ capex_pct_revenue=[0.07],
+ nwc_chg_pct_delta_rev=[0.02],
+ tax_rate=[0.25],
+ wacc=0.0,
+ terminal_growth=0.03,
+ shares_outstanding=100.0,
+ total_debt=0.0,
+ cash=0.0,
+ preferred_equity=0.0,
+ minority_interest=0.0,
+ projection_years=1,
+ )
+
+ # Then
+ assert result["available"] is True
+ assert "WACC" in result["error"]
+ assert "intrinsic_value_per_share" not in result
+
+
+@pytest.mark.parametrize("shares_outstanding", [0.0, -1.0])
+def test_run_dcf_explicit_build_nonpositive_shares_return_error(shares_outstanding: float) -> None:
+ # Given / When
+ result = _run_dcf_explicit_build(
+ base_revenue=1_000.0,
+ revenue_growth=[0.05],
+ ebitda_margin=[0.30],
+ dna_pct_revenue=[0.05],
+ capex_pct_revenue=[0.07],
+ nwc_chg_pct_delta_rev=[0.02],
+ tax_rate=[0.25],
+ wacc=0.10,
+ terminal_growth=0.03,
+ shares_outstanding=shares_outstanding,
+ total_debt=0.0,
+ cash=0.0,
+ preferred_equity=0.0,
+ minority_interest=0.0,
+ projection_years=1,
+ )
+
+ # Then
+ assert result["available"] is True
+ assert "Shares outstanding" in result["error"]
+ assert "intrinsic_value_per_share" not in result
+
+
+def test_run_dcf_explicit_build_zero_base_revenue_returns_error() -> None:
+ # Given / When
+ result = _run_dcf_explicit_build(
+ base_revenue=0.0,
+ revenue_growth=[0.05],
+ ebitda_margin=[0.30],
+ dna_pct_revenue=[0.05],
+ capex_pct_revenue=[0.07],
+ nwc_chg_pct_delta_rev=[0.02],
+ tax_rate=[0.25],
+ wacc=0.10,
+ terminal_growth=0.03,
+ shares_outstanding=100.0,
+ total_debt=0.0,
+ cash=0.0,
+ preferred_equity=0.0,
+ minority_interest=0.0,
+ projection_years=1,
+ )
+
+ # Then
+ assert result["available"] is True
+ assert "Base revenue" in result["error"]
+ assert "intrinsic_value_per_share" not in result