Skip to content

datasteg money-flow

Money-flow methodology, version 1.5

2026-11-02 · release 20261102.2

datasteg (2026), “Money-flow methodology”, version 1.5, datasteg money-flow, 2 November 2026, https://money-flow.datasteg.com/en/method?v=1.5.

Rules

R1Units

All positions are in US dollar billions. Where the publisher converts (BIS, IMF, TIC), its dollar figure is used. National series are converted at BIS rates: a stock at the period-end rate, a period average at the period's average rate. The rate is named in the provenance. An economy whose currency is another's (Ecuador, El Salvador, Timor-Leste and Panama in dollars; Kosovo, Andorra, Montenegro and San Marino in euros; Guinea-Bissau in CFA francs; West Bank and Gaza in shekels) is converted at that currency's rate, and so is a dated regime (Zimbabwe in dollars from February 2009 to June 2019). A source series whose early segment is in a unit the source later superseded (Sierra Leone's broad money before 2015 in old leones) is corrected by a listed factor before anything else. A value with no rate is left out, never filled in, and the Method page says which economies and months; the IMF's currency-union aggregates (ECCU, WAEMU) are never drawn and are listed apart.

Why: Sums across sources need one unit; a stock converted at an average rate is misstated. The verification of 31 Oct 2026 found 6,331 values without a rate, of which 539 Zimbabwean months fell in its dollar years and 1,206 West Bank and Gaza months had a shekel rate under another code.

  • In release 20261102.2: 551 converted at a period-average rate
  • In release 20261102.2: 293,522 converted at a period-end rate
  • In release 20261102.2: 9,370 converted at one, a dollarised economy or a dollar regime (currency map, dated regimes)
  • In release 20261102.2: 36 of which BRA: no BIS rate for its currency, 1950-01-31 to 1952-12-31
  • In release 20261102.2: 365 of which GIN: no BIS rate for its currency, 2021-08-31 to 2025-12-31
  • In release 20261102.2: 28 of which LBR: no BIS rate for its currency, 2025-11-30 to 2026-05-31
  • In release 20261102.2: 56 of which MOZ: no BIS rate for its currency, 2025-11-30 to 2026-06-30
  • In release 20261102.2: 30 of which MWI: no BIS rate for its currency, 2024-12-31 to 2025-04-30
  • In release 20261102.2: 20 of which PNG: no BIS rate for its currency, 2026-03-31 to 2026-07-31
  • In release 20261102.2: 70 of which SLE: no BIS rate for its currency, 2025-07-31 to 2026-04-30
  • In release 20261102.2: 372 of which SOM: no BIS rate for its currency, 2018-01-31 to 2026-03-31
  • In release 20261102.2: 91 of which SSD: no BIS rate for its currency, 2025-08-31 to 2026-08-31
  • In release 20261102.2: 36 of which TZA: no BIS rate for its currency, 2025-07-31 to 2026-06-30
  • In release 20261102.2: 210 of which ZWE: no BIS rate for its currency, 2024-03-31 to 2026-08-31
  • In release 20261102.2: 3,234 of which an IMF currency-union aggregate (ECCU, WAEMU: never drawn)
  • In release 20261102.2: 38 of which economies with fewer than 20 such values (the newest months, before the BIS rate file reaches them)
  • In release 20261102.2: 4,586 stock values without a rate, left out

Code: scripts/sitebuild/rules.py · r1_units · tests: test_r1_stock_at_period_end_average_at_average, test_r1_dollarised_economy_converts_at_one, test_r1_dated_currency_regime

R2Totals only

A ribbon reads only total rows: all sectors, all currencies, one instrument per channel. Breakdowns appear on hover and in the table, never in a sum.

Why: The links table keeps breakdown rows next to totals.

  • In release 20261102.2: 1,661,960 breakdown rows left out of sums (sector or currency)

Code: scripts/sitebuild/rules.py · r2_totals_only · tests: test_r2_takes_total_not_breakdowns

R3One frequency per period

Where a source has a half-yearly and an annual figure for the same December, the half-yearly one is used; if they differ, the pair is flagged.

Why: CPIS (PIP) carries S and A rows at each December.

  • In release 20261102.2: 882,327 annual rows dropped where a half-yearly row exists
  • In release 20261102.2: 0 pairs flagged (annual and half-yearly differ)

Code: scripts/sitebuild/rules.py · r3_one_frequency · tests: test_r3_prefers_half_yearly

R4One report per pair

For direct investment, one reporter per pair for the whole series: the reporter with the most years, and on a tie the host's (debtor's) own report, then the investor's (creditor's), then a mirror. Who reported it is shown, and the other report's figure, where one exists, is in the tooltip. A negative position (reverse investment, netted intercompany debt) is kept as reported and enters its ladder as a negative part; a confidential cell has no value in the IMF file and is indistinguishable from a year not reported.

Why: DIP has up to three reports per pair; adding them counts the same position up to three times. Mirrors are copies of the counterpart's report (0 differences in 329,399 pairs, 29 Oct 2026). Choosing per year made 2,027 pairs step from one reporter to another, by up to 50% and more. The longest series is chosen over the host's because a series that never changes reporter is worth more than a host's valuation in some years: 3,869 of 11,051 doubly reported pairs are drawn from the investor for that reason (31 Oct 2026).

  • In release 20261102.2: 684,911 direct investment pair reports dropped (the pair's chosen reporter is another)
  • In release 20261102.2: 475,839 pair-periods with a second report kept as context (alt)
  • In release 20261102.2: 15,449 pairs drawn from the investor's report (the host reports fewer years or none)

Code: scripts/sitebuild/rules.py · r4_one_report_per_pair · tests: test_r4_takes_host_report, test_r4_one_reporter_per_series, test_r4_negative_position_handling

R5One instrument

The bank channel takes BIS LBS loans and deposits only. The other instruments are split and never enter the bank ribbon: debt securities that banks hold stay in portfolio debt (shown as context); derivatives and other instruments, which no other channel holds, are a pool of their own, measured against the IIP derivatives item. Reporters that publish no instrument split by counterparty (Japan, Germany) are named in the not-identified node, never estimated, and the coverage panel shows their share of the all-reporter total (26% of claims on Thailand, 28% on the UK, 31 Oct 2026). The BIS all-reporter aggregate that the Signal Board reads (R17) already allocates them by instrument, so A1 and B1 carry them.

Why: BIS bank claims cover all instruments, and CPIS counts the bonds again. Worldwide, 7.8 tn of banks' derivatives and other instruments were in no channel (29 Oct 2026).

  • In release 20261102.2: 478,267 LBS all-instrument rows kept as context, out of the bank ribbon
  • In release 20261102.2: 25,534 LBS debt-securities rows kept as context (counted in portfolio debt)
  • In release 20261102.2: 24,634 LBS derivatives-and-other rows drawn as their own pool, never in the bank ribbon

Code: scripts/sitebuild/rules.py · r5_bank_loans_and_deposits · tests: test_r5_bank_channel_is_loans_and_deposits, test_r5_three_way_split, test_r5_no_split_reporters_disclosed

R6Gap to the whole

Each ladder adds up to its total for the channel. What the pair data do not identify is a 'not identified' node, and the identified share is shown as coverage. The IMF's confidential group of reserve managers and international organisations (SEFER and SSIO) is an identified holder, drawn as one node and never ranked. The FDI total is the DIP's own all-investor figure where the DIP has the year, so that parts and total are on one valuation basis; the IIP item is the border. When pair data exceed the total, the excess is shown and flagged, never clipped, and coverage is capped at 100%.

Why: Some holders do not report, and some BIS reporters give only an all-countries figure. Reserve managers held 5.0 tn of the 22.5 tn 'not identified' worldwide; the DIP is at book value for the largest hosts (USA 5,708 against 13,060 in the IIP), so the IIP made a valuation gap look like missing investors (29 Oct 2026).

Code: scripts/sitebuild/rules.py · r6_gap_to_total · tests: test_r6_gap_and_excess, test_r6_reserves_group_and_cap

R7Periods

Figures are added only within one period. In the aligned setting (the default), portfolio and bank sit at the newest period both share; direct investment, which is annual, sits at its own newest year at or before that period, labelled with the year, and is never summed with the other channels. In the newest setting each channel sits at its own period and no cross-period total is drawn. The IIP is part of the alignment: the border total is the IIP item of the aligned period itself, and an economy whose IIP is annual is aligned at a year-end; in the newest setting the IIP item of the newest portfolio period is shown, or none.

Why: Banks are quarterly, CPIS half-yearly, DIP annual. Waiting for a DIP year equal to the aligned quarter left the FDI ribbon unsplit in 289 of 324 ladders (29 Oct 2026).

Code: scripts/sitebuild/rules.py · r7_periods · tests: test_r7_aligned_shares_one_period, test_r7_fdi_own_period, test_r7_iip_border_period

R8Flows

Published flows (BIS adjusted changes, TIC net purchases, BOP transactions, fund flows) are used as published. Flows derived from two positions are labelled 'includes valuation changes and breaks'. The two kinds are never added together.

Why: Position changes mix price and exchange-rate moves with transactions.

Code: scripts/sitebuild/rules.py · r8_flow_kinds · tests: test_r8_never_adds_published_and_derived

R9Layers

Core money (layer 0: the central bank's balance sheet, currency, bank reserves) and bank money (layer 1: deposits, as each source defines broad money) are a hierarchy of what counts as money for whom, never addends: bank reserves are inside bank money's backing, so the layers are drawn side by side and no screen sums them. Layer 2 (L, money funds, stablecoins) is context and is never added to them. Cross-border positions are never added to money created: a cross-border bank loan creates a deposit at the lending bank (offshore money creation); bond-market and non-bank lending move existing money. Bank money is the publisher's broad money (IMF), M2 (United States, Korea) or M2 and M3 (euro area), named on each tile.

Why: Banks' lending creates money; bond-market and non-bank lending moves it. Monetary base and deposits overlap (US bank reserves alone are about USD 3 tn), so their sum would be a double count.

Code: scripts/sitebuild/rules.py · r9_layers · tests: test_r9_layers_not_added, test_r9_layers_not_summed_anywhere

R10Basis

Residence by default. Nationality changes only the bank channel (BIS CBS); every other channel stays on residence and is labelled so.

Why: Financial centres hold about a quarter of external positions; the nationality view reassigns positions to the parent's country.

  • In release 20261102.2: 215,815 ultimate-risk rows not drawn

Code: scripts/sitebuild/rules.py · r10_basis · tests: test_r10_nationality_only_bank

R11Aggregates

A source aggregate (BIS 'all reporters', the euro area, TIC's grand total) is used as a total, never added to its members.

Why: Aggregates and their members sit side by side in the tables.

  • In release 20261102.2: 416,122 rows whose counterparty is an aggregate (used as totals, never as parts)

Code: scripts/sitebuild/rules.py · r11_aggregates · tests: test_r11_aggregate_not_a_holder

R12Duplicates

Rows with the same key and the same value are kept once. Rows with the same key and different values stop the build.

Why: Some source files repeat a series (IMF IRFCL).

  • In release 20261102.2: 0 border_flows: exact repeats written once
  • In release 20261102.2: 0 border_flows: keys with conflicting values
  • In release 20261102.2: 0 links: exact repeats written once
  • In release 20261102.2: 0 links_0: keys with conflicting values
  • In release 20261102.2: 0 signals: exact repeats written once
  • In release 20261102.2: 0 signals: keys with conflicting values
  • In release 20261102.2: 0 stocks: exact repeats written once
  • In release 20261102.2: 0 stocks: keys with conflicting values
  • In release 20261102.2: 0 totals: exact repeats written once
  • In release 20261102.2: 0 totals: keys with conflicting values

Code: scripts/sitebuild/rules.py · r12_duplicates · tests: test_r12_exact_repeat_dropped_conflict_stops

R13Precision

Computed at full precision and rounded only for display (0.1 bn, 0.1%). Totals are computed before rounding, so a table's rows can differ from its total by rounding; the table says so. The browser never adds.

Why: Sums must not depend on display rounding.

Code: scripts/sitebuild/rules.py · r13_precision · tests: test_r13_totals_before_rounding

R14No commercial data

Every figure on the site comes from an official or open source. Commercial data (fund-flow and market-data vendors) are not published in any form, not even as aggregates; the check scans every public file for a vendor's name or a fund-level field. Vendor aggregates were shown from 29 Oct to 1 Nov 2026 and were then removed.

Why: The user's decision of 1 Nov 2026: no commercial data on datasteg sites; the files stay on the dev machines.

Code: scripts/sitebuild/rules.py · r14_no_commercial_data · tests: test_r14_no_commercial_data

R15Revisions

A release uses the newest vintage of each dataset at build time. A mark changes only when its source's vintage changes.

Why: Publishers revise past periods; IIP for 2025–26 is preliminary.

Code: scripts/sitebuild/rules.py · r15_revisions · tests: test_r15_change_needs_new_vintage

R16Quarantine

A monthly, quarterly or annual stock observation is judged when the series moves more than tenfold against the previous value in the source's own currency. A move that returns to the old level within two periods (a spike) is dropped and the gap flagged. A ratio that is a power of ten (a unit error in the source) rescales every value at the new level by that power of ten back to the earlier level, so the series goes on instead of stopping; the earlier segment is the one trusted, and a wrong earlier segment is corrected by a listed unit correction (R1) before this rule runs. A new level that is impossible or implausible, non-resident claims or liabilities above the economy's IIP total on that side (they are a part of it), is dropped with every later value at that level, so the series stops rather than jumps. Real moves stay; check V13 lists every segment with its raw values and marks any that starts within a month of a listed currency redenomination (config/redenominations.csv), the case a source that stopped back-converting would produce.

Why: Release 20261029.2 carried Portugal's banks' claims on non-residents at a million times their level, Switzerland's central bank liabilities at 218 times, Uruguay's monetary base at a thousand times: errors in the IMF files that a warn-only check let through (docs/DATA-AUDIT.md F7). Dropping a unit error ended Uruguay's monetary base in 2018-09 for good (94 months) and kept the wrong segment of Sierra Leone's broad money; the verification of 31 Oct 2026 found no redenomination among the segments, the IMF files being back-converted.

  • In release 20261102.2: 56 observations quarantined as source errors (spikes, implausible levels)
  • In release 20261102.2: 98 observations rescaled by a power of ten (unit errors in the source)
  • In release 20261102.2: 15 series affected

Code: scripts/sitebuild/rules.py · r16_quarantine · tests: test_r16_quarantine_spike_unit_and_bound, test_r16_keeps_real_moves, test_r16_unit_error_rescaled_not_dropped, test_r16_redenomination_guard

R17Signal Board indicators

Each borrowing economy is read from its own side. Scored exposures: A1 = foreign-currency credit to non-banks / GDP, by residence of the borrower: cross-border loans and deposits to resident non-banks in US dollars, euros and yen (BIS LBS), plus the foreign-currency claims of banks inside the economy on resident non-banks where the economy reports them to the LBS (local positions, all foreign currencies, all instruments: the only published cell with a sector split; 26 of the 36 board economies report it, the rest are marked), plus international debt securities of resident non-bank issuers in those currencies (BIS DSS by residence), the economy's own currency left out, over the four-quarter GDP implied by BIS total credit (the newest quarter carries the one before). A2 = BIS CBS international claims with remaining maturity up to one year (immediate counterparty, all reporting banks) / net reserves: IMF IRFCL official reserve assets (Section I) plus the predetermined net drains within one year (Section II: forwards and swaps falling due, scheduled debt service), at the quarter-end month, never below a tenth of gross reserves (Turkey's net reserves were below zero in 2023 Q2; a floored quarter is marked); scored only where reserves are the economy's last line of foreign-currency liquidity: not for a euro member, an issuer of a reserve currency (Japan, the UK) or an economy with a standing unlimited Fed swap line (Canada). Buffers: net IIP / GDP (IMF IIP) and the current account over four quarters / GDP (IMF BOP), quarterly where published, else the newest annual value at most four quarters old. Shown, not scored: A2 on gross reserves; A1 by nationality of issuer, with an offshore-issuance flag where it exceeds the cross-border residence figure by 5 points of GDP or is twice it; A3 = international debt securities by nationality / (those + LBS cross-border loans and deposits); and net external debt (IIP debt liabilities less debt assets with reserves) / GDP. Flows: B1 = the BIS FX- and break-adjusted change of cross-border loans and deposits, every sector and currency (interbank funding included, the channel of Korea in 2008); B2 = DSS net issues by nationality; flow score = (B1 + B2) / (the two stocks of the quarter before) × 4, in per cent, sign kept: below zero, non-resident banks and bondholders reduced their claims (a creditor withdrawal, not the balance of payments' net outflow, which includes residents' asset moves). B2 and its stock share the nationality basis because emerging-market firms issue through offshore affiliates; B1 and its stock share the LBS residence basis, the only one with adjusted changes; each flow is measured against its own stock.

Why: Method 1.2 mixed bases (bonds by nationality over domestic GDP, so a US finance arm serviced from dollar revenue counted against its parent's home GDP), scored a bond share whose direction the validation contradicted, scored short-term bank debt against national reserves inside a currency union, and had no buffers: a net creditor with a current-account surplus ranked first. Residence matches the numerator to GDP; the buffers are the IMF's own external-sector measures and were already in the data hub. Residence and nationality A1 validated alike (docs/methodology/vulnerability-v1.3.md). Method 1.4, after the verification of 31 Oct 2026: gross reserves hid Turkey's and Argentina's position (predetermined drains of 40% and 32% of gross reserves at the latest quarter; net reserves below zero at their crisis dates), and the BIS global liquidity definition of foreign-currency credit includes the local foreign-currency loans the LBS already carried (Turkey's A1 doubles with them). Both were in the mirror (docs/methodology/vulnerability-v1.4.md).

  • In release 20261102.2: 36 economies drawn in the newest quarter
  • In release 20261102.2: 0 economies dropped in the newest quarter (a component missing)

Code: scripts/sitebuild/rules.py · r17_indicators · tests: test_r17_indicators_and_drop_reason, test_r17_own_currency_not_foreign, test_r17_residence_buffers_and_a2_scope, test_r17_a2_uses_net_reserves, test_r17_a1_includes_local_fx_credit, test_r17_flow_components_share_basis, test_r17_offshore_gap_flag, test_r17_a1_break_marker_on_adoption

R18Vulnerability score

Score = ½ × exposure + ½ × buffer weakness, on 0–100. Exposure is the mean of the scored exposures' signals (A1; A2 where scored). Each signal is ½ × level + ½ × own history. Level: the share of every board economy-quarter observed up to and including this quarter, all economies pooled, at or below this value. Own history: z = (value − the economy's own median) / max(1.4826 × MAD, floor), over its quarters from 2000 (or its first) up to and including this one, clipped to ±3 and mapped to 0–100 (50 = its own median); floors 1 point of GDP for A1 and 10 points of reserves for A2, so a narrow history cannot turn a small move into an extreme. Buffer weakness: the mean of 100 − level for net IIP / GDP and for the current account / GDP, of those published for the quarter; a buffer is read as a level only, because its own history carried no information in the validation and a buffer's level is what the IMF's external assessments read. The A2 pool holds scored A2 values only: a euro member's, Japan's, the UK's or Canada's A2 ranks no one. An indicator needs 8 quarters of history, the pool 40 observations. Every window is expanding: a past quarter's score uses only quarters up to it, its own and every other economy's. The score is not a ranking; the flow score is not transformed.

Why: Method 1.2 ranked each indicator against the economy's own past only: magnitude was ignored (Korea and Italy had nearly the same A2 at the 97th and 6th percentiles), a calm narrow history pushed small moves to the extremes, and the score separated stress episodes from calm quarters no better than chance (area under the ROC curve 0.51 on 27 named episodes, 0.45 against a mechanical currency-crash dating). Levels against peers, own history with a floor, and buffers gave 0.67 and 0.60, the best of twelve candidates tested point in time; the result is in the decision memo with every candidate.

Code: scripts/sitebuild/rules.py · r18_signals · tests: test_r18_robust_z_floor, test_r18_level_signal_pooled, test_r18_score_arithmetic, test_r18_no_look_ahead, test_r18_snapshot_2026q2, test_r18_buffer_uses_configured_measure, test_r18_pool_excludes_unscored_a2

R19The board's economies

Every economy with a GDP denominator in BIS total credit, except the United States (the hub, not a borrower in this sense), the BIS offshore centres (Hong Kong SAR, Singapore), the fund domiciles already flagged (Luxembourg, Ireland, the Netherlands, Switzerland) and the euro-area aggregate (its members are shown one by one; the euro is their own currency from the day they adopted it). Japan and the UK issue reserve currencies and Canada has a standing unlimited Fed swap line: they are on the board, with A2 shown but not scored (R17). An economy-quarter without its scored components, a buffer or both flows is not drawn and is logged with its reason (V18). The board is therefore 36 economies, the advanced and the larger emerging ones that BIS total credit covers; frontier borrowers (Egypt, Pakistan, Sri Lanka, Ghana, Kenya) are outside it. The fund-domicile exclusion is the audit's FD tag (R10): Belgium, a settlement centre, stays. The euro adoption dates come from config/economies.csv (Croatia 2023-01-01, Bulgaria 2026-01-01), and the board file names each member's date so the page can mark the break in A1.

Why: The IMF WEO is not in the data hub; BIS total credit gives a quarterly GDP for 43 economies, the same source family as the indicators.

  • In release 20261102.2: 36 economies on the board
  • In release 20261102.2: 8 economies with a GDP denominator left out (hub, offshore centre, fund domicile, aggregate)

Code: scripts/sitebuild/rules.py · r19_economy_set · tests: test_r19_exclusions, test_r19_euro_adoption_dates

R20One pulse

The World pulse and the change feed are computed once, at release, from the board history the release itself carries, and are published as files (world/global pulse; changes/global). No page and no downstream site recomputes them: a reader of money-flow, of global-network or of an article sees the same tiles and the same list for a given release. The change feed compares the newest board quarter with the one before, economy by economy: entering or leaving the at-risk corner (score 60 or more with a creditor withdrawal, flow below zero), a flow score changing sign (with B1 and B2 of the new quarter), A2 crossing 100% of net reserves (with its basis), and a score moving 10 points or more. The values are the board's published columns, so the feed and the board cannot disagree.

Why: Until 2 Nov 2026 global-network recomputed the pulse and the changes from money-flow's files (refurbish plan, WP1): two sites could say different things about one release, and a change of rounding or threshold on one side would not show on the other.

  • In release 20261102.2: 15 changes listed (newest board quarter against the one before)

Code: scripts/sitebuild/rules.py · r20_changes · tests: test_r20_changes_kinds, test_r20_changes_published_once

R21Cut a lender

First-round arithmetic on published figures, for every board economy at the newest BIS quarter: each reporting banking system's share of the all-reporter loans and deposits on the economy (BIS LBS, residence basis, loans and deposits as R5 defines the bank channel), in per cent of the all-reporter total, with reporters that hold less than 0.05 bn left out and the BIS aggregates never counted as a lender (R11). The loss when a lender cuts a share of its claims is cut share × lender share × bank claims, in US dollar billions, and is shown against the economy's net reserves, the Signal Board's A2 denominator (R17; absent where the board has none). Nothing else moves: no price, no replacement lender, no second round. The release carries the shares, the claims and the net reserves; the browser only multiplies by the chosen cut.

Why: The lender-cut scenario (S4) ran on global-network until 2 Nov 2026 on money-flow's data alone; it is money-side arithmetic and belongs beside the bank matrix (refurbish plan, WP4). Shares of the all-reporter total, not of the bilateral sum, so an economy whose lenders are largely unallocated shows small shares rather than inflated ones.

  • In release 20261102.2: 36 borrowing economies with lender shares
  • In release 20261102.2: 623 lender positions listed

Code: scripts/sitebuild/rules.py · r21_lender_cut · tests: test_r21_lender_cut_shares_and_loss

R22Sovereign 1. Debt level

General government gross debt over GDP, IMF World Economic Outlook (GGXWDG_NGDP), latest vintage, one value a year from 1990. On at 90% of GDP or more; adjustable on the page between 30 and 200 in steps of 5. The threshold is a convention (the level Reinhart and Rogoff made famous), not a limit.

Why: More debt means more to roll over each year and less room in a shock. The WEO is the one source with the same definition for all 36 economies back to 1990.

Code: scripts/sitebuild/sovereign.py · r22_debt_level · tests: test_r22_r23_pass_through_and_threshold

R23Sovereign 2. Deficit

General government net lending (+) or borrowing (−) over GDP, interest included, IMF WEO (GGXCNL_NGDP). On at −5% of GDP or below; adjustable between −15 and 0 in steps of 0.5. The EU's Maastricht reference is −3%; −5% marks a large deficit.

Why: A deficit has to be borrowed, so a large one adds to debt fast.

Code: scripts/sitebuild/sovereign.py · r23_deficit · tests: test_r22_r23_pass_through_and_threshold

R24Sovereign 3. Debt snowball

The primary balance that would hold the debt ratio steady, less the actual primary balance, in points of GDP, from WEO ratios and GDP in levels: interest paid = (primary balance − overall balance) / 100 × GDP; the effective rate i = interest / last year's debt (last year's ratio × last year's GDP); nominal growth g = GDP / last year's GDP − 1; debt-stabilising primary balance pb* = last year's debt ratio × (i − g) / (1 + g); gap = pb* − primary balance. On at 1 point of GDP or more; adjustable between −2 and 6 in steps of 0.5. Missing when any input is missing.

Why: If interest beats growth, debt grows by itself unless the budget saves before interest; a gap of 1% of GDP a year adds about 10 points of GDP to debt in a decade. Greece 2009 by hand: i 4.52%, g −1.85%, pb* 7.20%, gap 17.5 points (tests/test_sovereign.py).

  • In release 20261102.2: 1,214 economy-years with a debt-stabilising gap

Code: scripts/sitebuild/sovereign.py · r24_debt_snowball · tests: test_r24_snowball_round_numbers, test_r24_snowball_greece_2009_by_hand, test_r24_snowball_missing_input

R25Sovereign 4. Current account

The three-year average of the current account balance over GDP. Each year's value is the Signal Board's own four-quarter current account at the fourth quarter (R17, IMF BOP) where the board has that year, else the WEO's annual figure (BCA_NGDPD); the source of each year is recorded, and the average exists only when all three years do. On at −4% of GDP or below; adjustable between −12 and 0 in steps of 0.5 (the EU macroeconomic imbalance procedure's threshold).

Why: A persistent deficit is financed from abroad; three years smooth a commodity swing. The board's figure is preferred so the Sovereign section and the Signal Board read one number where both have it.

  • In release 20261102.2: 642 economy-years read from the Signal Board's current account

Code: scripts/sitebuild/sovereign.py · r25_current_account · tests: test_r25_current_account_three_year_average

R26Sovereign 5. Net IIP

The net international investment position over GDP at the year end: the Signal Board's net IIP at the fourth quarter (R17, IMF IIP over BIS-implied GDP) where the board has the year, else IMF IIP total assets less liabilities over the WEO's GDP in US dollars (NGDPD); the source is recorded; projection years are left empty. On at −35% of GDP or below; adjustable between −150 and 0 in steps of 5 (the EU macroeconomic imbalance procedure's threshold).

Why: A large net debtor position is what past deficits left behind; it is the buffer the Signal Board also reads (R18), here as a level against a fixed line.

  • In release 20261102.2: 713 economy-years read from the Signal Board's net IIP

Code: scripts/sitebuild/sovereign.py · r26_net_iip · tests: test_r26_net_iip_board_first_then_imf

R27Sovereign 6. Liquidity (A2)

The Signal Board's A2 at the fourth quarter: BIS CBS international claims with remaining maturity up to one year over net reserves (IRFCL Section I plus Section II, floored; R17, method 1.4), in per cent. Not applicable where the board does not score A2 (euro members, Japan, the UK, Canada), and greyed throughout for an economy whose newest quarter is unscored; missing before 2005 and in projection years. On at 100% or more; adjustable between 25 and 400 in steps of 5 (the Greenspan–Guidotti rule: reserves should cover debt falling due within a year).

Why: Short-term foreign-currency debt above reserves is the classic run exposure (Korea 1997, Türkiye 2018); the Signal Board already builds it on net reserves, so the Sovereign section reads the same column.

  • In release 20261102.2: 12 economies with A2 not applicable (unscored on the board)

Code: scripts/sitebuild/sovereign.py · r27_liquidity · tests: test_r27_liquidity_not_applicable_where_unscored

R28Sovereign 7. Spread

The 10-year government bond yield less the benchmark's, OECD long-term interest rates via FRED (IRLTLT01{iso2}M156N, monthly averages): Germany is the benchmark for EU members, the United States for the rest, and the benchmark itself is not applicable. The annual value is the average of the monthly spreads of the months both series have, at least six; the newest value is the average of the last twelve months when the series ends within two months of the newest month any economy has. Only the spread is published, never a yield series. On at 4 points or more; adjustable between 1 and 10 in steps of 0.5 (400 basis points, a common distress marker).

Why: The market's own price of sovereign risk, available monthly where the fiscal data are annual; Russia's series stops in 2018, so a stale spread is shown as missing, not as calm.

  • In release 20261102.2: 25 economies with a yield spread

Code: scripts/sitebuild/sovereign.py · r28_spread · tests: test_r28_spread_needs_six_months_and_benchmark

Worked reconciliation: Korea, inflows

The newest aligned ladder (portfolio end-2025, banks Q4 2025), followed from the IIP total down.

R6, Portfolio. IIP portfolio liabilities 1,364.6 bn = 1,064.0 bn identified (994.4 bn by reporting holders, of which 21.2 bn with no instrument split, and 69.6 bn by the reserves-and-international-organisations group) + 300.6 bn reported by no holder. Coverage 78.0%. Of the reporting holders' part, equity 705.2 bn and debt 268.0 bn. The IMF's own derived liability, 1,064.0 bn, equals the identified part (V16).

R6, R5, Bank claims. All BIS reporters' loans and deposits to Korea 158.5 bn = 85.2 bn from single reporters + 73.2 bn not identified (coverage 53.8%; of which reporters with no instrument split DEU 10.2 bn, JPN 27.2 bn). All instruments 381.3 bn = loans and deposits + debt securities 167.9 bn (counted in portfolio debt) + derivatives and other 54.9 bn (a pool of its own, against IIP derivatives 47.2 bn). IIP loans 153.2 bn and deposits 43.0 bn (V15).

R7, R4, R6, Direct investment. DIP end-2024 all-investor total 255.2 bn (the host's valuation) = 255.2 bn identified by investor + 0.0 bn not identified. IIP direct investment liabilities 296.3 bn (market value) sit on the border.

What the World page can and cannot see

Where the page uses nationality or ultimate risk

Source: Aldasoro, Hardy, von Peter and Wooldridge (2026), BIS Quarterly Review, March 2026

The board's economies (36)

Argentina, Australia, Austria, Belgium, Brazil, Canada, Chile, China, Colombia, Czechia, Germany, Denmark, Spain, Finland, France, UK, Greece, Hungary, Indonesia, India, Israel, Italy, Japan, Korea, Mexico, Malaysia, Norway, New Zealand, Poland, Portugal, Russia, Saudi Arabia, Sweden, Thailand, Türkiye, South Africa.

Left out, and why

Checks

Definitions

Changelog

datasteg: the flow sites