Comments (14)
Hi @I-Valchev,
I think there you picked maybe one of the most complicated parts of ghostfolio. We need to separate between the absolute net performance and the net performance percentage. I think the absolute net performance is straight forward to calculate (just subtract the fees). While it's more difficult to calculate the percentage. @dtslvr found already an example how to calculate them, which we might be able to use as a base. We only need to check out if that includes all required input parameters and if we are able to create a test case out of it.
Ignoring the fact that you need to display the numbers later on in the UI, there @dtslvr is maybe the better person to explain what needs to be done, the main class which needs to be adapted is the portfolio-calculator.ts. That class is the core of all the calculations. Let me explain in short what it is doing:
-
It's taking all (or a limited set) of the users order as an input and calculating a structure which can later on be used to do the calculation itself. I called those elements which it returns
TransactionPoint
, but that name can be discussed and improved. ATransactionPoint
is created for every day on which the user has an order. For eachTransactionPoint
there is a list of all symbols the user has starting from this day. Let me give an example: You have first order of buy 10xsymbol A
, then next order of by 5xsymbol B
and then you sell 5xsymbol A
. The transaction points will be for the first day 10xsymbol A
, for the second point 10xsymbol A
and 5xsymbol B
, and the last transaction point will include 5xsymbol A
and 5xsymbol B
. That format allows to quickly know for every given date which symbols the user has. You only need to figure out at which date within the transaction point list are you (since it's sorted, you can just walk through it) and you will see what transactions you have. This intermediate structure is generated in the methodcomputeTransactionPoints
and would need to be adapted to include the fees of the orders. Here the first question would be, how we represent those, since they are a one-time fee for each symbol. But maybe as part of the order entry in the list here. -
The next step is now depending on which information you need. The list below the graph is for example a point in time snapshot which is calculated inside
getCurrentPositions
. This method calculates then based on the information thegrossPerformancePercentage
and other values. Since the operation is for a given time frame (you can pick them on the dashboard, like1M
,1Y
,max
) it is looking only at the relevant transaction points and using them then to calculate the different numbers. For some it's more complex, for some it's less complex. I would say net performance percentage would be once of the more complex ones. The calculation of the different values is combined here in the one function to reduce the iterating over the different transaction points. -
There is one last component related to this, which is
calculateTimeline
. This method is used to draw the graph on the dashboard. I am not sure if that is really required for the change at the beginning, and might be a candidate for a second phase. It's calculating for every single day the performance (as part of the methodgetTimePeriodForDate
and creating a list of performances. Here it's again using theTransactionPoint
's from the beginning to do those calculations.
One side note: The portfolio-calculator.ts
assumes by design that all the values are in the user currency. The exchange rate calculator is used to change them to the user currency before and eventually once they are out. This is just for simplicity that this class doesn't need to deal with different currencies for each symbols. Anyway, the class is still aware of the currency to give it to the current rate service.
Finally, and that might be the most important part: All of this is covered by a few unit tests. Creating one of those and preparing an example as a test scenario would be already a great help to get the feature done.
I hope I didn't scare you and the explanation helps and please let us know what your thoughts are. I am also happy to help or support the implementation once we agreed on a calculation approach.
Valentin
from ghostfolio.
@vzickner @dtslvr I've just tested it out, now deployed, and gotta say I love it! Perfectly matches the figures I calculate semi-manually, which is a great relief. Thank you both so much for the quick work on this 🙌
from ghostfolio.
Thanks for coming up with this idea. So basically besides the current (gross) performance rate, you would like to have the net performance rate? (Wikipedia: Time-weighted return > Fees)
In my opinion, net performance should be the default and the user can find the gross performance in the summary.
So far, I have only found an example with annual fees here.
What do you think?
from ghostfolio.
Hi @vzickner and @dtslvr , thanks both for the detailed explanations!
First, just to clarify why in my view this feature is very needed: starting from the assumption that most people using ghostfolio will be novice and/or small amount investors (because otherwise they'd likely use paid tools), the fees will make up a notable percentage of the investment. That means that by looking at your portfolio, you get exaggerated profit figures. In my own case, that's the only show-stopper I have at the moment for not transitioning fully into ghostfolio instead of the google sheet...
Anyway, moving to the implementation: I did explore the code a bit and also thanks for the guidelines @vzickner , but indeed you are right it is a bit complicated with the calculations and also I'm not that familiar with the tech stack... for now I won't go ahead with implementation. I'm planning on making some entry-level contributions like #326 first.
from ghostfolio.
Hi @I-Valchev, hi @dtslvr,
maybe we can start with a simple calculation example to help me understand how you expect the calculation to happen. Since I am not sure how the calculation works at the end.
Let's assume we have one symbol VTI and we buy twice, first we buy 10 at 2019-02-01
, followed by another 10 at 2020-08-03
. Just to add the ultimate complexity, let's assume we are interested in our portfolio view since 2020-01-01
. Furthermore, let's assume today is the 2020-10-24
. This example is exactly what is covered by this unit test.
Out VTI has in our example a linear value to simplify testing. Let's assume we have for the following days this value:
Day | Value VTI | Quantity | Value of Portfolio | Gross Performance Percentage |
---|---|---|---|---|
2020-01-01 | 171.1 | 10 | 1711 | |
2020-08-03 | 188.3 | 10 | 1883 | 1883/1711 = 1.100526008 |
2020-08-03 | 188.3 | 20 | 3766 | |
2020-10-24 [today] | 194.86 | 20 | 3897.2 | 3897.2/(1883+1479.9) = 1.158880728 |
The overall gross performance percentage is now calculated as described in the test with the following formula:
1.100526008 * 1.158880728 = 1.275378381 => 27.5378381 %
Now let's assume we have for every order a fee of
Now since we have had two orders, the first question is: Are the fees of the first order included in the calculation? Due to the fact that we are starting the calculation at Jan 1st, 2020, I would assume the fees of the Feb 1st, 2019 order don't matter in this calculation? Do you agree with me?
Now, I think the fee of the second order which took place at Aug 3rd, 2020 definitely needs to be included. This fee is then part of the second gross performance calculations and the current formula of 3897.2/(1883+1479.9) = 1.158880728 would need to include the fee as well. So let's break it into parts to see what those numbers mean. 3897.2 is the final value of the portfolio, while 1883 is the value of my portfolio before I submitted the second order. Now the most complicated number in this calculation is 1479.7 which is the actual cash flow: 2923.7-1443.8=1479.9. With 2923.7 is what I have invested now (fees not included) and 1443.8 is what I invested initially (fees not included). You actually see this as part of the transaction items in the test, while they do not really reflect the cash flow due to the transaction point abstraction.
Considering this, we need to include our $50 fee somewhere in this gross performance calculation to make it a net performance calculation. I would say it's part of the cash flow, which would reduce the net performance percentage for this specific time to 3897.2/(1883+1479.9+50) = 1.14190278. Which would give us a total net performance percentage of 1.100526008 * 1.14190278 = 1.25669371 => 25.669371 %.
Thoughts? @I-Valchev, how are you doing those calculation in your spreadsheet?
Valentin
from ghostfolio.
Hi @vzickner , really appreciate the explanation! Yes, indeed this is how I envisioned it to work. The spreadsheet is a lot less sophisticated (naturally doesn't have varying periods or multiple transactions for the same stock), but the way in which the fees affect the net performance percentage is the same. This, in my eyes, gives you the break-even point of the investment.
One more thing, I believe the fee for any SELL transactions within the selected period should also be included, in exactly the same way you described above.
from ghostfolio.
Hi @I-Valchev,
thanks for the quick answer. SELL transactions are actually really interesting. I think it works in the same way when you still have the symbol after the sell transaction. But I am not sure if it works the same way in case your quantity is zero after the last SELL operation, since in this case the gross performance change for this period isn't calculated anymore. Any ideas how we could solve this?
Edit: it might make sense to include sell fees at the end of the period in which the selling happened, and not in the next.
Thanks,
Valentin
from ghostfolio.
Hi @vzickner , interesting edge-case indeed. I think that would depend on how ghostfolio handles cash. I know in some other platforms, there's a "cash" account, so that after you sell a stock you see the value of the portfolio including the amounts left in cash. If that's the case, I think those last SELL fees can be subtracted from the net cash amount (as en expanse at the date of the SELL operation, like you suggest)
Is this how ghostfolio works (i.e., what happens when you SELL a stock to 0 quantity)? If the tool doesn't care about net gains/losses from selling stocks, then I'd assume the last fee also shouldn't be counted, or at least I can't think of a good place to do that.
from ghostfolio.
@vzickner your solution sketch looks fine to me 👍🏻
from ghostfolio.
Hi @I-Valchev,
I added a first PR which adds the net performance to the current positions: #330
If you want you can already check it out. But the UI still needs to be created. You won't see the new information in the user interface yet (PR's welcome here!)
Valentin
from ghostfolio.
@hi @vzickner , 👍wow this looks great! I'm happy to work on a PR for the frontend part. @dtslvr do you have some pointers for what you'd like it to look/work like?
from ghostfolio.
Thank you @vzickner! 😎
@hi @vzickner , 👍wow this looks great! I'm happy to work on a PR for the frontend part. @dtslvr do you have some pointers for what you'd like it to look/work like?
I will take a look now and let you know @I-Valchev if there is something you can do here.
from ghostfolio.
#330 has finally been merged and deployed.
Thanks @vzickner for this great enhancement! ❤️
from ghostfolio.
@vzickner @dtslvr I've just tested it out, now deployed, and gotta say I love it! Perfectly matches the figures I calculate semi-manually, which is a great relief. Thank you both so much for the quick work on this 🙌
Thanks for your feedback. I'm glad to hear you are happy! 😃
from ghostfolio.
Related Issues (20)
- [BUG] Missing chart in "Presenter View" / "Zen Mode"
- [BUG] No exchange rate has been found for USDEUR at 1992 HOT 4
- Ghostfolio installation using docker / portainer postgres credential issue
- Allow to edit of asset profile in Admin Control panel HOT 2
- Add-api-example-for-export
- [Bug] Upgrading from 2.68.0 to 2.69.0 breaks on ARM HOT 2
- [BUG] API errors for forms not communicated to the user HOT 4
- [BUG] Could not get historical market data for bitcoin (COINGECKO) when the time range is more than one year HOT 3
- [BUG] Dividend fees affect performance, but dividends don't HOT 2
- Add support to create an account cash balance HOT 2
- Add to close user account
- Allow user to activate / deactivate X-ray rule
- [BUG] opening menu items in a new tab redirects to /en/start instead of the expected route HOT 8
- Saving Market Data is broken as of 2.69.0 (was working in 2.68.0) HOT 2
- [BUG] currency of my country is wrong HOT 4
- [BUG] know issue about timezone, possible fix HOT 1
- [BUG] Can't Import via API HOT 3
- [BUG] Gathering Profile Data Error (Invalid Crumb) HOT 1
- [BUG] couple tickers seem to be shown incorrectly HOT 1
- [BUG] cant install (unknown flag: --env-file)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ghostfolio.