-
Notifications
You must be signed in to change notification settings - Fork 7
DRAFT: Use date for market conversion #96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
DRAFT: Use date for market conversion #96
Conversation
c329b1d
to
11c4c63
Compare
market = market_value_of_inv(p.pricer, p.target_currency, balance, clamp_date) | ||
cost = cost_value_of_inv(p.pricer, p.target_currency, balance) | ||
cash = -inv_to_currency(p.pricer, p.target_currency, cf_balance) # sum of cash flows | ||
cash = -inv_to_currency(p.pricer, p.target_currency, cf_balance, clamp_date) # sum of cash flows |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now the line chart will fluctuate due to currency fluctuations, even if the underlying investment stays constant. I guess that's correct, but it's also a bit confusing 🤔
Currently this function returns data points for all dates of (INVESTMENT, CURRENCY)
in the price db, and dates of all transactions. If the data points are now also dependent on the target currency, we should also create data points for every entry of (CURRENY, TARGET_CURRENCY)
in the price db. Can you add this here:
fava-portfolio-returns/src/fava_portfolio_returns/api/portfolio.py
Lines 58 to 75 in 0d439af
currency_pairs: set[tuple[str, str]] = set() | |
for entry in transactions: | |
for posting in entry.postings: | |
if posting.meta["category"] is Cat.ASSET and posting.cost: | |
# ex. (CORP, USD) | |
currency_pairs.add((posting.units.currency, posting.cost.currency)) | |
def first(x): | |
return x[0] | |
# Get dates of transactions and price directives | |
entry_dates = sorted( | |
itertools.chain( | |
((date, None) for pair in currency_pairs for date, _ in get_prices(p.pricer, pair) if date <= end_date), | |
((entry.date, entry) for entry in transactions), # already filtered above | |
), | |
key=first, | |
) |
currency_pairs
set?
E.g. if CORP
is bought in USD
, but my target currency is set to EUR
, we should also calculate data points for all price entries of USD/EUR
.
And please add a unit test in api/portfolio_test.py
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now the line chart will fluctuate due to currency fluctuations, even if the underlying investment stays constant. I guess that's correct, but it's also a bit confusing 🤔
That was actually my expectation, the fact that switching between currencies in the interface didn't affect the graph was subjectively more confusing.
"Even if the underlying investment stays constant" asks for a somewhat philosophical question "relative to what" :). But with this change there will still be an option to choose the cost basis currency in the interface and achieve the same-as-previous results I think, at least for investments comprised of the same base currency holdings.
At least for me comparing the graphs using different currencies was interesting/useful. For example, USD has been fluctuating a lot recently and the difference is noticeable. Also I import consumer price index metrics as an approximation for inflation and it's interesting to see returns relative to estimated inflation as well.
If that makes sense, will do requested changes soon.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it makes sense!
Also I import consumer price index metrics as an approximation for inflation and it's interesting to see returns relative to estimated inflation as well.
That's a nice idea! When I get time I'll add it to the example ledger and the screenshots :)
11c4c63
to
cd50639
Compare
Had to wrap my head a bit around why cash flows / cost basis dont't have to be reduced at the specific dates of each particular one. I think the following describes this intuition. If you had converted currency to invest (e.g. GBP to USD) then the cost basis would be in GBP and changing rates would affect the returns. On the charts (Portolio page) the cost basis line will move around with the currency rate if the target currency is different from the cost basis' currency. Which, I believe, makes sense: at that point the amount in cost currency was worth that much in target currency. It's like the target currency switch is now used to recalculate points as converted to that currency throughout time, not just taking the latest conversion rate. |
cd50639
to
381d320
Compare
381d320
to
1649c26
Compare
It required some thinking on what's the correct approach so here is some more reasoning I used. I wish there was a good reference implementation but I'm not familiar with financial tools that are advanced enough to do something similar... Cost basis and returnsDefinition https://www.investopedia.com/terms/c/costbasis.asp Normal returns (percentages) are not affected by change of the target currency because the cost basis that it's compared against gets converted to the target currency at the same point in time. TWRDefinition: https://en.wikipedia.org/wiki/Time-weighted_return It seems that a) should be the answer.
|
In the current version switching currencies in the UI has no effect on the shape of the line chart because it assumes constant (latest?) conversion between currencies.
If we ccalculate values at date of the datapoint, the currency conversions are also taken into account and results make sense, at least in my charts.