From f77bdf19c307811d4659b6e85d147cdd5eee5ef3 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 3 Aug 2019 13:37:58 -0700 Subject: Add --averaged-lot-prices This joins together lots of the same underlying, averaging the reported price and using the date of the oldest lot. --- src/balance.cc | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'src/balance.cc') 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, + std::pair > balance_map; + balance_map bycomm; + + foreach (const balance_t::amounts_map::value_type& pair, bal.amounts) { + optional 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(*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 -- cgit v1.2.3