feat(finmodel): financing overlay (кредит 15%) поверх unlevered DCF (epic #1881 PR-5) #1886

Merged
bot-backend merged 1 commit from feat/finmodel-financing into main 2026-06-23 20:23:48 +00:00
Collaborator

Summary

Эпик #1881 PR-5 — финансирование (кредит/проектное 15%) как overlay поверх DCF. Последняя крупная статья Excel-эталона («поток по финдеятельности» + «задолженность по кредиту»).

Дизайн

  • Unlevered (project) NPV/IRR — остаётся HEADLINE, НЕ меняется (интринсивная доходность; инвариант Σ cashflow == net_profit сохранён).
  • Финансирование — ДОПОЛНИТЕЛЬНЫЙ overlay: _compute_financing(operating_cf, annual_rate) читает готовый unlevered cashflow READ-ONLY, не пересобирает. Кредитная линия покрывает кассовый разрыв, проценты капитализируются (compound), _CREDIT_RATE_ANNUAL=15% отдельно от ставки дисконтирования (разная семантика).
  • MVP: только агрегатыpeak_debt_rub / total_interest_rub / net_profit_after_financing_rub. БЕЗ levered IRR (хрупко на хардкод-100%-долге — отдельный PR). БЕЗ debt_schedule в схему.

Honesty

financing_is_simplified=True. Caveat: проценты — реальная стоимость (net после < net до); 100% покрытие разрыва (нет equity/LTC); compound; эскроу не моделируется точно; ставка-норматив; unlevered headline не затронут.

Test plan

  • _compute_financing поведенчески выверено code-review: compound (точное значение vs simple), no-mutation входа, repay=min(cf,debt) не уходит в минус, no-gap→0
  • инвариант-регресс Σ unlevered == net_profit прошёл без изменений (overlay чисто additive)
  • монотонность (выше ставка→больше %), net_after<net для проекта с разрывом
  • mypy strict clean; ruff/tsc/lint clean; 9 backend + 3 frontend тестов
  • api-types регенерён авторитетно; deps не тронуты (hand-roll); two-rate separation
  • code-reviewer APPROVE
  • post-deploy: concept/кокпит финмодель-drawer показывает пиковый долг/проценты/прибыль после финанс.

Эпик #1881 — теперь покрыты все крупные статьи Excel-эталона

включая финансирование. Остаётся: levered IRR (опц.), §22 sales-pace, гео-радиус калибровки, расширение зонинг-покрытия для видимости в кокпите, точный НК-НДС.

Refs #1881

🤖 Generated with Claude Code

## Summary Эпик #1881 **PR-5** — финансирование (кредит/проектное 15%) как **overlay** поверх DCF. Последняя крупная статья Excel-эталона («поток по финдеятельности» + «задолженность по кредиту»). ## Дизайн - **Unlevered (project) NPV/IRR — остаётся HEADLINE, НЕ меняется** (интринсивная доходность; инвариант Σ cashflow == net_profit сохранён). - Финансирование — **ДОПОЛНИТЕЛЬНЫЙ overlay**: `_compute_financing(operating_cf, annual_rate)` читает готовый unlevered cashflow READ-ONLY, не пересобирает. Кредитная линия покрывает кассовый разрыв, проценты капитализируются (compound), `_CREDIT_RATE_ANNUAL=15%` **отдельно** от ставки дисконтирования (разная семантика). - **MVP: только агрегаты** — `peak_debt_rub` / `total_interest_rub` / `net_profit_after_financing_rub`. БЕЗ levered IRR (хрупко на хардкод-100%-долге — отдельный PR). БЕЗ debt_schedule в схему. ## Honesty `financing_is_simplified=True`. Caveat: проценты — реальная стоимость (net после < net до); 100% покрытие разрыва (нет equity/LTC); compound; эскроу не моделируется точно; ставка-норматив; unlevered headline не затронут. ## Test plan - [x] `_compute_financing` поведенчески выверено code-review: compound (точное значение vs simple), no-mutation входа, repay=min(cf,debt) не уходит в минус, no-gap→0 - [x] **инвариант-регресс** Σ unlevered == net_profit прошёл без изменений (overlay чисто additive) - [x] монотонность (выше ставка→больше %), net_after<net для проекта с разрывом - [x] mypy strict clean; ruff/tsc/lint clean; 9 backend + 3 frontend тестов - [x] api-types регенерён авторитетно; deps не тронуты (hand-roll); two-rate separation - [x] code-reviewer ✅ APPROVE - [ ] post-deploy: concept/кокпит финмодель-drawer показывает пиковый долг/проценты/прибыль после финанс. ## Эпик #1881 — теперь покрыты все крупные статьи Excel-эталона включая финансирование. Остаётся: levered IRR (опц.), §22 sales-pace, гео-радиус калибровки, расширение зонинг-покрытия для видимости в кокпите, точный НК-НДС. Refs #1881 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bot-backend added 1 commit 2026-06-23 20:13:10 +00:00
feat(finmodel): financing overlay (кредит 15%) поверх unlevered DCF (epic #1881 PR-5)
All checks were successful
CI / frontend-tests (pull_request) Successful in 59s
CI / openapi-codegen-check (pull_request) Successful in 1m53s
CI / backend-tests (pull_request) Successful in 10m1s
CI / changes (pull_request) Successful in 7s
d350d27325
Финансирование как ДОПОЛНИТЕЛЬНЫЙ overlay поверх готового unlevered cashflow:
кредитная линия покрывает накопительный кассовый разрыв, проценты капитализируются
(compound), ставка _CREDIT_RATE_ANNUAL=15% (норматив, ОТДЕЛЬНО от ставки
дисконтирования — разная семантика: стоимость долга vs требуемая доходность).

Backend (financial.py):
- _compute_financing(operating_cf, annual_rate) — чистая (READ-ONLY вход, не
  мутирует): процент на остаток на начало месяца ДО движений → капитализация;
  draw=-cf при оттоке, repay=min(cf,debt) при притоке (долг не уходит в минус).
  Возвращает peak_debt_rub / total_interest_rub / ending_debt_rub.
- compute_financial: вызов после DCF, net_profit_after_financing = net − interest.
- _build_monthly_cashflow и unlevered NPV/IRR/PBP НЕ ТРОНУТЫ → инвариант
  Σ unlevered cashflow == net_profit сохранён (регресс-тест).
- FinancialModel +6 полей (financing_enabled/annual_rate_used/peak_debt_rub/
  total_interest_rub/net_profit_after_financing_rub/financing_is_simplified).

Frontend: ParcelFinancialEstimate +6 полей; adaptFinanceDrawer + concept-каскад
показывают пиковый долг/проценты/чистую прибыль после финанс. (когда enabled).

MVP: только агрегаты, БЕЗ levered IRR (хрупко на хардкод-100%-долге — отдельный
PR). HEAVY caveat: проценты — реальная стоимость (net после < net до); 100%
покрытие разрыва (нет equity/LTC); compound; эскроу не моделируется; unlevered
headline не затронут. financing_is_simplified=True флаг.

mypy strict clean, +9 backend + 3 frontend тестов (compound точное значение,
no-mutation, инвариант-регресс, монотонность, net_after<net), api-types
регенерён авторитетно, deps не тронуты (hand-roll).

Refs #1881
bot-backend merged commit f0b689318e into main 2026-06-23 20:23:48 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1886
No description provided.