From eb50a1920da57ce4349c5e5d91ab978aff72bb32 Mon Sep 17 00:00:00 2001 From: Tanguy Herbron Date: Thu, 15 Feb 2024 17:40:19 +0100 Subject: [PATCH] feat: Initial commit --- README.md | 8 +++++ main.py | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 README.md create mode 100644 main.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..db43d72 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# Ghostfolio nordnet importer + +Export your Nordnet transactions and convert them into a Ghostfolio compatible import format + +## TODO +- Add usage documentation +- Import cash transactions +- Autonomous export ? diff --git a/main.py b/main.py new file mode 100644 index 0000000..39c0831 --- /dev/null +++ b/main.py @@ -0,0 +1,96 @@ +import csv +import json +from datetime import datetime +from argparse import ArgumentParser + +parser = ArgumentParser() +parser.add_argument("-i", "--input", dest="input_filename", + help="Nordnet source file", metavar="INPUT") +parser.add_argument("-o", "--output", dest="output_filename", + help="Ghostfolio destination file", metavar="OUTPUT") + +args = parser.parse_args() + +NORDNET_ACCOUNT_ID="cae3d45f-53bc-4dee-83a4-4448b409f8b2" + +format = "%Y-%m-%d" + +data = { + 'activities': [] +} + +splits = { + "NOVO B": { + "2023-09-20 00:00:00 UTC": 0.5 + } +} + +symbol_translations = { + "NOVO B": "NOVO-B.CO", + "XZEC": "XZEC.DE" +} + +#print("Date", "Code", "DataSource", "Currency", "Price", "Quantity", "Action", "Fee", "account", sep=',') + +# Date, Code, DataSource, Currency, Price, Quantity, Action, Free, Note +with open(args.input_filename, newline='') as csvfile: + reader = csv.reader(csvfile, delimiter='\t', quotechar='|') + + for row in reader: + if row[5] in ("INDBETALING", "HÆVNING", "INDSÆTTELSE", "AFKASTSKAT ASK", "MAKULERING AFKASTSKAT ASK", "Transaktionstype", ""): + continue + + date = None + t_type = None + price = 0 + + try: + date = datetime.strptime(row[2], format) + except ValueError: + data = None + print("Failed parsing date") + + price = row[10].replace('.', '') + price = price.replace(',', '.') + quantity = row[9] + fee = row[27] + symbol = row[6] + currency = row[17] + + match row[5]: + case "KØBT": + t_type = "BUY" + case "SOLGT": + t_type = "SELL" + case "UDB.": + t_type = "DIVIDEND" + fee = 0 + currency = row[15] + + if symbol in splits: + key = list(splits[symbol].keys())[0] + if date.isoformat() < key: + ratio = splits[symbol][key] + price = float(price) * ratio; + quantity = float(quantity) * (1 / ratio); + + if symbol in symbol_translations: + symbol = symbol_translations[symbol] + + data['activities'].append({ + 'accountId': NORDNET_ACCOUNT_ID, + 'fee': float(str(fee).replace(',', '.')), + 'quantity': int(quantity), + 'type': t_type, + 'unitPrice': float(price), + 'currency': currency, + 'dataSource': 'YAHOO', + 'date': date.isoformat(), + 'symbol': symbol, + }) + +json_data = json.dumps(data) + +f = open(args.output_filename, "w") +f.write(json_data) +f.close()