fintech-algorithms
Using a coding agent? Give it the skill: npx skills add IslamBaraka90/Fintech-Algorithms-Library What it does →

Economic Value Added

Install and import#

bash
npm install fintech-algorithms
ts
import { economicValueAdded } from "fintech-algorithms/fundamental-analysis-and-valuation/intrinsic-valuation/economic-value-added";

Signature#

economicValueAdded(data)

Charges each period's opening invested capital at the WACC, discounts the NOPAT that remains above that charge, and adds a growing-perpetuity continuing value to give market value added and an enterprise value equal to opening invested capital plus that premium.

Parameters#

NameTypeNotes
data{ opening_invested_capital: number; nopat: number[]; net_investment: number[]; wacc: number; terminal_eva_growth: number }opening_invested_capital starts the capital roll-forward, to which each period's net_investment is added. nopat supplies net operating profit after tax per period and must be the same length as net_investment. wacc sets both the capital charge on opening capital and the discount rate, and terminal_eva_growth grows the last period's EVA into the continuing value. Other keys in the record are not read.

Returns#

{ state: string; method: string; schedule: { period: number; opening_invested_capital: number; nopat: number; net_investment: number; capital_charge: number; roic: number; roic_wacc_spread: number; eva: number; discount_factor: number; present_value: number; closing_invested_capital: number }[]; pv_explicit_eva: number; terminal_eva: number; continuing_value: number; terminal_discount_factor: number; pv_continuing_value: number; market_value_added: number; continuing_value_share: number; closing_invested_capital: number; enterprise_value: number }

A schedule row per period with its capital_charge, roic, roic_wacc_spread, eva, discount_factor and present_value, plus the capital roll-forward. Then pv_explicit_eva, the continuing block (terminal_eva, continuing_value, terminal_discount_factor, pv_continuing_value), market_value_added as the sum of both present values, the final closing_invested_capital, and enterprise_value as opening invested capital plus market value added. continuing_value_share is the continuing present value over enterprise value, emitted as 0 when enterprise value is 0. No per-share figure is returned.

Errors#

  • When data is absent, an array, or not an object — throws Error
  • When opening_invested_capital is not a positive finite number — throws Error
  • When nopat or net_investment is not an array holding at least one finite number — throws Error
  • When net_investment differs in length from nopat — throws Error
  • When wacc is not strictly between 0 and 1 — throws Error
  • When terminal_eva_growth is at or below -1, or at or above wacc — throws Error
  • When the invested-capital roll-forward reaches a non-positive closing balance — throws Error

Complexity: time O(n), space O(n).

Worked example#

executed Captured by running this function on the input its own test provides. Real output of real code — but not asserted against a published figure.

Input#

data
{
  "valuation_date": "2026-08-04",
  "currency": "USD",
  "unit_scale": "millions",
  "opening_invested_capital": 800,
  "nopat": [92, 100, 110, 121, 132],
  "net_investment": [50, 50, 55, 60, 60],
  "wacc": 0.09,
  "terminal_eva_growth": 0.03,
  "adjustment_basis": "already-adjusted synthetic NOPAT and invested capital"
}

Call#

economicValueAdded(data)

Returns#

object with 12 fields: state, method, schedule, pv_explicit_eva, terminal_eva, continuing_value, terminal_discount_factor, pv_continuing_value, …

{
  "state": "valued",
  "method": "economic-value-added",
  "schedule": [
    {
      "period": 1,
      "opening_invested_capital": 800,
      "nopat": 92,
      "net_investment": 50,
      "capital_charge": 72,
      "roic": 0.115,
      "roic_wacc_spread": 0.02500000000000001,
      "eva": 20,
      "discount_factor": 0.9174311926605504,
      "present_value": 18.34862385321101,
      "closing_invested_capital": 850
    },
    {
      "period": 2,
      "opening_invested_capital": 850,
      "nopat": 100,
      "net_investment": 50,
      "capital_charge": 76.5,
      "roic": 0.11764705882352941,
      "roic_wacc_spread": 0.027647058823529413,
      "eva": 23.5,
      "discount_factor": 0.84167999326656,
      "present_value": 19.779479841764157,
      "closing_invested_capital": 900
    },
    {
      "period": 3,
      "opening_invested_capital": 900,
      "nopat": 110,
      "net_investment": 55,
      "capital_charge": 81,
      "roic": 0.12222222222222222,
      "roic_wacc_spread": 0.03222222222222222,
      "eva": 29,
      "discount_factor": 0.772183480061064,
      "present_value": 22.393320921770854,
      "closing_invested_capital": 955
    }
  ],
  "pv_explicit_eva": 111.77143911760888,
  "terminal_eva": 41.86950000000001,
  "continuing_value": 697.8250000000002,
  "terminal_discount_factor": 0.6499313862983452,
  "pv_continuing_value": 453.53836964364285,
  "market_value_added": 565.3098087612517,
  "continuing_value_share": 0.33218714663387583,
  "closing_invested_capital": 1075,
  "enterprise_value": 1365.3098087612516
}

Other exports#

This module also exports calculate, freeCashFlowDcf, dividendDiscountModel, gordonGrowthModel, residualIncomeModel. Every module additionally exports run as an alias of its primary function, and a meta object carrying its catalog id, domain, family, shape and article URL.

Diagrams#

Economic Value Added — article hero
Economic Value Added — model boundaries
Economic Value Added — reconciliation bridge
Economic Value Added — sensitivity map
Economic Value Added — system map
Economic Value Added — valuation timeline

How it works#

This page states the contract — how to call it correctly. The article explains the concept: why it works, and where it breaks.

Read the article →

References#

The rest of the Intrinsic Valuation family#