mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
edefc9e57c
commit
7adc5e4451
@ -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);
|
||||||
|
@ -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)),
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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))
|
||||||
|
@ -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
|
||||||
|
@ -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)))))
|
||||||
|
@ -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)))
|
||||||
|
Loading…
Reference in New Issue
Block a user