accountant
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -27,3 +27,3 @@ /** | ||
var transaction = function(t, banks, stocks){ | ||
var transaction = function(t, banks, stocks, invoices){ | ||
banks[t.src] = banks[t.src] || {balance:0} | ||
@@ -38,2 +38,6 @@ banks[t.dest] = banks[t.dest] || {balance:0} | ||
if (t.invoice){ | ||
resolveInvoice(t, banks, stocks, invoices) | ||
} | ||
_.each(reports, function(r){ | ||
@@ -45,2 +49,43 @@ if (r.onTransaction) | ||
var invoice = function(t, banks, stocks, invoices){ | ||
if (!invoices[t.to]){ | ||
invoices[t.to] = { | ||
outstanding : [] | ||
, paid : [] | ||
} | ||
} | ||
invoices[t.to].outstanding.push(t); | ||
_.each(reports, function(r){ | ||
if (r.onInvoice) | ||
r.onInvoice(t, banks, stocks, invoices); | ||
}) | ||
} | ||
var resolveInvoice = function(transaction, banks, stocks, invoices){ | ||
var id = transaction.invoice | ||
for (var to in invoices){ | ||
var outstanding = invoices[to].outstanding | ||
for (var i in outstanding){ | ||
if (outstanding[i].id == id){ | ||
// Move the invoice to closed | ||
var inv = outstanding[i]; | ||
invoices[to].paid.push(inv); | ||
outstanding.splice(i,1); | ||
_.each(reports, function(r){ | ||
if (r.onInvoiceClose){ | ||
r.onInvoiceClose(transaction, inv, invoices); | ||
} | ||
}) | ||
return; | ||
} | ||
} | ||
} | ||
throw "Outstanding invoice not found: " + id | ||
} | ||
var equityBuy = function(buy, stocks, banks){ | ||
@@ -66,3 +111,3 @@ var s = stocks[buy.symbol] || {} | ||
s.chunks = s.chunks || [] | ||
s.chunks.push({date: buy.date, quantity: buy.quantity}) | ||
s.chunks.push(buy) | ||
@@ -81,2 +126,3 @@ stocks[buy.symbol] = s | ||
stocks[buy.symbol].etf = (buy.typ =='etf-buy') | ||
stocks[buy.symbol].mutual_fund = (buy.typ =='mutfund-buy') | ||
stocks[buy.symbol].brokerage = buy.account // TODO!!! ASSUMES NO DUPE OF STOCK BETWEEN ACCTS | ||
@@ -92,2 +138,47 @@ | ||
var equitySell = function(sell, stocks, banks){ | ||
var s = stocks[sell.symbol] | ||
if (!s) | ||
throw "Selling equity that does not exist" | ||
var amount; | ||
if (sell.gross){ | ||
amount = sell.gross - sell.commission | ||
} else { // Price | ||
amount = (sell.quantity * sell.price) - sell.commission | ||
} | ||
sell.value = amount | ||
s.quantity = s.quantity - sell.quantity | ||
sell.cb = 0 | ||
// FIFO | ||
for (var i = 0, j = sell.quantity; i< s.chunks.length && j > 0; i++){ | ||
var chunk = s.chunks[i]; | ||
if (chunk.quantity > j){ | ||
chunk.quantity -= j; | ||
sell.cb += j * chunk.cost | ||
break; | ||
} else { | ||
s.chunks.splice(i, 1); | ||
sell.cb += chunk.quantity * chunk.cost | ||
j -= chunk.quantity; | ||
//TODO | ||
} | ||
} | ||
s.cost_basis -= sell.cb | ||
stocks[sell.symbol] = s | ||
banks[sell.account].balance -= amount | ||
banks[sell.account].positions[sell.symbol] -= sell.quantity | ||
_.each(reports, function(r){ | ||
if (r.onEquitySell) | ||
r.onEquitySell(sell, banks, stocks); | ||
}) | ||
} | ||
var dividend = function(div, stocks, banks){ | ||
@@ -146,2 +237,3 @@ var s = stocks[div.symbol] | ||
, banks = {} | ||
, invoices = {} | ||
@@ -153,3 +245,7 @@ for (var i=0; i<accts.length; i++){ | ||
} | ||
if (acct.typ == 'sell' || acct.typ== 'stock-sell' || acct.typ == 'etf-sell' || acct.typ == 'mutfund-sell'){ | ||
equitySell(acct, stocks, banks); | ||
} | ||
if (acct.typ == 'dividend'){ | ||
@@ -164,4 +260,8 @@ dividend(acct, stocks, banks) | ||
if (acct.typ == 'transaction'){ | ||
transaction(acct, banks, stocks) | ||
transaction(acct, banks, stocks, invoices) | ||
} | ||
if (acct.typ == 'invoice'){ | ||
invoice(acct, banks, stocks, invoices) | ||
} | ||
@@ -172,3 +272,3 @@ } | ||
if (r.onComplete) | ||
r.onComplete(banks, stocks); | ||
r.onComplete(banks, stocks, invoices); | ||
}) | ||
@@ -227,5 +327,5 @@ | ||
// $ gain of stock | ||
// unrealised $ gain of stock | ||
exports.stockGain = function(stock){ | ||
return stock.quantity * stock.current + stock.dividend - stock.cost_basis | ||
return stock.quantity * stock.current - stock.cost_basis | ||
} | ||
@@ -232,0 +332,0 @@ |
@@ -9,6 +9,6 @@ // This is an accounts.json file - it's just json but you can use comments | ||
, {"date" : "2012-01-03", "typ" : "transaction", "src" : "myjob", "dest" : "mybank", "amount" : 3000, "currency" : "USD"} | ||
, {"date" : "2012-01-04", "typ" : "transaction", "src" : "mybank", "dest" : "foo", "amount" : 10.99, "currency" : "USD"} | ||
, {"date" : "2012-01-04", "typ" : "transaction", "src" : "mybank", "dest" : "foo", "amount" : 51.50, "currency" : "USD"} | ||
, {"date" : "2012-01-04", "typ" : "statement", "acct" : "mybank", "balance" : 917.52, "currency" : "USD"} | ||
, {"date" : "2012-01-03", "typ" : "transaction", "src" : "myjob", "dest" : "mybank", "amount" : 3000, "currency" : "USD"} | ||
, {"date" : "2012-01-04", "typ" : "statement", "acct" : "mybank", "balance" : 3917.52, "currency" : "USD"} | ||
@@ -19,4 +19,10 @@ | ||
, {"date" : "2012-01-04", "typ" : "etf-buy", "symbol" : "BND", "quantity" : 10, "cost" : 83.73, "commission" : 10, "acct" : "mybank", "asset_class" : "Bonds"} | ||
, {"date" : "2012-01-04", "typ" : "etf-buy", "symbol" : "VTI", "quantity" : 10, "cost" : 60, "commission" : 10, "acct" : "mybank", "asset_class" : "US Stock Fund"} | ||
, {"date" : "2012-02-04", "typ" : "etf-buy", "symbol" : "VTI", "quantity" : 10, "cost" : 60, "commission" : 10, "acct" : "mybank", "asset_class" : "US Stock Fund"} | ||
, {"date" : "2012-03-04", "typ" : "etf-buy", "symbol" : "VTI", "quantity" : 10, "cost" : 60, "commission" : 10, "acct" : "mybank", "asset_class" : "US Stock Fund"} | ||
, {"date" : "2012-04-04", "typ" : "etf-buy", "symbol" : "VTI", "quantity" : 10, "cost" : 60, "commission" : 10, "acct" : "mybank", "asset_class" : "US Stock Fund"} | ||
, {"date" : "2013-05-17", "typ" : "etf-sell", "symbol" : "BND", "quantity" : 5, "price" : 89.73, "commission" : 10, "acct" : "mybank"} | ||
, {"date" : "2013-05-17", "typ" : "sell", "symbol" : "VTI", "quantity" : 25, "price" : 70, "commission" : 10, "acct" : "mybank"} | ||
] |
@@ -5,3 +5,3 @@ { | ||
"description": "Double Entry Accounting", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"repository": { | ||
@@ -30,3 +30,4 @@ "url": "" | ||
"acct-mix": "./scripts/mix.js", | ||
"acct-io": "./scripts/monthly-balances.js" | ||
"acct-io": "./scripts/monthly-balances.js", | ||
"acct-perf": "./scripts/realized-performance.js" | ||
}, | ||
@@ -33,0 +34,0 @@ "scripts": { |
@@ -40,2 +40,9 @@ var ac = require('../accountant') | ||
} | ||
, onEquityBuy: function(buy){ | ||
checkMonth(buy.date.slice(0, 7)); | ||
currmonthData.outgoing -= buy.cb; | ||
if (currmonthData.outgoing < 0) currmonthData.outgoing = 0 | ||
// Hacky - basically don't include stock purchases as 'outgoing' transactions | ||
// by reversing the amount | ||
} | ||
, onDividend: function(d){ | ||
@@ -42,0 +49,0 @@ checkMonth(d.date.slice(0,7)); |
@@ -96,3 +96,3 @@ var request = require('request') | ||
, gain = ac.stockGain(v) | ||
, ret = (gain)/v.cost_basis | ||
, ret = (gain + v.dividend)/v.cost_basis | ||
@@ -108,3 +108,3 @@ /* | ||
var vals = { | ||
symbol: v.etf ? k.yellow : k | ||
symbol: (v.etf || v.mutual_fund) ? k.yellow : k | ||
, price: c(v.current) | ||
@@ -124,3 +124,3 @@ , chg: cv(parseFloat(v.change), '', '', (-0.02 * v.current)) | ||
vals.sec = c((gain / age * 30) / v.cost_basis * 100) | ||
vals.sec = c(((gain + v.dividend)/ age * 30) / v.cost_basis * 100) | ||
@@ -127,0 +127,0 @@ |
@@ -26,2 +26,7 @@ var ac = require('../accountant') | ||
} | ||
, onEquitySell : function(sell){ | ||
if (SHOW_STOCK) | ||
console.log(ac.pad(sell.symbol, 5), 'Sell'.red, sell.quantity, sell.price, ": $", ac.c(sell.cb), "->", ac.c(sell.value)) | ||
} | ||
@@ -28,0 +33,0 @@ , onDividend : function(acct, banks, stocks){ |
@@ -25,3 +25,3 @@ var request = require('request') | ||
_.each(banks, function(v, k){ | ||
if (!v.balance || !v.last_statement) | ||
if (!v.last_statement) | ||
return; | ||
@@ -38,3 +38,3 @@ | ||
dollar_balance += v.cost_basis | ||
unrealised_gain += (v.current * v.quantity) - v.cost_basis; | ||
unrealised_gain += ac.stockGain(v); | ||
}) | ||
@@ -52,2 +52,4 @@ } | ||
} | ||
if (!v.balance && !unrealised_gain) | ||
return false; | ||
@@ -54,0 +56,0 @@ vals.push([k, dollar_balance, liquid, unrealised_gain]) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
456882
38
963
13