ghostfolio / ghostfolio

Open Source Wealth Management Software. Angular + NestJS + Prisma + Nx + TypeScript 🤍
https://Ghostfol.io
GNU Affero General Public License v3.0
3.85k stars 362 forks source link

Inconsistent change/performance values in Holdings tab #554

Closed FedericoComoglio closed 1 year ago

FedericoComoglio commented 2 years ago

Hi,

I promised to report a few inconsistencies that I noticed while testing Ghostfolio functionalities. When thinking about the performance of a security, I generally think of three components:

Clearly, change/performance can be gross or net, depending on whether transaction fees are taken into account. Looking into previous issues, I noticed that recent releases of Ghostfolio indeed feature both net and gross performance (nice!). In addition, I am aware that some features -such as introducing a DIVIDEND transaction type - are in the making and cannot contribute to the issue I am reporting here. For simplicity, I also picked an example of a stock in CHF, to rule out currency effects.

Based on the attached screenshot, I would like to understand how the indicated "change" and "performance" are exactly computed (of note, the total transaction fee for this position amounts to CHF 11.35). In particular:

Could you please clarify how are these quantities computed, and what am I missing here, in case?

Thanks a lot!

Screen Shot 2021-12-18 at 3 31 40 PM
dtslvr commented 2 years ago

Thank you for documenting your findings @FedericoComoglio!

Ghostfolio uses the Time-Weighted Rate of Return (TWR) to eliminate distorting effects created by inflows and outflows of money. This makes the calculation more complex compared to your example.

Nevertheless, I would expect that the change and the performance have the same algebraic sign. A starting point to analyze this issue would be to design a very simple unit test to reproduce this behaviour.

FedericoComoglio commented 2 years ago

Hi @dtslvr, thank you for looking into this issue.

Using TWR makes sense. Performance estimates anyway converge to the simple performance measures I reported above for typical buy-and-hold (at regular intervals) investors who use dollar-cost averaging (all subperiods for TWR would be same).

To reproduce the issue above (coming from a stock simulator), I exported and formatted the relevant transactions:

date,type,ticker,currency,units,price,fee 30.11.2021,BUY,BALN.SW,CHF,2.00,136.60,1.55 26.11.2021,BUY,BALN.SW,CHF,3.00,139.90,2.40 22.11.2021,BUY,BALN.SW,CHF,7.00,142.90,5.75 12.11.2021,BUY,BALN.SW,CHF,2.00,146.00,1.65

Likely, it is possible to further simplify this set for a unit test but I hope this offers a starting point. Thank you!

FedericoComoglio commented 2 years ago

Hi @dtslvr, not sure if this helps but I noticed another performance inconsistency, this time in the Summary tab. With a time in the market of 5 months for a simulated portfolio, I get:

I assume this once again stems from the use of TWR, with some positions in the simulated portfolio opened just a few days ago at the "dip" preceding the recent swift recovery.

vzickner commented 2 years ago

Hi @FedericoComoglio,

thank you for sharing the portfolio, that helped to create a test case.

First, I am not a financial expert and only contributed to the portfolio calculation because it was challenging and fun to write an efficient algorithm for the TWR. There might be a bug in there, but as far as my analysis is telling me, everything works as expected.

You can find the test case with some manual calculations here: https://github.com/ghostfolio/ghostfolio/commit/56c9b9c05f0f7b30221006ba6a686c610ddadaf7

My thoughts about your calculations vs TWR:

I personally don't consider this a bug or inconsistency. Maybe we are using the wrong calculation methods, but in this case, the question is what we could switch to make the behavior better. Also, this example doesn't include the calculation of the performance since a given date, which makes everything even more complex (since you don't really have an average buy price anymore).

I wish you all happy holidays,

Valentin

dtslvr commented 2 years ago

Thanks for your detailed comments @FedericoComoglio and @vzickner.

Another thought on this: Is the time-weighted return (TWR) only suited for an investment portfolio and not for a single position?

FedericoComoglio commented 2 years ago

Thank you both for your feedback. I suggest that we focus on the change computation before venturing into performance metrics. The first issue in the example above remains the change value, which is not reflecting the change value of the position (neither net nor gross). I imagine a typical user would like to quickly gauge the total unrealised gain/loss here. I also noticed in a few occasions negative change values for a positive, unrealized return. I see no logical/plausible explanation for it. I’m very happy to discuss these issue with you further. Thank you!

On Fri, 24 Dec 2021 at 17:33, Thomas Kaul @.***> wrote:

Thanks for your detailed comments @FedericoComoglio https://github.com/FedericoComoglio and @vzickner https://github.com/vzickner.

Another thought on this: Is the time-weighted return (TWR) only suited for an investment portfolio and not for a single position?

— Reply to this email directly, view it on GitHub https://github.com/ghostfolio/ghostfolio/issues/554#issuecomment-1000893705, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABJRB3UHF5GG5QGVBFTKB2TUSSOF3ANCNFSM5KKXDLIQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you were mentioned.Message ID: @.***>

FedericoComoglio commented 2 years ago

Re. Performance metrics, how about offering the user the possibility to select one (or more) metric best suited for their strategy. I feel a standard measure as straightforward as ROI could be a starting point.

dtslvr commented 2 years ago

Thank you both for your feedback. I suggest that we focus on the change computation before venturing into performance metrics.

I have recalculated the change for your example and have found a mismatch. Can you confirm the result? (New: 67.20 vs. 53.15 currently in the app)

BALN-change
FedericoComoglio commented 2 years ago

Hi @dtslvr, thank you. I confirm the computed change is correct and precisely as I defined it initially. Thank you also for splitting up the original issue.

FedericoComoglio commented 2 years ago

Hi @dtslvr, with reference to your request for help in #512, I would like to advocate for a simple and pragmatic incremental approach once it comes to computing change and performance metrics. It is always possible to add features later on. More details below.

Hope this helps. Happy to discuss further. Thank you so much once again for all the efforts you are putting into building Ghostfolio!

FedericoComoglio commented 2 years ago

Hi @dtslvr, I hope you are well. Any update the on above?

dtslvr commented 2 years ago

Yes @FedericoComoglio, there is work in progress going on in #632.

The calculation will be based on this (first tab): https://docs.google.com/spreadsheets/d/1k7wwGIdvDmYM5yTs_0WM0cBZG7ZxiNXtrAX9Kezch9s/edit

If you have feedback, please post it here.

FedericoComoglio commented 2 years ago

Thank you, @dtslvr. I reviewed the calculation for BALN and it looks good. I assume you will account for transaction fees when computing the net return, as already implemented. Thanks!

FedericoComoglio commented 2 years ago

Hi @dtslvr, a quick update on the new calculation engine. I tested it with a number of securities (in CHF) and I confirm it works as expected. Thank you very much! At this stage, I think it would be very useful to:

  1. Consider splitting the individual contributions to change as described in the original issue
  2. Introduce an ROI as a performance metric, so that users can benefit from a widely adopted and fairly standard metric to measure performance.

What do you think about it?

FedericoComoglio commented 2 years ago

Hi @dtslvr, revamping this discussion because implementing the three components of performance indicated in my original post would, in my view, greatly enhance the Ghostfolio experience.

To provide a dummy example, consider the purchase of a US short term bond ETF (denominated in USD) in the period Dec 2021-Jan 2022 by a user whose base currency is CHF. The performance currently calculated by Ghostfolio would be significantly negative (short-term bond ETFs lost between 3 and 6% since then). However, the currency effect entirely compensates for this loss (the USD has weakened >6% over the same period), i.e. the performance is actually positive when accounting for this factor. In addition, any distribution does not currently contribute to the performance calculation.

Hence, as I said before, it would be really useful to compute three different performance contributors:

Let me know if I can support you, in case. Thanks a lot!

FedericoComoglio commented 1 year ago

Hi @dtslvr, I hope you are well. Although I kept quiet for a few months, I kept using (and testing) Ghostfolio in the meantime :) Is there any update on the above? What is your view on the proposed three-component contribution to performance? Thank you!

dtslvr commented 1 year ago

Hi @FedericoComoglio

I have not prioritized that. However, I think it is a good idea and I would be supportive if there was a pull request from the community. So that it does not get lost, I have created a new discussion topic.