{% extends "base.html" %} {% block title %}{{ _("Portfolio") }} · Wealth Dashboard{% endblock %} {% block heading %}{{ _("Portfolio") }}{% endblock %} {% block lede %}

{{ _("Everything you hold, aggregated by ISIN across accounts — the same fund at two brokers is one position from where you are standing. Values use the last market price, and each one names its day; a holding no price could be found for uses the price of your last trade, and says so.") }}

{% endblock %} {% block content %}
{{ _("Securities") }}
{{ money(s.securities, s.base_currency) }}
{{ _n(s.holdings | length, "{n} position", "{n} positions") }}
{{ _("Cash") }}
{{ money(s.cash, s.base_currency) }}
{{ _("across all accounts") }}
{{ _("Net invested") }}
{% set invested = s.holdings | selectattr('currency', 'equalto', s.base_currency) | sum(attribute='net_invested') %}
{{ money(invested, s.base_currency) }}
{{ _f("what you put in, {currency} positions", currency=s.base_currency) }}
{{ _("Difference") }}
{% set diff = s.securities - invested %}
{{ money(diff, s.base_currency) }}
{% if s.prices_as_of %}{{ _f("at market prices of {date}", date=d(s.prices_as_of)) }}{% endif %} {% if s.holdings_at_trade %}{{ _n(s.holdings_at_trade, "{n} holding at its last traded price", "{n} holdings at their last traded price") }}{% endif %} {% if not s.prices_as_of and not s.holdings_at_trade %}—{% endif %}
{% if s.holdings %} {% macro pct(v) %}{% if v is none %}—{% else %}{{ '%+.1f' | format(100 * v) }} %{% endif %}{% endmacro %}

{{ _("Return") }}

{{ _("the securities as one investment, in the base currency; cash left out on purpose") }}
{{ _("Since the first trade") }}{{ _("This year") }}{{ _("Last twelve months") }}
{{ _("Time-weighted (TWR)") }} {{ pct(perf.all.twr) }}{% if perf.all.twr_annual is not none %}{{ _f("{pct} % a year", pct='%+.1f' | format(100 * perf.all.twr_annual)) }}{% endif %} {{ pct(perf.ytd.twr) }} {{ pct(perf['1y'].twr) }}
{{ _("Money-weighted (MWR), a year") }} {{ pct(perf.all.mwr) }} {{ pct(perf.ytd.mwr) }} {{ pct(perf['1y'].mwr) }}

{% if perf.all.since %}{{ _f("Measured from {date}, day by day, on the prices the app has — backfilled to each security's first trade. A dash means there is nothing to measure yet.", date=d(perf.all.since)) }}{% endif %}

{% from "_benchmark.html" import benchmark_card with context %} {{ benchmark_card(benchmarks) }} {% if realised.sales %}

{{ _("Realised gains") }}

{{ _("what the sales made, by lots") }} · {{ _("FIFO") if realised.method == 'fifo' else _("average cost") }} · {{ _("change") }}
{% for y in realised.by_year %} {% endfor %}
{{ _("Year") }}{{ _("Realised") }}
{{ y.year }} {% for ccy, v in y.amounts.items() %}{{ money(v, ccy) }}{% if not loop.last %} · {% endif %}{% endfor %}
{{ _("All time") }} {% for ccy, v in realised.total.items() %}{{ money(v, ccy) }}{% if not loop.last %} · {% endif %}{% endfor %}

{{ _("Each sale against the cost of the units it sold — the oldest units first under FIFO, every unit at the average paid under average cost. Proceeds and costs as the broker booked them, fees included; a position closed years ago still counts. Kept per currency: a gain in dollars is not a gain in euros without a rate, and this is the figure a tax form asks for.") }}

{% endif %}

{{ _("Holdings") }}

{{ _("largest first") }} · {{ _("Export as CSV") }}
{% for h in s.holdings %} {# Not `d`: that is the date helper, and a global shadowed halfway down a table is a bug that only shows up in the rows. #} {% set delta = h.unrealised if h.unrealised is not none else ((h.value - h.net_invested) if h.value else None) %} {% endfor %}
{{ _("Security") }}{{ _("ISIN") }}{{ _("Where") }}{{ _("Quantity") }} {{ _("Price") }}{{ _("Net invested") }} {{ _("Value") }} {{ _("Unrealised") }} {{ _("Realised") }} TWR MWR
{{ h.name or h.isin }}{{ _f("last trade {date}", date=d(h.last_trade)) }} {{ h.isin }} {{ h.accounts | unique | join(', ') }} {{ qty(h.quantity) }} {% if h.price_kind == 'market' %}{{ qty(h.price | round(2)) }}{{ h.symbol }} · {{ d(h.price_as_of) }} {% elif h.price_kind == 'trade' %}{{ qty(h.price | round(2)) }}{{ _("last trade, no market price") }} {% else %}—{% endif %} {{ money(h.net_invested, h.currency) }} {{ money(h.value, h.currency) if h.value else '—' }} {{ money(delta, h.currency) if delta is not none else '—' }} {{ money(h.realised, h.currency) if h.realised is not none else '—' }} {{ pct(h.perf.twr_annual if h.perf.twr_annual is not none else h.perf.twr) }}{% if h.perf.twr_annual is not none %}{{ _("a year") }}{% endif %} {{ pct(h.perf.mwr) }}
{% if s.converted %}

{{ _("Amounts in another currency are in the totals above, converted at the ECB reference rate — a published mid-market rate, not one your broker would give you.") }} {{ _f("Rates of {date}.", date=d(s.fx_as_of)) }}

{% endif %} {% if s.unconverted %}

{{ _("These are not in the totals above, because no rate here covers them:") }} {% for u in s.unconverted %}{{ money(u.amount, u.currency) }}{{ ", " if not loop.last }}{% endfor %}.

{% endif %}
{% else %}

{{ _("No holdings yet.") }}

{{ _("Import a broker export from an account and the positions are computed from its trades.") }}

{% endif %} {% if s.closed %}

{{ _("Sold out") }}

{{ _n(s.closed | length, "{n} security no longer held", "{n} securities no longer held") }} · {{ _("newest first") }}
{% for h in s.closed %} {% endfor %}
{{ _("Security") }}{{ _("ISIN") }}{{ _("Where") }}{{ _("Held") }} {{ _("Bought") }}{{ _("Sold") }}{{ _("Income") }} {{ _("Realised") }}
{{ h.name or h.isin }} {{ h.isin }} {{ h.accounts }} {{ d(h.first) }} — {{ d(h.last) }} {{ money(h.bought, h.currency) }} {{ money(h.sold, h.currency) }} {{ money(h.income, h.currency) if h.income else '—' }} {{ money(h.realised, h.currency) if h.realised is not none else '—' }}

{{ _("A position sold down to nothing leaves the table above; it is kept here so what it made does not vanish with it. Its rows are on its page, like any other's.") }}

{% endif %} {% endblock %}