UI blocks forever in getCostBasis() when opening investment account

Lucas's Avatar

Lucas

Oct 13, 2022 @ 02:11 PM

My ledger has an investment account with a longish history (say 10 years), mostly trades in GOOG. It's never had problems until I deleted one bogus transaction, and now clicking that account in the UI causes it to hang every time. It appears to be in a pathological calculation in InvestUtil.getCostBasis() in the UI thread; see the thread stack dump below where it's spent nearly a half-hour of CPU time (!) trying to complete that method. Note that GOOG had a split in July, so I wonder if this business is related.

This is Moneydance 2021 (2006).

"AWT-EventQueue-0" #23 prio=6 os_prio=0 cpu=1664933.53ms elapsed=1782.48s tid=0x00007fdae546f800 nid=0xfd894 >
   java.lang.Thread.State: RUNNABLE
        at com.infinitekind.moneydance.model.CostCalculation.allocateAverageCostSales(CostCalculation.java:13>
        at com.infinitekind.moneydance.model.CostCalculation.<init>(CostCalculation.java:59)
        at com.infinitekind.moneydance.model.CostCalculation.<init>(CostCalculation.java:41)
        at com.infinitekind.moneydance.model.InvestUtil.getNewAverageCost(InvestUtil.java:48)
        at com.infinitekind.moneydance.model.InvestUtil.getAverageCostBasis(InvestUtil.java:36)
        at com.infinitekind.moneydance.model.InvestUtil.getCostBasis(InvestUtil.java:221)
        at com.infinitekind.moneydance.model.InvestUtil.getCostBasis(InvestUtil.java:253)
        at com.moneydance.apps.md.view.gui.SecurityDetailPanel.updateSummaryInfoNow(SecurityDetailPanel.java:>
        at com.moneydance.apps.md.view.gui.SecurityDetailPanel$7.run(SecurityDetailPanel.java:739)
        at com.moneydance.awt.CollapsibleRefresher$1.run(CollapsibleRefresher.java:19)
        at java.awt.event.InvocationEvent.dispatch([email blocked].1/InvocationEvent.java:316)
        at java.awt.EventQueue.dispatchEventImpl([email blocked].1/EventQueue.java:770)
        at java.awt.EventQueue$4.run([email blocked].1/EventQueue.java:721)
        at java.awt.EventQueue$4.run([email blocked].1/EventQueue.java:715)
        at java.security.AccessController.executePrivileged([email blocked].1/AccessController.java:753)
        at java.security.AccessController.doPrivileged([email blocked].1/AccessController.java:391)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege([email blocked].1/Pro>
        at java.awt.EventQueue.dispatchEvent([email blocked].1/EventQueue.java:740)
        at java.awt.EventDispatchThread.pumpOneEventForFilters([email blocked].1/EventDispatchThread.java:2>
        at java.awt.EventDispatchThread.pumpEventsForFilter([email blocked].1/EventDispatchThread.java:124)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy([email blocked].1/EventDispatchThread.java:1>
        at java.awt.EventDispatchThread.pumpEvents([email blocked].1/EventDispatchThread.java:109)
        at java.awt.EventDispatchThread.pumpEvents([email blocked].1/EventDispatchThread.java:101)
        at java.awt.EventDispatchThread.run([email blocked].1/EventDispatchThread.java:90)
  1. Support Staff 1 Posted by Maddy on Oct 13, 2022 @ 02:27 PM

    Maddy's Avatar

    Hi Lucas,

    We are sorry to hear about the problem you have encountered.

    Since the version of Moneydance that you are running is slightly outdated and you are entitled to a free upgrade to the latest stable version, we would recommend downloading and installing Moneydance 2022.5 (4091) - available to download from this page.

    You should remove or choose to overwrite the older version and restart Moneydance!

    Additionally, it is my understanding that when you want to delete a security you need to be sure that there are no investment accounts that have sub accounts priced in that security.

    I hope this information is helpful. Please let us know if you have further questions or need more assistance.

    --
    Maddy, Infinite Kind Support

  2. 2 Posted by Lucas on Oct 13, 2022 @ 02:59 PM

    Lucas's Avatar

    Hi, thanks for the response. I just retried with the new version and got the same result.

  3. 3 Posted by Stuart Beesley ... on Oct 13, 2022 @ 03:11 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    Please upgrade to 2022.5(4091) and retest.

    Now save this attached file: test_cost_basis.py
    Go to MD: Window/Show Moneybot Console/Open Script. Select this file. Then click RUN (not run snippet).
    Select the investment account in error and watch the output on screen..
    .. We need to identify which security it's failing on.. If you have to kill MD, or it crashes, then find and upload errlog.txt BEFORE you relaunch MD.

    Next install/run toolbox.
    Top left, toolbox options, enable update mode.

    • Menu: Transaction tools: run: FIX: Non-Hierarchical Security Acct Txns

    • Menu: Currency and Security tools. run: "FIX: Detect and fix Investment Security records not properly linked to Security Master records"
      run: FIX: Detect and merge/fix duplicate Securities within same Investment Account(s)

    Did any of those find/fix a problem? If yes, rerun the script...

  4. Support Staff 4 Posted by Maddy on Oct 13, 2022 @ 03:18 PM

    Maddy's Avatar

    @ Stuart

    The test_cost_basis.py attachment is missing. Would you mind attaching it again, please?

    Thank you

    --
    Maddy, Infinite Kind Support

  5. 5 Posted by Stuart Beesley ... on Oct 13, 2022 @ 03:24 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    .

  6. 6 Posted by Stuart Beesley ... on Oct 13, 2022 @ 03:25 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    attached

  7. 7 Posted by Stuart Beesley ... on Oct 13, 2022 @ 04:12 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    ... you will need to right click the link and 'save as' (plain text file) or 'download linked file as'.....

  8. 8 Posted by Stuart Beesley ... on Oct 13, 2022 @ 05:33 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    Hi Lucas, any joy?

  9. 9 Posted by Lucas on Oct 13, 2022 @ 06:49 PM

    Lucas's Avatar

    Hi, Stuart, thanks for the toolbox pointers (wow, I've never seen this before; it's wild). The error log from test_cost_basis.py is below:

    Investment account selected: ACCOUNTNAME
    Processing security: ACCOUNTNAME:Google Inc
    Info: buy transactions overran sells; going short
    Info: buy transactions overran sells; going short
    

    Then the Python runner thread hangs with the same stack as the original problem (not surprisingly). Neither of the toolbox fixes found any problems.

  10. 10 Posted by Stuart Beesley ... on Oct 13, 2022 @ 07:02 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    … thanks for the messages… I’ll dig deeper tomorrow and see if we can debug into the issue.

  11. 11 Posted by Stuart Beesley ... on Oct 14, 2022 @ 11:36 AM

    Stuart Beesley (Mr Toolbox)'s Avatar

    Can you run this latest script and let's see where it's hanging. Again, I will need the kill log and the errlog.txt (before restart)..

  12. 12 Posted by Stuart Beesley ... on Oct 14, 2022 @ 04:59 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    Lucas, any joy?

  13. 13 Posted by Lucas on Oct 14, 2022 @ 05:29 PM

    Lucas's Avatar

    This is an adventure. Thanks for your continuing help. "Luckily" for both of us, I know Python so I've been able to narrow things down a bit.

    1. The script as written doesn't do anything new/useful, since the call to getCostBasis() on line 266 goes off in the weeds like the original report.
    2. However commenting that out so that it does the CostCalculation.allocateAverageCostSales() call in Python is interesting. So far, I've figured out that it ends up in an infinite loop at line 213-232; specifically sell.unallottedSharesAdded = -9 forever.

    I'll keep digging.

  14. 14 Posted by Stuart Beesley ... on Oct 14, 2022 @ 06:05 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    Rooky error... I meant to comment out line 266 - sorry...
    Yes, I have reproduced the java code in Python for you, so that we can see where it's looping..

    Can you run this version (3); it will dump the positions to screen. Can you send me the output. If you would rather email me direct, fine too...:

  15. 15 Posted by Lucas on Oct 14, 2022 @ 06:56 PM

    Lucas's Avatar

    Sent to email; thanks again

  16. 16 Posted by Stuart Beesley ... on Oct 14, 2022 @ 07:17 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    Got it. I’ll analyse tomorrow. What time zone are you in?

  17. 17 Posted by Lucas on Oct 14, 2022 @ 08:10 PM

    Lucas's Avatar

    Cheers very much. I'm in US/Central.

  18. 18 Posted by Stuart Beesley ... on Oct 15, 2022 @ 07:13 AM

    Stuart Beesley (Mr Toolbox)'s Avatar

    I've found the bug. It's the combination of a negative stock balance (of -2) prior to stock split (20:1 on 18th July 2022) followed by any buy/sell after that date. If you want to get back into your Investment account screens to fix the negative balance, then go to Tools/Securities for Google and change the stock split date to year 2032 instead of 2022. THIS IS TEMPORARY ONLY. Now go into the investment account, fix the negative share qty prior to the split date... Then change the split date back..

    I presume the errant txn is 02/05/2022 sell 82 instead of 80 making -2 balance?

    Let me know if this works for you?

    Next.... I'll work out how to fix the internal code...... ;->

  19. 19 Posted by Stuart Beesley ... on Oct 15, 2022 @ 03:38 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    Update: given the split, I am guessing that the errant txn is 02/05/2022 sell 4.1 instead of 4 making the calculated -2 balance? (using unconverted split conversions)

  20. 20 Posted by Stuart Beesley ... on Oct 15, 2022 @ 04:24 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    I will liaise with the developer on the actual code fix… It’s a bit of a brain-twister.

    For anyone interested…:

    BUG: com.infinitekind.moneydance.model.CostCalculation in allocateAverageCostSales()

    The code does this:

            long sharesFromBuy = Math.min(unallottedSellShares, buy.unallottedSharesAdded);
            long sharesFromBuyAdjusted = this.secCurr.adjustValueForSplitsInt(buy.date, sharesFromBuy, sell.date);
    
    (The second is a backwards unsplit calculation)

    And then later does this:

    sell.unallottedSharesAdded += sharesFromBuyAdjusted
    
    But the inner while loop does this:
    while (buyIdx < numPositions && sell.unallottedSharesAdded < 0L) {
    
    So… sell.unallottedSharesAdded has been incremented by (in this case) 2 instead of 40 (or something like that) and therefore it’s still negative and just carries on… there is no break out.

    Quite a rare situation. The code needs fixing for this situation and/or a catch/breakout to prevent infinite loops occurring....

    You can reproduce by creating the following in a new investment account:
    - Stock - Split 18/July/2022 20:1 Three TXNs as attached:
    You then will not be able to select that Investment account as the Infinite Loop will be triggered...

  21. 21 Posted by Stuart Beesley ... on Oct 17, 2022 @ 05:32 PM

    Stuart Beesley (Mr Toolbox)'s Avatar

    Hi Lucas, did this (removing the split so you can go and edit the txns) work?

  22. 22 Posted by Lucas on Oct 18, 2022 @ 12:59 PM

    Lucas's Avatar

    Thanks, Stuart, the workaround to make it so the negative balance didn't straddle the split worked! Wish I'd thought of that.

    I know it was a weird bug, and I appreciate the prompt help. Let me know if I can assist further.

  23. System closed this discussion on Jan 17, 2023 @ 01:00 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac