Income Methods API¶
Relief from Royalty, Multi-Period Excess Earnings, and Incremental Cash Flow methods.
Relief from Royalty¶
relief_from_royalty
¶
Relief from Royalty method.
Values an intangible asset as the present value of after-tax royalty payments that the owner avoids by owning the asset rather than licensing it.
Implements the method from Chapter 4 with Tax Amortization Benefit (TAB).
Functions¶
relief_from_royalty(revenue_projections: list[float], royalty_rate: float, discount_rate: float, tax_rate: float, useful_life: int, tab_enabled: bool = True) -> dict
¶
Calculate asset value using the Relief from Royalty method.
The Relief from Royalty method values an intangible asset as the present value of the after-tax royalty payments the owner avoids by owning the asset rather than licensing it from a third party.
Formula
For each period t: Royalty_t = Revenue_t * royalty_rate AfterTax_Royalty_t = Royalty_t * (1 - tax_rate) PV_t = AfterTax_Royalty_t / (1 + discount_rate)^t
With TAB (Tax Amortization Benefit): TAB = 1 / (1 - (tax_rate * PV_annuity_factor / useful_life)) Value = PV_of_after_tax_royalties * TAB
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
revenue_projections
|
list[float]
|
Projected revenue for each period of useful life. |
required |
royalty_rate
|
float
|
Arm's length royalty rate as decimal (e.g., 0.04 for 4%). |
required |
discount_rate
|
float
|
Discount rate as decimal. |
required |
tax_rate
|
float
|
Corporate tax rate as decimal. |
required |
useful_life
|
int
|
Expected useful life in periods. |
required |
tab_enabled
|
bool
|
Whether to include Tax Amortization Benefit. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
dict
|
Dict with: - value: Present value of relief from royalty (with TAB if enabled) - method: 'Relief from Royalty' - formula_reference: 'Chapter 4: Income Methods - Relief from Royalty' - pv_before_tab: PV before tax amortization benefit - tab_factor: TAB multiplier (1.0 if disabled) - steps: List of calculation steps - assumptions: Key assumptions used |
Raises:
| Type | Description |
|---|---|
ValueError
|
If inputs are invalid or inconsistent. |
Example
result = relief_from_royalty( ... revenue_projections=[1000000, 1100000, 1200000, 1300000, 1400000], ... royalty_rate=0.05, ... discount_rate=0.12, ... tax_rate=0.25, ... useful_life=5, ... ) result["value"] > 0 True
Source code in src/income_methods/relief_from_royalty.py
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | |
Multi-Period Excess Earnings¶
excess_earnings
¶
Excess Earnings methods.
Implements Multi-Period Excess Earnings Method (MPEEM) and Single-Period Excess Earnings Method from Chapter 4. Includes Contributory Asset Charge (CAC) calculations.
Classes¶
ContributoryAssetInput
¶
Bases: BaseModel
Validated contributory asset input.
Functions¶
contributory_asset_charges(assets: list[dict]) -> dict
¶
Calculate total contributory asset charges (CACs).
Contributory asset charges represent the return required by providers of capital to each contributory asset that supports the subject intangible asset's earnings.
Formula
CAC_i = asset_value_i * return_rate_i Total_CAC = sum(CAC_i)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
assets
|
list[dict]
|
List of dicts with 'type', 'value', 'return_rate' keys. value must be positive, return_rate must be between 0 and 1. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Dict with: - total_cac: Sum of all contributory asset charges - breakdown: List of individual CAC calculations - method: 'Contributory Asset Charges' - formula_reference: 'Chapter 4: Income Methods - Excess Earnings' - steps: List of calculation steps - assumptions: Key assumptions used |
Raises:
| Type | Description |
|---|---|
ValueError
|
If assets is empty or contains invalid data. |
Example
assets = [ ... {"type": "working_capital", "value": 500000, "return_rate": 0.08}, ... {"type": "fixed_assets", "value": 1000000, "return_rate": 0.10}, ... ] result = contributory_asset_charges(assets) result["total_cac"] 140000.0
Source code in src/income_methods/excess_earnings.py
mpeem(cash_flow_projections: list[float], contributory_asset_charges: list[dict], discount_rate: float, tax_rate: float, tab_enabled: bool = True) -> dict
¶
Calculate asset value using the Multi-Period Excess Earnings Method (MPEEM).
MPEEM values an intangible asset as the present value of projected cash flows after deducting contributory asset charges (returns on all other assets that contribute to generating those cash flows).
Formula
For each period t: Excess_Earnings_t = (CashFlow_t - Total_CAC_t) * (1 - tax_rate) PV_t = Excess_Earnings_t / (1 + discount_rate)^t
With TAB: TAB = 1 / (1 - (tax_rate * PV_annuity_factor / n)) Value = PV_of_excess_earnings * TAB
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cash_flow_projections
|
list[float]
|
Projected cash flows for each period. |
required |
contributory_asset_charges
|
list[dict]
|
List of dicts, one per period, with CAC breakdowns. Each dict must have 'total_cac' key. Length must match cash_flow_projections. |
required |
discount_rate
|
float
|
Discount rate as decimal. |
required |
tax_rate
|
float
|
Corporate tax rate as decimal. |
required |
tab_enabled
|
bool
|
Whether to include Tax Amortization Benefit. Defaults to True. |
True
|
Returns:
| Type | Description |
|---|---|
dict
|
Dict with: - value: Present value of excess earnings (with TAB if enabled) - method: 'Multi-Period Excess Earnings Method (MPEEM)' - formula_reference: 'Chapter 4: Income Methods - MPEEM' - pv_before_tab: PV before tax amortization benefit - tab_factor: TAB multiplier (1.0 if disabled) - steps: List of calculation steps - assumptions: Key assumptions used |
Raises:
| Type | Description |
|---|---|
ValueError
|
If inputs are invalid or inconsistent. |
Example
cfs = [200000, 220000, 240000, 260000, 280000] cacs = [ ... {"total_cac": 50000}, {"total_cac": 52000}, {"total_cac": 54000}, ... {"total_cac": 56000}, {"total_cac": 58000}, ... ] result = mpeem(cfs, cacs, discount_rate=0.12, tax_rate=0.25) result["value"] > 0 True
Source code in src/income_methods/excess_earnings.py
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | |
single_period_excess_earnings(normalized_earnings: float, contributory_asset_charges: list[dict], capitalization_rate: float) -> dict
¶
Calculate asset value using the Single-Period Excess Earnings Method.
Values an intangible asset by capitalizing a single period of normalized excess earnings (earnings after deducting CACs).
Formula
Total_CAC = sum(cac['total_cac'] for cac in contributory_asset_charges) Excess_Earnings = normalized_earnings - Total_CAC Value = Excess_Earnings / capitalization_rate
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
normalized_earnings
|
float
|
Normalized earnings attributable to all assets. |
required |
contributory_asset_charges
|
list[dict]
|
List of dicts with 'total_cac' key. |
required |
capitalization_rate
|
float
|
Capitalization rate as decimal. Must be positive. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Dict with: - value: Capitalized excess earnings value - method: 'Single-Period Excess Earnings Method' - formula_reference: 'Chapter 4: Income Methods - Single Period Excess Earnings' - total_cac: Sum of contributory asset charges - excess_earnings: Normalized earnings minus total CAC - steps: List of calculation steps - assumptions: Key assumptions used |
Raises:
| Type | Description |
|---|---|
ValueError
|
If inputs are invalid or excess earnings are non-positive. |
Example
result = single_period_excess_earnings( ... normalized_earnings=500000, ... contributory_asset_charges=[{"total_cac": 140000}], ... capitalization_rate=0.12, ... ) result["value"] 3000000.0
Source code in src/income_methods/excess_earnings.py
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | |
Incremental Cash Flow¶
incremental_cashflow
¶
Incremental Cash Flow method.
Values an intangible asset as the present value of the difference between cash flows with and without the asset.
Implements the method from Chapter 4.
Functions¶
incremental_cashflow(cash_flows_with: list[float], cash_flows_without: list[float], discount_rate: float) -> dict
¶
Calculate asset value using the Incremental Cash Flow method.
The Incremental Cash Flow method values an intangible asset as the present value of the additional cash flows generated by having the asset versus not having it.
Formula
For each period t: Incremental_CF_t = CashFlow_with_t - CashFlow_without_t PV_t = Incremental_CF_t / (1 + discount_rate)^t
Value = sum(PV_t)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cash_flows_with
|
list[float]
|
Projected cash flows with the asset. |
required |
cash_flows_without
|
list[float]
|
Projected cash flows without the asset. Must be the same length as cash_flows_with. |
required |
discount_rate
|
float
|
Discount rate as decimal. Must be positive. |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Dict with: - value: Present value of incremental cash flows - method: 'Incremental Cash Flow' - formula_reference: 'Chapter 4: Income Methods - Incremental Cash Flow' - incremental_cash_flows: List of period-by-period differences - steps: List of calculation steps - assumptions: Key assumptions used |
Raises:
| Type | Description |
|---|---|
ValueError
|
If inputs are invalid or inconsistent. |
Example
result = incremental_cashflow( ... cash_flows_with=[500000, 550000, 600000, 650000, 700000], ... cash_flows_without=[400000, 420000, 440000, 460000, 480000], ... discount_rate=0.10, ... ) result["value"] > 0 True