The old model valued holdings in ADJ (total-return index) units but computed distribution flows as raw per-share dollars — so every distribution, and its tax, was overstated by the raw/adj ratio (JLPSX: 30.10/11.25 = 2.7x; the Dec-2020 cap-gain tax showed as 12.1% of the account instead of the true 4.5%). The wiggle in the after-tax curve was this bug, not a convention issue. tax.py now: - values holdings in RAW share units on close prices (bundle.close); - receives the per-share distribution on its event date, pays the tax (recorded in TaxResult.taxes), and reinvests the after-tax remainder at the same day's raw close — the tax's effect lives in the (smaller) reinvested units and is NOT also deducted from cash (double-count caught and fixed in review); - recomputes market value after the reinvestment so equity[t] is the post-event liquidation value. With the fix, the 'as-if-liquidated' equity on JLPSX's ex-div day drops by exactly the true tax cost (4.72% vs 12.1% before); the -22.9% price drop is offset by the distribution kept. Also: - app.py passes bundle.close to the after-tax model (pre-tax portfolio_returns still uses adj); - JLPSX/JLPYX: the 2020-12-11 6.824 capital-gain distribution is moved to the true ex-div date 2020-12-14 (remove/add correction ops), so the reinvestment prices at the post-drop close; - tests/test_tax.py: 8 synthetic regression tests (tax magnitude, reinvestment MV, no double-count, ex-div equity step, per-component rates); run_tests.sh now runs it.
34 lines
978 B
Bash
Executable File
34 lines
978 B
Bash
Executable File
#!/usr/bin/env bash
|
|
# Full test suite: app-level (Streamlit AppTest) + real-browser e2e (Playwright).
|
|
#
|
|
# Usage: ./run_tests.sh
|
|
# The browser e2e part needs the server running (./run.sh, port 8599);
|
|
# it is skipped automatically if the server is down.
|
|
set -uo pipefail
|
|
cd "$(dirname "$0")"
|
|
|
|
fail=0
|
|
|
|
echo "=== 1/4 data cache tests (incremental refresh) ==="
|
|
.venv/bin/python tests/test_data.py || fail=1
|
|
echo
|
|
|
|
echo "=== 2/4 after-tax model tests (synthetic) ==="
|
|
.venv/bin/python tests/test_tax.py || fail=1
|
|
echo
|
|
|
|
echo "=== 3/4 app tests (AppTest, no browser) ==="
|
|
.venv/bin/python tests/test_app.py || fail=1
|
|
echo
|
|
|
|
echo "=== 4/4 browser e2e (Playwright, needs the server) ==="
|
|
if curl -s -m 3 -o /dev/null http://localhost:8599/healthz; then
|
|
.venv/bin/python tests/test_e2e_browser.py || fail=1
|
|
else
|
|
echo "server not reachable on :8599 — skipping e2e (start it with ./run.sh)"
|
|
fi
|
|
echo
|
|
|
|
[ $fail -eq 0 ] && echo "ALL TESTS PASSED" || echo "TESTS FAILED"
|
|
exit $fail
|