Handle reversed prices from gnc_pricedb_lookup*.

In several cases replaces attempting to check both directions directly. This
had produced incorrect results because an older forward price would be preferred
over a reverse price.
This commit is contained in:
John Ralls 2015-10-29 14:13:37 -07:00
parent edefc9e57c
commit 7adc5e4451
10 changed files with 383 additions and 405 deletions

View File

@ -1122,9 +1122,6 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
price = gnc_pricedb_lookup_latest(price_db, first_cmdty, split_cmdty); price = gnc_pricedb_lookup_latest(price_db, first_cmdty, split_cmdty);
if (price == NULL) if (price == NULL)
{ {
price = gnc_pricedb_lookup_latest(price_db, split_cmdty, first_cmdty);
if (price == NULL)
{
GString *err = g_string_new(""); GString *err = g_string_new("");
g_string_printf(err, "could not find pricedb entry for commodity-pair (%s, %s).", g_string_printf(err, "could not find pricedb entry for commodity-pair (%s, %s).",
gnc_commodity_get_mnemonic(first_cmdty), gnc_commodity_get_mnemonic(first_cmdty),
@ -1135,6 +1132,8 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
} }
else else
{ {
if (gnc_commodity_equiv(first_cmdty,
gnc_price_get_commodity(price)))
exchange = gnc_numeric_invert(gnc_price_get_value(price)); exchange = gnc_numeric_invert(gnc_price_get_value(price));
exchange = gnc_numeric_convert(exchange, 1000, exchange = gnc_numeric_convert(exchange, 1000,
GNC_HOW_RND_ROUND_HALF_UP); GNC_HOW_RND_ROUND_HALF_UP);

View File

@ -263,34 +263,18 @@ lookup_price(PriceReq *pr, PriceDate pd)
case SAME_DAY: case SAME_DAY:
prc = gnc_pricedb_lookup_day (pr->pricedb, pr->from, prc = gnc_pricedb_lookup_day (pr->pricedb, pr->from,
pr->to, pr->ts); pr->to, pr->ts);
if (!prc)
{
prc = gnc_pricedb_lookup_day (pr->pricedb, pr->to,
pr->from, pr->ts);
pr->reverse = TRUE;
}
break; break;
case NEAREST: case NEAREST:
prc = gnc_pricedb_lookup_nearest_in_time (pr->pricedb, pr->from, prc = gnc_pricedb_lookup_nearest_in_time (pr->pricedb, pr->from,
pr->to, pr->ts); pr->to, pr->ts);
if (!prc)
{
prc = gnc_pricedb_lookup_nearest_in_time (pr->pricedb, pr->to,
pr->from, pr->ts);
pr->reverse = TRUE;
}
break; break;
case LATEST: case LATEST:
prc = gnc_pricedb_lookup_latest (pr->pricedb, pr->from, pr->to); prc = gnc_pricedb_lookup_latest (pr->pricedb, pr->from, pr->to);
if (!prc)
{
prc = gnc_pricedb_lookup_latest (pr->pricedb, pr->to, pr->from);
pr->reverse = TRUE;
}
break; break;
} }
if (pr->reverse) if (gnc_commodity_equiv(gnc_price_get_currency(prc), pr->from))
{ {
pr->reverse = TRUE;
PINFO("Found reverse price: 1 %s = %f %s", PINFO("Found reverse price: 1 %s = %f %s",
gnc_commodity_get_mnemonic(pr->to), gnc_commodity_get_mnemonic(pr->to),
gnc_numeric_to_double(gnc_price_get_value(prc)), gnc_numeric_to_double(gnc_price_get_value(prc)),

View File

@ -90,38 +90,16 @@ static gnc_numeric
gtu_sr_get_rate_from_db (gnc_commodity *from, gnc_commodity *to) gtu_sr_get_rate_from_db (gnc_commodity *from, gnc_commodity *to)
{ {
GNCPrice *prc; GNCPrice *prc;
gnc_numeric rate_split;
gboolean have_rate = FALSE;
QofBook *book = gnc_get_current_book (); QofBook *book = gnc_get_current_book ();
/* Do we have a rate allready */
prc = gnc_pricedb_lookup_latest (gnc_pricedb_get_db (book), from, to); prc = gnc_pricedb_lookup_latest (gnc_pricedb_get_db (book), from, to);
if (prc)
{
rate_split = gnc_price_get_value (prc);
gnc_price_unref (prc);
have_rate = TRUE;
}
/* Lets try reversing the commodities */ if (!prc)
if (!have_rate) return gnc_numeric_create (100, 100);
{
prc = gnc_pricedb_lookup_latest (gnc_pricedb_get_db (book), to, from);
if (prc)
{
rate_split = gnc_numeric_div (gnc_numeric_create (100, 100), gnc_price_get_value (prc),
GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
gnc_price_unref (prc); if (gnc_commodity_equiv(from, gnc_price_get_currency(prc)))
have_rate = TRUE; return gnc_numeric_invert(gnc_price_get_value(prc));
} return gnc_price_get_value(prc);
}
/* No rate, set to 1/1 */
if (!have_rate)
rate_split = gnc_numeric_create (100, 100);
return rate_split;
} }

View File

@ -231,6 +231,9 @@ refresh_details_page (StockSplitInfo *info)
if (prices) if (prices)
{ {
/* Use the first existing price */ /* Use the first existing price */
if (gnc_commodity_equiv (commodity, gnc_price_get_currency(prices->data)))
currency = gnc_price_get_commodity(prices->data);
else
currency = gnc_price_get_currency(prices->data); currency = gnc_price_get_currency(prices->data);
} }
else else

View File

@ -347,7 +347,11 @@ pedit_commodity_changed_cb (GtkComboBox *cbwe, gpointer data)
(pedit_dialog->price_db, commodity); (pedit_dialog->price_db, commodity);
if (price_list) if (price_list)
{ {
currency = gnc_price_get_currency((GNCPrice *)price_list->data); GNCPrice * price = (GNCPrice*)price_list->data;
if (gnc_commodity_equiv(commodity, gnc_price_get_currency(price)))
currency = gnc_price_get_commodity((GNCPrice *)price);
else
currency = gnc_price_get_currency((GNCPrice *)price);
if (currency) if (currency)
gnc_currency_edit_set_currency gnc_currency_edit_set_currency

View File

@ -2067,15 +2067,9 @@ record_price (SplitRegister *reg, Account *account, gnc_numeric value,
return; return;
gnc_date_cell_get_date ((DateCell*)cell, &ts); gnc_date_cell_get_date ((DateCell*)cell, &ts);
price = gnc_pricedb_lookup_day (pricedb, comm, curr, ts); price = gnc_pricedb_lookup_day (pricedb, comm, curr, ts);
if (!price) if (gnc_commodity_equiv (comm, gnc_price_get_currency (price)))
{
price = gnc_pricedb_lookup_day (pricedb, curr, comm, ts);
if (price)
/* It might be better to raise an error here: We shouldn't be creating
* currency->commodity prices.
*/
swap = TRUE; swap = TRUE;
}
if (price) if (price)
{ {
price_value = gnc_price_get_value(price); price_value = gnc_price_get_value(price);

View File

@ -724,12 +724,15 @@
(begin ;; do so (begin ;; do so
(set! missing-pricedb-entry? #f) (set! missing-pricedb-entry? #f)
(set! pricedb-lookup-price (set! pricedb-lookup-price
(gnc-pricedb-lookup-nearest-in-time (let ((price (gnc-pricedb-lookup-nearest-in-time
pricedb pricedb
account-commodity account-commodity
USD-currency USD-currency
(timespecCanonicalDayTime (timespecCanonicalDayTime
lookup-date))) lookup-date))))
(if (gnc-commodity-equiv account-commodity (gnc-price-get-currency price))
(set! price (gnc-price-invert price)))
price))
(set! pricedb-lookup-price-value (set! pricedb-lookup-price-value
(gnc-price-get-value (gnc-price-get-value
pricedb-lookup-price)) pricedb-lookup-price))

View File

@ -359,7 +359,9 @@
(for-each (for-each
(lambda (p) (lambda (p)
(if (gnc-commodity-equiv currency (gnc-price-get-currency p)) (if (gnc-commodity-equiv currency (gnc-price-get-currency p))
(set! price p))) (set! price p))
(if (gnc-commodity-equiv currency (gnc-price-get-commodity p))
(set! price (gnc-price-invert p))))
price-list) price-list)
(gnc-price-ref price) (gnc-price-ref price)
(gnc-price-list-destroy price-list) (gnc-price-list-destroy price-list)
@ -1047,7 +1049,7 @@
(sum-total-gain (gnc-numeric-zero)) (sum-total-gain (gnc-numeric-zero))
(sum-total-ugain (gnc-numeric-zero)) (sum-total-ugain (gnc-numeric-zero))
(sum-total-brokerage (gnc-numeric-zero)) (sum-total-brokerage (gnc-numeric-zero))
(sum-total-totalreturn (gnc-numeric-zero))) (sum-total-totalreturn (gnc-numeric-zero))) ;;end of let
;;begin building lists for which columns to display ;;begin building lists for which columns to display
(if show-symbol (if show-symbol

View File

@ -219,7 +219,13 @@
(gnc-pricedb-lookup-latest-any-currency (gnc-pricedb-lookup-latest-any-currency
pricedb foreign)) pricedb foreign))
(fn (if (and price (> (length price) 0)) (fn (if (and price (> (length price) 0))
(let ((v (gnc-price-get-value (car price)))) (let* ((the_price
(if (gnc-commodity-equiv
foreign
(gnc-price-get-commodity (car price)))
(car price)
(gnc-price-invert (car price))))
(v (gnc-price-get-value the_price)))
(gnc-price-ref (car price)) (gnc-price-ref (car price))
(cons (car price) v)) (cons (car price) v))
(cons #f (gnc-numeric-zero))))) (cons #f (gnc-numeric-zero)))))
@ -231,7 +237,13 @@
(gnc-pricedb-lookup-nearest-in-time-any-currency (gnc-pricedb-lookup-nearest-in-time-any-currency
pricedb foreign (timespecCanonicalDayTime date))) pricedb foreign (timespecCanonicalDayTime date)))
(fn (if (and price (> (length price) 0)) (fn (if (and price (> (length price) 0))
(let ((v (gnc-price-get-value (car price)))) (let* ((the_price
(if (gnc-commodity-equiv
foreign
(gnc-price-get-commodity (car price)))
(car price)
(gnc-price-invert (car price))))
(v (gnc-price-get-value (car price))))
(gnc-price-ref (car price)) (gnc-price-ref (car price))
(cons (car price) v)) (cons (car price) v))
(cons #f (gnc-numeric-zero))))) (cons #f (gnc-numeric-zero)))))

View File

@ -419,13 +419,11 @@
(set! saved-price (gnc-pricedb-lookup-day pricedb (set! saved-price (gnc-pricedb-lookup-day pricedb
commodity currency commodity currency
gnc-time)) gnc-time))
(if (null? saved-price) ;;See if there's a reversed price. (if (not (null? saved-price))
(begin (begin
(set! saved-price (gnc-pricedb-lookup-day pricedb currency (if (gnc-commodity-equiv (gnc-price-get-currency saved-price)
commodity gnc-time)) commodity)
(if (not (null? saved-price)) (set! price (gnc-numeric-invert price)))
(set! price (gnc-numeric-invert price)))))
(if (not (null? saved-price))
(if (> (gnc-price-get-source saved-price) PRICE-SOURCE-FQ) (if (> (gnc-price-get-source saved-price) PRICE-SOURCE-FQ)
(begin (begin
(gnc-price-begin-edit saved-price) (gnc-price-begin-edit saved-price)
@ -450,7 +448,8 @@
(gnc-price-set-value gnc-price price) (gnc-price-set-value gnc-price price)
(gnc-price-commit-edit gnc-price) (gnc-price-commit-edit gnc-price)
gnc-price))))) gnc-price)))))
))) ))
))
(define (book-add-prices! book prices) (define (book-add-prices! book prices)
(let ((pricedb (gnc-pricedb-get-db book))) (let ((pricedb (gnc-pricedb-get-db book)))