Skip to content
/ ESPP2 Public

Calculate Norwegian taxes on stocks held with US brokers.

License

Notifications You must be signed in to change notification settings

otroan/ESPP2

Repository files navigation

ESPP 2

pytest

Overview

The ESPP2 tool serves both as a backend for a web frontend and a command line tool. The tool is built to help calculate Norwegian taxes on ESPP (Employee Stock Purchase Plan) and RSU (Restricted Stock Unit) shares. It also supports other shares held from Schwab.

To calculate taxes, the tool needs to know the whole history of each stock position in your posession or sold during the year. The purchase price and date when it was acquired, as well as any dividends and tax-free deductions accumulated.

The espp2 tool takes a transaction history for the current year, a holdings file listing all held positions at the end of the previous year, and a list of "wires" received, all in JSON format. Then it calculates the gains/losses and outputs that in a tax-report file and a holdings file for the current year.

Note: Norwegian tax law requires selling FIFO and this tools assumes this, while some brokers allow the user to sell an arbitrary lot. When selling, you must make sure to sell the oldest stocks first.

The tool runs in multiple phases to collect all the required data. The various use cases are described below. Most support is for Schwab users, Morgan Stanley is experimental. A few advanced but less tested methods are further down in this document.

Installation

Requires Python3.11 or 3.12

git clone https://github.com/otroan/ESPP2.git
cd ESPP2
python3 -m venv venv
source venv/bin/activate
pip install git+https://github.com/otroan/ESPP2.git#egg=espp2

Development Setup

Pre-commit Hooks

This project uses pre-commit hooks to ensure code quality. To set up the development environment:

  1. Install the package with development dependencies:
git clone https://github.com/otroan/ESPP2.git
cd ESPP2
pip install -e ".[dev]"
# Or if using poetry:
poetry install --with dev
  1. Install the pre-commit hooks:
pre-commit install

The pre-commit hooks will now run automatically on every commit, checking:

  • Tests pass (pytest)

To manually run all pre-commit hooks:

pre-commit run --all-files

To run a specific hook:

pre-commit run pytest

Schwab

Download transaction history

The transaction history for Schwab can be downloaded from https://client.schwab.com:

  • Choose Equity Awards
  • Choose Transaction History
  • Make sure the blue drop down box is set to Equity Award Center
  • Date range Previous 4 Years
  • Click Search
  • Using the export link in the upper right corner of the page, export as JSON
  • Copy that file into a folder, it is referred to as schwab-transactions.json later on

This transaction history only covers transactions from the last 4 years. If this file covers all your transactions, then you won't need more.

If your history of transactions reaches further back and you have last year's holdings file holdings-2023.json at hand, then you will need to add it as a parameter as shown below.

Add information about wires

If you have made transfers to a Norwegian bank account, run the tool with the --outwires option to generate a template file for the wires.

espp2 <schwab-transactions.json> [--inholdings holdings-2023.json] --outwires wires-2024.json

Now edit wires-2024.json and fill in the actual amount you have received in your bank acount in NOK where you see 'NaN'. Save the changes. This is required to be able to calculate transfer gain/loss that must be reported.

Main run

Now you can perform the main run with all the information to generate the tax report.

espp2 <schwab-transactions.json> [--inholdings holdings-2023.json] --wires wires-2024.json --outholdings holdings-2024.json --output calc-2024.zip

A new holdings file will be generated that you must store in a safe place for next year. It will also generate a zip file with a spreadsheet that has all the transactions and underlaying calculations neatly documented, mainly in case that the tax office asks you to provide documentation.

Morgan Stanley

Note: Morgan support is still under construction. Proceed with caution!

Morgan Stanley provides a semi-complete transaction history for all years. The tool can be run with the Morgan Stanley transaction file as input.

espp2 <morgan-2024.html> --outholdings <morgan-holdings-2024.json> --output calc-2024.zip

espp2 --help will show the available options. The --verbose option will show the tax calculations in more detail and it is important to verify that these are correct.

In particular it is important to verify that the total stock positions match the statements from the stock broker. If these numbers do not match, the resulting tax calculation will be wrong.

Less tested options for special cases and advanced users

Option 1: Schwab - Complete transaction history and no holdigns file

Schwab provides a complete transaction history back to 2009 in 4 year increments. The holdinator tool can be used to generate a holdings file for any year.

holdinator <schwab-all-transaction-files> --outholdings holdings-2023.json
espp2 <schwab-all-transactions.json> --inholdings holdings-2023.json --output calc-2024.zip

Release notes 2025

  • Removed old plugins
    • Removed support for TD Ameritrade (acquired by Schwab)
    • Removed support for Schwab CSV1 and CSV2 formats
    • Removed ESPPv1 pickle
  • Split holdings generation into separate CLI tool (holdinator)
  • Committed known symbol cache files to repo

Release notes 2023

  • Upgraded to Python 3.11/3.12
  • Upgraded to Pydantic v2
  • Added support for Schwab JSON format
  • Added support for Schwab CSV2 format
  • New tax calculation module (portfolio) that generates an excel sheet for added tracability
  • Relay error and warning messages to the web frontend
  • Split positions with sales to correctly calculate tax-free deduction for part positions held at end of year
  • Updated tax-free deduction rates and ESPP rates for 2023.
  • Updated morgan importer for 2023

About

Calculate Norwegian taxes on stocks held with US brokers.

Resources

License

Stars

Watchers

Forks

Packages

No packages published