Created several alternate 'value' methods to support the upcoming commodity
valuation changes.
This commit is contained in:
parent
697f6a6bce
commit
79a8fc5a87
3 changed files with 90 additions and 51 deletions
|
|
@ -650,7 +650,8 @@ amount_t& amount_t::in_place_unreduce()
|
||||||
optional<amount_t> amount_t::value(const optional<datetime_t>& moment) const
|
optional<amount_t> amount_t::value(const optional<datetime_t>& moment) const
|
||||||
{
|
{
|
||||||
if (quantity) {
|
if (quantity) {
|
||||||
optional<amount_t> amt(commodity().value(moment));
|
// jww (2008-09-21): 'none' is not the right argument here.
|
||||||
|
optional<amount_t> amt(commodity().value(none, moment));
|
||||||
if (amt)
|
if (amt)
|
||||||
return (*amt * number()).round();
|
return (*amt * number()).round();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
105
src/commodity.cc
105
src/commodity.cc
|
|
@ -43,6 +43,44 @@
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
|
optional<commodity_t::history_t&>
|
||||||
|
commodity_t::history(const optional<const commodity_t&>& commodity) const
|
||||||
|
{
|
||||||
|
if (base->varied_history) {
|
||||||
|
const commodity_t * comm = NULL;
|
||||||
|
if (! commodity) {
|
||||||
|
if (base->varied_history->size() > 1)
|
||||||
|
// jww (2008-09-20): Document which option switch to use here
|
||||||
|
throw_(commodity_error, "Cannot determine history for '"
|
||||||
|
<< *this << "': prices known for multiple commodities (use -?)");
|
||||||
|
comm = (*base->varied_history->begin()).first;
|
||||||
|
} else {
|
||||||
|
comm = &(*commodity);
|
||||||
|
}
|
||||||
|
|
||||||
|
history_by_commodity_map::iterator i = base->varied_history->find(comm);
|
||||||
|
if (i != base->varied_history->end())
|
||||||
|
return (*i).second;
|
||||||
|
}
|
||||||
|
return none;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<commodity_t::history_t&>
|
||||||
|
commodity_t::history(const std::vector<const commodity_t *>& commodities) const
|
||||||
|
{
|
||||||
|
// This function differs from the single commodity case avoid in that
|
||||||
|
// 'commodities' represents a list of preferred valuation commodities.
|
||||||
|
// If no price can be located in terms of the first commodity, then
|
||||||
|
// the second is chosen, etc.
|
||||||
|
|
||||||
|
foreach (const commodity_t * commodity, commodities) {
|
||||||
|
if (optional<commodity_t::history_t&> hist =
|
||||||
|
history(*commodity))
|
||||||
|
return hist;
|
||||||
|
}
|
||||||
|
return none;
|
||||||
|
}
|
||||||
|
|
||||||
void commodity_t::add_price(const datetime_t& date, const amount_t& price)
|
void commodity_t::add_price(const datetime_t& date, const amount_t& price)
|
||||||
{
|
{
|
||||||
if (! base->varied_history)
|
if (! base->varied_history)
|
||||||
|
|
@ -85,57 +123,42 @@ bool commodity_t::remove_price(const datetime_t& date, const commodity_t& comm)
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<amount_t>
|
optional<amount_t>
|
||||||
commodity_t::value(const optional<datetime_t>& moment,
|
commodity_t::value(const history_t& history,
|
||||||
const optional<std::vector<const commodity_t *> >& commodities)
|
const optional<datetime_t>& moment)
|
||||||
{
|
{
|
||||||
optional<datetime_t> age;
|
optional<datetime_t> age;
|
||||||
optional<amount_t> price;
|
optional<amount_t> price;
|
||||||
optional<history_t&> hist;
|
|
||||||
|
|
||||||
if (base->varied_history) {
|
if (history.prices.size() == 0)
|
||||||
const commodity_t * comm = NULL;
|
return none;
|
||||||
if (commodities) {
|
|
||||||
// Walk the list of commodities, finding the first one applicable
|
if (! moment) {
|
||||||
comm = commodities->back();
|
history_map::const_reverse_iterator r = history.prices.rbegin();
|
||||||
|
age = (*r).first;
|
||||||
|
price = (*r).second;
|
||||||
|
} else {
|
||||||
|
history_map::const_iterator i = history.prices.lower_bound(*moment);
|
||||||
|
if (i == history.prices.end()) {
|
||||||
|
history_map::const_reverse_iterator r = history.prices.rbegin();
|
||||||
|
age = (*r).first;
|
||||||
|
price = (*r).second;
|
||||||
} else {
|
} else {
|
||||||
if (base->varied_history->size() > 1)
|
age = (*i).first;
|
||||||
throw_(commodity_error,
|
if (*moment != *age) {
|
||||||
"Cannot find commodity value: multiple possibilities exist");
|
if (i != history.prices.begin()) {
|
||||||
comm = (*base->varied_history->begin()).first;
|
--i;
|
||||||
}
|
age = (*i).first;
|
||||||
|
price = (*i).second;
|
||||||
hist = history(*comm);
|
|
||||||
if (hist) {
|
|
||||||
assert(hist->prices.size() > 0);
|
|
||||||
|
|
||||||
if (! moment) {
|
|
||||||
history_map::reverse_iterator r = hist->prices.rbegin();
|
|
||||||
age = (*r).first;
|
|
||||||
price = (*r).second;
|
|
||||||
} else {
|
|
||||||
history_map::iterator i = hist->prices.lower_bound(*moment);
|
|
||||||
if (i == hist->prices.end()) {
|
|
||||||
history_map::reverse_iterator r = hist->prices.rbegin();
|
|
||||||
age = (*r).first;
|
|
||||||
price = (*r).second;
|
|
||||||
} else {
|
} else {
|
||||||
age = (*i).first;
|
age = none;
|
||||||
if (*moment != *age) {
|
|
||||||
if (i != hist->prices.begin()) {
|
|
||||||
--i;
|
|
||||||
age = (*i).first;
|
|
||||||
price = (*i).second;
|
|
||||||
} else {
|
|
||||||
age = none;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
price = (*i).second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
price = (*i).second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (! has_flags(COMMODITY_STYLE_NOMARKET) && parent().get_quote) {
|
if (! has_flags(COMMODITY_STYLE_NOMARKET) && parent().get_quote) {
|
||||||
if (optional<amount_t> quote = parent().get_quote
|
if (optional<amount_t> quote = parent().get_quote
|
||||||
(*this, age, moment,
|
(*this, age, moment,
|
||||||
|
|
@ -143,6 +166,8 @@ commodity_t::value(const optional<datetime_t>& moment,
|
||||||
(*hist->prices.rbegin()).first : optional<datetime_t>())))
|
(*hist->prices.rbegin()).first : optional<datetime_t>())))
|
||||||
return *quote;
|
return *quote;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return price;
|
return price;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -201,21 +201,34 @@ public:
|
||||||
return *base->varied_history;
|
return *base->varied_history;
|
||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
optional<history_t&> history(const commodity_t& comm) const {
|
|
||||||
if (base->varied_history) {
|
optional<history_t&>
|
||||||
history_by_commodity_map::iterator i = base->varied_history->find(&comm);
|
history(const optional<const commodity_t&>& commodity) const;
|
||||||
if (i != base->varied_history->end())
|
optional<history_t&>
|
||||||
return (*i).second;
|
history(const std::vector<const commodity_t *>& commodities) const;
|
||||||
}
|
|
||||||
return none;
|
|
||||||
}
|
|
||||||
|
|
||||||
void add_price(const datetime_t& date, const amount_t& price);
|
void add_price(const datetime_t& date, const amount_t& price);
|
||||||
bool remove_price(const datetime_t& date, const commodity_t& comm);
|
bool remove_price(const datetime_t& date, const commodity_t& comm);
|
||||||
|
|
||||||
optional<amount_t>
|
optional<amount_t>
|
||||||
value(const optional<datetime_t>& moment = none,
|
value(const history_t& history,
|
||||||
const optional<std::vector<const commodity_t *> >& commodities = none);
|
const optional<datetime_t>& moment = none);
|
||||||
|
|
||||||
|
optional<amount_t>
|
||||||
|
value(const optional<const commodity_t&>& commodity = none,
|
||||||
|
const optional<datetime_t>& moment = none) {
|
||||||
|
if (optional<history_t&> hist = history(commodity))
|
||||||
|
return value(*hist, moment);
|
||||||
|
return none;
|
||||||
|
}
|
||||||
|
|
||||||
|
optional<amount_t>
|
||||||
|
value(const std::vector<const commodity_t *>& commodities,
|
||||||
|
const optional<datetime_t>& moment = none) {
|
||||||
|
if (optional<history_t&> hist = history(commodities))
|
||||||
|
return value(*hist, moment);
|
||||||
|
return none;
|
||||||
|
}
|
||||||
|
|
||||||
static void exchange(commodity_t& commodity,
|
static void exchange(commodity_t& commodity,
|
||||||
const amount_t& per_unit_cost,
|
const amount_t& per_unit_cost,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue