Приближенный расчет внутренней нормы доходности (IRR) на C

CBeginner
Практиковаться сейчас

Введение

В этом лабораторном практикуме мы изучим, как приближенно вычислить внутреннюю норму доходности (IRR) с помощью программы на языке C. Мы начнём с чтения потоков денежных средств, которые представляют инвестиции или полученные средства в различные временные периоды инвестиции. Затем мы воспользуемся итерационным подходом для поиска ставки, при которой чистая приведенная стоимость (NPV) приблизительно равна нулю, что даёт нам оценку IRR. Наконец, мы выведем рассчитанную IRR. Лабораторный практикум охватывает ключевые концепции финансовой математики и демонстрирует их реализацию на языке программирования C.

Чтение потоков денежных средств

В этом шаге мы научимся читать и хранить потоки денежных средств для расчета внутренней нормы доходности (IRR) в программе на языке C. Потоки денежных средств представляют собой инвестиции или полученные средства в различные временные периоды инвестиции.

Сначала создадим файл на языке C для реализации функциональности чтения потоков денежных средств:

cd ~/project
nano irr_calculation.c

Теперь напишем начальный код для чтения потоков денежных средств:

#include <stdio.h>
#define MAX_CASH_FLOWS 10

int main() {
    double cash_flows[MAX_CASH_FLOWS];
    int num_cash_flows;

    printf("Enter the number of cash flows (max %d): ", MAX_CASH_FLOWS);
    scanf("%d", &num_cash_flows);

    printf("Enter cash flows (negative for investments, positive for returns):\n");
    for (int i = 0; i < num_cash_flows; i++) {
        printf("Cash flow %d: ", i);
        scanf("%lf", &cash_flows[i]);
    }

    // Вывод введенных потоков денежных средств для проверки
    printf("\nEntered Cash Flows:\n");
    for (int i = 0; i < num_cash_flows; i++) {
        printf("Cash flow %d: %.2f\n", i, cash_flows[i]);
    }

    return 0;
}

Компилируем и запускаем программу:

gcc irr_calculation.c -o irr_calculation
./irr_calculation

Пример вывода:

Enter the number of cash flows (max 10): 4
Enter cash flows (negative for investments, positive for returns):
Cash flow 0: -1000
Cash flow 1: 300
Cash flow 2: 400
Cash flow 3: 500

Entered Cash Flows:
Cash flow 0: -1000.00
Cash flow 1: 300.00
Cash flow 2: 400.00
Cash flow 3: 500.00
Объяснение
  • Мы определяем максимальное количество потоков денежных средств (MAX_CASH_FLOWS), чтобы предотвратить чрезмерное использование памяти.
  • Программа сначала запрашивает у пользователя количество потоков денежных средств.
  • Затем она запрашивает у пользователя значение каждого потока денежных средств.
  • Отрицательные значения представляют начальные инвестиции.
  • Положительные значения представляют доход или возврат инвестиций.
  • Программа выводит введенные потоки денежных средств для проверки.

Использование итераций для поиска ставки, при которой NPV≈0

В этом шаге мы расширим нашу предыдущую программу для чтения потоков денежных средств, чтобы вычислить внутреннюю норму доходности (IRR) с помощью итерационного численного метода.

Сначала изменим наш существующий файл C:

cd ~/project
nano irr_calculation.c

Теперь реализуем логику расчета NPV и IRR:

#include <stdio.h>
#include <math.h>
#define MAX_CASH_FLOWS 10
#define EPSILON 0.0001

double calculate_npv(double cash_flows[], int num_cash_flows, double rate) {
    double npv = 0.0;
    for (int i = 0; i < num_cash_flows; i++) {
        npv += cash_flows[i] / pow(1 + rate, i);
    }
    return npv;
}

double find_irr(double cash_flows[], int num_cash_flows) {
    double rate_low = -0.9;
    double rate_high = 10.0;
    double rate = 0.1;

    while ((rate_high - rate_low) > EPSILON) {
        double npv = calculate_npv(cash_flows, num_cash_flows, rate);

        if (fabs(npv) < EPSILON) {
            return rate;
        }

        if (npv > 0) {
            rate_low = rate;
        } else {
            rate_high = rate;
        }

        rate = (rate_low + rate_high) / 2.0;
    }

    return rate;
}

int main() {
    double cash_flows[MAX_CASH_FLOWS];
    int num_cash_flows;

    printf("Enter the number of cash flows (max %d): ", MAX_CASH_FLOWS);
    scanf("%d", &num_cash_flows);

    printf("Enter cash flows (negative for investments, positive for returns):\n");
    for (int i = 0; i < num_cash_flows; i++) {
        printf("Cash flow %d: ", i);
        scanf("%lf", &cash_flows[i]);
    }

    double irr = find_irr(cash_flows, num_cash_flows);
    printf("\nApproximate Internal Rate of Return (IRR): %.4f or %.2f%%\n", irr, irr * 100);

    return 0;
}

Компилируем программу с математической библиотекой:

gcc irr_calculation.c -o irr_calculation -lm

Запускаем программу с примерами потоков денежных средств:

./irr_calculation

Пример вывода:

Enter the number of cash flows (max 10): 4
Enter cash flows (negative for investments, positive for returns):
Cash flow 0: -1000
Cash flow 1: 300
Cash flow 2: 400
Cash flow 3: 500

Approximate Internal Rate of Return (IRR): 0.2154 or 21.54%
Объяснение
  • calculate_npv() вычисляет чистую приведенную стоимость (NPV) для заданной процентной ставки.
  • find_irr() использует метод бисекции для поиска ставки, при которой NPV ≈ 0.
  • Мы используем EPSILON, чтобы определить точность сходимости.
  • Алгоритм итеративно сужает диапазон IRR.
  • Окончательная IRR вычисляется и отображается в виде десятичного числа и процента.

Вывод Оценки IRR

В этом заключительном шаге мы улучшим нашу программу расчета IRR, чтобы предоставить более подробный вывод и продемонстрировать различные сценарии инвестиций.

Изменим наш существующий файл C, чтобы добавить более всеобъемлющий анализ IRR:

cd ~/project
nano irr_calculation.c

Обновим код дополнительным выводом и анализом:

#include <stdio.h>
#include <math.h>
#define MAX_CASH_FLOWS 10
#define EPSILON 0.0001

double calculate_npv(double cash_flows[], int num_cash_flows, double rate) {
    double npv = 0.0;
    for (int i = 0; i < num_cash_flows; i++) {
        npv += cash_flows[i] / pow(1 + rate, i);
    }
    return npv;
}

double find_irr(double cash_flows[], int num_cash_flows) {
    double rate_low = -0.9;
    double rate_high = 10.0;
    double rate = 0.1;

    while ((rate_high - rate_low) > EPSILON) {
        double npv = calculate_npv(cash_flows, num_cash_flows, rate);

        if (fabs(npv) < EPSILON) {
            return rate;
        }

        if (npv > 0) {
            rate_low = rate;
        } else {
            rate_high = rate;
        }

        rate = (rate_low + rate_high) / 2.0;
    }

    return rate;
}

void print_investment_analysis(double cash_flows[], int num_cash_flows, double irr) {
    double total_investment = 0;
    double total_returns = 0;

    printf("\n--- Анализ инвестиций ---\n");

    // Подробный разбор потоков денежных средств
    for (int i = 0; i < num_cash_flows; i++) {
        printf("Период %d: $%.2f\n", i, cash_flows[i]);

        if (cash_flows[i] < 0) {
            total_investment += fabs(cash_flows[i]);
        } else {
            total_returns += cash_flows[i];
        }
    }

    // Резюме инвестиций
    printf("\nОбщая сумма инвестиций: $%.2f\n", total_investment);
    printf("Общая сумма доходов: $%.2f\n", total_returns);
    printf("Чистая прибыль: $%.2f\n", total_returns - total_investment);

    // Подробности IRR
    printf("\nВнутренняя норма доходности (IRR):\n");
    printf("Десятичное значение: %.4f\n", irr);
    printf("Процентное значение: %.2f%%\n", irr * 100);

    // Интерпретация эффективности инвестиций
    if (irr > 0.15) {
        printf("\nЭффективность инвестиций: Отлично\n");
    } else if (irr > 0.10) {
        printf("\nЭффективность инвестиций: Хорошо\n");
    } else if (irr > 0) {
        printf("\nЭффективность инвестиций: Умеренно\n");
    } else {
        printf("\nЭффективность инвестиций: Плохо\n");
    }
}

int main() {
    double cash_flows[MAX_CASH_FLOWS];
    int num_cash_flows;

    printf("Введите количество потоков денежных средств (макс. %d): ", MAX_CASH_FLOWS);
    scanf("%d", &num_cash_flows);

    printf("Введите потоки денежных средств (отрицательные для инвестиций, положительные для доходов):\n");
    for (int i = 0; i < num_cash_flows; i++) {
        printf("Поток денежных средств %d: ", i);
        scanf("%lf", &cash_flows[i]);
    }

    double irr = find_irr(cash_flows, num_cash_flows);
    print_investment_analysis(cash_flows, num_cash_flows, irr);

    return 0;
}

Компилируем программу:

gcc irr_calculation.c -o irr_calculation -lm

Запускаем программу со сценарием инвестиций:

./irr_calculation

Пример вывода:

Введите количество потоков денежных средств (макс. 10): 4
Введите потоки денежных средств (отрицательные для инвестиций, положительные для доходов):
Поток денежных средств 0: -1000
Поток денежных средств 1: 300
Поток денежных средств 2: 400
Поток денежных средств 3: 500

--- Анализ инвестиций ---
Период 0: $-1000.00
Период 1: $300.00
Период 2: $400.00
Период 3: $500.00

Общая сумма инвестиций: $1000.00
Общая сумма доходов: $1200.00
Чистая прибыль: $200.00

Внутренняя норма доходности (IRR):
Десятичное значение: 0.2154
Процентное значение: 21.54%

Эффективность инвестиций: Отлично
Объяснение
  • Добавлена функция print_investment_analysis() для предоставления всеобъемлющего вывода.
  • Вычисляются общая сумма инвестиций, доходов и чистая прибыль.
  • Интерпретируется эффективность IRR с помощью описательных категорий.
  • Предоставляется подробный разбор потоков денежных средств и метрик инвестиций.

Резюме

В этом лабораторном практикуме мы изучили, как читать и хранить потоки денежных средств для расчета внутренней нормы доходности (IRR) в программе на языке C. Потоки денежных средств представляют собой инвестиции или полученные средства в различные временные периоды инвестиции. Затем мы рассмотрели использование итераций для нахождения ставки, при которой чистая приведенная стоимость (NPV) приближается к нулю, что и есть IRR. Наконец, мы изучили, как вывести оцененную IRR. Ключевыми моментами обучения являются понимание структур данных потоков денежных средств, реализация итерационных алгоритмов для нахождения IRR и представление конечного результата.