{% if not violations %} {# W1b: affirmative empty state. #}
✓ No wash-sale violations detected for {{ selected_year }} across all accounts.
net-alpha checks both directions and across accounts.
{% else %} {# Build the lag-sort URL preserving current filters #} {% set lag_qs = [] %} {% if filter_ticker %}{% set _ = lag_qs.append('ticker=' ~ filter_ticker) %}{% endif %} {% if filter_account %}{% set _ = lag_qs.append('account=' ~ filter_account) %}{% endif %} {% if filter_year %}{% set _ = lag_qs.append('year=' ~ filter_year) %}{% endif %} {% if filter_confidence %}{% set _ = lag_qs.append('confidence=' ~ filter_confidence) %}{% endif %} {% set _ = lag_qs.append('sort=lag') %} {% set _ = lag_qs.append('order=' ~ next_lag_order) %} {% set lag_url = '/wash-sales?' ~ lag_qs|join('&') %}
{% for g in groups %}
{% for v in g.violations %} {% set lag = lag_days(v) %} {% set src = source_label(v) %} {# Each violation gets its own so Alpine x-data scopes correctly over both the data row and the explain row. #} {# I1: id on the , so HTMX innerHTML swap inserts valid table content (a
inside a
is hoisted by browsers). #} {% endfor %}
Loss date Loss → Buy Trigger date Lag {% if sort == 'lag' %}{{ '▼' if order == 'desc' else '▲' }}{% endif %} Disallowed Matched qty Confidence Source
{{ v.loss_sale_date or "—" }} {{ v.loss_account or "—" }} → {{ v.buy_account or "—" }} {{ v.triggering_buy_date or "—" }} {% if lag is not none %}{{ lag }}d{% else %}—{% endif %} ${{ "%.2f"|format(v.disallowed_loss) }} {{ v.matched_quantity }} {{ v.confidence }} {% if src == "Schwab" %} {{ src }} {% elif src == "Cross-account" %} {{ src }} {% else %} {{ src }} {% endif %}
, not the
{% endfor %}
{% endif %} {# C4: Exempt matches — §1256 contracts that were skipped by the wash-sale detector. Shown as a sibling section below the violations table. Gray + line-through styling signals "detected but not penalised". #} {% if exempt_matches %}

§1256 Exempt Matches

These pairs were detected within the 30-day window but are exempt from wash-sale rules under IRC §1256(c).
{% for em in exempt_matches %} {% endfor %}
Loss date Loss → Buy Trigger date Ticker Notional disallowed Matched qty Confidence Exempt reason
{{ em.loss_sale_date or "—" }} {{ em.loss_account or "—" }} → {{ em.buy_account or "—" }} {{ em.triggering_buy_date or "—" }} {{ em.ticker or "—" }} ${{ "%.2f"|format(em.notional_disallowed|float) }} {{ em.matched_quantity }} {{ em.confidence }} {{ em.exempt_reason | replace("_", " ") | title }}
{% endif %}