diff options
author | John Wiegley <johnw@newartisans.com> | 2019-08-03 13:37:58 -0700 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2019-12-06 14:06:22 +0100 |
commit | f77bdf19c307811d4659b6e85d147cdd5eee5ef3 (patch) | |
tree | 7a3dcae3901cb1543feed902dce256cf3b751d69 /src/balance.cc | |
parent | 6a140f313433e4ac21882d7995dbbb56124b4079 (diff) | |
download | fork-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.cc | 59 |
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 |