summaryrefslogtreecommitdiff
path: root/src/balance.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2019-08-03 13:37:58 -0700
committerJohn Wiegley <johnw@newartisans.com>2019-12-06 14:06:22 +0100
commitf77bdf19c307811d4659b6e85d147cdd5eee5ef3 (patch)
tree7a3dcae3901cb1543feed902dce256cf3b751d69 /src/balance.cc
parent6a140f313433e4ac21882d7995dbbb56124b4079 (diff)
downloadfork-ledger-f77bdf19c307811d4659b6e85d147cdd5eee5ef3.tar.gz
fork-ledger-f77bdf19c307811d4659b6e85d147cdd5eee5ef3.tar.bz2
fork-ledger-f77bdf19c307811d4659b6e85d147cdd5eee5ef3.zip
Add --averaged-lot-prices
This joins together lots of the same underlying, averaging the reported price and using the date of the oldest lot.
Diffstat (limited to 'src/balance.cc')
-rw-r--r--src/balance.cc59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/balance.cc b/src/balance.cc
index 5f5e6fc9..f0065dc5 100644
--- a/src/balance.cc
+++ b/src/balance.cc
@@ -345,4 +345,63 @@ void put_balance(property_tree::ptree& st, const balance_t& bal)
put_amount(st.add("amount", ""), pair.second);
}
+balance_t average_lot_prices(const balance_t& bal)
+{
+ // First, we split the balance into multiple balances by underlying
+ // commodity.
+ typedef std::map<optional<std::string>,
+ std::pair<amount_t, annotation_t> > balance_map;
+ balance_map bycomm;
+
+ foreach (const balance_t::amounts_map::value_type& pair, bal.amounts) {
+ optional<std::string> sym(pair.first->symbol());
+ amount_t quant(pair.second.strip_annotations(keep_details_t()));
+
+ balance_map::iterator i = bycomm.find(sym);
+ if (i == bycomm.end()) {
+ bycomm.insert(
+ balance_map::value_type(sym, std::make_pair(quant, annotation_t())));
+ i = bycomm.find(sym); // must succeed now
+ } else {
+ (*i).second.first += quant;
+ }
+
+ if (pair.first->has_annotation()) {
+ annotated_commodity_t& acomm(static_cast<annotated_commodity_t&>(*pair.first));
+ annotation_t& ann((*i).second.second);
+
+ if (acomm.details.price) {
+ if (ann.price)
+ ann.price = *ann.price + (*acomm.details.price * quant);
+ else
+ ann.price = *acomm.details.price * quant;
+ }
+
+ if (acomm.details.date) {
+ if (! ann.date || *acomm.details.date < *ann.date)
+ ann.date = *acomm.details.date;
+ }
+ }
+ }
+
+ balance_t result;
+
+ foreach (balance_map::value_type& pair, bycomm) {
+ amount_t amt(pair.second.first);
+ if (! amt.is_realzero()) {
+ if (pair.second.second.price)
+ pair.second.second.price = *pair.second.second.price / amt;
+
+ commodity_t * acomm =
+ commodity_pool_t::current_pool->find_or_create(
+ amt.commodity(), pair.second.second);
+ amt.set_commodity(*acomm);
+
+ result += amt;
+ }
+ }
+
+ return result;
+}
+
} // namespace ledger