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 JavaScript

This JavaScript library contains functions for:

  • Compound interest calculations.
  • Estimating the number of U.S. financial market trading days in a given number of calendar days.
  • Forecasting the probability of future stock price movements, based on the stock's historical volatility.
  • Calculating the economic fair value of call and put options using the Black-Scholes method. These functions require some additional code from my probability library.

You can copy the code below, or download (Save) the file (9 KB).


Compound interest calculator

Instructions:

  1. Enter the three values that are known, leaving the unknown value blank.
  2. Click Calculate to solve for the unknown value.
  Interest rate per period Number of periods Present Value Future Value
%

Interest rate calculator

Instructions:

  1. Enter the annual percentage rate (APR).
  2. Click Calculate to convert the annual rate to the shorter periodic rates you might need for the compound interest calculator above.
  Annual
Rate
Semiannual
1/2
Quarterly
1/4
Monthly
1/12
Weekly
1/52
Daily
1/365
%

 


Calendar days / Trading days calculator

Instructions:

  1. Enter the number of calendar days or trading days. Leave the other field blank.
  2. Click Calculate to solve for the unknown.
  Calendar days Trading days

 


JavaScript financial functions source code

/*	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;
}
//----------------------------------------------------------------------------------------------

 

 

Valid HTML 4.01 Transitional Valid CSS
Yahoo! Search
Search the web Search this site
View content labeling at ICRA.
Copyright ©2009 Steven Whitney. Last modified 03/16/2009.