adlr / wash-sale-calculator

Calculator for wash sales for US taxes

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Assertion faiure: assert(not buy_lots_match(merge_from, merge_to))

drheld opened this issue · comments

Not sure what's going on here, but easily reproduced given the input below.

Triggering input:

Cnt,Sym,Desc,BuyDate,Basis,SellDate,Proeeds,AdjCode,Adj,FormPosition,BuyLot,IsReplacement
2,GOOG,GOOG,1/25/2014,100,1/28/2014,50,,,,,
5,GOOG,GOOG,2/25/2014,250,2/28/2014,125,,,,,

Results:

Printing 2 lots:
2 GOOG (GOOG) acq: 2014-01-25 100.00 sell: 2014-01-28 50.00 1
5 GOOG (GOOG) acq: 2014-02-25 250.00 sell: 2014-02-28 125.00 2
Totals: Basis 350.00 Proceeds 175.00 Adj: 0.00 (basis-adj: 350.00)
Found the following losses
2 GOOG (GOOG) acq: 2014-01-25 100.00 sell: 2014-01-28 50.00 1
5 GOOG (GOOG) acq: 2014-02-25 250.00 sell: 2014-02-28 125.00 2
hit enter>
Here are the replacements
2 GOOG (GOOG) acq: 2014-01-25 100.00 sell: 2014-01-28 50.00 1
5 GOOG (GOOG) acq: 2014-02-25 250.00 sell: 2014-02-28 125.00 2
hit enter>
Splitting buy
2 GOOG (GOOG) acq: 2014-01-25 100.00 sell: 2014-01-28 50.00 1
5 GOOG (GOOG) acq: 2014-02-25 250.00 sell: 2014-02-28 125.00 2
hit enter>
into these
2 GOOG (GOOG) acq: 2014-01-25 100.00 sell: 2014-01-28 50.00 1
2 GOOG (GOOG) acq: 2014-02-25 100.00 sell: 2014-02-28 50.00 .1 2
3 GOOG (GOOG) acq: 2014-02-25 150.00 sell: 2014-02-28 75.00 .2 2
hit enter>
pairing these
2 GOOG (GOOG) acq: 2014-01-25 100.00 sell: 2014-01-28 50.00 1
2 GOOG (GOOG) acq: 2014-02-25 100.00 sell: 2014-02-28 50.00 .1 2
3 GOOG (GOOG) acq: 2014-02-25 150.00 sell: 2014-02-28 75.00 .2 2
hit enter>
pair complete
2 GOOG (GOOG) acq: 2014-02-22 150.00 sell: 2014-02-28 50.00 .1 2,1 [IsRepl]
3 GOOG (GOOG) acq: 2014-02-25 150.00 sell: 2014-02-28 75.00 .2 2
hit enter>
pairing these
2 GOOG (GOOG) acq: 2014-02-22 150.00 sell: 2014-02-28 50.00 .1 2,1 [IsRepl]
3 GOOG (GOOG) acq: 2014-02-25 150.00 sell: 2014-02-28 75.00 .2 2
hit enter>
Traceback (most recent call last):
File "wash.py", line 172, in
main()
File "wash.py", line 164, in main
out = perform_wash(lots, logger)
File "wash.py", line 142, in perform_wash
merge_buy_lots(loss, buy)
File "wash.py", line 52, in merge_buy_lots
assert(not buy_lots_match(merge_from, merge_to))
AssertionError

Ah, definitely a bug. I'll look into it tonight.

I think this is fixed in 9522f4f

The example above has been added as a test

Thanks for fixing it. Looks like it still triggers in some cases though. Here's another example:

Cnt,Sym,Desc,BuyDate,Basis,SellDate,Proeeds,AdjCode,Adj,FormPosition,BuyLot,IsReplacement
2,GOOG,GOOGLE INC-CL A,1/25/2014,"$500",1/28/2014,"$490",,,,,
5,GOOG,GOOGLE INC-CL A,1/25/2014,"$2500",1/28/2014,"2475",,,,,

(Note: github doesn't let me reopen the issue. Happy to make a new one if you prefer, but it's the same assertion.)

Ah, I see the issue. I'll put a fix in later tonight. Here it is if you're eager:

--- a/wash.py
+++ b/wash.py
@@ -72,15 +72,6 @@ def earliest_wash_loss(lots):
     if not buys:
       continue
     ret.append(lot)
-    # Pull all the next lots w/ the same sell-date into ret if they have losses
-    i = i + 1
-    while i < len(lots):
-      if (lots[i].has_sell() and lots[i].proceeds < lots[i].basis and
-          lots[i].selldate == ret[0].selldate):
-        ret.append(lots[i])
-        i = i + 1
-        continue
-      break
     return ret

def split_head_lot(lots, ideal_head_count):

The issue is I was trying to optimize. The algorithm earlier would never pair up shares that were sold on the same day, so you could find a bunch of different losses all on the same day. Now that I realize you can pair shares up that were sold on the same day, we need to only return a single one at a time from the code that searches. I'll clean that up and submit.

With the latest commit, I think this is no longer an issue. Please reopen if I'm mistaken here.