Вопрос:
Should we invest in the initiative and what economic value does it create?/
Стоит ли инвестировать в инициативу и какой экономический эффект она создает?
Краткое содержание:
Оценка инвестиционной привлекательности инициативы внедрения системы управления запасами.
Анализ текущей модели (AS-IS) и целевой (TO-BE).
Расчет влияния инициативы на:
операционные затраты
уровень запасов
EBITDA
денежные потоки
оборотный капитал
Использование моделей оптимизации запасов (включая EOQ) как инструмента генерации экономического эффекта.
Формирование инвестиционного кейса и обоснование решения на основе:
денежного эффекта
срока окупаемости
экономической целесообразности
Методики:
Inventory Optimization (включая EOQ)
Total Cost of Inventory
Working Capital Analysis
AS-IS vs TO-BE Modeling
Unit Economics (запасы)
Investment Evaluation (NPV, Payback, IRR)
Automation via Apps Script
Результат:
✔ Модель AS-IS vs TO-BE по управлению запасами
✔ Расчет экономического эффекта: снижение затрат, высвобождение оборотного капитала
✔ Денежные потоки инициативы
✔ Расчет NPV / Payback
✔ Финансовое обоснование инициативы
✔ Управленческое решение: инвестировать / не инвестировать
✔ Прототип инструмента (Apps Script)
Инвестиционный анализ цифрового проекта — это процесс оценки экономической целесообразности внедрения инициативы на основе ее влияния на денежные потоки, прибыль и стоимость бизнеса. Цифровая инициатива рассматривается не как ИТ-решение, а как инвестиция, которая должна создавать измеримый финансовый результат.
Основная задача анализа — ответить на вопрос: стоит ли инвестировать в инициативу и окупаются ли вложенные средства. Для этого оценивается, какие изменения происходят в бизнесе после внедрения решения и как они трансформируются в денежные потоки.
Задача:
Рассчитать экономический эффект от внедрения системы управления запасами, построить финансовую модель и принять инвестиционное решение
Используя данные кейса, определите:
текущий уровень запасов
количество заказов
совокупные затраты на запасы:
▪ хранение
▪ организация заказов
Рассчитайте:
EOQ (как инструмент оптимизации)
точку заказа (ROP)
Пересчитайте показатели после внедрения системы:
▪ новый уровень запасов
▪ новая частота заказов
▪ новые затраты
Рассчитайте:
▪ снижение операционных затрат
▪ высвобождение оборотного капитала
Рассчитайте:
▪ годовой денежный эффект
▪ инвестиции (CAPEX)
▪ денежные потоки по годам
Средневзвешенная стоимость капитала / Weighted Average Cost of Capital (WACC)
Свободный денежный поток / Free Cash Flow (FCF)
Чистая приведенная стоимость / Net Present Value (NPV)
Индекс рентабельности инвестиций / Profitability Index (PI)
Дисконтированный срок окупаемости / Discounted Payback Period (DPP)
Срок окупаемости / Payback Period (PP)
Внутренняя норма доходности / Internal Rate of Return (IRR)
Рентабельность инвестиций / Return on Investment (ROI)
Ответьте:
▪ стоит ли инвестировать в систему управления запасами?
▪ за счет чего формируется эффект?
▪ какие ключевые риски?
Реализуйте:
▪ ввод параметров
▪ автоматический расчет EOQ и ROP
▪ расчет экономического эффекта
▪ Финансовая модель (Google Sheets)
▪ Расчет AS-IS vs TO-BE
▪ Денежные потоки проекта
▪ Расчет PP / NPV
▪ Краткое обоснование решения
Вы оцениваете не EOQ, а инвестиционное решение
Шаг 1 Оценка экономического эффекта
Анализ начинается с сравнения текущего состояния (AS-IS) и целевой модели (TO-BE).
EBITDA — операционная прибыль ΔWC — изменение оборотного капитала CAPEX — инвестиции
Шаг 2 Свободный денежный поток (Free Cash Flow (FCF))
Далее эффект переводится в денежные потоки, отражающие реальное движение денег. Должен быть положительным и устойчивым
EBITDA — операционная прибыль ΔWC — изменение оборотного капитала CAPEX — инвестиции
Шаг 3 Ставка дисконтирования (Weighted Average Cost of Capital - WACC)
Средняя стоимость привлеченного капитала компании с учетом доли собственного и заемного финансирования.
E — собственный капитал D — заемный капитал V=E+D — общий капитал Re — стоимость собственного капитала Rd — стоимость долга Tax— налог на прибыль
Шаг 4 Чистая приведенная стоимость/ Net Present Value (NPV)
Чистая приведенная стоимость (NPV) учитывает временную стоимость денег и показывает, создает ли проект дополнительную ценность. NPV > 0 → проект принимается, NPV < 0 → проект отклоняется.
CFt — денежный поток , r (WACC)— ставка дисконтирования
Шаг 5 Индекс рентабельности инвестиций/Profitability Index (PI)
Отношение приведенных доходов к инвестициям. PI>1 → проект создает стоимость PI=1 → проект на границе эффективности PI<1 → проект невыгоден
NPV — чистая приведенная стоимость проекта
Шаг 6 Внутренняя норма доходности/ Internal Rate of Return (IRR)
Внутренняя норма доходности (IRR) показывает фактическую доходность проекта с учетом всех будущих денежных потоков. IRR>WACC→ проект принимается
r1 — ставка дисконтирования, при которой NPV1>0, r2 — ставка дисконтирования, при которой NPV2<0
Шаг 7 Дисконтированный срок окупаемости/Discounted Payback Period (DPP)
Срок возврата инвестиций с учетом дисконтирования. Чем меньше, тем лучше
CFt — денежный поток , r (WACC)— ставка дисконтирования
Шаг 8 Рентабельность инвестиций/ Return on Investment (ROI)
Относительная прибыль от инвестиций. Чем выше, тем лучше. ROI>0 → проект прибыльный, ROI=0 → точка безубыточности, ROI<0 → проект убыточный
Net Profit — чистая прибыль от проекта, Investment — объем инвестиций
Создай веб-приложение на Google Apps Script (Web App) для оценки инвестиционного проекта уровня CFO.
Требования:
Архитектура:
Backend: Google Apps Script (Code.gs)
Frontend: HTML/CSS/JS (index.html)
Визуализация: Chart.js
Входные данные:
Срок проекта (years)
Инвестиции (CAPEX)
Норма амортизации
Налог на прибыль
Equity (сумма и ставка)
Debt (сумма и ставка)
Срок кредита (аннуитет)
EBITDA по годам (массив)
Расчеты:
Амортизация = Investment × rate
EBIT = EBITDA – DA
NOPAT = EBIT × (1 – tax)
FCFF = NOPAT + DA
Аннуитетный платеж, проценты и тело кредита
WACC = We × Re + Wd × Rd
DCF = FCFF / (1+WACC)^t
KPI:
NPV
IRR (итерационно)
PI
Payback Period
Дополнительно:
3 сценария: Base, Optimistic (+20%), Pessimistic (-20%)
Sensitivity analysis: изменение EBITDA от -30% до +30%
UI:
Заголовок: "Оценка инвестиционного проекта"
Layout: слева ввод (sidebar), справа dashboard
KPI в виде карточек
Подсветка KPI:
зелёный если NPV>0 и IRR>WACC
красный если нет
Графики:
Cash Flow
Sensitivity (NPV)
Подписи осей округлять до 1 знака
Decision блок:
Сравнение:
NPV > 0
IRR > WACC
PI > 1
Payback ≤ срок проекта
Текстовый вывод: принять / отклонить + краткое объяснение
PDF:
Кнопка "Скачать отчет"
Отчет содержит:
входные данные
KPI
решение
интерпретацию
Вывод:
Дай полный код двух файлов:
Code.gs
index.html
Код должен быть готов к копированию и запуску без доработок.
function doGet() {
return HtmlService.createHtmlOutputFromFile('index')
.setTitle('Investment Analysis PRO');
}
// ===== АННУИТЕТ =====
function calcAnnuity(P, r, n) {
return P * (r * Math.pow(1 + r, n)) / (Math.pow(1 + r, n) - 1);
}
// ===== IRR =====
function calculateIRR(cashflows) {
let guess = 0.1;
for (let i = 0; i < 100; i++) {
let npv = 0;
let dnpv = 0;
for (let t = 0; t < cashflows.length; t++) {
npv += cashflows[t] / Math.pow(1 + guess, t);
dnpv -= t * cashflows[t] / Math.pow(1 + guess, t + 1);
}
let newGuess = guess - npv / dnpv;
if (Math.abs(newGuess - guess) < 0.00001) return newGuess;
guess = newGuess;
}
return guess;
}
// ===== CORE MODEL =====
function calculateScenario(input, ebitdaArray) {
const n = input.years;
const tax = input.tax;
const investment = input.investment;
const dep = investment * input.depRate;
const debt = input.debt;
const debtRate = input.debtRate;
const equity = input.equity;
const equityRate = input.equityRate;
const total = debt + equity;
const wacc = (equity/total)*equityRate + (debt/total)*debtRate;
let loanBalance = debt;
const annuity = calcAnnuity(debt, debtRate, input.loanYears);
let cashflows = [-investment];
let fcff = [];
for (let t = 1; t <= n; t++) {
const ebitda = ebitdaArray[t-1];
const interest = loanBalance * debtRate;
const principal = annuity - interest;
loanBalance -= principal;
const ebit = ebitda - dep;
const nopat = ebit * (1 - tax);
const fcff_t = nopat + dep;
fcff.push(fcff_t);
cashflows.push(fcff_t);
}
// NPV
let npv = 0;
let dcf = [];
for (let t = 0; t < cashflows.length; t++) {
const disc = cashflows[t] / Math.pow(1 + wacc, t);
dcf.push(disc);
npv += disc;
}
const irr = calculateIRR(cashflows);
// PI
let pvPositive = 0;
for (let i = 1; i < dcf.length; i++) {
pvPositive += dcf[i];
}
const pi = pvPositive / Math.abs(dcf[0]);
// Payback
let cumulative = 0;
let payback = null;
for (let i = 0; i < cashflows.length; i++) {
cumulative += cashflows[i];
if (cumulative >= 0 && payback === null) {
payback = i;
}
}
return {
npv, irr, wacc, pi, payback,
fcff, dcf,
decision: (npv > 0 && irr > wacc) ? "ПРОЕКТ ПРИНЯТ" : "ПРОЕКТ ОТКЛОНЕН"
};
}
// ===== MULTI SCENARIO =====
function runAllScenarios(input) {
const base = input.ebitda;
const optimistic = base.map(v => v * 1.2);
const pessimistic = base.map(v => v * 0.8);
return {
base: calculateScenario(input, base),
optimistic: calculateScenario(input, optimistic),
pessimistic: calculateScenario(input, pessimistic)
};
}
// ===== SENSITIVITY =====
function sensitivityAnalysis(input) {
let results = [];
for (let change = -0.3; change <= 0.3; change += 0.1) {
const adj = input.ebitda.map(v => v * (1 + change));
const res = calculateScenario(input, adj);
results.push({
change: change,
npv: res.npv
});
}
return results;
}
// ===== AI =====
function generateInsights(result) {
let text = "";
text += result.npv > 0
? "Проект создает стоимость. "
: "Проект уничтожает стоимость. ";
text += result.irr > result.wacc
? "Доходность выше стоимости капитала. "
: "Доходность ниже стоимости капитала. ";
text += result.npv < 10000
? "Высокая чувствительность к рискам."
: "Достаточный запас устойчивости.";
return text;
}
// ===== PDF =====
function generatePDF(input, result) {
const doc = DocumentApp.create('Investment Report');
const body = doc.getBody();
body.appendParagraph("ИНВЕСТИЦИОННЫЙ ОТЧЕТ")
.setHeading(DocumentApp.ParagraphHeading.HEADING1);
body.appendParagraph("Инвестиции: " + input.investment);
body.appendParagraph("Срок: " + input.years + " лет");
body.appendParagraph("NPV: " + result.npv.toFixed(0));
body.appendParagraph("IRR: " + (result.irr * 100).toFixed(2) + "%");
body.appendParagraph("WACC: " + (result.wacc * 100).toFixed(2) + "%");
body.appendParagraph("Решение: " + result.decision);
body.appendParagraph(generateInsights(result));
doc.saveAndClose();
return DriveApp.getFileById(doc.getId()).getUrl();
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
body {
margin: 0;
font-family: Inter, Arial;
background: #0f172a;
color: #e2e8f0;
}
.header {
background: linear-gradient(135deg, #1e3a8a, #06b6d4);
padding: 20px;
text-align: center;
font-size: 26px;
font-weight: bold;
color: white;
}
.container {
display: grid;
grid-template-columns: 320px 1fr;
height: calc(100vh - 80px);
}
.sidebar {
background: #020617;
padding: 20px;
border-right: 1px solid #1e293b;
overflow-y: auto;
}
input {
width: 100%;
padding: 8px;
margin: 5px 0 12px;
border-radius: 6px;
border: none;
background: #1e293b;
color: white;
}
button {
width: 100%;
padding: 10px;
margin-top: 10px;
border-radius: 8px;
border: none;
background: linear-gradient(135deg, #3b82f6, #06b6d4);
color: white;
font-weight: bold;
cursor: pointer;
}
.main {
padding: 20px;
overflow-y: auto;
}
.kpi-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 15px;
margin-bottom: 20px;
}
.kpi {
padding: 15px;
border-radius: 10px;
text-align: center;
background: #1e293b;
}
.kpi.green { background: #064e3b; }
.kpi.red { background: #7f1d1d; }
.kpi h3 {
margin: 0;
font-size: 13px;
color: #94a3b8;
}
.kpi p {
font-size: 20px;
margin: 5px 0 0;
font-weight: bold;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.card {
background: #1e293b;
padding: 15px;
border-radius: 12px;
}
.decision {
margin-top: 20px;
padding: 15px;
border-radius: 10px;
font-size: 18px;
text-align: center;
background: #022c22;
}
.analysis {
margin-top: 20px;
padding: 15px;
border-radius: 10px;
background: #312e81;
font-size: 14px;
}
</style>
</head>
<body>
<div class="header">
📊 Оценка инвестиционного проекта
</div>
<div class="container">
<!-- SIDEBAR -->
<div class="sidebar">
<b>Параметры</b>
Срок
<input id="years" value="3">
Инвестиции
<input id="investment" value="273600">
Налог
<input id="tax" value="0.2">
Амортизация
<input id="depRate" value="0.05">
<b>Финансирование</b>
Equity
<input id="equity" value="200000">
Equity %
<input id="equityRate" value="0.25">
Debt
<input id="debt" value="73600">
Debt %
<input id="debtRate" value="0.07">
Срок кредита
<input id="loanYears" value="3">
<b>EBITDA</b>
<input id="e1" value="80000">
<input id="e2" value="160000">
<input id="e3" value="280000">
<button onclick="run()">Рассчитать</button>
<button onclick="downloadPDF()">PDF отчет</button>
</div>
<!-- MAIN -->
<div class="main">
<!-- KPI -->
<div class="kpi-grid">
<div id="kpi-npv" class="kpi"><h3>NPV</h3><p id="npv">-</p></div>
<div id="kpi-irr" class="kpi"><h3>IRR</h3><p id="irr">-</p></div>
<div id="kpi-wacc" class="kpi"><h3>WACC</h3><p id="wacc">-</p></div>
<div class="kpi"><h3>PI</h3><p id="pi">-</p></div>
<div class="kpi"><h3>Payback</h3><p id="payback">-</p></div>
</div>
<!-- GRAPHS -->
<div class="grid">
<div class="card">
<h3>Cash Flow</h3>
<canvas id="cfChart"></canvas>
</div>
<div class="card">
<h3>NPV Sensitivity</h3>
<canvas id="npvChart"></canvas>
</div>
</div>
<!-- DECISION -->
<div id="decision" class="decision"></div>
<!-- ANALYSIS -->
<div id="analysis" class="analysis"></div>
</div>
</div>
<script>
let lastInput, lastResult;
function getInput(){
return {
years: +years.value,
investment: +investment.value,
tax: +tax.value,
depRate: +depRate.value,
equity: +equity.value,
equityRate: +equityRate.value,
debt: +debt.value,
debtRate: +debtRate.value,
loanYears: +loanYears.value,
ebitda: [+e1.value, +e2.value, +e3.value]
};
}
function run(){
const input = getInput();
lastInput = input;
google.script.run.withSuccessHandler(function(res){
const r = res.base;
lastResult = r;
npv.innerText = r.npv.toFixed(0);
irr.innerText = (r.irr*100).toFixed(1) + "%";
wacc.innerText = (r.wacc*100).toFixed(1) + "%";
pi.innerText = r.pi.toFixed(2);
payback.innerText = r.payback + " лет";
// KPI coloring
document.getElementById("kpi-npv").className = "kpi " + (r.npv > 0 ? "green" : "red");
document.getElementById("kpi-irr").className = "kpi " + (r.irr > r.wacc ? "green" : "red");
decision.innerText = r.decision;
// ДЕТАЛЬНЫЙ ВЫВОД
analysis.innerHTML = `
NPV ${r.npv > 0 ? ">" : "<"} 0 → ${r.npv > 0 ? "создание стоимости" : "уничтожение стоимости"}<br>
IRR ${(r.irr*100).toFixed(1)}% vs WACC ${(r.wacc*100).toFixed(1)}% → ${r.irr > r.wacc ? "эффективен" : "неэффективен"}<br>
PI ${r.pi.toFixed(2)} → ${r.pi > 1 ? "привлекателен" : "непривлекателен"}<br>
Payback: ${r.payback} лет → ${r.payback <= r.years ? "приемлемый" : "долгий"}
`;
new Chart(cfChart, {
type: 'bar',
data: {
labels: ['1','2','3'],
datasets: [{ label: 'FCFF', data: r.fcff }]
}
});
}).runAllScenarios(input);
google.script.run.withSuccessHandler(function(data){
new Chart(npvChart, {
type: 'line',
data: {
labels: data.map(d => (d.change*100).toFixed(1)+'%'),
datasets: [{
label: 'NPV',
data: data.map(d => Number(d.npv.toFixed(1)))
}]
}
});
}).sensitivityAnalysis(input);
}
function downloadPDF(){
google.script.run.withSuccessHandler(function(url){
window.open(url);
}).generatePDF(lastInput, lastResult);
}
</script>
</body>
</html>
После завершения командной работы каждый участник обязан заполнить форму оценки индивидуального вклада. Оценка закрывается преподавателем после урока.