Output:
Chunk ID: da28c1
Wall time: 0.0000 seconds
Process exited with code 0
Original token count: 1232
Output:
                     benchmark_mapping["provider_symbol"], quote.currency.upper(), _fmt(quote.close),
                     _fmt(quote.adjusted_close), _fmt(rates[quote.currency.upper()]), _fmt(benchmark_value),
                     return_type, effective.isoformat(), benchmark_quote_date.isoformat(), now, "fresh", "[]"),
                )
                benchmark_stored = 1

        price_total = len(positions)
        price_stored = price_writes
        fx_total = len(currencies)
        fx_stored = fx_writes
        current_prices = sum(1 for _, _, quote_as_of, _ in quotes.values() if 0 <= _business_day_age(quote_as_of, effective) <= 2)
        price_coverage = _pct(current_prices, price_total)
        fx_covered_positions = sum(
            1 for _, quote, _, _ in quotes.values()
            if quote.currency.upper() in rates and 0 <= _business_day_age(rate_dates[quote.currency.upper()], effective) <= 2
        )
        fx_coverage = _pct(fx_covered_positions, price_total)
        benchmark_coverage = _pct(benchmark_stored, benchmark_total) if benchmark_total else ZERO
        if price_total == 0:
            quality = "unavailable"
            reasons.add("no_confirmed_positions")
        elif price_coverage == HUNDRED and fx_coverage == HUNDRED and (benchmark_total == 0 or benchmark_coverage == HUNDRED):
            quality = "complete"
        else:
            quality = "partial"
        risk = _risk_summary(conn, values, account_values, missing)
        analysis_id = stable_id("portfolio-analysis", run_id)
        conn.execute(
            """INSERT OR REPLACE INTO portfolio_analysis_snapshots(
                analysis_snapshot_id,run_id,as_of,base_currency,total_value_chf,price_coverage_pct,
                fx_coverage_pct,benchmark_coverage_pct,quality_status,reason_codes_json,summary_json,created_at)
                VALUES(?,?,?,?,?,?,?,?,?,?,?,?)""",
            (analysis_id, run_id, effective.isoformat(), "CHF", _fmt(sum(account_values.values(), ZERO)),
             _fmt(price_coverage), _fmt(fx_coverage), _fmt(benchmark_coverage), quality,
             json.dumps(sorted(reasons)), json.dumps({"positions": values, "risk": risk}, sort_keys=True), now),
        )
        audit_id = record_audit_event(
            conn, source=SOURCE_KEY, action="daily_market_valuation_completed", entity_type="market_data_run",
            entity_id=run_id, old_values={}, new_values={"as_of": effective.isoformat(), "status": quality,
            "price_coverage_pct": _fmt(price_coverage), "fx_coverage_pct": _fmt(fx_coverage),
            "benchmark_coverage_pct": _fmt(benchmark_coverage), "price_inputs_accepted": len(quotes),
            "price_rows_written": price_writes, "fx_inputs_accepted": len(rates), "fx_rows_written": fx_writes,
            "cached_price_inputs": cached_price_inputs, "reason_codes": sorted(reasons)}, created_by="system",
        )
        conn.execute(
            """UPDATE market_data_runs SET status=?,completed_at=?,price_total=?,price_stored=?,fx_total=?,fx_stored=?,
               benchmark_total=?,benchmark_stored=?,valuation_stored=?,missing_instruments_json=?,reason_codes_json=?,audit_id=?
               WHERE run_id=?""",
            (quality if quality != "unavailable" else "partial", utc_now(), price_total, price_stored, fx_total,
             fx_stored, benchmark_total, benchmark_stored, valuation_stored, json.dumps(missing),
             json.dumps(sorted(reasons)), audit_id, run_id),
        )
        conn.commit()
        return _result_from_row(conn.execute("SELECT * FROM market_data_runs WHERE run_id=?", (run_id,)).fetchone(), idempotent=False)

def _latest_cash_entries(conn: Connection) -> list[dict[str, Any]]:
    rows = conn.execute(
        """WITH ranked AS (
               SELECT c.account_id,c.currency,c.amount_chf,
                      ROW_NUMBER() OVER (
        CREATE INDEX IF NOT EXISTS idx_benchmark_snapshots_policy_time
            ON benchmark_snapshots(policy_id, benchmark_reference, as_of, fetched_at);

        CREATE TABLE IF NOT EXISTS portfolio_analysis_snapshots (
            analysis_snapshot_id TEXT PRIMARY KEY,
            run_id TEXT NOT NULL UNIQUE REFERENCES market_data_runs(run_id),
            as_of TEXT NOT NULL,
            base_currency TEXT NOT NULL DEFAULT 'CHF',
            total_value_chf TEXT,
            price_coverage_pct TEXT NOT NULL,
            fx_coverage_pct TEXT NOT NULL,
            benchmark_coverage_pct TEXT NOT NULL,
            quality_status TEXT NOT NULL CHECK(quality_status IN ('complete','partial','unavailable')),
            reason_codes_json TEXT NOT NULL DEFAULT '[]'
                CHECK(json_valid(reason_codes_json) AND json_type(reason_codes_json)='array'),
            summary_json TEXT NOT NULL DEFAULT '{}'
                CHECK(json_valid(summary_json) AND json_type(summary_json)='object'),
            created_at TEXT NOT NULL
        );


[P2] Respect as_of when using official PF cash

When `build_portfolio_reconciliation` is called for a historical `as_of` before the latest PostFinance import, this pulls the absolute latest official cash components and then injects that future cash into the depot account total. That can make historical reconciliations match against values that did not exist yet; the lookup needs to select the latest official snapshot at or before the requested `as_of`/cutoff.

[P2] Use historical official positions for as_of runs

For an `as_of` that is earlier than the newest PostFinance snapshot but later than a previous one, this filters the newest snapshot out and leaves `official` empty instead of loading the latest official snapshot valid for that date. In that scenario the settlement-account positions are not removed and the depot override is omitted, so historical market valuation can double count or miss PostFinance holdings.

[P3] Preserve currency when opening cash position details

When an official PostFinance cash account has multiple currencies, this creates multiple positions with IDs like `account:EUR` and `account:USD`, but `get_cash_position_detail` still finds a position by `account_id` only. Opening the USD row can therefore return whichever currency was appended first rather than the requested component.

The patch fixes current aggregation paths but introduces incorrect behavior for historical/as-of reconciliation and valuation, and multi-currency official cash details can resolve to the wrong component. These are functional issues that should be addressed before considering the patch correct.