{# Inputs: allocation: AllocationView from portfolio.allocation.build_allocation() #} {% set rank_palette = [ '#0A84FF', '#FFD60A', '#30D158', '#FF375F', '#5E5CE6', '#64D2FF', '#5AC8FA', '#BF5AF2', 'rgba(181,181,255,0.65)', 'rgba(255,255,255,0.40)' ] %} {% set rest_color = 'rgba(255,255,255,0.14)' %} {% set cash_color = 'rgba(142,142,147,0.6)' %} {# neutral gray; matches Apple's systemGray — free cash #} {% set cash_pledged_color = 'rgba(255,159,10,0.65)' %} {# orange (matches Cash KPI's pledged bar) — distinct from free cash + rest #} {% if allocation.symbol_count == 0 %}
No priced open positions in scope.
{% else %}
{# Donut — click opens full allocation details modal #} {# Concentration stats #}
Top holding {% set top = allocation.slices[0] %}{{ top.symbol }} · {{ "%.1f"|format(top.pct|float) }}%
Top 3 share {{ "%.1f"|format(allocation.top3_pct|float) }}%
Top 5 share {{ "%.1f"|format(allocation.top5_pct|float) }}%
Top 10 share {{ "%.1f"|format(allocation.top10_pct|float) }}%
{# Chip leaderboard #}
Top {{ allocation.slices|rejectattr('is_rest')|rejectattr('is_cash')|list|length }} holdings
{% for s in allocation.slices %} {% if s.is_rest %} +{{ allocation.symbol_count - allocation.slices|rejectattr('is_rest')|rejectattr('is_cash')|list|length }} more ${{ "%.1f"|format(s.market_value|float / 1000) }}k {{ "%.1f"|format(s.pct|float) }}% {% elif s.is_cash %} {% set _color = cash_pledged_color if s.is_pledged_cash else cash_color %} {% set _label = 'Cash · pledged' if s.is_pledged_cash else 'Cash · free' %} {% set _title = 'Cash currently securing open short puts (CSP collateral). Cannot be deployed elsewhere until the puts close, expire, or are bought back.' if s.is_pledged_cash else 'Cash not pledged to any open option position.' %} {{ _label }} ${{ "%.1f"|format(s.market_value|float / 1000) }}k {{ "%.1f"|format(s.pct|float) }}% {% else %} {% set color = rank_palette[s.rank - 1] %} {% set glow = s.rank <= 6 %} {{ s.symbol }} ${{ "%.1f"|format(s.market_value|float / 1000) }}k {{ "%.1f"|format(s.pct|float) }}% {% endif %} {% endfor %}
{# Click-through details modal — full ranked breakdown including small positions normally rolled into the 'rest' aggregate. UX: with 50+ holdings the bare table was an undifferentiated wall. Now the modal has a typeahead filter, sticky table header, and a compact row density so the user can find a symbol in two seconds. #} {% endif %}