|
25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more... |
Home Projects Up Sitemap Search Blog Forum+Chat About Us Privacy Terms of Use Feedback FAQ Images Services Payments Humor Music |
Financial calculations in JavaScriptThis JavaScript library contains functions for:
You can copy the code below, or download (Save) the file (9 KB). |
| Interest rate per period | Number of periods | Present Value | Future Value | |
| % |
| Annual Rate |
Semiannual 1/2 |
Quarterly 1/4 |
Monthly 1/12 |
Weekly 1/52 |
Daily 1/365 |
|
| % |
| Calendar days | Trading days | |
/* financial.js 1-11-2009 JavaScript
Copyright (C)1985, 2008-2009 Steven Whitney.
Initially published by http://25yearsofprogramming.com.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License (GPL)
Version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Financial calculations.
REFERENCES
--Wikipedia
--How To Make Money In Stock Options, by Norman Saint-Peter.
*/
//----------------------------------------------------------------------------------------------
// COMPOUND INTEREST
// present value, future value, imputed compound interest rate per period.
// NumPeriods and InterestPerPeriod are relative to each other, regardless of the units used for either.
//----------------------------------------------------------------------------------------------
function PresentValue(NumPeriods, InterestPerPeriod, FutureValue)
{
return FutureValue / Math.pow(1 + InterestPerPeriod, NumPeriods);
}
function FutureValue(NumPeriods, InterestPerPeriod, PresentValue)
{
return PresentValue * Math.pow(1 + InterestPerPeriod, NumPeriods);
}
function ImputedInterest(PresentValue, FutureValue, NumPeriods)
{
return Math.pow(FutureValue / PresentValue, 1 / NumPeriods) - 1;
}
function NumPeriods(PresentValue, FutureValue, InterestPerPeriod)
{
return (Math.log(FutureValue) - Math.log(PresentValue)) / Math.log(1 + InterestPerPeriod);
}
//----------------------------------------------------------------------------------------------
// PERIODIC INTEREST RATES
// Given an annual rate, returns an array containing the rates for shorter periods.
// The elements can be accessed as, for example, Rates["Daily"] or Rates.Daily.
function GetPeriodicInterestRates(AnnualRate)
{
var Rates = new Array();
Rates["Annually"] = AnnualRate;
Rates["Semiannually"] = AnnualRate / 2;
Rates["Quarterly"] = AnnualRate / 4;
Rates["Monthly"] = AnnualRate / 12;
Rates["Weekly"] = AnnualRate / 52;
Rates["Daily"] = AnnualRate / 365;
return Rates;
}
//----------------------------------------------------------------------------------------------
// 252 is generally used as the number of trading days in a year, 21 in a month.
// Those are what the values returned by this function round to, except for February.
// When calculating time to option expiration, you usually know the number of
// calendar days, not trading days, so this can be used to convert the number.
// 365.25 days in a year, 5/7 are weekdays, - 9 U.S. trading holidays
// The multiplier is 0.68964505720152537400997359929598
function TradingDaysIn(CalendarDays)
{
return CalendarDays * (((365.25 * 5/7) - 9) / 365.25);
}
// How many calendar days are required for the given number of trading days to occur.
// The multiplier is 1.4500212675457252233092301148447
function CalendarDaysFor(TradingDays)
{
return TradingDays * (365.25 / ((365.25 * 5/7) - 9));
}
//----------------------------------------------------------------------------------------------
// Given a current stock price, its volatility, and a time period, these functions compute the
// boundaries that the stock could be expected to stay within during a time period (with 68% probability).
// There is a 16% probability it will be above UpperLimit, and 16% probability it will be below LowerLimit.
// These are really just the 1 standard deviation points that define the price envelope at the end of the time period.
// Using these as indicators of "potential" upside and downside price targets is highly questionable
// because the choice to use 1 standard deviation is arbitrary.
// TimePeriod is a fraction (or multiple) of the Volatility period: if volatility is annualized,
// TimePeriod is the fraction of 1 year.
function UpperLimitPrice84(CurrentPrice, VolatilityPerPeriod, TimePeriod)
{
return CurrentPrice * Math.exp(Math.sqrt(TimePeriod) * VolatilityPerPeriod);
}
function LowerLimitPrice84(CurrentPrice, VolatilityPerPeriod, TimePeriod)
{
return CurrentPrice * Math.exp(Math.sqrt(TimePeriod) * (-VolatilityPerPeriod));
}
//----------------------------------------------------------------------------------------------
// Given the current stock price, a price objective, and an annualized volatility,
// calculates the number of CALENDAR days it should take for the stock to reach the objective.
// This equation is derived from the "potential upside and downside stock prices" equations.
// What this derivation does is start with the envelope and calculate at what
// point in time the 1 standard deviation point first reaches the target price.
// The probability that the price will actually have reached or exceeded the objective price is only 16%.
// Thus, this calculation has a lot more uncertainty in it than its name implies.
function CalendarDaysToReachPrice16(CurrentPrice, TargetPrice, Volatility)
{
var diff = Math.log(TargetPrice) - Math.log(CurrentPrice);
var yearfrac = (diff * diff) / (Volatility * Volatility);
// We now have the estimated time in fraction of a year.
// .5 trading year = .5 calendar years (it's just a different number of days),
// so we can simply multiply by the number of days in the type of year we want.
return yearfrac * 365.25;
}
//----------------------------------------------------------------------------------------------
// Given current price, a target price, annualized volatility, years (or fraction) from now till target date,
// calculates the probability of stock price being below the target.
// TimePeriod is a fraction (or multiple) of the Volatility period:
// if volatility is annualized, TimePeriod is the fraction of 1 year.
function ProbabilityStockPriceBelow(CurrentPrice, TargetPrice, VolatilityPerPeriod, TimePeriod)
{
// Prevents divide by zero. If time is 0, the probability is known to be either 0% or 100%.
if(TimePeriod === 0)
return CurrentPrice < TargetPrice ? 1 : 0;
return StandardNormalPx(Math.log(TargetPrice / CurrentPrice) / (VolatilityPerPeriod * Math.sqrt(TimePeriod)));
}
//----------------------------------------------------------------------------------------------
// Probability of stock price being above the target price.
function ProbabilityStockPriceAbove(CurrentPrice, TargetPrice, VolatilityPerPeriod, TimePeriod)
{
if(TimePeriod === 0)
return CurrentPrice > TargetPrice ? 1 : 0;
return StandardNormalQx(Math.log(TargetPrice / CurrentPrice) / (VolatilityPerPeriod * Math.sqrt(TimePeriod)));
}
//----------------------------------------------------------------------------------------------
// Functions for calculating value of a stock option using the Black-Scholes model.
function BlackScholesDen1(Current, Strike, TBillRate, Volatility, FractionalYear)
{
return (Math.log(Current / Strike) + ((TBillRate + ((Volatility * Volatility) / 2)) * FractionalYear)) / (Volatility * Math.sqrt(FractionalYear));
}
//----------------------------------------------------------------------------------------------
function BlackScholesDen2(Current, Strike, TBillRate, Volatility, FractionalYear)
{
return (Math.log(Current / Strike) + ((TBillRate - ((Volatility * Volatility) / 2)) * FractionalYear)) / (Volatility * Math.sqrt(FractionalYear));
}
//----------------------------------------------------------------------------------------------
function BlackScholesCallHedgeRatio(Current, Strike, TBillRate, Volatility, FractionalYear)
{
return StandardNormalPx(BlackScholesDen1(Current, Strike, TBillRate, Volatility, FractionalYear));
}
//----------------------------------------------------------------------------------------------
function BlackScholesPutHedgeRatio(Current, Strike, TBillRate, Volatility, FractionalYear)
{
return BlackScholesCallHedgeRatio(Current, Strike, TBillRate, Volatility, FractionalYear) - 1;
}
//----------------------------------------------------------------------------------------------
function BlackScholesCallValue(Current, Strike, TBillRate, Volatility, FractionalYear)
{
var a = (Current * BlackScholesCallHedgeRatio(Current, Strike, TBillRate, Volatility, FractionalYear));
var b = (StandardNormalPx(BlackScholesDen2(Current, Strike, TBillRate, Volatility, FractionalYear)));
var d = (Strike * Math.exp(TBillRate * (-FractionalYear)));
return a - (b * d);
}
//----------------------------------------------------------------------------------------------
function BlackScholesPutValue(Current, Strike, TBillRate, Volatility, FractionalYear)
{
var a = (Current * (StandardNormalPx(-BlackScholesDen1(Current, Strike, TBillRate, Volatility, FractionalYear))));
var b = (StandardNormalPx(-BlackScholesDen2(Current, Strike, TBillRate, Volatility, FractionalYear)));
var d = (Strike * Math.exp(-TBillRate * FractionalYear));
return (b * d) - a;
}
//----------------------------------------------------------------------------------------------
|
|
|