GithubHelp home page GithubHelp logo

Comments (14)

vzickner avatar vzickner commented on May 18, 2024 1

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:

  1. 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. A TransactionPoint is created for every day on which the user has an order. For each TransactionPoint 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 10x symbol A, then next order of by 5x symbol B and then you sell 5x symbol A. The transaction points will be for the first day 10x symbol A, for the second point 10x symbol A and 5x symbol B, and the last transaction point will include 5x symbol A and 5x symbol 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 method computeTransactionPoints 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.

  2. 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 the grossPerformancePercentage and other values. Since the operation is for a given time frame (you can pick them on the dashboard, like 1M, 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.

  3. 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 method getTimePeriodForDate and creating a list of performances. Here it's again using the TransactionPoint'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.

I-Valchev avatar I-Valchev commented on May 18, 2024 1

@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.

dtslvr avatar dtslvr commented on May 18, 2024

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.

I-Valchev avatar I-Valchev commented on May 18, 2024

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.

vzickner avatar vzickner commented on May 18, 2024

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 $50 and all of the above is of course also in $.

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.

I-Valchev avatar I-Valchev commented on May 18, 2024

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.

vzickner avatar vzickner commented on May 18, 2024

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.

I-Valchev avatar I-Valchev commented on May 18, 2024

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.

dtslvr avatar dtslvr commented on May 18, 2024

@vzickner your solution sketch looks fine to me 👍🏻

from ghostfolio.

vzickner avatar vzickner commented on May 18, 2024

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.

I-Valchev avatar I-Valchev commented on May 18, 2024

@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.

dtslvr avatar dtslvr commented on May 18, 2024

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.

dtslvr avatar dtslvr commented on May 18, 2024

#330 has finally been merged and deployed.

Thanks @vzickner for this great enhancement! ❤️

from ghostfolio.

dtslvr avatar dtslvr commented on May 18, 2024

@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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.