-
Notifications
You must be signed in to change notification settings - Fork 44
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
Improve precision of which transaction caused balance to go negative #113
Conversation
4737db3
to
c70e2e3
Compare
If you like you can run checks locally on your machine with |
5c9ee17
to
24695e5
Compare
@eprbell Thanks, static analysis should be passing. Completely forgot to mention this when opening the PR - a lot of test data fails this check now, which leads to a bunch of failing tests. Easiest way would be to turn the check off for these tests, but there's a chance other issues are being hidden by the test data being off. For example, tab
Relevant cells showing the error to be correct are highlighted in yellow: |
I still need to look at the code of this PR (I'll do that in the weekend or sooner), but this is a good check, so thanks for identifying and fixing this problem! In fact I had already found that some tests end up with a negative balance (even without this fix) and added the I imagine this PR probably causes even more tests balances to go negative, however I'm reluctant to change the tests: the reason is that I did a lot of manual verification of these tests and they estabilish a strong baseline against regression (the balance may go negative here and there, but the tax engine logic is still tested thoroughly by these tests). So my suggestion is to:
This should give us the best of both worlds. Do you have any concerns with this approach? |
Makes sense as an approach - my main concern is having a giant PR that's infeasible to work with. Hopefully it's feasible to land smaller bits using your Just for an order-of-magnitude, I'm seeing 47 tests passing, 1 failed, and 66 errors. The latter bucket seems to all be ODS output diff style tests. |
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.
I did a first review: looks good. After we fix the tests, as discussed above, this can be merged.
src/rp2/balance.py
Outdated
|
||
# Balances for sold and gifted currency | ||
for transaction in self.__input_data.unfiltered_out_transaction_set: | ||
transactions: List[Union[InTransaction, IntraTransaction, OutTransaction]] = in_transactions + intra_transactions + out_transactions |
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.
Could this be List[AbstractTransaction]
instead of a Union
?
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.
Solved this in the most recent commit via this approach: https://peps.python.org/pep-0484/#type-variables-with-an-upper-bound.
This can be simplified when 3.11 is the minimum supported version via PEP 673
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.
This looks great: I have just a couple of nits and then we can merge this.
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.
LGTM. Thanks for fixing this!
The existing logic accumulates all buys first before decrementing from sells. As a result, it can only detect negative balances that persist until the end of the calculation period. It also means that the blamed transaction can be incorrect. Consider the following transaction sequence:
Under the current logic, an exception would be raised when processing the
SELL 0.2 BTC
transaction. This code, would raise an exception on theSELL 0.9 BTC
transaction instead. A subtler case looks like this:The current code would not raise any exception, despite going significantly negative for a period. The new code would correctly flag the invariant being violated.