mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge 4f05cd8424
into 5ce3a9dd1d
This commit is contained in:
commit
15d544a012
@ -60,12 +60,14 @@
|
||||
(define optname-show-sold-columns (N_ "Show sold columns"))
|
||||
(define optname-show-end-columns (N_ "Show end columns"))
|
||||
(define optname-show-realized-gain-columns
|
||||
(N_ "Show realized gain column(s)"))
|
||||
(N_ "Show realized gain columns"))
|
||||
(define optname-show-unrealized-gain-columns
|
||||
(N_ "Show unrealized gain column(s)"))
|
||||
(N_ "Show unrealized gain columns"))
|
||||
(define optname-group-gains-by-age
|
||||
(N_ "Group gains by age (short term and long term)"))
|
||||
(define optname-long-term-years (N_ "Long term gains age (years)"))
|
||||
(define optname-show-roi-columns (N_ "Show ROI columns"))
|
||||
(define optname-show-cagr-columns (N_ "Show CAGR columns"))
|
||||
|
||||
;; Display
|
||||
(define optname-show-long-account-names (N_ "Show long account names"))
|
||||
@ -123,10 +125,12 @@
|
||||
(define colname-short-term-realized-gain (N_ "ST Realized Gain"))
|
||||
(define colname-long-term-realized-gain (N_ "LT Realized Gain"))
|
||||
(define colname-realized-roi (N_ "Realized ROI"))
|
||||
(define colname-realized-cagr (N_ "Realized CAGR"))
|
||||
(define colname-unrealized-gain (N_ "Unrealized Gain"))
|
||||
(define colname-short-term-unrealized-gain (N_ "ST Unrealized Gain"))
|
||||
(define colname-long-term-unrealized-gain (N_ "LT Unrealized Gain"))
|
||||
(define colname-unrealized-roi (N_ "Unrealized ROI"))
|
||||
(define colname-unrealized-cagr (N_ "Unrealized CAGR"))
|
||||
|
||||
(define label-account-total (N_ "Account Lots Total"))
|
||||
(define label-grand-total (N_ "Grand Total"))
|
||||
@ -135,7 +139,22 @@
|
||||
;; will use to display a dialog where the user can select
|
||||
;; values for the report's parameters.
|
||||
(define (options-generator)
|
||||
(let* ((options (gnc-new-optiondb)))
|
||||
(let* ((options (gnc-new-optiondb))
|
||||
(uncommited-show-realized-gain-columns #f)
|
||||
(uncommited-show-unrealized-gain-columns #f))
|
||||
|
||||
;; When both realized and unrealized gain columns are hidden, the gain
|
||||
;; percentage columns (ROI and CAGR) won't be visible anyways, so disable
|
||||
;; their corresponding options.
|
||||
(define (update-gain-percentage-columns-enabled)
|
||||
(let ((enabled (or uncommited-show-realized-gain-columns
|
||||
uncommited-show-unrealized-gain-columns)))
|
||||
(for-each
|
||||
(lambda (name)
|
||||
(gnc-optiondb-set-option-selectable-by-name options
|
||||
pagename-columns name enabled))
|
||||
(list optname-show-roi-columns
|
||||
optname-show-cagr-columns))))
|
||||
|
||||
;; Accounts tab
|
||||
(gnc-register-account-list-limited-option options
|
||||
@ -207,7 +226,7 @@
|
||||
(cons 'percent 50.0))
|
||||
|
||||
;; Columns tab
|
||||
(gnc-register-simple-boolean-option options
|
||||
(gnc-register-simple-boolean-option options
|
||||
pagename-columns
|
||||
optname-show-lot-guid-column
|
||||
"a"
|
||||
@ -242,19 +261,25 @@
|
||||
(N_ "Show end date amount and value table columns")
|
||||
#t)
|
||||
|
||||
(gnc-register-simple-boolean-option options
|
||||
(gnc-register-complex-boolean-option options
|
||||
pagename-columns
|
||||
optname-show-realized-gain-columns
|
||||
"f"
|
||||
(N_ "Show realized gain table column(s) for sold shares")
|
||||
#t)
|
||||
#t
|
||||
(lambda (x)
|
||||
(set! uncommited-show-realized-gain-columns x)
|
||||
(update-gain-percentage-columns-enabled)))
|
||||
|
||||
(gnc-register-simple-boolean-option options
|
||||
(gnc-register-complex-boolean-option options
|
||||
pagename-columns
|
||||
optname-show-unrealized-gain-columns
|
||||
"g"
|
||||
(N_ "Show unrealized gain table column(s) for unsold shares")
|
||||
#t)
|
||||
#t
|
||||
(lambda (x)
|
||||
(set! uncommited-show-unrealized-gain-columns x)
|
||||
(update-gain-percentage-columns-enabled)))
|
||||
|
||||
(gnc-register-multichoice-callback-option options
|
||||
pagename-columns
|
||||
@ -285,6 +310,20 @@
|
||||
10E9 ;; upper-bound
|
||||
1) ;; step-size
|
||||
|
||||
(gnc-register-simple-boolean-option options
|
||||
pagename-columns
|
||||
optname-show-roi-columns
|
||||
"j"
|
||||
(N_ "Show Return On Investment (ROI) columns")
|
||||
#f)
|
||||
|
||||
(gnc-register-simple-boolean-option options
|
||||
pagename-columns
|
||||
optname-show-cagr-columns
|
||||
"k"
|
||||
(N_ "Show Compound Annual Growth Rate (CAGR) columns")
|
||||
#t)
|
||||
|
||||
;; Display tab
|
||||
(gnc-register-simple-boolean-option options
|
||||
gnc:pagename-display
|
||||
@ -325,6 +364,14 @@
|
||||
(gnc:options-add-date-interval!
|
||||
options gnc:pagename-general optname-from-date optname-to-date "a")
|
||||
|
||||
;; Use a default report date of 'today'. Otherwise,
|
||||
;; 'end of accounting period' would be the default. A future date
|
||||
;; makes a poor default because they may result in misleading/non-sensical
|
||||
;; unrealized CAGR percentages.
|
||||
(GncOption-set-default-value
|
||||
(gnc-lookup-option options gnc:pagename-general optname-to-date)
|
||||
'today)
|
||||
|
||||
(gnc:options-add-currency!
|
||||
options
|
||||
gnc:pagename-general
|
||||
@ -402,8 +449,7 @@
|
||||
|
||||
;; This is a helper function for looking up option values.
|
||||
(define (get-option section name)
|
||||
(gnc:option-value
|
||||
(gnc:lookup-option (gnc:report-options report-obj) section name)))
|
||||
(gnc-optiondb-lookup-value (gnc:report-options report-obj) section name))
|
||||
|
||||
;; Given a price list and a currency find the price for that currency on the
|
||||
;; list. If there is none for the requested currency, return the first one.
|
||||
@ -458,6 +504,10 @@
|
||||
(get-option pagename-columns optname-group-gains-by-age))
|
||||
(long-term-years
|
||||
(get-option pagename-columns optname-long-term-years))
|
||||
(show-roi-columns
|
||||
(get-option pagename-columns optname-show-roi-columns))
|
||||
(show-cagr-columns
|
||||
(get-option pagename-columns optname-show-cagr-columns))
|
||||
|
||||
;; Display options
|
||||
(include-closed-lots
|
||||
@ -578,6 +628,18 @@
|
||||
(> years-held long-term-years))
|
||||
#f))
|
||||
|
||||
;; Returns the Compound Annual Growth Rate (CAGR). Returns false if basis
|
||||
;; and/or years are zero or false.
|
||||
(define (get-cagr basis end-value years)
|
||||
(if (or (eq? basis #f)
|
||||
(gnc-numeric-zero-p basis)
|
||||
(eq? years #f)
|
||||
(zero? years))
|
||||
#f ; Unable to compute CAGR.
|
||||
(- (expt (/ end-value basis)
|
||||
(/ 1 years))
|
||||
1)))
|
||||
|
||||
;; Gets the account name.
|
||||
(define (account->name account)
|
||||
(if show-long-account-names
|
||||
@ -830,6 +892,28 @@
|
||||
;; accounts may have different commodities, so combining their amounts
|
||||
;; would not make sense).
|
||||
(define (get-column-header-list is-grand-total)
|
||||
|
||||
;; Helper function for getting the list of gains-related column names.
|
||||
(define (get-gains-column-header-list
|
||||
colname-short-term-gain
|
||||
colname-long-term-gain
|
||||
colname-gain
|
||||
colname-roi
|
||||
colname-cagr)
|
||||
(append
|
||||
(if group-gains-by-age
|
||||
(list
|
||||
colname-short-term-gain
|
||||
colname-long-term-gain)
|
||||
(list
|
||||
colname-gain))
|
||||
(if show-roi-columns
|
||||
(list colname-roi)
|
||||
'())
|
||||
(if show-cagr-columns
|
||||
(list
|
||||
(if is-grand-total #f colname-cagr))
|
||||
'())))
|
||||
(append
|
||||
(list (if is-grand-total #f colname-lot-title))
|
||||
(if show-lot-guid-column
|
||||
@ -871,24 +955,20 @@
|
||||
colname-end-value)
|
||||
'())
|
||||
(if show-realized-gain-columns
|
||||
(if group-gains-by-age
|
||||
(list
|
||||
colname-short-term-realized-gain
|
||||
colname-long-term-realized-gain
|
||||
colname-realized-roi)
|
||||
(list
|
||||
colname-realized-gain
|
||||
colname-realized-roi))
|
||||
(get-gains-column-header-list
|
||||
colname-short-term-realized-gain
|
||||
colname-long-term-realized-gain
|
||||
colname-realized-gain
|
||||
colname-realized-roi
|
||||
colname-realized-cagr)
|
||||
'())
|
||||
(if show-unrealized-gain-columns
|
||||
(if group-gains-by-age
|
||||
(list
|
||||
colname-short-term-unrealized-gain
|
||||
colname-long-term-unrealized-gain
|
||||
colname-unrealized-roi)
|
||||
(list
|
||||
colname-unrealized-gain
|
||||
colname-unrealized-roi))
|
||||
(get-gains-column-header-list
|
||||
colname-short-term-unrealized-gain
|
||||
colname-long-term-unrealized-gain
|
||||
colname-unrealized-gain
|
||||
colname-unrealized-roi
|
||||
colname-unrealized-cagr)
|
||||
'())))
|
||||
|
||||
;; The number of table columns.
|
||||
@ -965,8 +1045,10 @@
|
||||
end-value
|
||||
short-term-realized-gain
|
||||
long-term-realized-gain
|
||||
realized-cagr
|
||||
short-term-unrealized-gain
|
||||
long-term-unrealized-gain)
|
||||
long-term-unrealized-gain
|
||||
unrealized-cagr)
|
||||
;; Helper function for converting a numeric value to an html table cell.
|
||||
(define (to-cell val format-val-fn)
|
||||
(if (or (not val)
|
||||
@ -1022,7 +1104,7 @@
|
||||
(value->monetary value))))
|
||||
|
||||
;; Helper function for adding capital gains columns
|
||||
(define (get-gains-fn show-columns basis short-gain long-gain)
|
||||
(define (get-gains-fn show-columns basis short-gain long-gain cagr-value)
|
||||
(append
|
||||
(if show-columns
|
||||
(let* ((total-gain (gnc-numeric-add-fixed
|
||||
@ -1036,15 +1118,24 @@
|
||||
((gnc-numeric-zero-p basis)
|
||||
0)
|
||||
(else
|
||||
(* 100 (/ total-gain basis)))))))
|
||||
(if group-gains-by-age
|
||||
(list
|
||||
(value->cell short-gain)
|
||||
(value->cell long-gain)
|
||||
roi)
|
||||
(list
|
||||
(value->cell total-gain)
|
||||
roi)))
|
||||
(* 100 (/ total-gain basis))))))
|
||||
(cagr (percentage->cell
|
||||
(if cagr-value
|
||||
(* 100 cagr-value)
|
||||
#f))))
|
||||
(append
|
||||
(if group-gains-by-age
|
||||
(list
|
||||
(value->cell short-gain)
|
||||
(value->cell long-gain))
|
||||
(list
|
||||
(value->cell total-gain)))
|
||||
(if show-roi-columns
|
||||
(list roi)
|
||||
'())
|
||||
(if show-cagr-columns
|
||||
(list cagr)
|
||||
'())))
|
||||
'())))
|
||||
|
||||
(if is-bold
|
||||
@ -1113,12 +1204,14 @@
|
||||
show-realized-gain-columns
|
||||
sold-basis
|
||||
short-term-realized-gain
|
||||
long-term-realized-gain)
|
||||
long-term-realized-gain
|
||||
realized-cagr)
|
||||
(get-gains-fn
|
||||
show-unrealized-gain-columns
|
||||
end-basis
|
||||
short-term-unrealized-gain
|
||||
long-term-unrealized-gain))))
|
||||
long-term-unrealized-gain
|
||||
unrealized-cagr))))
|
||||
(gnc:html-table-append-row/markup!
|
||||
table
|
||||
(if is-bold "grand-total" (get-row-style is-odd-row))
|
||||
@ -1163,12 +1256,14 @@
|
||||
(long-term-sold-basis (get-report-value-zero))
|
||||
(long-term-sold-value (get-report-value-zero))
|
||||
(long-term-realized-gain (get-report-value-zero))
|
||||
(weighted-realized-cagr 0.0)
|
||||
(end-amount (get-amount-zero))
|
||||
(end-basis (get-report-value-zero))
|
||||
(end-value (get-report-value-zero))
|
||||
(unrealized-gain (get-report-value-zero))
|
||||
(short-term-unrealized-gain (get-report-value-zero))
|
||||
(long-term-unrealized-gain (get-report-value-zero))
|
||||
(weighted-unrealized-cagr 0.0)
|
||||
(has-warnings #f)
|
||||
(is-active-in-window #f)
|
||||
(currency '())
|
||||
@ -1221,7 +1316,8 @@
|
||||
sold-basis
|
||||
sold-value
|
||||
sold-gain
|
||||
is-long-term)
|
||||
is-long-term
|
||||
cagr)
|
||||
(if show-split-rows
|
||||
(let ((date-cell
|
||||
(to-split-cell (qof-print-date trans-date) split))
|
||||
@ -1260,8 +1356,10 @@
|
||||
(if (and is-long-term sold-gain) 0 sold-gain)
|
||||
;; long-term-realized-gain
|
||||
(if (and is-long-term sold-gain) sold-gain 0)
|
||||
cagr ;; realized-cagr
|
||||
#f ;; short-term-unrealized-gain
|
||||
#f)))) ;; long-term-unrealized-gain
|
||||
#f ;; long-term-unrealized-gain
|
||||
#f)))) ;; unrealized-cagr
|
||||
|
||||
;; Adds the stats to the given html table.
|
||||
(define (add-to-table table is-odd-row)
|
||||
@ -1287,7 +1385,32 @@
|
||||
(cond
|
||||
(is-lot-row (lot->title lot))
|
||||
(is-account-row label-account-total)
|
||||
(is-grand-total-row label-grand-total))))
|
||||
(is-grand-total-row label-grand-total)))
|
||||
(years-held
|
||||
(cond
|
||||
(is-lot-row
|
||||
(gnc:date-year-delta
|
||||
latest-bought-split-date
|
||||
to-date))
|
||||
(else #f)))
|
||||
(unrealized-cagr
|
||||
(cond
|
||||
(is-lot-row (get-cagr end-basis end-value years-held))
|
||||
(is-account-row
|
||||
(if (gnc-numeric-zero-p end-amount)
|
||||
0
|
||||
(/ weighted-unrealized-cagr end-amount)))
|
||||
(is-grand-total-row #f)))
|
||||
(sold-amount (gnc-numeric-add-fixed
|
||||
long-term-sold-amount
|
||||
short-term-sold-amount))
|
||||
(realized-cagr
|
||||
(cond
|
||||
((or is-lot-row is-account-row)
|
||||
(if (gnc-numeric-zero-p sold-amount)
|
||||
0
|
||||
(/ weighted-realized-cagr sold-amount)))
|
||||
(is-grand-total-row #f))))
|
||||
(add-data-row
|
||||
table
|
||||
(if (not is-grand-total-row) currency #f)
|
||||
@ -1311,11 +1434,18 @@
|
||||
end-value
|
||||
short-term-realized-gain
|
||||
long-term-realized-gain
|
||||
(if (not is-grand-total-row) realized-cagr #f)
|
||||
short-term-unrealized-gain
|
||||
long-term-unrealized-gain)
|
||||
long-term-unrealized-gain
|
||||
(if (not is-grand-total-row) unrealized-cagr #f))
|
||||
|
||||
(if is-lot-row
|
||||
(copy-table-rows splits-table table (get-row-style is-odd-row)))
|
||||
(begin
|
||||
(if unrealized-cagr
|
||||
(set! weighted-unrealized-cagr
|
||||
(+ weighted-unrealized-cagr
|
||||
(* unrealized-cagr end-amount))))
|
||||
(copy-table-rows splits-table table (get-row-style is-odd-row))))
|
||||
|
||||
(add-warnings-to-table table)
|
||||
|
||||
@ -1508,7 +1638,7 @@
|
||||
;; Merges in the given split.
|
||||
(define (merge-split split trans-date trans-currency)
|
||||
(let* (; Convert split value to the report's currency.
|
||||
(value
|
||||
(value
|
||||
(value->report-currency-value
|
||||
(xaccSplitGetValue split)
|
||||
trans-currency))
|
||||
@ -1572,45 +1702,58 @@
|
||||
|
||||
(cond
|
||||
((>= trans-date from-date)
|
||||
;; Remember if a sale within the report window causes the
|
||||
;; lot's balance to go negative.
|
||||
(if (and (null? first-negative-split)
|
||||
(gnc-numeric-negative-p end-amount))
|
||||
(set! first-negative-split split))
|
||||
(let* ((years-held
|
||||
(gnc:date-year-delta
|
||||
latest-bought-split-date
|
||||
trans-date))
|
||||
(cagr (get-cagr basis value years-held)))
|
||||
;; Remember if a sale within the report window causes the
|
||||
;; lot's balance to go negative.
|
||||
(if (and (null? first-negative-split)
|
||||
(gnc-numeric-negative-p end-amount))
|
||||
(set! first-negative-split split))
|
||||
|
||||
(cond
|
||||
(is-long-term
|
||||
(set! long-term-sold-amount
|
||||
(gnc-numeric-add-fixed long-term-sold-amount amount))
|
||||
(set! long-term-sold-basis
|
||||
(gnc-numeric-add-fixed long-term-sold-basis basis))
|
||||
(set! long-term-sold-value
|
||||
(gnc-numeric-add-fixed long-term-sold-value value))
|
||||
(set! long-term-realized-gain
|
||||
(gnc-numeric-add-fixed long-term-realized-gain gain)))
|
||||
(else
|
||||
(set! short-term-sold-amount
|
||||
(gnc-numeric-add-fixed short-term-sold-amount amount))
|
||||
(set! short-term-sold-basis
|
||||
(gnc-numeric-add-fixed short-term-sold-basis basis))
|
||||
(set! short-term-sold-value
|
||||
(gnc-numeric-add-fixed short-term-sold-value value))
|
||||
(set! short-term-realized-gain
|
||||
(gnc-numeric-add-fixed short-term-realized-gain gain))))
|
||||
;; if CAGR could not be computed because the basis and/or the
|
||||
;; years held are zero (like if a security was bought and sold
|
||||
;; on the same day), then do not include it in the total.
|
||||
(if cagr
|
||||
(set! weighted-realized-cagr
|
||||
(+ weighted-realized-cagr (* cagr amount))))
|
||||
|
||||
(add-split-row
|
||||
split
|
||||
trans-date
|
||||
#f ;; bought-amount
|
||||
#f ;; bought-value
|
||||
amount ;; sold-amount
|
||||
basis ;; sold-basis
|
||||
value ;; sold-value
|
||||
gain ;; sold-gain
|
||||
is-long-term)
|
||||
(cond
|
||||
(is-long-term
|
||||
(set! long-term-sold-amount
|
||||
(gnc-numeric-add-fixed long-term-sold-amount amount))
|
||||
(set! long-term-sold-basis
|
||||
(gnc-numeric-add-fixed long-term-sold-basis basis))
|
||||
(set! long-term-sold-value
|
||||
(gnc-numeric-add-fixed long-term-sold-value value))
|
||||
(set! long-term-realized-gain
|
||||
(gnc-numeric-add-fixed long-term-realized-gain gain)))
|
||||
(else
|
||||
(set! short-term-sold-amount
|
||||
(gnc-numeric-add-fixed short-term-sold-amount amount))
|
||||
(set! short-term-sold-basis
|
||||
(gnc-numeric-add-fixed short-term-sold-basis basis))
|
||||
(set! short-term-sold-value
|
||||
(gnc-numeric-add-fixed short-term-sold-value value))
|
||||
(set! short-term-realized-gain
|
||||
(gnc-numeric-add-fixed short-term-realized-gain gain))))
|
||||
|
||||
(set! sold-split-count (+ sold-split-count 1))
|
||||
(set! last-sold-split split)))))
|
||||
(add-split-row
|
||||
split
|
||||
trans-date
|
||||
#f ;; bought-amount
|
||||
#f ;; bought-value
|
||||
amount ;; sold-amount
|
||||
basis ;; sold-basis
|
||||
value ;; sold-value
|
||||
gain ;; sold-gain
|
||||
is-long-term
|
||||
cagr)
|
||||
|
||||
(set! sold-split-count (+ sold-split-count 1))
|
||||
(set! last-sold-split split))))))
|
||||
|
||||
;; Merges in the purchase split info.
|
||||
(define (merge-purchase-split split trans-date amount value)
|
||||
@ -1646,7 +1789,8 @@
|
||||
#f ;; sold-basis
|
||||
#f ;; sold-value
|
||||
#f ;; sold-gain
|
||||
#f)) ;; is-long-term
|
||||
#f ;; is-long-term
|
||||
#f)) ;; cagr
|
||||
|
||||
;; The split is from before the report's start date.
|
||||
;; So we won't include it in the report table, but
|
||||
@ -1709,6 +1853,9 @@
|
||||
(gnc-numeric-add-fixed
|
||||
long-term-realized-gain
|
||||
(stats 'get-long-term-realized-gain)))
|
||||
(set! weighted-realized-cagr
|
||||
(+ weighted-realized-cagr
|
||||
(stats 'get-weighted-realized-cagr)))
|
||||
(set! end-basis
|
||||
(gnc-numeric-add-fixed end-basis (stats 'get-end-basis)))
|
||||
(set! end-value
|
||||
@ -1725,6 +1872,9 @@
|
||||
(gnc-numeric-add-fixed
|
||||
long-term-unrealized-gain
|
||||
(stats 'get-long-term-unrealized-gain)))
|
||||
(set! weighted-unrealized-cagr
|
||||
(+ weighted-unrealized-cagr
|
||||
(stats 'get-weighted-unrealized-cagr)))
|
||||
(set! has-warnings
|
||||
(or has-warnings
|
||||
(stats 'get-has-warnings)))
|
||||
@ -1781,6 +1931,7 @@
|
||||
((get-short-term-realized-gain)
|
||||
(lambda () short-term-realized-gain))
|
||||
((get-long-term-realized-gain) (lambda () long-term-realized-gain))
|
||||
((get-weighted-realized-cagr) (lambda () weighted-realized-cagr))
|
||||
((get-end-amount) (lambda () end-amount))
|
||||
((get-end-basis) (lambda () end-basis))
|
||||
((get-end-value) (lambda () end-value))
|
||||
@ -1789,6 +1940,7 @@
|
||||
(lambda () short-term-unrealized-gain))
|
||||
((get-long-term-unrealized-gain)
|
||||
(lambda () long-term-unrealized-gain))
|
||||
((get-weighted-unrealized-cagr) (lambda () weighted-unrealized-cagr))
|
||||
((get-has-warnings) (lambda () has-warnings))
|
||||
((get-is-active-in-window) (lambda () is-active-in-window))
|
||||
((get-currency) (lambda () currency))
|
||||
|
Loading…
Reference in New Issue
Block a user