Skip to content

Instantly share code, notes, and snippets.

@egill512
Forked from whistler/ofx2csv.py
Last active May 8, 2020 16:18
Show Gist options
  • Save egill512/5936018de4d99b96b3742390f04bc28f to your computer and use it in GitHub Desktop.
Save egill512/5936018de4d99b96b3742390f04bc28f to your computer and use it in GitHub Desktop.
Convert QFX/OFX to CSV
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from csv import DictWriter
from glob import glob
import ofxparse
import csv
DATE_FORMAT = "%m/%d/%Y"
def write_csv(statement, out_file):
if len(statement) == 0:
print("Empty statement. Not outputting conversion")
return
print("Writing: " + out_file)
header = statement[0].keys()
with open(out_file, 'w', newline='') as f:
writer = DictWriter(f, fieldnames=header)
wr = csv.writer(f, dialect='excel')
wr.writerow(header)
writer.writerows(statement)
def get_bank_statement_from_qfx(qfx):
balance = qfx.account.statement.balance
statement = []
credit_transactions = ['credit', 'dep', 'int', 'directdep']
debit_transactions = ['debit', 'atm', 'pos', 'xfer', 'check', 'fee', 'payment']
for transaction in qfx.account.statement.transactions:
credit = ""
debit = ""
balance = balance + transaction.amount
if transaction.type in credit_transactions:
credit = transaction.amount
elif transaction.type in debit_transactions:
debit = -transaction.amount
else:
raise ValueError("Unknown transaction type:" + transaction.type)
line = {
'date': transaction.date.strftime(DATE_FORMAT),
'payee': transaction.payee,
'memo' : transaction.memo,
'debit': debit,
'credit': credit,
'balance': balance
}
statement.append(line)
return statement
def get_investment_transactions_statement_from_qfx(qfx):
statement = []
for transaction in qfx.account.statement.transactions:
line = {
'type': getattr(transaction, 'type', ''),
'tradeDate': getattr(transaction, 'tradeDate', ''),
'settleDate': getattr(transaction, 'settleDate', ''),
'memo': getattr(transaction, 'memo', ''),
'income_type': getattr(transaction, 'income_type', ''),
'units': getattr(transaction, 'units', ''),
'unit_price': getattr(transaction, 'unit_price', ''),
'comission': getattr(transaction, 'comission', ''),
'fees': getattr(transaction, 'fees', ''),
'total': getattr(transaction, 'total', ''),
'tferaction': getattr(transaction, 'tferaction', '')
}
line.update(get_security_info(getattr(transaction, 'security', ''), qfx))
statement.append(line)
return statement
def get_security_info(sec_id, qfx):
sec_dict = {
'securityid':'',
'securityname': '',
'securityticker': '',
'securitymemo': ''
}
if sec_id == '' or sec_id is None:
return sec_dict
for sec in qfx.security_list:
if sec.uniqueid == sec_id :
sec_dict['securityid'] = getattr(sec,'uniqueid','')
sec_dict['securityname'] = getattr(sec,'name','')
sec_dict['securityticker'] = getattr(sec,'ticker','')
sec_dict['securitymemo'] = getattr(sec,'memo','')
return sec_dict
def get_statement_from_qfx(qfx):
if isinstance(qfx.account.statement, ofxparse.ofxparse.InvestmentStatement):
return get_investment_transactions_statement_from_qfx(qfx)
else:
return get_bank_statement_from_qfx(qfx)
files = glob("*.qfx")
for qfx_file in files:
qfx = ofxparse.OfxParser.parse(open(qfx_file, encoding="latin-1"))
statement = get_statement_from_qfx(qfx)
out_file = "converted_" + qfx_file.replace(".qfx",".csv")
write_csv(statement, out_file)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment