Cross-account wash sale detection for stocks, options, and ETFs — local-first, IRS Pub 550 rules, with a tax-harvest planner and pre-trade simulator.
Project description
_ _ _____ _____ ___ _ ____ _ _ _
| \ | || ____|_ _| / _ \ | | | _ \| | | | / \
| \| || _| | | _____| |_| || | | |_) | |_| | / _ \
| |\ || |___ | | |_____| _ || |___| __/| _ |/ ___ \
|_| \_||_____| |_| |_| |_||_____|_| |_| |_/_/ \_\
The definitive open-source engine for cross-account wash sale detection.
Stop flying blind. Detect wash sales across accounts, options, and ETFs in seconds.
Installation • Features • Usage • How it Works
⭐ If wash-alpha saves you a CPA call this tax season, please star the repo on GitHub. It's the single best signal for other traders looking for a tool they can trust with their tax data.
⚡ The Problem
When you trade across multiple brokerages, each platform only tracks wash sales within its own ecosystem. A loss sale on Schwab can be silently neutralized by a repurchase on Robinhood, and you won't find out until tax season.
The problem compounds when you trade options alongside stocks, or ETFs that track the same underlying index.
net-alpha solves this by providing a single, unified view of your wash sale exposure—before it's too late to act.
🌟 Key Features
- 📂 Bundled Broker Parsers: Schwab transactions + Schwab Realized G/L are supported out of the box. Other brokers can be added by contributing a parser — no configuration needed for supported formats.
- 🌐 Cross-Account Intelligence: Seamlessly match a loss sale on one broker against a repurchase on another in a single pass.
- 🔒 100% Local & Zero-Knowledge: Your financial data is yours.
net-alpharuns entirely locally. No cloud uploads, no tracking, no telemetry. (Quote fetches are the one exception — only the symbol leaves the box, never trades; disable withprices.enable_remote: false.) - 🖥 Local Web UI:
net-alpha uiopens a complete local dashboard — Portfolio, Positions, Tax, Sim, Imports, per-ticker drill-down — all rendered server-side via HTMX. No Node, no npm, no CDN at runtime. - 🧪 Pre-Trade Simulation: Planning a trade? The Sim page surfaces one-click suggestion chips (largest unrealized loss, wash-sale risk, largest unrealized gain) and shows FIFO lot consumption, realized P&L, and a cross-account wash-sale verdict before you execute. Available as
net-alpha simfrom the CLI. - 🌾 Tax Harvest Planner: A forward-looking, plan-builder assistant turns the harvest queue into a ranked, editable plan (greedy by tax saved, capped by §1211's $3,000 ordinary-loss limit). Honours user-declared position targets so it never closes something you want to keep.
- 🧮 §1256 Awareness: Index options (SPX, NDX, RUT, VIX, etc.) are recognized as §1256 contracts — wash-sale-exempt with statutory 60/40 LT/ST classification.
- 🔍 Auditable Explanations & Reconciliation: Every wash-sale flag includes rule citation, source trades, match reason, math, and confidence reasoning — accessible inline in the web UI or via
--detailon the CLI. Per-symbol reconciliation cross-checks computed realized P&L against your broker's Realized G/L file. - 📊 After-Tax Performance: The Tax → Performance view shows your realized P&L after estimated taxes, with a tax-drag breakdown and ST/LT/§1256 mix bar.
- ✍️ Manual Trade CRUD: Add, edit, transfer, or delete trades by hand from the web UI — wash sales recompute automatically over the affected window.
🚀 Installation
net-alpha requires Python 3.11 or higher. We recommend using uv for lightning-fast installation.
pip install wash-alpha
For the local UI:
pip install 'wash-alpha[ui]'
[!NOTE] While the package is named
wash-alphaon PyPI, the CLI command isnet-alpha.
💻 Usage
Local web UI (recommended)
net-alpha ui
Boots an ephemeral local server on 127.0.0.1 (free port in 8765–8775), opens your default browser, and exits when you press Ctrl-C. Drag CSVs into the dashboard, drill into any ticker, build a harvest plan, hand-enter trades, run pre-trade sims with suggested chips.
Optional flags: --port N · --no-browser · --reload (dev).
Install with UI extras:
pip install wash-alpha[ui](oruv sync --extra uifrom source). The CLI works without UI deps; UI deps are optional.
Import + check from the CLI
net-alpha schwab.csv --account personal
This imports the CSV, recomputes wash sales over the affected window, and prints a watch list plus a year-to-date impact summary. Add --detail for a per-violation breakdown. The same import is available via drag-and-drop in the web UI.
Pre-trade simulation
net-alpha sim TSLA 10 --price 180
Lists every account that holds the ticker, with FIFO lot consumption, realized P&L, and a cross-account wash-sale verdict per account. The web Sim page additionally surfaces one-click suggestion chips and remembers your recents.
Manage past imports
net-alpha imports # list
net-alpha imports rm 3 --yes # remove an import (recomputes wash sales)
Migrate from v0.x
net-alpha migrate-from-v1 --yes
Reads ~/.net_alpha/net_alpha.db (v1 schema) and writes a fresh v2 DB at ~/.net_alpha/net_alpha.db.v2. This helper exists only in the v2.0.x line.
🧠 How the Rules Work
net-alpha strictly follows IRS Publication 550. A wash sale is triggered when you sell a security at a loss and buy a "substantially identical" security within 30 days before or after the sale.
| Asset Type | Scenario | Confidence |
|---|---|---|
| Equities | Sold ticker X at a loss, bought ticker X within 30 days. |
🟢 Confirmed |
| Options | Sold option at a loss, bought same option (exact strike + expiry). | 🟢 Confirmed |
| Options | Sold option at a loss, bought option on the same underlying. | 🟡 Probable |
| ETFs | Sold ETF at a loss, bought the exact same ETF ticker. | 🟢 Confirmed |
| ETFs | Sold ETF at a loss, bought ETF tracking the same index (e.g., SPY → VOO). |
🟠 Unclear |
Custom ETF Matching: You can easily add your own "substantially identical" security pairs (like custom ETFs) by editing
~/.net_alpha/etf_pairs.yaml. Bundled defaults live in the package and are merged with your overrides — your file adds, never replaces.
Supported brokers (v2.0): Schwab — both transaction CSVs and Realized G/L exports (the latter powers per-symbol reconciliation).
Other brokers can be added by contributing a parser at src/net_alpha/brokers/<name>.py — implement the BrokerParser Protocol and register it in brokers/registry.py. Realized G/L parsers go in src/net_alpha/audit/brokers/.
🛡️ Disclaimer
[!IMPORTANT] This tool is for informational purposes only and does not constitute tax or legal advice. Wash sale rules—especially concerning options and ETFs—involve unsettled areas of tax law. Scenarios marked as
ProbableorUnclearshould always be reviewed with a qualified CPA or tax professional before making filing decisions.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wash_alpha-0.46.2.tar.gz.
File metadata
- Download URL: wash_alpha-0.46.2.tar.gz
- Upload date:
- Size: 4.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
84ead67ebc3d1aa48205c82e349a1e26f45a11ce006e89196849c6bf6dfd96ed
|
|
| MD5 |
6f54e6e30ebf1eae477384ab1b5b1bf9
|
|
| BLAKE2b-256 |
d872d71760c31638ca7712a0bbf9aabcf88903e2c0473ca1f986456be5880ecd
|
Provenance
The following attestation bundles were made for wash_alpha-0.46.2.tar.gz:
Publisher:
release.yml on chen-star/net_alpha
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wash_alpha-0.46.2.tar.gz -
Subject digest:
84ead67ebc3d1aa48205c82e349a1e26f45a11ce006e89196849c6bf6dfd96ed - Sigstore transparency entry: 1435999808
- Sigstore integration time:
-
Permalink:
chen-star/net_alpha@f8fb9b516f38a67ec31799128a1edf6807dc9d52 -
Branch / Tag:
refs/tags/v0.46.2 - Owner: https://github.com/chen-star
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f8fb9b516f38a67ec31799128a1edf6807dc9d52 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wash_alpha-0.46.2-py3-none-any.whl.
File metadata
- Download URL: wash_alpha-0.46.2-py3-none-any.whl
- Upload date:
- Size: 1.2 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fce864c3803141ef65a98280444a3ab367bddb38aae31f21b26aeb1a70e4fac9
|
|
| MD5 |
43467f20d6e9d2e9e25d7923a032392a
|
|
| BLAKE2b-256 |
97ae91f8a7d86f351d66921b54f153878636ef8e552d04644be899b755667552
|
Provenance
The following attestation bundles were made for wash_alpha-0.46.2-py3-none-any.whl:
Publisher:
release.yml on chen-star/net_alpha
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wash_alpha-0.46.2-py3-none-any.whl -
Subject digest:
fce864c3803141ef65a98280444a3ab367bddb38aae31f21b26aeb1a70e4fac9 - Sigstore transparency entry: 1435999825
- Sigstore integration time:
-
Permalink:
chen-star/net_alpha@f8fb9b516f38a67ec31799128a1edf6807dc9d52 -
Branch / Tag:
refs/tags/v0.46.2 - Owner: https://github.com/chen-star
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f8fb9b516f38a67ec31799128a1edf6807dc9d52 -
Trigger Event:
push
-
Statement type: