linxus fs fixes
This commit is contained in:
parent
ac23b70146
commit
0b7846fe67
292 changed files with 41947 additions and 41947 deletions
|
|
@ -1,391 +1,391 @@
|
|||
/**
|
||||
* Basic Financial Calculations
|
||||
* Core mathematical functions for financial analysis
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculate percentage change between two values
|
||||
*/
|
||||
export function percentageChange(oldValue: number, newValue: number): number {
|
||||
if (oldValue === 0) return 0;
|
||||
return ((newValue - oldValue) / oldValue) * 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate simple return
|
||||
*/
|
||||
export function simpleReturn(initialPrice: number, finalPrice: number): number {
|
||||
if (initialPrice === 0) return 0;
|
||||
return (finalPrice - initialPrice) / initialPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate logarithmic return
|
||||
*/
|
||||
export function logReturn(initialPrice: number, finalPrice: number): number {
|
||||
if (initialPrice <= 0 || finalPrice <= 0) return 0;
|
||||
return Math.log(finalPrice / initialPrice);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate compound annual growth rate (CAGR)
|
||||
*/
|
||||
export function cagr(startValue: number, endValue: number, years: number): number {
|
||||
if (years <= 0 || startValue <= 0 || endValue <= 0) return 0;
|
||||
return Math.pow(endValue / startValue, 1 / years) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate annualized return from periodic returns
|
||||
*/
|
||||
export function annualizeReturn(periodicReturn: number, periodsPerYear: number): number {
|
||||
return Math.pow(1 + periodicReturn, periodsPerYear) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate annualized volatility from periodic returns
|
||||
*/
|
||||
export function annualizeVolatility(periodicVolatility: number, periodsPerYear: number): number {
|
||||
return periodicVolatility * Math.sqrt(periodsPerYear);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate present value
|
||||
*/
|
||||
export function presentValue(futureValue: number, rate: number, periods: number): number {
|
||||
return futureValue / Math.pow(1 + rate, periods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate future value
|
||||
*/
|
||||
export function futureValue(presentValue: number, rate: number, periods: number): number {
|
||||
return presentValue * Math.pow(1 + rate, periods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate net present value of cash flows
|
||||
*/
|
||||
export function netPresentValue(cashFlows: number[], discountRate: number): number {
|
||||
return cashFlows.reduce((npv, cashFlow, index) => {
|
||||
return npv + cashFlow / Math.pow(1 + discountRate, index);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate internal rate of return (IRR) using Newton-Raphson method
|
||||
*/
|
||||
export function internalRateOfReturn(cashFlows: number[], guess: number = 0.1, maxIterations: number = 100): number {
|
||||
let rate = guess;
|
||||
|
||||
for (let i = 0; i < maxIterations; i++) {
|
||||
let npv = 0;
|
||||
let dnpv = 0;
|
||||
|
||||
for (let j = 0; j < cashFlows.length; j++) {
|
||||
npv += cashFlows[j] / Math.pow(1 + rate, j);
|
||||
dnpv += -j * cashFlows[j] / Math.pow(1 + rate, j + 1);
|
||||
}
|
||||
|
||||
if (Math.abs(npv) < 1e-10) break;
|
||||
if (Math.abs(dnpv) < 1e-10) break;
|
||||
|
||||
rate = rate - npv / dnpv;
|
||||
}
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate payback period
|
||||
*/
|
||||
export function paybackPeriod(initialInvestment: number, cashFlows: number[]): number {
|
||||
let cumulativeCashFlow = 0;
|
||||
|
||||
for (let i = 0; i < cashFlows.length; i++) {
|
||||
cumulativeCashFlow += cashFlows[i];
|
||||
if (cumulativeCashFlow >= initialInvestment) {
|
||||
return i + 1 - (cumulativeCashFlow - initialInvestment) / cashFlows[i];
|
||||
}
|
||||
}
|
||||
|
||||
return -1; // Never pays back
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate compound interest
|
||||
*/
|
||||
export function compoundInterest(
|
||||
principal: number,
|
||||
rate: number,
|
||||
periods: number,
|
||||
compoundingFrequency: number = 1
|
||||
): number {
|
||||
return principal * Math.pow(1 + rate / compoundingFrequency, compoundingFrequency * periods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate effective annual rate
|
||||
*/
|
||||
export function effectiveAnnualRate(nominalRate: number, compoundingFrequency: number): number {
|
||||
return Math.pow(1 + nominalRate / compoundingFrequency, compoundingFrequency) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate bond price given yield
|
||||
*/
|
||||
export function bondPrice(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
yieldToMaturity: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2
|
||||
): number {
|
||||
const couponPayment = (faceValue * couponRate) / paymentsPerYear;
|
||||
const discountRate = yieldToMaturity / paymentsPerYear;
|
||||
|
||||
let price = 0;
|
||||
|
||||
// Present value of coupon payments
|
||||
for (let i = 1; i <= periodsToMaturity; i++) {
|
||||
price += couponPayment / Math.pow(1 + discountRate, i);
|
||||
}
|
||||
|
||||
// Present value of face value
|
||||
price += faceValue / Math.pow(1 + discountRate, periodsToMaturity);
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate bond yield given price (Newton-Raphson approximation)
|
||||
*/
|
||||
export function bondYield(
|
||||
price: number,
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2,
|
||||
guess: number = 0.05
|
||||
): number {
|
||||
let yield_ = guess;
|
||||
const maxIterations = 100;
|
||||
const tolerance = 1e-8;
|
||||
|
||||
for (let i = 0; i < maxIterations; i++) {
|
||||
const calculatedPrice = bondPrice(faceValue, couponRate, yield_, periodsToMaturity, paymentsPerYear);
|
||||
const diff = calculatedPrice - price;
|
||||
|
||||
if (Math.abs(diff) < tolerance) break;
|
||||
|
||||
// Numerical derivative
|
||||
const delta = 0.0001;
|
||||
const priceUp = bondPrice(faceValue, couponRate, yield_ + delta, periodsToMaturity, paymentsPerYear);
|
||||
const derivative = (priceUp - calculatedPrice) / delta;
|
||||
|
||||
if (Math.abs(derivative) < tolerance) break;
|
||||
|
||||
yield_ = yield_ - diff / derivative;
|
||||
}
|
||||
|
||||
return yield_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate duration (Macaulay duration)
|
||||
*/
|
||||
export function macaulayDuration(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
yieldToMaturity: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2
|
||||
): number {
|
||||
const couponPayment = (faceValue * couponRate) / paymentsPerYear;
|
||||
const discountRate = yieldToMaturity / paymentsPerYear;
|
||||
const bondPriceValue = bondPrice(faceValue, couponRate, yieldToMaturity, periodsToMaturity, paymentsPerYear);
|
||||
|
||||
let weightedTime = 0;
|
||||
|
||||
// Weighted time of coupon payments
|
||||
for (let i = 1; i <= periodsToMaturity; i++) {
|
||||
const presentValue = couponPayment / Math.pow(1 + discountRate, i);
|
||||
weightedTime += (i * presentValue) / bondPriceValue;
|
||||
}
|
||||
|
||||
// Weighted time of face value
|
||||
const faceValuePV = faceValue / Math.pow(1 + discountRate, periodsToMaturity);
|
||||
weightedTime += (periodsToMaturity * faceValuePV) / bondPriceValue;
|
||||
|
||||
return weightedTime / paymentsPerYear; // Convert to years
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate modified duration
|
||||
*/
|
||||
export function modifiedDuration(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
yieldToMaturity: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2
|
||||
): number {
|
||||
const macDuration = macaulayDuration(faceValue, couponRate, yieldToMaturity, periodsToMaturity, paymentsPerYear);
|
||||
return macDuration / (1 + yieldToMaturity / paymentsPerYear);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate bond convexity
|
||||
*/
|
||||
export function bondConvexity(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
yieldToMaturity: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2
|
||||
): number {
|
||||
const couponPayment = (faceValue * couponRate) / paymentsPerYear;
|
||||
const discountRate = yieldToMaturity / paymentsPerYear;
|
||||
|
||||
let convexity = 0;
|
||||
const bondPriceValue = bondPrice(faceValue, couponRate, yieldToMaturity, periodsToMaturity, paymentsPerYear);
|
||||
|
||||
for (let i = 1; i <= periodsToMaturity; i++) {
|
||||
const presentValue = couponPayment / Math.pow(1 + discountRate, i);
|
||||
convexity += (i * (i + 1) * presentValue) / Math.pow(1 + discountRate, 2);
|
||||
}
|
||||
|
||||
const faceValuePV = faceValue / Math.pow(1 + discountRate, periodsToMaturity);
|
||||
convexity += (periodsToMaturity * (periodsToMaturity + 1) * faceValuePV) / Math.pow(1 + discountRate, 2);
|
||||
|
||||
return convexity / (bondPriceValue * paymentsPerYear * paymentsPerYear);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate dollar duration
|
||||
*/
|
||||
export function dollarDuration(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
yieldToMaturity: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2,
|
||||
basisPointChange: number = 0.01 // 1 basis point = 0.01%
|
||||
): number {
|
||||
const modifiedDur = modifiedDuration(faceValue, couponRate, yieldToMaturity, periodsToMaturity, paymentsPerYear);
|
||||
const bondPriceValue = bondPrice(faceValue, couponRate, yieldToMaturity, periodsToMaturity, paymentsPerYear);
|
||||
return modifiedDur * bondPriceValue * basisPointChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate accrued interest
|
||||
*/
|
||||
export function accruedInterest(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
daysSinceLastCoupon: number,
|
||||
daysInCouponPeriod: number
|
||||
): number {
|
||||
return (faceValue * couponRate) * (daysSinceLastCoupon / daysInCouponPeriod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate clean price
|
||||
*/
|
||||
export function cleanPrice(dirtyPrice: number, accruedInterestValue: number): number {
|
||||
return dirtyPrice - accruedInterestValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate dirty price
|
||||
*/
|
||||
export function dirtyPrice(cleanPriceValue: number, accruedInterestValue: number): number {
|
||||
return cleanPriceValue + accruedInterestValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate dividend discount model (DDM)
|
||||
*/
|
||||
export function dividendDiscountModel(
|
||||
currentDividend: number,
|
||||
growthRate: number,
|
||||
discountRate: number
|
||||
): number {
|
||||
if (discountRate <= growthRate) return NaN; // Indeterminate
|
||||
return currentDividend * (1 + growthRate) / (discountRate - growthRate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate weighted average cost of capital (WACC)
|
||||
*/
|
||||
export function weightedAverageCostOfCapital(
|
||||
costOfEquity: number,
|
||||
costOfDebt: number,
|
||||
equityWeight: number,
|
||||
debtWeight: number,
|
||||
taxRate: number
|
||||
): number {
|
||||
return (equityWeight * costOfEquity) + (debtWeight * costOfDebt * (1 - taxRate));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate capital asset pricing model (CAPM)
|
||||
*/
|
||||
export function capitalAssetPricingModel(
|
||||
riskFreeRate: number,
|
||||
beta: number,
|
||||
marketRiskPremium: number
|
||||
): number {
|
||||
return riskFreeRate + beta * marketRiskPremium;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate hurdle rate
|
||||
*/
|
||||
export function hurdleRate(
|
||||
costOfCapital: number,
|
||||
riskPremium: number
|
||||
): number {
|
||||
return costOfCapital + riskPremium;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate degree of operating leverage (DOL)
|
||||
*/
|
||||
export function degreeOfOperatingLeverage(
|
||||
contributionMargin: number,
|
||||
operatingIncome: number
|
||||
): number {
|
||||
return contributionMargin / operatingIncome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate degree of financial leverage (DFL)
|
||||
*/
|
||||
export function degreeOfFinancialLeverage(
|
||||
ebit: number,
|
||||
earningsBeforeTax: number
|
||||
): number {
|
||||
return ebit / earningsBeforeTax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate degree of total leverage (DTL)
|
||||
*/
|
||||
export function degreeOfTotalLeverage(
|
||||
dol: number,
|
||||
dfl: number
|
||||
): number {
|
||||
return dol * dfl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate economic value added (EVA)
|
||||
*/
|
||||
export function economicValueAdded(
|
||||
netOperatingProfitAfterTax: number,
|
||||
capitalInvested: number,
|
||||
wacc: number
|
||||
): number {
|
||||
return netOperatingProfitAfterTax - (capitalInvested * wacc);
|
||||
}
|
||||
/**
|
||||
* Basic Financial Calculations
|
||||
* Core mathematical functions for financial analysis
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculate percentage change between two values
|
||||
*/
|
||||
export function percentageChange(oldValue: number, newValue: number): number {
|
||||
if (oldValue === 0) return 0;
|
||||
return ((newValue - oldValue) / oldValue) * 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate simple return
|
||||
*/
|
||||
export function simpleReturn(initialPrice: number, finalPrice: number): number {
|
||||
if (initialPrice === 0) return 0;
|
||||
return (finalPrice - initialPrice) / initialPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate logarithmic return
|
||||
*/
|
||||
export function logReturn(initialPrice: number, finalPrice: number): number {
|
||||
if (initialPrice <= 0 || finalPrice <= 0) return 0;
|
||||
return Math.log(finalPrice / initialPrice);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate compound annual growth rate (CAGR)
|
||||
*/
|
||||
export function cagr(startValue: number, endValue: number, years: number): number {
|
||||
if (years <= 0 || startValue <= 0 || endValue <= 0) return 0;
|
||||
return Math.pow(endValue / startValue, 1 / years) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate annualized return from periodic returns
|
||||
*/
|
||||
export function annualizeReturn(periodicReturn: number, periodsPerYear: number): number {
|
||||
return Math.pow(1 + periodicReturn, periodsPerYear) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate annualized volatility from periodic returns
|
||||
*/
|
||||
export function annualizeVolatility(periodicVolatility: number, periodsPerYear: number): number {
|
||||
return periodicVolatility * Math.sqrt(periodsPerYear);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate present value
|
||||
*/
|
||||
export function presentValue(futureValue: number, rate: number, periods: number): number {
|
||||
return futureValue / Math.pow(1 + rate, periods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate future value
|
||||
*/
|
||||
export function futureValue(presentValue: number, rate: number, periods: number): number {
|
||||
return presentValue * Math.pow(1 + rate, periods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate net present value of cash flows
|
||||
*/
|
||||
export function netPresentValue(cashFlows: number[], discountRate: number): number {
|
||||
return cashFlows.reduce((npv, cashFlow, index) => {
|
||||
return npv + cashFlow / Math.pow(1 + discountRate, index);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate internal rate of return (IRR) using Newton-Raphson method
|
||||
*/
|
||||
export function internalRateOfReturn(cashFlows: number[], guess: number = 0.1, maxIterations: number = 100): number {
|
||||
let rate = guess;
|
||||
|
||||
for (let i = 0; i < maxIterations; i++) {
|
||||
let npv = 0;
|
||||
let dnpv = 0;
|
||||
|
||||
for (let j = 0; j < cashFlows.length; j++) {
|
||||
npv += cashFlows[j] / Math.pow(1 + rate, j);
|
||||
dnpv += -j * cashFlows[j] / Math.pow(1 + rate, j + 1);
|
||||
}
|
||||
|
||||
if (Math.abs(npv) < 1e-10) break;
|
||||
if (Math.abs(dnpv) < 1e-10) break;
|
||||
|
||||
rate = rate - npv / dnpv;
|
||||
}
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate payback period
|
||||
*/
|
||||
export function paybackPeriod(initialInvestment: number, cashFlows: number[]): number {
|
||||
let cumulativeCashFlow = 0;
|
||||
|
||||
for (let i = 0; i < cashFlows.length; i++) {
|
||||
cumulativeCashFlow += cashFlows[i];
|
||||
if (cumulativeCashFlow >= initialInvestment) {
|
||||
return i + 1 - (cumulativeCashFlow - initialInvestment) / cashFlows[i];
|
||||
}
|
||||
}
|
||||
|
||||
return -1; // Never pays back
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate compound interest
|
||||
*/
|
||||
export function compoundInterest(
|
||||
principal: number,
|
||||
rate: number,
|
||||
periods: number,
|
||||
compoundingFrequency: number = 1
|
||||
): number {
|
||||
return principal * Math.pow(1 + rate / compoundingFrequency, compoundingFrequency * periods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate effective annual rate
|
||||
*/
|
||||
export function effectiveAnnualRate(nominalRate: number, compoundingFrequency: number): number {
|
||||
return Math.pow(1 + nominalRate / compoundingFrequency, compoundingFrequency) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate bond price given yield
|
||||
*/
|
||||
export function bondPrice(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
yieldToMaturity: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2
|
||||
): number {
|
||||
const couponPayment = (faceValue * couponRate) / paymentsPerYear;
|
||||
const discountRate = yieldToMaturity / paymentsPerYear;
|
||||
|
||||
let price = 0;
|
||||
|
||||
// Present value of coupon payments
|
||||
for (let i = 1; i <= periodsToMaturity; i++) {
|
||||
price += couponPayment / Math.pow(1 + discountRate, i);
|
||||
}
|
||||
|
||||
// Present value of face value
|
||||
price += faceValue / Math.pow(1 + discountRate, periodsToMaturity);
|
||||
|
||||
return price;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate bond yield given price (Newton-Raphson approximation)
|
||||
*/
|
||||
export function bondYield(
|
||||
price: number,
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2,
|
||||
guess: number = 0.05
|
||||
): number {
|
||||
let yield_ = guess;
|
||||
const maxIterations = 100;
|
||||
const tolerance = 1e-8;
|
||||
|
||||
for (let i = 0; i < maxIterations; i++) {
|
||||
const calculatedPrice = bondPrice(faceValue, couponRate, yield_, periodsToMaturity, paymentsPerYear);
|
||||
const diff = calculatedPrice - price;
|
||||
|
||||
if (Math.abs(diff) < tolerance) break;
|
||||
|
||||
// Numerical derivative
|
||||
const delta = 0.0001;
|
||||
const priceUp = bondPrice(faceValue, couponRate, yield_ + delta, periodsToMaturity, paymentsPerYear);
|
||||
const derivative = (priceUp - calculatedPrice) / delta;
|
||||
|
||||
if (Math.abs(derivative) < tolerance) break;
|
||||
|
||||
yield_ = yield_ - diff / derivative;
|
||||
}
|
||||
|
||||
return yield_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate duration (Macaulay duration)
|
||||
*/
|
||||
export function macaulayDuration(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
yieldToMaturity: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2
|
||||
): number {
|
||||
const couponPayment = (faceValue * couponRate) / paymentsPerYear;
|
||||
const discountRate = yieldToMaturity / paymentsPerYear;
|
||||
const bondPriceValue = bondPrice(faceValue, couponRate, yieldToMaturity, periodsToMaturity, paymentsPerYear);
|
||||
|
||||
let weightedTime = 0;
|
||||
|
||||
// Weighted time of coupon payments
|
||||
for (let i = 1; i <= periodsToMaturity; i++) {
|
||||
const presentValue = couponPayment / Math.pow(1 + discountRate, i);
|
||||
weightedTime += (i * presentValue) / bondPriceValue;
|
||||
}
|
||||
|
||||
// Weighted time of face value
|
||||
const faceValuePV = faceValue / Math.pow(1 + discountRate, periodsToMaturity);
|
||||
weightedTime += (periodsToMaturity * faceValuePV) / bondPriceValue;
|
||||
|
||||
return weightedTime / paymentsPerYear; // Convert to years
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate modified duration
|
||||
*/
|
||||
export function modifiedDuration(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
yieldToMaturity: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2
|
||||
): number {
|
||||
const macDuration = macaulayDuration(faceValue, couponRate, yieldToMaturity, periodsToMaturity, paymentsPerYear);
|
||||
return macDuration / (1 + yieldToMaturity / paymentsPerYear);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate bond convexity
|
||||
*/
|
||||
export function bondConvexity(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
yieldToMaturity: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2
|
||||
): number {
|
||||
const couponPayment = (faceValue * couponRate) / paymentsPerYear;
|
||||
const discountRate = yieldToMaturity / paymentsPerYear;
|
||||
|
||||
let convexity = 0;
|
||||
const bondPriceValue = bondPrice(faceValue, couponRate, yieldToMaturity, periodsToMaturity, paymentsPerYear);
|
||||
|
||||
for (let i = 1; i <= periodsToMaturity; i++) {
|
||||
const presentValue = couponPayment / Math.pow(1 + discountRate, i);
|
||||
convexity += (i * (i + 1) * presentValue) / Math.pow(1 + discountRate, 2);
|
||||
}
|
||||
|
||||
const faceValuePV = faceValue / Math.pow(1 + discountRate, periodsToMaturity);
|
||||
convexity += (periodsToMaturity * (periodsToMaturity + 1) * faceValuePV) / Math.pow(1 + discountRate, 2);
|
||||
|
||||
return convexity / (bondPriceValue * paymentsPerYear * paymentsPerYear);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate dollar duration
|
||||
*/
|
||||
export function dollarDuration(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
yieldToMaturity: number,
|
||||
periodsToMaturity: number,
|
||||
paymentsPerYear: number = 2,
|
||||
basisPointChange: number = 0.01 // 1 basis point = 0.01%
|
||||
): number {
|
||||
const modifiedDur = modifiedDuration(faceValue, couponRate, yieldToMaturity, periodsToMaturity, paymentsPerYear);
|
||||
const bondPriceValue = bondPrice(faceValue, couponRate, yieldToMaturity, periodsToMaturity, paymentsPerYear);
|
||||
return modifiedDur * bondPriceValue * basisPointChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate accrued interest
|
||||
*/
|
||||
export function accruedInterest(
|
||||
faceValue: number,
|
||||
couponRate: number,
|
||||
daysSinceLastCoupon: number,
|
||||
daysInCouponPeriod: number
|
||||
): number {
|
||||
return (faceValue * couponRate) * (daysSinceLastCoupon / daysInCouponPeriod);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate clean price
|
||||
*/
|
||||
export function cleanPrice(dirtyPrice: number, accruedInterestValue: number): number {
|
||||
return dirtyPrice - accruedInterestValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate dirty price
|
||||
*/
|
||||
export function dirtyPrice(cleanPriceValue: number, accruedInterestValue: number): number {
|
||||
return cleanPriceValue + accruedInterestValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate dividend discount model (DDM)
|
||||
*/
|
||||
export function dividendDiscountModel(
|
||||
currentDividend: number,
|
||||
growthRate: number,
|
||||
discountRate: number
|
||||
): number {
|
||||
if (discountRate <= growthRate) return NaN; // Indeterminate
|
||||
return currentDividend * (1 + growthRate) / (discountRate - growthRate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate weighted average cost of capital (WACC)
|
||||
*/
|
||||
export function weightedAverageCostOfCapital(
|
||||
costOfEquity: number,
|
||||
costOfDebt: number,
|
||||
equityWeight: number,
|
||||
debtWeight: number,
|
||||
taxRate: number
|
||||
): number {
|
||||
return (equityWeight * costOfEquity) + (debtWeight * costOfDebt * (1 - taxRate));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate capital asset pricing model (CAPM)
|
||||
*/
|
||||
export function capitalAssetPricingModel(
|
||||
riskFreeRate: number,
|
||||
beta: number,
|
||||
marketRiskPremium: number
|
||||
): number {
|
||||
return riskFreeRate + beta * marketRiskPremium;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate hurdle rate
|
||||
*/
|
||||
export function hurdleRate(
|
||||
costOfCapital: number,
|
||||
riskPremium: number
|
||||
): number {
|
||||
return costOfCapital + riskPremium;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate degree of operating leverage (DOL)
|
||||
*/
|
||||
export function degreeOfOperatingLeverage(
|
||||
contributionMargin: number,
|
||||
operatingIncome: number
|
||||
): number {
|
||||
return contributionMargin / operatingIncome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate degree of financial leverage (DFL)
|
||||
*/
|
||||
export function degreeOfFinancialLeverage(
|
||||
ebit: number,
|
||||
earningsBeforeTax: number
|
||||
): number {
|
||||
return ebit / earningsBeforeTax;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate degree of total leverage (DTL)
|
||||
*/
|
||||
export function degreeOfTotalLeverage(
|
||||
dol: number,
|
||||
dfl: number
|
||||
): number {
|
||||
return dol * dfl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate economic value added (EVA)
|
||||
*/
|
||||
export function economicValueAdded(
|
||||
netOperatingProfitAfterTax: number,
|
||||
capitalInvested: number,
|
||||
wacc: number
|
||||
): number {
|
||||
return netOperatingProfitAfterTax - (capitalInvested * wacc);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue