financier
A Node.js module that helps with calculations concerning stocks and portfolios.
Introduction
Financier is a simple, object-oriented way of managing a portfolio. Please feel free to request any features. Code contributions are always welcome!
Installation
$ npm install financier
Financier uses the Sylvester matrix math library for calculations. NPM will automatically install Sylvester as a dependency.
var financier = ;var Stock = financierStock;var Portfolio = financierPortfolio;
Usage
Here is an example featuring comprehensive usage of Financier.
// Load financier.var financier = ;var Stock = financierStock;var Portfolio = financierPortfolio; var stocks = {};// A bit of pseudo-code to load return data from a CSV.var stockData = CSV; // Initialize the stocks.for var stock in stockData stocksstock = stock; for var tick in stockDatastock stocksstock; stocksstock; // Gather the securities for the portfolio.var securities = stock: stocksAAPL value: 1023434 stock: stocksGOOG value: 6346453 stock: stocksMSFT value: 43522 stock: stocksAIG value: 63099 stock: stocksC value: 90211 ; // Build the portfolio.var clientPortfolio = ;for var i = 0; i < securitieslength; i++ var security = securitiesi; clientPortfolio; // Spit out the risk.console;
API
Stock(String ticker)
Used to calculate returns and averages for individual stocks. The parameter
ticker
determines the stock symbol for the stock.
var AAPL = 'AAPL';
Properties
- ticker -
String
The stock symbol. - returns -
Array
The array of tick returns for the stock. - average -
Float
The average of all the tick returns. - value -
Float
The market value of the stock. (Initialized when added to a portfolio.) - weight -
Float
The weight of the stock in comparison to the total portfolio market value. (Initialized when added to a portfolio.)
Stock.push(Float open, Float close, Boolean [Opt] wait)
Add a tick of data to the stock history. This new return is stored in
Stock.returns
. Default behaviour immediately recalculates the overall average on
returns.
The parameters open
and close
are floats
representing the price of the stock.
If wait
is true
, the average is not calculated.
// Push a return of 5.8 to the list of returns. The overall average return will// be automagically calculated.AAPL;
Float Stock.calculateAverage()
Calculate the average of all the returns. This new average is both returned and
stored in Stock.average
.
It is only necessary to call this function if you are adding returns in bulk.
{ return 100 + Math * 30;} // Simulate adding thousands of returns to a stock.for var i = 0; i < 10000; i++ // Push the data, but hold off on calculating the average. AAPL; // Now calculate the overall average.AAPL;
Portfolio()
Keeps data on a portfolio, and has methods to calculate its attributes.
var clientPortfolio = ;
Properties
- stocks -
Object
Stocks included in the portfolio. - value -
Float
Total market value for the stock. - risk -
Float
Risk for the entire portfolio. - cache -
Cache
Cache of portfolio securities.
Portfolio.addStock(Stock stock, Float value, Boolean [Opt] clone)
Add a stock to the portfolio. This stock is stored in the Portfolio.stocks
.
Stock.weight
for all securities are automagically recalculated.
The parameter stock
is the Stock
object being added. value
represents the
market value for the security as a float
. Currency should be kept consistent.
If clone
is true
, a new Stock
is created with identical Stock.ticker
,
Stock.return
, and Stock.average
properties.
IMPORTANT: If stocks are reused in multiple portfolios, or need to be kept independent of the portfolio, they MUST be cloned to prevent discrepencies with how JavaScript passes objects by reference.
// Add AAPL to multiple client portfolios:clientPortfolio;otherClientPortfolio; var open = 1353;var close = 12353; // If new return history needs to be added, it must be done individually.AAPL;clientPortfoliostocksAAPL;otherClientPortfoliostocksAAPL;
Portfolio.removeStock(Stock|String stock)
Remove a stock from the portfolio. Portfolio.stocks
is updated. Additionally,
Stock.weight
for all stocks are recalculated.
// Both of these are valid:clientPortfolio;clientPortfolio;
Portfolio.updateStock(Stock|String stock, Float value)
Update a stock with a new market value. Weights for all the stocks are recalculated. However, the new value is not validated. Stocks are not deleted if the value is 0 or negative.
Array Portfolio.getStockTickers()
Get the tickers for all the stocks in the portfolio.
Boolean Portfolio.hasStock(Stock|String stock)
Checks if the stock is currently in the portfolio.
Float Portfolio.calculateTotalValue()
Calculate the total market value of the portfolio. Portfolio.value
is updated, as
well as returned. This function is called everytime Portfolio.calculateWeights()
is called.
Portfolio.calculateWeights()
Calculate and update Stock.weight
for all securities in the portfolio. This
function is called whenever securities in the portfolio are altered.
Float Portfolio.calculateCovariance(Stock stockA, Stock stockB)
Calculate the covariance between two stocks. If stockA
and stockB
are the same
instance of Stock
the function returns 1 by definition.
While it is better to create a Portfolio
to calculate covariance, this function can
be called to examine individual stocks.
var GOOG = 'GOOG';var AAPL = 'AAPL'; // Pretend that we have filled out the stocks with tick history...GOOG;AAPL; // Find the covariance between Google and Apple.var covariance = Portfolio;
Sylvester.Matrix Portfolio.createWeightMatrix()
Create the matrix of security weights. We do not use Sylvestor.Vector
because it does
not have a transpose method. Portfolio.calculateRisk()
calls this function.
Sylvester.Matrix Portfolio.createCovarianceMatrix()
Create the covariance matrix of all securities. Portfolio.caulcateCovariance()
is called
for every possible pair of securities. Portfolio.calculateRisk()
calls this function.
Float Portfolio.calculateRisk()
Calculate risk for the entire portfolio. We first check against Portfolio.cache
to prevent any
unnecessary work (i.e. securities have not been altered since last time the risk was calculated).
Portfolio.cache
and Portfolio.risk
are then updated.