How to do taxes on ESPP sales ([ex]msft folks)
Figure if I don't post this, a third person will come along and ask about it.
So here's how I do these. It's different from the official explanation, but I've convinced myself it's completely equivalent and (IMHO) a lot easier. (YMMV / I'm not a CPA / I don't play one on TV / etc ...)
First, a big wall 'o numbers. Copy and paste into a .csv file if you want to play with them in Excel or whatever.
Each share has a cost basis for the purpose of Schedule D. In the World of ESPP, the basis for a given share will always be >= what you actually paid for it. The difference, if nonzero, is ordinary income.
Once you have the basis per share, you multiply by the number of shares, enter in column (e) (*).
Ordinary income is always basis minus
And that's basically it.
Re TurboTax: I've never used TurboTax myself, but it should be possible to just pretend that you bought the shares on the end-period date for the basis price and enter the ordinary income portion separately as if that were money coming magically out of nowhere that has nothing to do with the sale of the shares.
And now some examples:
Suppose we sold 100 shares from the Dec-2000 lot. Grabbing the appropriate row from above, we see that
If we had sold on 11-July-2002 (qualifying disposition) for $60/share, $45/share, or $35/share (yeah, I know it hasn't gotten that low... yet...), we'd have, respectively,
(where the 25.77 amount for commission+SEC_fees on the sale was pulled directly out of my ass; I have no idea what Schwab's rates are like these days).
If we had sold on 11-May-2002 (disqualifying disposition) instead...
(*) Note that for most brokers these days, the number they put on the 1099B is after subtracting off commissions and fees. If it so happens that Schwab turns out to be weird and doesn't subtract commissions and fees (there's a checkbox on the form that will tell you this), then you need to add these into whatever basis you enter in column (e). This won't affect the ordinary income portion. Repeating the first set of examples above for this world:
Whichever way they do it, the 1099B number is what goes in column (d).
Also, there's a place on the Schedule D where you sum all of the column (d)s and you want to make sure that number matches the sum of all of the Box 2's on the 1099B forms. That's one of the audit flags. Unless you've been doing short sales or wonky option things, this shouldn't be a problem.
(**) One might suppose that it's always zero, but there's a detail that I'm not entirely sure about, namely what happens with commissions+fees. The actual law (26 USC sec 423) says "fair market value", which I assume means not including commissions+fees, which suggests that commissions+fees always show up as a slight capital loss in this case.
(***) There is some funky rounding going on here. Basically, if you're anal-retentive and want the calculations to come out exactly the same (I'm sure the IRS won't care) as the way the HR folks are doing it, what you really want here is not 0.15 * StartPrice but rather StartPrice minus what ActualCost would have been if EndPrice had been higher, the latter being rounded in exactly the way they would have done it. So for example, for the 30-Jun-2000 period, 15% of StartPrice is actually 17.484375, but if that actually had determined the price for the period, they would actually have taken 85% of 116.5625 and rounded it to two places to get 99.08, which is why the MaxIncome number is actually 17.4825. As I said, I'm pretty sure the IRS won't care (unless you've got hundreds of thousands of shares, and maybe not even then).
So here's how I do these. It's different from the official explanation, but I've convinced myself it's completely equivalent and (IMHO) a lot easier. (YMMV / I'm not a CPA / I don't play one on TV / etc ...)
First, a big wall 'o numbers. Copy and paste into a .csv file if you want to play with them in Excel or whatever.
These are all per-share and adjusted for splits. I had to get the last 4 rows off of bigcharts.com, so you might want to check my start + end prices against the official list that they gave you (and that's on a Microsoft internal webpage somewhere; not the Schwab mailing). And whenever MSFT does its upcoming split, you'll need to divide these all by two or whatever --- or you could just multiply by the number of shares you actually have right now, jot those numbers down somewhere and just forget about splits from now on.Date, Start_Price, End_Price, Actual_Cost, Max_Income, Max_Basis 31-Dec-1997, 31.234375, 32.31250, 26.550, 4.684375, 31.234375 30-Jun-1998, 32.78125, 54.18750, 27.865, 4.91625, 32.78125 31-Dec-1998, 54.6875, 69.34375, 46.485, 8.2025, 54.6875 30-Jun-1999, 70.5000, 90.18750, 59.930, 10.5700, 70.5000 31-Dec-1999, 91.1875, 116.750, 77.510, 13.6775, 91.1875 30-Jun-2000, 116.5625, 80.000, 68.00, 17.4825, 85.4825 31-Dec-2000, 80.0000, 43.375, 36.87, 12.0000, 48.8700 30-Jun-2001, 43.3750, 73.000, 36.87, 6.5050, 43.3750 31-Dec-2001, 70.6000, 66.250, 56.31, 10.5900, 66.9000 30-Jun-2002, 67.0400, 54.700, 46.50, 10.0600, 56.5600 Start_Price = closing price on the first trading day of the period End_Price = closing price on the last trading day of the period Max_Income = 0.15 * Start_Price (***) Max_Basis = Actual_Cost + Max_Income
Each share has a cost basis for the purpose of Schedule D. In the World of ESPP, the basis for a given share will always be >= what you actually paid for it. The difference, if nonzero, is ordinary income.
- If it's a disqualifying disposition (meaning the holding period was less than 18 months and you're still alive), ignore the last two columns.
Your basis is
The ordinary income portion has already been included on your W-2 so there won't be anything for you to do other than check that they got the amount correct --- according to my own scorecard based on experience going back to 1994, there's only about a 70% chance that the Schwab folks will get this right the first time; be vigilant.End_Price. - If it's a qualifying disposition (meaning you held it more than 18 months or you're dead), only the last 3 columns matter. The basis depends on the sale price (fair market value) that you get when you sell/die.
The ordinary income portion goes on Line 21 of your 1040; put something like "ESPP ORDINARY INCOME" on the dotted line next to it.- If you sold for <=
Actual_Cost, - your basis is
Actual_Cost(ordinary income is zero). - If you sold for >=
Max_Basis, - your basis is
Max_Basis(ordinary income isMax_Income). - Otherwise,
- your basis is what you sold for
(i.e., your capital gain/loss will be essentially zero (**)).
In this case, nothing from the Schwab ESPP-tracking folks goes to the IRS (the 1099B does, but that's sent out by different people at Schwab), so if their information is subtly (or completely) wrong, don't sweat it. - If you sold for <=
Once you have the basis per share, you multiply by the number of shares, enter in column (e) (*).
Ordinary income is always basis minus
Actual_Cost.And that's basically it.
Re TurboTax: I've never used TurboTax myself, but it should be possible to just pretend that you bought the shares on the end-period date for the basis price and enter the ordinary income portion separately as if that were money coming magically out of nowhere that has nothing to do with the sale of the shares.
And now some examples:
Suppose we sold 100 shares from the Dec-2000 lot. Grabbing the appropriate row from above, we see that
End_Price = $43.375 Actual Cost = $36.87 Max_Income = $12.00 Max_Basis = $48.87per share.
If we had sold on 11-July-2002 (qualifying disposition) for $60/share, $45/share, or $35/share (yeah, I know it hasn't gotten that low... yet...), we'd have, respectively,
| (a) desc | (b) acquired | (c) sold | (d) proceeds | (e) basis | (f) gain | Line 21 of 1040 |
| 100 sh. MSFT | 31-Dec-2000 | 11-July-2002 | 5974.23 | 4887.00 | 1087.23 | 1200.00 |
| 100 sh. MSFT | 31-Dec-2000 | 11-July-2002 | 4474.23 | 4500.00 | (25.77) | 813.00 |
| 100 sh. MSFT | 31-Dec-2000 | 11-July-2002 | 3474.23 | 3687.00 | (212.77) | 0.00 |
(where the 25.77 amount for commission+SEC_fees on the sale was pulled directly out of my ass; I have no idea what Schwab's rates are like these days).
If we had sold on 11-May-2002 (disqualifying disposition) instead...
| (a) desc | (b) acquired | (c) sold | (d) proceeds | (e) basis | (f) gain | Included on W-2 |
| 100 sh. MSFT | 31-Dec-2000 | 11-May-2002 | 5974.23 | 4337.50 | 1636.73 | 650.50 |
| 100 sh. MSFT | 31-Dec-2000 | 11-May-2002 | 4474.23 | 4337.50 | 136.73 | 650.50 |
| 100 sh. MSFT | 31-Dec-2000 | 11-May-2002 | 3474.23 | 4337.50 | (863.27) | 650.50 |
(*) Note that for most brokers these days, the number they put on the 1099B is after subtracting off commissions and fees. If it so happens that Schwab turns out to be weird and doesn't subtract commissions and fees (there's a checkbox on the form that will tell you this), then you need to add these into whatever basis you enter in column (e). This won't affect the ordinary income portion. Repeating the first set of examples above for this world:
| (a) desc | (b) acquired | (c) sold | (d) proceeds | (e) basis | (f) gain | Line 21 of 1040 |
| 100 sh. MSFT | 31-Dec-2000 | 11-July-2002 | 6000.00 | 4912.77 | 1087.23 | 1200.00 |
| 100 sh. MSFT | 31-Dec-2000 | 11-July-2002 | 4500.00 | 4525.77 | (25.77) | 813.00 |
| 100 sh. MSFT | 31-Dec-2000 | 11-July-2002 | 3500.00 | 3712.77 | (212.77) | 0.00 |
Whichever way they do it, the 1099B number is what goes in column (d).
Also, there's a place on the Schedule D where you sum all of the column (d)s and you want to make sure that number matches the sum of all of the Box 2's on the 1099B forms. That's one of the audit flags. Unless you've been doing short sales or wonky option things, this shouldn't be a problem.
(**) One might suppose that it's always zero, but there's a detail that I'm not entirely sure about, namely what happens with commissions+fees. The actual law (26 USC sec 423) says "fair market value", which I assume means not including commissions+fees, which suggests that commissions+fees always show up as a slight capital loss in this case.
(***) There is some funky rounding going on here. Basically, if you're anal-retentive and want the calculations to come out exactly the same (I'm sure the IRS won't care) as the way the HR folks are doing it, what you really want here is not 0.15 * StartPrice but rather StartPrice minus what ActualCost would have been if EndPrice had been higher, the latter being rounded in exactly the way they would have done it. So for example, for the 30-Jun-2000 period, 15% of StartPrice is actually 17.484375, but if that actually had determined the price for the period, they would actually have taken 85% of 116.5625 and rounded it to two places to get 99.08, which is why the MaxIncome number is actually 17.4825. As I said, I'm pretty sure the IRS won't care (unless you've got hundreds of thousands of shares, and maybe not even then).
no subject
no subject
BTW, each of those lines was supposed to be a separate example --- though if you want you could imagine, e.g., having had a block of 300 shares sold in 3 separate transactions on the same day, and there was just utterly huge volatility that day.
If you look at the way the law on ESPPs is worded, these things are described as if the employee were awarded some (rather funky) call options. It's a little weird because no one knows in advance just how many there are. They get awarded on the first day of the period (e.g., July 1), the strike price is set to be whatever the closing price is for that day, they expire six months later (Dec 31), and they can only be exercised on the last day of the period.
And the general rule for positions opened by an option exercise is that you use the exercise date. As I understand it for ESPPs, the convention is such that you still use the "exercise" date even if the stock price went down over the period so that the "options" never actually get "exercised".
Note that for ordinary (listed) equity options, exercises/assignments take place on the 3rd Saturday of every month and it's the same deal (i.e., nobody gets freaked out by stuff getting bought/sold on a Saturday even though the market isn't open).