Skip to content

Instantly share code, notes, and snippets.

@ross
Last active February 15, 2023 17:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ross/1ffc2a81c12cce68e262891cd358c58b to your computer and use it in GitHub Desktop.
Save ross/1ffc2a81c12cce68e262891cd358c58b to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# https://github.com/simonmichael/hledger/blob/master/examples/TXF-spec-v042.org
# https://github.com/andreasg123/stock-gain-tax-import/blob/main/create-txf-2018.py
from collections import defaultdict
from datetime import date
from io import StringIO
from pprint import pprint
from sys import argv
symbols = defaultdict(list)
with open(argv[1]) as fh:
# skip pass the header
lines = fh.read().split('\n')
for i, line in enumerate(lines):
if line.startswith('Symbol'):
break
# parse the symbols
for i in range(i+1, len(lines)):
line = lines[i]
if line[0] != ' ':
# new symbol
symbol = line.split(',', 1)[0]
continue
(
_,
quantity,
acquired,
cost_per_share,
cost,
disposed,
price_per_share,
proceeds,
gain,
deferred_loss,
term,
lot_selection,
_
) = line.strip().split(',')
if deferred_loss in ('--', '.00'):
deferred_loss = None
symbols[symbol].append({
'quantity': quantity,
'acquired': acquired,
'cost_per_share': cost_per_share,
'cost': cost,
'disposed': disposed,
'price_per_share': price_per_share,
'proceeds': proceeds,
'gain': gain,
'deferred_loss': deferred_loss,
'term': term,
'lot_selection': lot_selection
})
print('V042')
print('Aextrade-to-txf.py')
print('D', date.today().strftime('%m/%d/%y'))
print('^')
# WARNING: e*Trade doesn't provide enough information to know what was reported
# to the IRS and what wasn't in their CSVs. If you hav box B, E, or X stuff.
# You'll have to grab the pdf version and manually change the boxes for those
# :-(
codes = {
# A
'Short': 321,
# D
'Long': 323,
}
wash_codes = {
# A
'Short': 682,
# D
'Long': 323,
}
for symbol, lots in sorted(symbols.items()):
for lot in lots:
print('TD')
if lot['deferred_loss']:
code = wash_codes[lot['term']]
else:
code = codes[lot['term']]
print(f'N{code}')
print(f'P {lot["quantity"]} sh {symbol}')
print(f'D{lot["acquired"]}')
print(f'D{lot["disposed"]}')
print(f'${lot["cost"]}')
print(f'${lot["proceeds"]}')
if lot['deferred_loss']:
print(f'${-lot["deferred_loss"]}')
print('^')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment