{% extends "base.html" %} {% from "_recon_table.html" import render_table, drill_table, drill_table2 %} {% block title %}Reconciliation — RWA Calculator{% endblock %} {% block content %}

Parallel-run reconciliation

Run this calculator and reconcile its output against your legacy calculator, component by component (EAD, RWA, risk weight, PD, LGD, CCF, exposure class, …). Each row is bucketed as match / within-tolerance / break / missing, with our reason and input drivers attached so a break can be triaged to a data fix or an engine fix.

{% if error %}
Reconciliation failed: {{ error }}
{% endif %}
{% if reusable_run %}
{% elif data_changed %}
Input data has changed since the last matching calculation — it will be recomputed.
{% endif %}

Declare the join key(s) and which legacy column maps to each canonical component. legacy_file resolves relative to the data path above; numeric components accept scale and unit = "percent", categoricals a value_map of synonyms.

{% if has_saved_run %}Reset to defaults{% endif %}
{% if result %} {% if result.warnings %}
{% for w in result.warnings %}
{{ w }}
{% endfor %}
{% endif %} {% if not result.success %}
No comparable components — check the mapping (legacy file path, join keys and column names).
{% else %}
{% if result.hide_immaterial %} Showing material rows only — {{ "{:,}".format(result.hidden_count) }} zero-gross-exposure row(s) hidden from the breakdown counts below (money totals are unaffected). Show all rows. {% else %} Breakdown counts include every row. Hide zero-gross-exposure rows for a cleaner view of the real differences. {% endif %}

1 · Headline — does it tie out?

{% for s in result.headline %}
{{ "{:,.0f}".format(s.our_total) }}
{{ s.component }} — ours
legacy {{ "{:,.0f}".format(s.legacy_total) }}{% if s.delta_pct is not none %} · Δ {{ "%+.2f"|format(s.delta_pct) }}%{% endif %}
{% endfor %}

Tie-out — legacy vs ours per component

{{ result.chart_tie_out | safe }}

Where the money differs — Σ|Δ| by component

{{ result.chart_abs_delta | safe }}

By component

{{ render_table(result.component_table) }}

2 · Segment — where do breaks concentrate?

Each row links into the per-key explorer, pre-filtered to that segment.

{% if result.allocation_table.rows %}

Asset-class allocation — legacy vs ours (RWA)

{{ result.chart_allocation | safe }} {% if result.allocation_method_sections %}

Split by method

The same money again, one section per methodology — STD (standardised), FIRB, AIRB (advanced IRB, retail included), and slotting / equity where present — because each asset class is reported per method (SA on COREP C 07.00, IRB on C 08.0x). All sections share one bar scale, so a small method reads as genuinely small.

{% for section in result.allocation_method_sections %}

{{ section.method }}

{{ section.chart | safe }} {% endfor %} {% endif %}

Asset-class allocation — EAD & RWA by risk class

Money totalled by risk class, post-guarantee: a guaranteed exposure's guaranteed slice is counted under the guarantor's class and its retained slice under the borrower's, matching a post-substitution legacy extract. Offsetting deltas show where the two engines allocate an exposure to different classes.

{{ render_table(result.allocation_table) }} {% if result.allocation_method_table.rows %}

Asset-class allocation — EAD & RWA by risk class & method

The same post-guarantee money, split by the methodology each side applied. Summing a class's methods reproduces its combined row above, so a class that ties out in total but is allocated to different approaches by the two engines shows here as offsetting deltas instead of a clean match. The guaranteed slice of an SA-guaranteed exposure is counted under the guarantor's class and its standardised method.

{{ render_table(result.allocation_method_table) }} {% endif %} {% endif %}

By bucket

{{ drill_table(result.bucket_table, "row_bucket", result.explorer_url, "bucket", result.hide_qs) }}

Breaks by exposure class (borrower class)

Where breaks concentrate. Each exposure is a single key, so its break is attributed to its borrower (origination) class — a guaranteed exposure is not split here (that post-guarantee split is in the allocation above).

{{ drill_table(result.class_table, "our_exposure_class", result.explorer_url, "exposure_class", result.hide_qs) }}

By approach

{{ drill_table(result.approach_table, "our_approach", result.explorer_url, "approach", result.hide_qs) }}

By exposure class & method

Our-side view — how our breaks distribute across methodology (STD / FIRB / AIRB / slotting / equity) within each exposure class. Click a method to drill the explorer to that class × method. {% if result.allocation_method_sections %}(Break attribution is at the borrower grain, so this stays our-side only — the two-sided, post-guarantee money split is the by-method allocation above.){% else %}(Map [components.approach] to give the legacy side a method too and split the asset-class allocation above by methodology.){% endif %}

{{ drill_table2(result.class_method_table, "method", result.explorer_url, "exposure_class", "our_exposure_class", "method", "method", result.hide_qs) }}

3 · Worklist — top {{ result.biggest_n }} of {{ "{:,}".format(result.break_count) }} break(s), largest first

Click a key to open its single-loan forensic and sign it off (accept / reject with a reason), or open the full per-key explorer ({{ "{:,}".format(result.total_rows) }} row(s)). Reviewed breaks drop off this worklist. Download the full per-key detail: CSV · Excel.

{% if result.signoff_progress and result.signoff_progress.total %}

Sign-off progress: {{ "{:,}".format(result.signoff_progress.reviewed) }} of {{ "{:,}".format(result.signoff_progress.total) }} break(s) reviewed — {{ "{:,}".format(result.signoff_progress.open) }} still open ({{ "{:,}".format(result.signoff_progress.accepted) }} accepted, {{ "{:,}".format(result.signoff_progress.rejected) }} rejected{% if result.signoff_progress.changed %}, {{ "{:,}".format(result.signoff_progress.changed) }} changed since sign-off & back on the worklist{% endif %}).

{% endif %} {% if result.signoff_decision_count %}
{% endif %} {% if result.biggest_breaks.rows %} {{ drill_table(result.biggest_breaks, "_recon_key", result.loan_url_base, "key") }} {% elif result.break_count %}
Every break has been reviewed (or its difference is unchanged). Switch the explorer's status filter to accepted / rejected to review your decisions.
{% endif %}

Explore open differences →

{% endif %} {% endif %} {% endblock %} {% block scripts %} {% endblock %}