Docs, submodule SWIFT_DOT-FIN, data pipelines, and module updates
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "SWIFT_DOT-FIN"]
|
||||
path = SWIFT_DOT-FIN
|
||||
url = https://gitea.d-bis.org/d-bis/SWIFT_DOT-FIN.git
|
||||
24
CHANGELOG.md
Normal file
24
CHANGELOG.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to the FQBM project are documented here.
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- **CBDC in state**: `FQBMState.cbdc_liability`; workbook sets it on CBDC shift; IPSAS statement of financial position (CB/consolidated) shows CBDC liability; dashboard snapshot includes cbdc_liability.
|
||||
- **Repo multiplier in workbook/dashboard**: `run_workbook(shadow_params=ShadowBankingParams(...))` optional; repo_multiplier always computed and included in `result["dashboard"]["repo_multiplier"]` and `result["repo_multiplier"]`.
|
||||
- **Real data pipelines**: `fqbm.data.pipelines` — `fetch_fed_h41()`, `fetch_bis_series()` (BIS bulk CSV), `fetch_imf_series()` (IMF API with optional api_key).
|
||||
- Documentation: RECOMMENDATIONS.md (consolidated list); framework_summary one sentence per Part; REFERENCES weblinks (IPSASB Handbook, BIS bulk, IMF Data, Fed Data Download); IPSAS_COMPLIANCE and GAPS_AND_MISSING reference RECOMMENDATIONS; CONTRIBUTING links RECOMMENDATIONS; USER_GUIDE and DATA_DICTIONARY mention pipelines extension and RECOMMENDATIONS; MISSING_COMPONENTS 2.2 status updated; docstrings: Part X and Required columns in regressions, Part XII in capital_stress.
|
||||
- IPSAS: structures for IPSAS 3, 5, 9/47, 10, 14, 19, 20, 23, 29/41, 38, 46, 48; cash-basis; RPG 2; functional/presentation currency.
|
||||
- budget_actual_from_state() for IPSAS 24 from state + budget dict.
|
||||
- State: functional_currency, presentation_currency.
|
||||
- Matrix: cross_sector_consistency_check().
|
||||
- Part XI: get_case_narrative(name) for historical case narrative and coded outputs.
|
||||
- Docs: USER_GUIDE, API_REFERENCE, DATA_DICTIONARY, WHITE_PAPER stub, CHANGELOG, CONTRIBUTING; updates to IPSAS_COMPLIANCE, GAPS_AND_MISSING, framework_summary, REFERENCES, README.
|
||||
|
||||
## [0.2.0]
|
||||
|
||||
- L_cb, open_economy_view, reporting_date. IPSAS presentation helpers. Part VII/VIII, Part XI presets. Workbook scenario support and Excel export.
|
||||
|
||||
## [0.1.0]
|
||||
|
||||
- Initial implementation: state, matrix, sheets, Monte Carlo, differential model, regressions.
|
||||
68
CONTRIBUTING.md
Normal file
68
CONTRIBUTING.md
Normal file
@@ -0,0 +1,68 @@
|
||||
# Contributing to FQBM
|
||||
|
||||
Thank you for your interest in contributing to the Four-Quadrant Balance Sheet Matrix (FQBM) project.
|
||||
|
||||
---
|
||||
|
||||
## Development setup
|
||||
|
||||
```bash
|
||||
git clone <repo>
|
||||
cd FOUR-QUADRANT_BALANCE_SHEET_MATRIX
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||||
pip install -e ".[dev]" # or pip install -e . && pip install pytest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running tests
|
||||
|
||||
```bash
|
||||
pytest tests/ -v
|
||||
```
|
||||
|
||||
Add new tests under `tests/`; keep module layout aligned with `src/fqbm/`.
|
||||
|
||||
---
|
||||
|
||||
## Code style
|
||||
|
||||
- Follow existing style in the codebase (PEP 8–style).
|
||||
- Use type hints for public function parameters and returns where practical.
|
||||
- Docstrings: include purpose, main parameters, and return value; for IPSAS functions, reference the standard (e.g. IPSAS 3); for regression helpers, note “Required columns” for DataFrames.
|
||||
|
||||
---
|
||||
|
||||
## Adding a new sheet
|
||||
|
||||
1. Add a module under `src/fqbm/sheets/` (e.g. `new_sheet.py`) with a step function that takes state and params and returns updated state or a result dict.
|
||||
2. Wire the sheet into `fqbm.workbook.runner.run_workbook()` (read initial state, call the step, write result into the workbook result dict).
|
||||
3. Optionally add export in `_export_excel()` for the new result key.
|
||||
4. Add tests in `tests/` that call the new step and assert on outputs.
|
||||
|
||||
---
|
||||
|
||||
## Adding a new scenario
|
||||
|
||||
1. In `src/fqbm/scenarios/presets.py`, add a builder function (e.g. `_new_scenario()`) that returns a `ScenarioPreset` (name, description, state, optional params and shock_spec).
|
||||
2. Register it in `_build_registry()`.
|
||||
3. Optionally add an entry in `get_case_narrative()` for the structured narrative and key_drivers/suggested_shocks.
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
- User-facing: update [docs/USER_GUIDE.md](docs/USER_GUIDE.md) and [docs/API_REFERENCE.md](docs/API_REFERENCE.md) when adding public API.
|
||||
- Data: update [docs/DATA_DICTIONARY.md](docs/DATA_DICTIONARY.md) for new state fields, sheet I/O, or regression columns.
|
||||
- Gaps: if adding IPSAS or matrix-related features, update [docs/IPSAS_COMPLIANCE.md](docs/IPSAS_COMPLIANCE.md) and [docs/GAPS_AND_MISSING.md](docs/GAPS_AND_MISSING.md) as needed.
|
||||
- Changelog: add a short entry under `[Unreleased]` in [CHANGELOG.md](CHANGELOG.md).
|
||||
- Recommendations: see [docs/RECOMMENDATIONS.md](docs/RECOMMENDATIONS.md) for the full list of suggestions.
|
||||
|
||||
---
|
||||
|
||||
## Pull requests
|
||||
|
||||
- Keep PRs focused; prefer smaller, reviewable changes.
|
||||
- Ensure tests pass and that new code is covered where practical.
|
||||
- Update the docs and changelog as above.
|
||||
59
README.md
59
README.md
@@ -2,6 +2,31 @@
|
||||
|
||||
A unified institutional framework for monetary, fiscal, financial, and open-economy dynamics. This codebase implements the full FQBM from the white paper: simulation workbook (eight sheets), Monte Carlo stress engine, differential system model, and empirical regression suite.
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Quick start](#quick-start)
|
||||
- [Install](#install)
|
||||
- [Run](#run)
|
||||
- [Test](#test)
|
||||
- [Optional features](#optional-features)
|
||||
- [IPSAS compliance](#ipsas-compliance)
|
||||
- [Submodule (SWIFT DOT-FIN)](#submodule-swift-dot-fin)
|
||||
- [Framework and docs](#framework-and-docs)
|
||||
|
||||
## Quick start
|
||||
|
||||
```python
|
||||
from fqbm.workbook.runner import run_workbook
|
||||
from fqbm.state import FQBMState
|
||||
|
||||
state = FQBMState(B=100, R=50, C=20, Loans=800, Deposits=700, E_cb=30, E_b=100)
|
||||
result = run_workbook(initial_state=state, mc_runs=50, export_path="out.xlsx")
|
||||
# Or use a scenario:
|
||||
run_workbook(scenario="asia_1997", mc_runs=100, export_path="asia.xlsx")
|
||||
```
|
||||
|
||||
See [docs/USER_GUIDE.md](docs/USER_GUIDE.md) for a full walkthrough.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
@@ -11,7 +36,7 @@ source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
Optional: `pip install pytest` for tests.
|
||||
Optional: `pip install pytest` for tests; `pip install streamlit` for the dashboard.
|
||||
|
||||
## Run
|
||||
|
||||
@@ -28,25 +53,31 @@ Optional: `pip install pytest` for tests.
|
||||
pytest tests/ -v
|
||||
```
|
||||
|
||||
## Optional: Streamlit dashboard
|
||||
## Optional features
|
||||
|
||||
```bash
|
||||
pip install streamlit
|
||||
streamlit run scripts/streamlit_dashboard.py
|
||||
```
|
||||
|
||||
## Optional: Historical scenarios (Part XI)
|
||||
|
||||
Use preset scenarios in code: `run_workbook(scenario="asia_1997")` or `"gfc_2008"`, `"pandemic_2020"`, `"rate_shock_2022"`. See `fqbm.scenarios`.
|
||||
- **Streamlit dashboard**: `pip install streamlit` then `streamlit run scripts/streamlit_dashboard.py`
|
||||
- **Historical scenarios (Part XI)**: `run_workbook(scenario="asia_1997")` or `"gfc_2008"`, `"pandemic_2020"`, `"rate_shock_2022"`; `get_case_narrative(name)` for narrative and coded outputs
|
||||
- **CBDC / CCP / repo**: `run_workbook(cbdc_params=..., ccp_params=..., shadow_params=...)`; state has `cbdc_liability` after CBDC shift; repo multiplier is in `result["dashboard"]["repo_multiplier"]`
|
||||
- **Real data**: `from fqbm.data.pipelines import fetch_fed_h41, fetch_bis_series, fetch_imf_series` (Fed H.4.1, BIS bulk CSV, IMF with optional api_key)
|
||||
|
||||
## References
|
||||
|
||||
See [docs/REFERENCES.md](docs/REFERENCES.md) for Chicago Author–Date references (Adrian & Shin, BIS, Dornbusch, Fed H.4.1, IMF, McLeay et al., Obstfeld & Rogoff, etc.).
|
||||
See [docs/REFERENCES.md](docs/REFERENCES.md) for Chicago Author–Date references and optional weblinks (IPSASB, BIS, IMF, Fed H.4.1).
|
||||
|
||||
## IPSAS compliance
|
||||
|
||||
The framework includes an **IPSAS-aligned presentation layer** (IPSAS 1 statement of financial position, IPSAS 24 budget vs actual structure). Use `fqbm.ipsas.presentation.statement_of_financial_position(state, entity="central_bank"|"commercial_bank"|"consolidated")` and `budget_vs_actual_structure()`. Excel export adds IPSAS-style sheets when available. See [docs/IPSAS_COMPLIANCE.md](docs/IPSAS_COMPLIANCE.md) for the compliance assessment. **[docs/GAPS_AND_MISSING.md](docs/GAPS_AND_MISSING.md)** lists IPSAS standards and FQBM gaps. Additional helpers: **notes_to_financial_statements_structure**, **statement_of_financial_position_comparative**, **maturity_risk_disclosure_structure**, **cash_flow_from_state_changes**, **fx_translate**. Part VII: **repo_multiplier**, **margin_spiral_simulation**. Part VIII: **variation_margin_flow**, **ccp_clearing_simulation**.
|
||||
The framework includes an **IPSAS-aligned presentation layer** (IPSAS 1 statement of financial position, IPSAS 24 budget vs actual, and structures for IPSAS 2, 3, 4, 5, 9, 10, 14, 19, 20, 23, 29/41, 38, 46, 48, cash basis, RPG 2, functional/presentation currency). Use `fqbm.ipsas.presentation.statement_of_financial_position(state, entity="central_bank"|"commercial_bank"|"consolidated")`, `budget_vs_actual_structure()`, `budget_actual_from_state(state, budget)`, and other helpers. Excel export adds IPSAS-style sheets when available. See [docs/IPSAS_COMPLIANCE.md](docs/IPSAS_COMPLIANCE.md) and [docs/GAPS_AND_MISSING.md](docs/GAPS_AND_MISSING.md).
|
||||
|
||||
## Framework
|
||||
## Submodule (SWIFT DOT-FIN)
|
||||
|
||||
See [docs/framework_summary.md](docs/framework_summary.md) and the white paper for the theoretical foundation (Parts I–XVI).
|
||||
This repo includes **SWIFT_DOT-FIN** as a submodule (ledger entries and payloads, creation to transfers). Clone with submodules: `git clone --recurse-submodules <repo>`, or after clone run `git submodule update --init --recursive`. The submodule lives at `SWIFT_DOT-FIN/`; its source path is `/home/intlc/projects/SWIFT_DOT-FIN` (or `../SWIFT_DOT-FIN` relative to this project).
|
||||
|
||||
## Framework and docs
|
||||
|
||||
- [docs/framework_summary.md](docs/framework_summary.md) — Parts I–XVI and module mapping
|
||||
- [docs/WHITE_PAPER.md](docs/WHITE_PAPER.md) — Placeholder for canonical white paper
|
||||
- [docs/USER_GUIDE.md](docs/USER_GUIDE.md) — Tutorial and usage
|
||||
- [docs/API_REFERENCE.md](docs/API_REFERENCE.md) — Public API
|
||||
- [docs/DATA_DICTIONARY.md](docs/DATA_DICTIONARY.md) — State variables, sheet I/O, regression columns
|
||||
- [docs/MISSING_COMPONENTS_AND_DOCUMENTATION.md](docs/MISSING_COMPONENTS_AND_DOCUMENTATION.md) — Consolidated gap list and documentation checklist
|
||||
- [docs/RECOMMENDATIONS.md](docs/RECOMMENDATIONS.md) — Additional recommendations and suggestions
|
||||
|
||||
1
SWIFT_DOT-FIN
Submodule
1
SWIFT_DOT-FIN
Submodule
Submodule SWIFT_DOT-FIN added at 35d97c3b14
40
docs/API_REFERENCE.md
Normal file
40
docs/API_REFERENCE.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# FQBM API Reference
|
||||
|
||||
Public functions and classes, with main parameters and return types. For full docstrings, see the source.
|
||||
|
||||
## State and matrix
|
||||
|
||||
**fqbm.state**
|
||||
- `FQBMState`: Dataclass (B, R, C, Loans, Deposits, E_cb, E_b, S, K, Spread, O, L_cb, cbdc_liability, reporting_date, functional_currency, presentation_currency). Methods: to_vector(), from_vector(), copy().
|
||||
- `open_economy_view(A_dom, A_ext, L_dom, L_ext, E)`: Returns dict with totals and identity_holds.
|
||||
|
||||
**fqbm.matrix**
|
||||
- `four_quadrant_matrix(state, L_cb=None)`: pd.DataFrame (Assets Dr/Cr, Liabilities Dr/Cr).
|
||||
- `four_quadrant_summary(state, L_cb=None)`: dict (total_assets_dr, total_liabilities_dr, total_liabilities_cr, identity_A_eq_L_plus_E).
|
||||
- `cross_sector_consistency_check(state, L_cb=None)`: dict (consistent, cb_balance, bank_balance, matrix_identity, message, sector/matrix totals).
|
||||
|
||||
## Workbook and sheets
|
||||
|
||||
**fqbm.workbook.runner**
|
||||
- `run_workbook(initial_state=None, scenario=None, mc_runs=100, export_path=None, include_ipsas=True, cbdc_params=None, ccp_params=None)`: Returns dict (state, stress_tables, fx_parity, sovereign, commodity, monte_carlo, dashboard, ipsas).
|
||||
- `main()`: CLI entry point.
|
||||
|
||||
**fqbm.sheets**: CentralBankParams/central_bank_step; CommercialBankParams/commercial_bank_step; StressParams/stress_tables; FXParams/fx_parity_step; SovereignParams/sovereign_debt_step; CommodityParams/commodity_step; ShockSpec/run_n_simulations; dashboard_aggregate (includes repo_multiplier when computed); ShadowBankingParams/repo_multiplier, margin_spiral_simulation; CCPParams/variation_margin_flow, ccp_clearing_simulation; CBDCParams/deposit_to_cbdc_shift.
|
||||
|
||||
**fqbm.data.pipelines**: fetch_fed_h41(url?, date_col?); fetch_bis_series(dataset?, country?, api_key?) — dataset in credit_gap, debt_service, property, total_credit, cb_assets; fetch_imf_series(database_id?, indicator?, country?, api_key?) — optional api_key for IMF API.
|
||||
|
||||
## IPSAS presentation (fqbm.ipsas.presentation)
|
||||
|
||||
Statement of financial position; budget_vs_actual_structure; budget_actual_from_state; cash flow structure and cash_flow_from_state_changes; statement of financial performance; statement of changes in net assets; fx_translate; notes template; comparative; maturity_risk_disclosure; accounting_policies (IPSAS 3); borrowing_costs (5); revenue_recognition (9/47); hyperinflation_restatement (10); events_after_reporting_date (14); provisions_contingencies (19); related_party_disclosure (20); revenue_non_exchange (23); financial_instruments_measurement (29/41); interests_in_other_entities (38); measurement_basis (46); transfer_expenses (48); cash_basis_statement; fs_discussion_and_analysis (RPG 2); functional_presentation_currency.
|
||||
|
||||
## Scenarios (fqbm.scenarios.presets)
|
||||
|
||||
- `list_scenarios()`: list of names.
|
||||
- `get_scenario(name)`: ScenarioPreset or None.
|
||||
- `get_case_narrative(name)`: dict (name, description, narrative, state_summary, key_drivers, suggested_shocks) or None.
|
||||
|
||||
## System and empirical
|
||||
|
||||
**fqbm.system.differential_model**: DifferentialParams; solve_trajectory(x0, t_span, params); check_stability(params).
|
||||
|
||||
**fqbm.empirical.regressions**: generate_synthetic_inflation, run_inflation_pass_through; generate_synthetic_spread, run_sovereign_spread; generate_synthetic_capital_flow, run_capital_flow_sensitivity. Required columns: see [DATA_DICTIONARY.md](DATA_DICTIONARY.md). Further suggestions: [RECOMMENDATIONS.md](RECOMMENDATIONS.md).
|
||||
25
docs/DATA_DICTIONARY.md
Normal file
25
docs/DATA_DICTIONARY.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# FQBM Data Dictionary
|
||||
|
||||
Definitions of state variables, sheet inputs/outputs, and regression variables.
|
||||
|
||||
## 1. State vector (FQBMState)
|
||||
|
||||
- **B**: Government securities (CB assets). **R**: Reserve balances. **C**: Currency in circulation. **Loans**: Commercial bank loans. **Deposits**: Commercial bank deposits. **E_cb**, **E_b**: Central bank and bank net assets/equity. **S**: Exchange rate (domestic per foreign). **K**: Capital flows. **Spread**: Sovereign spread. **O**: Oil/commodity index. **L_cb**: Central bank loans. **cbdc_liability**: CBDC liability (Part IX). **reporting_date**, **functional_currency**, **presentation_currency**: Optional.
|
||||
|
||||
Identities: B + L_cb = R + C + E_cb; Loans = Deposits + E_b; Total assets (Dr) = Total liab (Dr) + Total liab (Cr).
|
||||
|
||||
## 2. Sheet I/O
|
||||
|
||||
Central bank / commercial bank: state + params -> updated state. Capital stress: state + StressParams -> stress_tables. FX parity: state + FXParams -> fx_parity. Sovereign: state + SovereignParams -> spread, sustainability. Commodity: state + CommodityParams -> commodity. Monte Carlo: state + ShockSpec, n_runs -> list of states. Dashboard: state + optional stress/mc -> dashboard_aggregate. IPSAS: state (and prior) -> presentation DataFrames.
|
||||
|
||||
## 3. Regression columns (Part X)
|
||||
|
||||
Model 1 (inflation pass-through): d_fx, pi/inflation; synthetic: generate_synthetic_inflation(n). Model 2 (sovereign spread): debt_gdp, reserves_gdp, fx_vol, growth_differential, spread; synthetic: generate_synthetic_spread(n). Model 3 (capital flow): spread/r_dom/r_foreign, growth, capital_flow; synthetic: generate_synthetic_capital_flow(n).
|
||||
|
||||
## 4. Four-quadrant matrix
|
||||
|
||||
Assets (Dr): B, L_cb, Loans. Liabilities (Dr): C, R, Deposits. Liabilities (Cr): E_cb, E_b. cross_sector_consistency_check(state) returns consistent, cb_balance, bank_balance, matrix_identity, message.
|
||||
|
||||
## 5. Real data pipelines (fqbm.data.pipelines)
|
||||
|
||||
fetch_fed_h41: Fed H.4.1 CSV (optional url, date_col). fetch_bis_series: BIS bulk CSV (dataset in credit_gap, debt_service, property, total_credit, cb_assets; optional country). fetch_imf_series: IMF data (optional api_key for API). Pipelines can be extended (e.g. more series, caching, retries). See RECOMMENDATIONS.md.
|
||||
@@ -1,152 +1,46 @@
|
||||
# Complete IPSAS and FQBM Matrix — Gaps and Missing
|
||||
# IPSAS and FQBM — Gaps and Missing
|
||||
|
||||
This document lists **all remaining IPSAS standards** and **all FQBM/Matrix gaps and missing elements** as of the current codebase. It extends [IPSAS_COMPLIANCE.md](IPSAS_COMPLIANCE.md).
|
||||
Short summary of **remaining gaps** and **FQBM/Matrix status**. Full scope: [IPSAS_COMPLIANCE.md](IPSAS_COMPLIANCE.md). Suggestions: [RECOMMENDATIONS.md](RECOMMENDATIONS.md).
|
||||
|
||||
---
|
||||
|
||||
## Part A — IPSAS: Full standards list and status
|
||||
## 1. IPSAS: Summary by status
|
||||
|
||||
| # | Standard | Status | Gap / note |
|
||||
|---|----------|--------|-------------|
|
||||
| **CF** | Conceptual Framework | Partial | A = L + E aligned; no revenue/expense/definition of surplus. |
|
||||
| **1** | Presentation of Financial Statements | Supported | Structure + current/non-current in `fqbm.ipsas.presentation`. |
|
||||
| **2** | Cash Flow Statements | Structure only | Template in `cash_flow_statement_structure()`; no activity classification from FQBM. |
|
||||
| **3** | Accounting Policies, Changes in Estimates and Errors | **Missing** | No policy note, prior-period adjustment, or error correction. |
|
||||
| **4** | Effects of Changes in Foreign Exchange Rates | Partial | S and pass-through only; no translation of FC assets/liabilities, no FX gain/loss disclosure. |
|
||||
| **5** | Borrowing Costs | **Missing** | No borrowing-cost capitalisation or expense classification. |
|
||||
| **6** | Consolidated and Separate Financial Statements | Partial | Sectoral (CB, bank) and consolidated view in presentation; no control definition or full consolidation mechanics. |
|
||||
| **7** | Investments in Associates | **Missing** | Not applicable to core FQBM; no equity method. |
|
||||
| **8** | Interests in Joint Ventures | **Missing** | Not applicable; no joint arrangement. |
|
||||
| **9** | Revenue from Exchange Transactions | **Missing** | No revenue recognition or measurement. |
|
||||
| **10** | Financial Reporting in Hyperinflationary Economies | **Missing** | No hyperinflation restatement (FQBM has inflation π but not restatement). |
|
||||
| **11** | Construction Contracts | **Missing** | Not applicable to monetary/financial core. |
|
||||
| **12** | Inventories | **Missing** | Not applicable. |
|
||||
| **13** | Leases | **Missing** | Not applicable to core; no right-of-use asset/lease liability. |
|
||||
| **14** | Events After the Reporting Date | **Missing** | No adjustment vs disclosure classification. |
|
||||
| **15** | Financial Instruments: Disclosure and Presentation | Partial | Presentation only; no disclosure (maturity, risk). |
|
||||
| **16** | Investment Property | **Missing** | Not applicable. |
|
||||
| **17** | Property, Plant, and Equipment | **Missing** | Not applicable; no PP&E or depreciation. |
|
||||
| **18** | Segment Reporting | **Missing** | No segment definition or segment P&L. |
|
||||
| **19** | Provisions, Contingent Liabilities and Contingent Assets | **Missing** | No provisions or contingencies. |
|
||||
| **20** | Related Party Disclosures | **Missing** | No related party identification or disclosure. |
|
||||
| **21** | Impairment of Non-Cash-Generating Assets | **Missing** | Not applicable to financial core. |
|
||||
| **22** | Disclosure of Financial Information About the General Government Sector | Partial | Sectoral structure supported; GGS boundary and entity list external. |
|
||||
| **23** | Revenue from Non-Exchange Transactions | **Missing** | No tax/transfer revenue. |
|
||||
| **24** | Presentation of Budget Information in Financial Statements | Structure only | Template in `budget_vs_actual_structure()`; budget data external. |
|
||||
| **25** | Employee Benefits | **Missing** | Not applicable to core. |
|
||||
| **26** | Impairment of Cash-Generating Assets | **Missing** | No impairment model. |
|
||||
| **27** | Agriculture | **Missing** | Not applicable. |
|
||||
| **28** | Financial Instruments: Presentation | Partial | Asset/liability split in statement of financial position. |
|
||||
| **29** | Financial Instruments: Recognition and Measurement | **Missing** | No measurement basis (amortised cost, FVOCI, FVPL) or ECL. |
|
||||
| **30** | Financial Instruments: Disclosures | **Missing** | No risk or maturity disclosure. |
|
||||
| **31** | Intangible Assets | **Missing** | Not applicable. |
|
||||
| **32** | Service Concession Arrangements: Grantor | **Missing** | Not applicable. |
|
||||
| **33** | First-Time Adoption of Accrual Basis IPSAS | **Missing** | Not applicable (no full IPSAS adoption). |
|
||||
| **34** | Separate Financial Statements | Partial | Entity-level (CB, bank) supported. |
|
||||
| **35** | Consolidated Financial Statements | Partial | Consolidated layout; no full consolidation rules. |
|
||||
| **36** | Investments in Associates and Joint Ventures | **Missing** | Not applicable. |
|
||||
| **37** | Joint Arrangements | **Missing** | Not applicable. |
|
||||
| **38** | Disclosure of Interests in Other Entities | **Missing** | No disclosure. |
|
||||
| **39** | Employee Benefits | **Missing** | Not applicable. |
|
||||
| **40** | Public Sector Combinations | **Missing** | Not applicable. |
|
||||
| **41** | Financial Instruments | **Missing** | No classification, measurement, or ECL. |
|
||||
| **42** | Social Benefits | **Missing** | Not applicable. |
|
||||
| **43** | Leases | **Missing** | Not applicable. |
|
||||
| **44** | Non-Current Assets Held for Sale and Discontinued Operations | **Missing** | Not applicable. |
|
||||
| **45** | Property, Plant, and Equipment | **Missing** | Not applicable. |
|
||||
| **46** | Measurement | **Missing** | No measurement basis (historical, FV, etc.). |
|
||||
| **47** | Revenue | **Missing** | No revenue model. |
|
||||
| **48** | Transfer Expenses | **Missing** | No transfer expense. |
|
||||
| **49** | Retirement Benefit Plans | **Missing** | Not applicable. |
|
||||
| **50** | Exploration for and Evaluation of Mineral Resources | **Missing** | Not applicable. |
|
||||
| **Cash basis** | Financial Reporting Under the Cash Basis | **Missing** | No cash-basis statement. |
|
||||
| **RPG 1** | Long-Term Sustainability of an Entity's Finances | Partial | Debt sustainability (r−g) in sovereign module; no full RPG 1 disclosure. |
|
||||
| **RPG 2** | Financial Statement Discussion and Analysis | **Missing** | No narrative. |
|
||||
| **RPG 3** | Reporting Service Performance Information | **Missing** | Not applicable. |
|
||||
| **SRS 1** | Climate-related Disclosures | **Missing** | Not applicable. |
|
||||
| Status | Count | Notes |
|
||||
|--------|--------|--------|
|
||||
| **Supported** | 1 | IPSAS 1 (statement of financial position: structure, current/non-current). |
|
||||
| **Structure** | 20+ | Templates in `fqbm.ipsas.presentation`: 3, 5, 9, 10, 14, 19, 20, 23, 24 (+ budget_actual_from_state), 29/30/41, 38, 46, 47, 48, cash basis, RPG 2, functional/presentation currency. |
|
||||
| **Partial** | 6 | CF (no revenue/expense); 2 (no activity classification); 4 (S, pass-through only); 6, 22, 28, 34, 35 (sectoral/consolidated layout only); 15 (maturity_risk_disclosure_structure); RPG 1 (r−g in sovereign module). |
|
||||
| **Missing / N/A** | 25+ | Not applicable to monetary/financial core: 7, 8, 11–13, 16–18, 21, 25–27, 31–33, 36–37, 39–45, 49–50, RPG 3, SRS 1. 26: no impairment model. |
|
||||
|
||||
**Main gaps for entity-level IPSAS:** Cash flow by activity (IPSAS 2); FX translation of FC positions and gain/loss disclosure (4); measurement basis and ECL (41); full consolidation rules (6, 35). Budget data is external; use `budget_actual_from_state(state, budget)` for actuals.
|
||||
|
||||
---
|
||||
|
||||
## Part B — FQBM / Four-Quadrant Matrix: Gaps and missing
|
||||
## 2. FQBM / Matrix: What’s implemented
|
||||
|
||||
### B.1 State vector and identities
|
||||
|
||||
| Item | Status | Note |
|
||||
|------|--------|------|
|
||||
| **L_cb (central bank loans)** | **Added** | `FQBMState.L_cb` (default 0); central_bank_step updates L_cb; matrix uses state.L_cb. |
|
||||
| **Open-economy split A_dom / A_ext, L_dom / L_ext** | **Added** | `open_economy_view(A_dom, A_ext, L_dom, L_ext, E)` in `fqbm.state` returns identity check and totals. |
|
||||
| **Reporting period / reporting date** | **Added** | `FQBMState.reporting_date` (optional); `statement_of_financial_position(..., reporting_date=)` uses state.reporting_date when not passed. |
|
||||
|
||||
### B.2 Four-quadrant matrix (Part I)
|
||||
|
||||
| Item | Status | Note |
|
||||
|------|--------|------|
|
||||
| **Explicit four-quadrant layout** | **Added** | `fqbm.matrix.four_quadrant_matrix(state)` and `four_quadrant_summary(state)` return the 4-column matrix and identity check. |
|
||||
| **Quadrant balance checks** | **Added** | Summary includes `identity_A_eq_L_plus_E`. |
|
||||
| **Cross-sector consistency** | Partial | CB and bank identities implemented; no automatic check that matrix totals equal sectoral sums. |
|
||||
|
||||
### B.3 White paper parts not implemented
|
||||
|
||||
| Part | Topic | Status | Gap |
|
||||
|------|--------|--------|-----|
|
||||
| **VII** | Shadow banking and leverage | **Integrated** | `leverage_ratio()` in dashboard ratios; `margin_spiral_risk()` available; repo multiplier not modeled. |
|
||||
| **VIII** | Derivatives clearing and CCP | **Integrated** | `run_workbook(ccp_params=CCPParams(...))` returns `result["ccp"]` with identity and waterfall flag. |
|
||||
| **IX** | CBDC and digital reserve architecture | **Integrated** | `run_workbook(cbdc_params=CBDCParams(...))` applies deposit/reserve shift; `result["cbdc"]` has cbdc_liability. |
|
||||
| **XI** | Historical case expansion | **Partial** | Presets (1997, 2008, 2020, 2022) in scenarios; no narrative or coded “case” outputs. |
|
||||
|
||||
### B.4 IPSAS presentation structures added (templates only where no FQBM data)
|
||||
|
||||
| Item | Status | Location |
|
||||
|------|--------|----------|
|
||||
| Statement of financial position (IPSAS 1) | Supported | `statement_of_financial_position()` |
|
||||
| Budget vs actual (IPSAS 24) | Structure | `budget_vs_actual_structure()` |
|
||||
| Cash flow statement (IPSAS 2) | Structure | `cash_flow_statement_structure()` |
|
||||
| Statement of financial performance | Structure | `statement_of_financial_performance_structure()` |
|
||||
| Four-quadrant matrix | Supported | `fqbm.matrix.four_quadrant_matrix()` |
|
||||
|
||||
### B.5 Other missing
|
||||
|
||||
| Item | Status |
|
||||
|------|--------|
|
||||
| **Statement of changes in net assets/equity** | **Added** | `statement_of_changes_in_net_assets_structure()`. |
|
||||
| **Notes to the financial statements** | **Added** | `notes_to_financial_statements_structure()`. |
|
||||
| **Comparative period** | **Added** | `statement_of_financial_position_comparative(state_prior, state_current, entity)`. |
|
||||
| **Functional currency / presentation currency** | **Missing**. |
|
||||
| **Financial instrument maturity breakdown** | **Added** | `maturity_risk_disclosure_structure()` (maturity buckets, interest rate +100bp, credit exposure, ECL). |
|
||||
| **Interest rate sensitivity** | **Partial** | Column in maturity_risk_disclosure_structure. |
|
||||
| **Credit risk / ECL disclosure** | **Partial** | Columns in maturity_risk_disclosure_structure. |
|
||||
| **FX translation of FC positions** | **Added** | `fx_translate(fc_amount, S_prev, S_curr)`. |
|
||||
| **Cash flow from balance sheet changes** | **Added** | `cash_flow_from_state_changes(state_prev, state_curr)`. |
|
||||
- **State:** L_cb, cbdc_liability, reporting_date, functional_currency, presentation_currency. **Open economy:** `open_economy_view(A_dom, A_ext, L_dom, L_ext, E)`.
|
||||
- **Matrix:** `four_quadrant_matrix()`, `four_quadrant_summary()`, `cross_sector_consistency_check()`.
|
||||
- **Parts VII–IX, XI:** Shadow banking (repo_multiplier in dashboard, margin_spiral_simulation); CCP (ccp_params, result["ccp"]); CBDC (cbdc_liability in state and IPSAS); scenarios + `get_case_narrative()`.
|
||||
- **IPSAS layer:** Statement of financial position (CB, bank, consolidated), budget vs actual (template + budget_actual_from_state), cash flow from Δstate, comparative, notes, maturity/risk, FX translate, and all structure templates above.
|
||||
|
||||
---
|
||||
|
||||
## Part C — Implementation checklist (done vs to do)
|
||||
## 3. Remaining gaps (concise)
|
||||
|
||||
### Done
|
||||
|
||||
- IPSAS 1 statement of financial position (CB, bank, consolidated); uses state.L_cb and state.reporting_date.
|
||||
- IPSAS 24 budget vs actual template.
|
||||
- IPSAS 2 cash flow statement template; **cash_flow_from_state_changes(state_prev, state_curr)** infers amounts from Δstate.
|
||||
- Statement of financial performance template.
|
||||
- **Statement of changes in net assets** template.
|
||||
- **FX translation**: **fx_translate(fc_amount, S_prev, S_curr)**.
|
||||
- Four-quadrant matrix and summary; **L_cb** from state.
|
||||
- **L_cb in state**: `FQBMState.L_cb` and `reporting_date`; central_bank_step updates L_cb; differential model 12-element vector.
|
||||
- **Open economy**: **open_economy_view(A_dom, A_ext, L_dom, L_ext, E)**.
|
||||
- **Part VII**: Leverage ratio in dashboard; **run_workbook** exposes shadow metrics.
|
||||
- **Part VIII**: **run_workbook(ccp_params=CCPParams(...))** returns result["ccp"].
|
||||
- **Part IX**: **run_workbook(cbdc_params=CBDCParams(...))** applies deposit/reserve shift; result["cbdc"].
|
||||
|
||||
### Optional work (completed)
|
||||
|
||||
1. **Part VII**: **repo_multiplier(initial_collateral, haircut, rounds)** and **margin_spiral_simulation(...)** in `fqbm.sheets.shadow_banking`.
|
||||
2. **Part VIII**: **variation_margin_flow(mark_to_market_change)** and **ccp_clearing_simulation(vm_calls_per_period, liquidity_buffer_start)** in `fqbm.sheets.ccp`.
|
||||
3. **IPSAS**: **notes_to_financial_statements_structure()**; **statement_of_financial_position_comparative(state_prior, state_current, entity)**; **maturity_risk_disclosure_structure()** in `fqbm.ipsas.presentation`.
|
||||
| Area | Gap |
|
||||
|------|-----|
|
||||
| **Part VIII** | Full clearing balance sheet not modeled (margin/waterfall only). |
|
||||
| **IPSAS 2** | No operating/investing/financing classification of cash flows. |
|
||||
| **IPSAS 4** | No translation of FC assets/liabilities or FX gain/loss in performance statement. |
|
||||
| **IPSAS 41 / 46** | No measurement basis or ECL model; use templates + user data. |
|
||||
| **RPG 1** | Full long-term sustainability disclosure not implemented. |
|
||||
| **GGS** | Sectoral structure only; boundary and entity list set by jurisdiction. |
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
## 4. References
|
||||
|
||||
- [IPSAS_COMPLIANCE.md](IPSAS_COMPLIANCE.md) — Scope and how to use the IPSAS layer.
|
||||
- IPSASB (2025). *Handbook of International Public Sector Accounting Pronouncements*. IFAC.
|
||||
- White paper: Four-Quadrant Balance Sheet Matrix, Parts I–XVI.
|
||||
- [IPSAS_COMPLIANCE.md](IPSAS_COMPLIANCE.md) — Scope and use of the IPSAS layer.
|
||||
- [RECOMMENDATIONS.md](RECOMMENDATIONS.md) — Further suggestions.
|
||||
- [MISSING_COMPONENTS_AND_DOCUMENTATION.md](MISSING_COMPONENTS_AND_DOCUMENTATION.md) — Checklist.
|
||||
|
||||
@@ -39,7 +39,7 @@ IPSAS 1 requires **current** and **non-current** classification for assets and l
|
||||
|
||||
| IPSAS 1-style line item | FQBM variable | Suggested classification | Notes |
|
||||
|-------------------------|---------------|---------------------------|--------|
|
||||
| Financial assets (at amortised cost / FV) | B (government bonds), L_cb (loans) | Non-current (hold-to-maturity / policy portfolio) or split by maturity | L_cb not in state; can be added. |
|
||||
| Financial assets (at amortised cost / FV) | B (government bonds), L_cb (loans) | Non-current (hold-to-maturity / policy portfolio) or split by maturity | L_cb is in state (`FQBMState.L_cb`). |
|
||||
| Cash and cash equivalents / Reserves | R | Current | |
|
||||
| Currency in circulation | C | Liability (current) | |
|
||||
| Liabilities (reserve accounts) | R (bank reserves) | Current | |
|
||||
@@ -75,7 +75,7 @@ See `fqbm.ipsas.presentation.budget_vs_actual_structure()`.
|
||||
|
||||
- **Presentation**: Financial assets vs liabilities, and (where applicable) current vs non-current — supported by the IPSAS 1-style layout.
|
||||
- **Recognition and measurement**: FQBM does not implement measurement bases (amortised cost, FVOCI, FVPL) or impairment (e.g. ECL). **Gap** for full IPSAS 41 compliance.
|
||||
- **Disclosure**: No maturity breakdown, interest rate sensitivity, or credit risk disclosure. **Gap**; can be extended with user-supplied data.
|
||||
- **Disclosure**: Maturity and risk templates in `maturity_risk_disclosure_structure()`; extend with user-supplied data for full interest rate sensitivity and credit risk/ECL disclosure.
|
||||
|
||||
---
|
||||
|
||||
@@ -105,7 +105,11 @@ See `fqbm.ipsas.presentation.budget_vs_actual_structure()`.
|
||||
| Financial instrument measurement (IPSAS 41) | **Not supported** | No measurement basis or ECL |
|
||||
| FX translation (IPSAS 4) | **Partial** | Exchange rate and pass-through only |
|
||||
| Disclosure of GGS (IPSAS 22) | **Partial** | Sectoral structure supported |
|
||||
| Reporting period / reporting date | **Not defined** | FQBM is period-agnostic; user must set |
|
||||
| Reporting period / reporting date | **Supported** | `FQBMState.reporting_date`; `statement_of_financial_position(..., reporting_date=)` |
|
||||
| Comparative period (prior/current) | **Supported** | `statement_of_financial_position_comparative()` |
|
||||
| Notes and maturity/risk disclosure | **Structure** | `notes_to_financial_statements_structure()`, `maturity_risk_disclosure_structure()` |
|
||||
| Cash flow from balance sheet changes | **Supported** | `cash_flow_from_state_changes()`; FX: `fx_translate()` |
|
||||
| Additional IPSAS structures (3, 5, 9, 10, 14, 19, 20, 23, 29/41, 38, 46, 48, cash basis, RPG 2, functional/presentation currency) | **Structure** | Templates in `fqbm.ipsas.presentation`; budget vs actual from state: `budget_actual_from_state()` |
|
||||
|
||||
---
|
||||
|
||||
@@ -123,7 +127,7 @@ For **full IPSAS compliance** at entity level, the reporting entity must:
|
||||
- Populate budget information (IPSAS 24) and provide variance analysis.
|
||||
- Apply IPSAS 4 for FX and other standards as applicable.
|
||||
|
||||
The FQBM IPSAS layer supports **presentation consistency** and **structural alignment** with IPSAS 1 and IPSAS 24, not end-to-end compliance by itself.
|
||||
The FQBM IPSAS layer supports **presentation consistency** and **structural alignment** with IPSAS 1 and IPSAS 24, not end-to-end compliance by itself. For a consolidated list of recommendations (e.g. full CCP balance sheet, FX disclosure, white paper), see [RECOMMENDATIONS.md](RECOMMENDATIONS.md).
|
||||
|
||||
---
|
||||
|
||||
|
||||
121
docs/MISSING_COMPONENTS_AND_DOCUMENTATION.md
Normal file
121
docs/MISSING_COMPONENTS_AND_DOCUMENTATION.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Missing Components and Required Documentation
|
||||
|
||||
Consolidated list of **missing components** (code/IPSAS/FQBM) and **documentation that is required** or recommended for the FQBM project. Derived from [GAPS_AND_MISSING.md](GAPS_AND_MISSING.md) and [IPSAS_COMPLIANCE.md](IPSAS_COMPLIANCE.md).
|
||||
|
||||
---
|
||||
|
||||
## 1. Missing components (code / functionality)
|
||||
|
||||
### 1.1 IPSAS standards (missing or partial)
|
||||
|
||||
| Component | Standard / area | Required for |
|
||||
|-----------|------------------|--------------|
|
||||
| Accounting policies, prior-period adjustments, error correction | IPSAS 3 | Full IPSAS 3 compliance |
|
||||
| Borrowing costs capitalisation / expense | IPSAS 5 | Borrowing cost treatment |
|
||||
| Revenue recognition and measurement | IPSAS 9, 47 | Statement of financial performance |
|
||||
| Hyperinflation restatement | IPSAS 10 | High-inflation reporting |
|
||||
| Events after the reporting date (adjust vs disclose) | IPSAS 14 | Post–reporting-date events |
|
||||
| Provisions and contingent liabilities/assets | IPSAS 19 | Provisions note |
|
||||
| Related party identification and disclosure | IPSAS 20 | Related party note |
|
||||
| Revenue from non-exchange (taxes, transfers) | IPSAS 23 | Government revenue |
|
||||
| Financial instrument recognition/measurement (amortised cost, FVOCI, FVPL, ECL) | IPSAS 29, 41 | Full instrument accounting |
|
||||
| Disclosure of interests in other entities | IPSAS 38 | Consolidation disclosure |
|
||||
| Measurement basis (historical cost, FV, etc.) | IPSAS 46 | Measurement policy |
|
||||
| Transfer expenses | IPSAS 48 | Transfer expense classification |
|
||||
| Cash-basis financial statement | Cash basis IPSAS | Cash-basis reporters |
|
||||
| Financial Statement Discussion and Analysis (narrative) | RPG 2 | Management commentary |
|
||||
| Functional currency / presentation currency | General | Multi-currency reporting |
|
||||
|
||||
### 1.2 FQBM / matrix (missing or partial)
|
||||
|
||||
| Component | Description | Required for |
|
||||
|-----------|-------------|---------------|
|
||||
| Cross-sector consistency check | Automatic check that four-quadrant matrix totals equal sectoral (CB + bank) sums | Matrix validation |
|
||||
| Budget / appropriation model | Internal representation of budget and appropriations (not only template) | IPSAS 24 actual vs budget from FQBM |
|
||||
| Historical case narrative / coded outputs | Part XI: structured narrative or coded “case” outputs for 1997, 2008, 2020, 2022 | Case study reporting |
|
||||
| Real data pipelines | Automated download of Fed H.4.1, BIS, IMF (e.g. for regressions) | Empirical use without manual data |
|
||||
|
||||
### 1.3 White paper / framework (out of scope but listed for completeness)
|
||||
|
||||
| Component | Note |
|
||||
|-----------|------|
|
||||
| Full CCP balance-sheet dynamics | Part VIII: margin flows and default waterfall exist; full clearing balance sheet not modeled. |
|
||||
| CBDC in state vector | **Done**: `FQBMState.cbdc_liability`; workbook updates it on CBDC shift; IPSAS presentation shows it. |
|
||||
| Repo multiplier in workbook | **Done**: wired into `run_workbook` (optional `shadow_params`); dashboard includes `repo_multiplier`. |
|
||||
|
||||
---
|
||||
|
||||
## 2. Required or recommended documentation
|
||||
|
||||
### 2.1 Documentation that does not exist (required or recommended)
|
||||
|
||||
| Document | Purpose | Priority |
|
||||
|----------|---------|----------|
|
||||
| **White paper (canonical source)** | The full FQBM white paper as a single file (e.g. `docs/WHITE_PAPER.md` or PDF) so the framework is versioned with the code | High – README and framework_summary refer to “the white paper” but it is not in the repo |
|
||||
| **User guide / tutorial** | Step-by-step: install, run workbook, run Monte Carlo, interpret stress tables, use scenarios, export Excel, use IPSAS layer | High – README is short; no walkthrough |
|
||||
| **API reference** | Documented list of public functions/classes, parameters, and return types (e.g. Sphinx or MkDocs, or a single `API.md`) | Medium – only docstrings in code |
|
||||
| **Data dictionary** | Definition of every state variable (B, R, C, Loans, …), sheet inputs/outputs, and regression variables (columns for Model 1–3) | Medium – scattered in docstrings |
|
||||
| **Changelog** | `CHANGELOG.md` or release notes for versions (e.g. 0.1.0, 0.2.0) | Low |
|
||||
| **Contributing / development** | How to add a sheet, add a scenario, run tests, code style | Low |
|
||||
|
||||
### 2.2 Documentation that exists but could be extended
|
||||
|
||||
| Document | Status / remaining gap |
|
||||
|----------|------------------------|
|
||||
| **README.md** | No “Quick start” example with copy-paste code; no table of contents; Streamlit and scenarios could be in a single “Optional features” section. |
|
||||
| **docs/framework_summary.md** | One sentence per Part (I–XVI) and module mapping in place. |
|
||||
| **docs/IPSAS_COMPLIANCE.md** | Section 3 still says “L_cb not in state” – should say L_cb is in state. Compliance checklist could reference new helpers (comparative, notes, maturity/risk). |
|
||||
| **docs/GAPS_AND_MISSING.md** | B.3 table says “repo multiplier not modeled” but `repo_multiplier()` exists – could say “repo multiplier implemented; not in dashboard”. |
|
||||
| **docs/REFERENCES.md** | Weblinks added (IPSASB, Handbook, BIS, BIS bulk, IMF, Fed H.4.1, Fed Data Download). |
|
||||
| **docs/RECOMMENDATIONS.md** | Created: consolidated list of recommendations and suggestions. |
|
||||
| **Inline docstrings** | Some modules lack “Part X” references or “Required columns” for regression DataFrames. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Summary checklist
|
||||
|
||||
Implementation status: structures and code listed below have been added (templates for IPSAS; cross-sector check; budget_actual_from_state; get_case_narrative; docs added or updated). Real data pipelines remain optional.
|
||||
|
||||
### Missing components (to implement if targeting full IPSAS / completeness)
|
||||
|
||||
- [x] IPSAS 3: Accounting policies / prior-period adjustment / error correction — `accounting_policies_structure()`
|
||||
- [x] IPSAS 5: Borrowing costs — `borrowing_costs_structure()`
|
||||
- [x] IPSAS 9/47: Revenue recognition — `revenue_recognition_structure()`
|
||||
- [x] IPSAS 10: Hyperinflation restatement — `hyperinflation_restatement_structure()`
|
||||
- [x] IPSAS 14: Events after the reporting date — `events_after_reporting_date_structure()`
|
||||
- [x] IPSAS 19: Provisions and contingencies — `provisions_contingencies_structure()`
|
||||
- [x] IPSAS 20: Related party disclosure — `related_party_disclosure_structure()`
|
||||
- [x] IPSAS 23: Revenue from non-exchange transactions — `revenue_non_exchange_structure()`
|
||||
- [x] IPSAS 29/41: Financial instrument measurement and ECL — `financial_instruments_measurement_structure()`
|
||||
- [x] IPSAS 38: Disclosure of interests in other entities — `interests_in_other_entities_structure()`
|
||||
- [x] IPSAS 46: Measurement basis — `measurement_basis_structure()`
|
||||
- [x] IPSAS 48: Transfer expenses — `transfer_expenses_structure()`
|
||||
- [x] Cash-basis statement — `cash_basis_statement_structure()`
|
||||
- [x] RPG 2: Financial Statement Discussion and Analysis (narrative) — `fs_discussion_and_analysis_structure()`
|
||||
- [x] Functional / presentation currency — state fields + `functional_presentation_currency_structure()`
|
||||
- [x] Cross-sector matrix consistency check — `cross_sector_consistency_check()` in fqbm.matrix
|
||||
- [x] Budget/appropriation model (optional) — `budget_actual_from_state()` in presentation
|
||||
- [x] Historical case narrative or coded outputs (Part XI) — `get_case_narrative(name)` in scenarios.presets
|
||||
- [x] Real data pipelines (optional) — `fqbm.data.pipelines`: fetch_fed_h41, fetch_bis_series, fetch_imf_series
|
||||
|
||||
### Required documentation (to add)
|
||||
|
||||
- [x] **White paper** in repo — `docs/WHITE_PAPER.md` (placeholder)
|
||||
- [x] **User guide / tutorial** — `docs/USER_GUIDE.md`
|
||||
- [x] **API reference** — `docs/API_REFERENCE.md`
|
||||
- [x] **Data dictionary** — `docs/DATA_DICTIONARY.md`
|
||||
- [x] **Changelog** — `CHANGELOG.md`
|
||||
- [x] **Contributing / development** — `CONTRIBUTING.md`
|
||||
- [x] Update **IPSAS_COMPLIANCE.md** (L_cb in state; new helpers)
|
||||
- [x] Update **GAPS_AND_MISSING.md** (repo_multiplier in dashboard note)
|
||||
- [x] Extend **framework_summary.md** (module mapping)
|
||||
|
||||
---
|
||||
|
||||
## 4. References
|
||||
|
||||
- [GAPS_AND_MISSING.md](GAPS_AND_MISSING.md) – Full IPSAS and FQBM gap list
|
||||
- [IPSAS_COMPLIANCE.md](IPSAS_COMPLIANCE.md) – Scope and use of the IPSAS layer
|
||||
- [RECOMMENDATIONS.md](RECOMMENDATIONS.md) – Additional recommendations and suggestions
|
||||
- [framework_summary.md](framework_summary.md) – Core identity and Parts I–XVI
|
||||
- [REFERENCES.md](REFERENCES.md) – Chicago Author–Date references and weblinks
|
||||
82
docs/RECOMMENDATIONS.md
Normal file
82
docs/RECOMMENDATIONS.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# FQBM Recommendations and Suggestions
|
||||
|
||||
Consolidated list of **additional recommendations and suggestions** for the FQBM project. See also [GAPS_AND_MISSING.md](GAPS_AND_MISSING.md) and [MISSING_COMPONENTS_AND_DOCUMENTATION.md](MISSING_COMPONENTS_AND_DOCUMENTATION.md).
|
||||
|
||||
---
|
||||
|
||||
## 1. Code and framework (white paper / FQBM)
|
||||
|
||||
| Item | Status / note |
|
||||
|------|----------------|
|
||||
| **Full CCP balance-sheet dynamics** | Part VIII: margin flows and default waterfall exist; full clearing balance sheet is not modeled. Future work. |
|
||||
| **Full IPSAS compliance at entity level** | FQBM provides presentation structures; the reporting entity must maintain recognition/measurement per IPSAS (e.g. 41, 46), prepare cash flow statement (IPSAS 2) and statement of financial performance, populate budget (IPSAS 24) with variance analysis, and apply IPSAS 4 for FX. See [IPSAS_COMPLIANCE.md](IPSAS_COMPLIANCE.md) §9. |
|
||||
| **Cash flow by activity (IPSAS 2)** | No classification of cash flows by operating/investing/financing from FQBM; use `cash_flow_from_state_changes()` for inferred amounts and templates for disclosure. |
|
||||
| **FX translation and disclosure** | Add explicit translation of foreign-currency assets/liabilities and FX gain/loss in a performance statement; `fx_translate()` and state `S` support analysis. |
|
||||
| **Financial instrument measurement and ECL** | No measurement bases (amortised cost, FVOCI, FVPL) or impairment model; use `financial_instruments_measurement_structure()` and `maturity_risk_disclosure_structure()`; extend with user-supplied data. |
|
||||
| **Budget data** | Budget columns (original/final) must be supplied by the reporting entity; use `budget_actual_from_state(state, budget)` to fill actuals from state. |
|
||||
| **GGS boundary** | General government sector boundary and entity list to be defined by the reporting jurisdiction; FQBM supports sectoral structure. |
|
||||
| **RPG 1 (long-term sustainability)** | Partial (e.g. debt sustainability r−g in sovereign module); full RPG 1 disclosure not implemented. |
|
||||
|
||||
---
|
||||
|
||||
## 2. Documentation
|
||||
|
||||
| Item | Priority / note |
|
||||
|------|-----------------|
|
||||
| **Canonical white paper in repo** | High. Replace [WHITE_PAPER.md](WHITE_PAPER.md) placeholder with full FQBM white paper (Markdown or PDF) versioned with the code. |
|
||||
| **Sphinx or MkDocs API docs** | Medium (optional). [API_REFERENCE.md](API_REFERENCE.md) exists; automated API docs could be added via Sphinx or MkDocs. |
|
||||
| **README** | Quick start and table of contents in place; Optional features in a single section. |
|
||||
| **framework_summary** | One sentence per Part (I–XVI) and module mapping in place; can be expanded. |
|
||||
| **REFERENCES weblinks** | IPSASB, IPSASB Handbook, BIS, BIS bulk, IMF, IMF Data, Fed H.4.1, Fed Data Download linked in [REFERENCES.md](REFERENCES.md). |
|
||||
| **Inline docstrings** | Add “Part X” references and “Required columns” for regression DataFrames where missing. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Contributing and process
|
||||
|
||||
| Item | Location |
|
||||
|------|----------|
|
||||
| Keep PRs focused; prefer smaller, reviewable changes | [CONTRIBUTING.md](../CONTRIBUTING.md) |
|
||||
| Ensure tests pass; add coverage where practical | CONTRIBUTING |
|
||||
| Update USER_GUIDE, API_REFERENCE, DATA_DICTIONARY when adding public API | CONTRIBUTING |
|
||||
| Update IPSAS_COMPLIANCE and GAPS_AND_MISSING when adding IPSAS/matrix features | CONTRIBUTING |
|
||||
| Add changelog entry under [Unreleased] in CHANGELOG.md | CONTRIBUTING |
|
||||
| When adding a sheet: optionally add Excel export for the new result key | CONTRIBUTING |
|
||||
| When adding a scenario: optionally add narrative in `get_case_narrative()` | CONTRIBUTING |
|
||||
|
||||
---
|
||||
|
||||
## 4. Data and empirical
|
||||
|
||||
| Item | Note |
|
||||
|------|------|
|
||||
| **Real data pipelines** | `fqbm.data.pipelines`: fetch_fed_h41, fetch_bis_series, fetch_imf_series. Can be extended (e.g. more series, caching, retries). See [USER_GUIDE.md](USER_GUIDE.md) and [DATA_DICTIONARY.md](DATA_DICTIONARY.md). |
|
||||
| **IMF API key** | Optional; programmatic IMF fetch benefits from registration and api_key. |
|
||||
|
||||
---
|
||||
|
||||
## 5. IPSAS and reporting (entity-level)
|
||||
|
||||
| Item | Note |
|
||||
|------|------|
|
||||
| Recognition and measurement per IPSAS (e.g. 41, 46) | Reporting entity responsibility. |
|
||||
| Prepare cash flow statement (IPSAS 2) and statement of financial performance | Reporting entity; FQBM provides structure and cash flow from Δstate. |
|
||||
| Populate budget (IPSAS 24) and provide variance analysis | Reporting entity; FQBM provides template and budget_actual_from_state. |
|
||||
| Apply IPSAS 4 for FX and other standards | Reporting entity. |
|
||||
| Disclosure: extend maturity, interest rate sensitivity, credit risk with user-supplied data | Use maturity_risk_disclosure_structure() and related templates. |
|
||||
|
||||
---
|
||||
|
||||
## 6. White paper
|
||||
|
||||
| Item | Note |
|
||||
|------|------|
|
||||
| Publish full white paper in repo (Markdown or PDF) and link from README and framework_summary | See [WHITE_PAPER.md](WHITE_PAPER.md); link already in README. |
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [GAPS_AND_MISSING.md](GAPS_AND_MISSING.md) — Full IPSAS and FQBM gap list
|
||||
- [IPSAS_COMPLIANCE.md](IPSAS_COMPLIANCE.md) — Scope and use of the IPSAS layer
|
||||
- [MISSING_COMPONENTS_AND_DOCUMENTATION.md](MISSING_COMPONENTS_AND_DOCUMENTATION.md) — Checklist and documentation status
|
||||
@@ -15,3 +15,14 @@ International Monetary Fund (IMF). 2014. *Government Finance Statistics Manual*.
|
||||
McLeay, Michael, Amar Radia, and Ryland Thomas. 2014. "Money Creation in the Modern Economy." *Bank of England Quarterly Bulletin*.
|
||||
|
||||
Obstfeld, Maurice, and Kenneth Rogoff. 1995. *Foundations of International Macroeconomics*.
|
||||
|
||||
## Weblinks (optional)
|
||||
|
||||
- IPSASB: https://www.ifac.org/ipsasb — International Public Sector Accounting Standards.
|
||||
- IPSASB Handbook: https://www.ifac.org/ipsasb/standards — Handbook of International Public Sector Accounting Pronouncements.
|
||||
- BIS: https://www.bis.org — Statistics and manuals.
|
||||
- BIS Statistics (bulk download): https://www.bis.org/statistics/full_data_sets.htm — Credit gaps, debt service, CB assets, etc.
|
||||
- IMF: https://www.imf.org — Data and Government Finance Statistics.
|
||||
- IMF Data: https://www.imf.org/en/Data — Data portal and API.
|
||||
- Fed H.4.1: https://www.federalreserve.gov/releases/h41/ — Factors Affecting Reserve Balances.
|
||||
- Fed Data Download (H.41): https://www.federalreserve.gov/datadownload/Choose.aspx?rel=H41 — CSV download.
|
||||
|
||||
161
docs/USER_GUIDE.md
Normal file
161
docs/USER_GUIDE.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# FQBM User Guide and Tutorial
|
||||
|
||||
This guide walks you through installing, running, and interpreting the Four-Quadrant Balance Sheet Matrix (FQBM) framework.
|
||||
|
||||
---
|
||||
|
||||
## 1. Install
|
||||
|
||||
```bash
|
||||
cd FOUR-QUADRANT_BALANCE_SHEET_MATRIX
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
Optional: `pip install pytest` for tests; `pip install streamlit` for the Streamlit dashboard.
|
||||
|
||||
---
|
||||
|
||||
## 2. Quick start: run the workbook
|
||||
|
||||
The workbook runs all eight sheets (central bank, commercial bank, capital stress, FX parity, sovereign debt, commodity, Monte Carlo, dashboard) in one go:
|
||||
|
||||
```python
|
||||
from fqbm.workbook.runner import run_workbook
|
||||
from fqbm.state import FQBMState
|
||||
|
||||
state = FQBMState(B=100, R=50, C=20, Loans=800, Deposits=700, E_cb=30, E_b=100)
|
||||
result = run_workbook(initial_state=state, mc_runs=50, export_path="out.xlsx")
|
||||
```
|
||||
|
||||
Or from the command line:
|
||||
|
||||
```bash
|
||||
python -m fqbm.workbook.runner
|
||||
```
|
||||
|
||||
This produces a result dictionary (and optionally an Excel file) with keys such as `state`, `stress_tables`, `fx_parity`, `sovereign`, `commodity`, `monte_carlo`, `dashboard`, and `ipsas` (if requested).
|
||||
|
||||
---
|
||||
|
||||
## 3. Using scenarios (Part XI)
|
||||
|
||||
Use built-in historical scenarios instead of building state by hand:
|
||||
|
||||
```python
|
||||
from fqbm.workbook.runner import run_workbook
|
||||
|
||||
run_workbook(scenario="asia_1997", mc_runs=100, export_path="asia_1997.xlsx")
|
||||
run_workbook(scenario="gfc_2008", mc_runs=100)
|
||||
run_workbook(scenario="pandemic_2020", mc_runs=50)
|
||||
run_workbook(scenario="rate_shock_2022", mc_runs=50)
|
||||
```
|
||||
|
||||
List scenarios and get structured narrative:
|
||||
|
||||
```python
|
||||
from fqbm.scenarios.presets import list_scenarios, get_scenario, get_case_narrative
|
||||
|
||||
print(list_scenarios()) # ['asia_1997', 'gfc_2008', 'pandemic_2020', 'rate_shock_2022']
|
||||
preset = get_scenario("gfc_2008")
|
||||
case = get_case_narrative("gfc_2008") # narrative, state_summary, key_drivers, suggested_shocks
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Interpreting stress tables and Monte Carlo
|
||||
|
||||
- **Capital stress** (`result["stress_tables"]`): capital and leverage under different shock assumptions; see Sheet 3.
|
||||
- **Monte Carlo** (`result["monte_carlo"]`): distribution of outcomes (e.g. equity, deposits) over many runs; use percentiles for VaR-style analysis.
|
||||
- **Dashboard** (`result["dashboard"]`): aggregated view of key ratios and totals.
|
||||
|
||||
---
|
||||
|
||||
## 5. IPSAS layer and export
|
||||
|
||||
Generate IPSAS-style outputs from state:
|
||||
|
||||
```python
|
||||
from fqbm.state import FQBMState
|
||||
from fqbm.ipsas.presentation import (
|
||||
statement_of_financial_position,
|
||||
budget_vs_actual_structure,
|
||||
budget_actual_from_state,
|
||||
cash_flow_from_state_changes,
|
||||
statement_of_financial_position_comparative,
|
||||
)
|
||||
|
||||
state = FQBMState(B=100, R=50, C=20, Loans=800, Deposits=700, E_cb=30, E_b=100)
|
||||
df = statement_of_financial_position(state, entity="central_bank")
|
||||
# Comparative: prior vs current
|
||||
state_prior = state.copy()
|
||||
state_prior.B = 80
|
||||
comparative = statement_of_financial_position_comparative(state_prior, state, entity="central_bank")
|
||||
# Budget vs actual from state
|
||||
budget_df = budget_actual_from_state(state, budget={"Total assets": 900, "Total liabilities": 650})
|
||||
# Cash flow from balance sheet changes
|
||||
cashflow = cash_flow_from_state_changes(state_prior, state)
|
||||
```
|
||||
|
||||
Excel export (when `export_path` is set) includes IPSAS-style sheets when available.
|
||||
|
||||
---
|
||||
|
||||
## 6. Matrix and cross-sector check
|
||||
|
||||
```python
|
||||
from fqbm.state import FQBMState
|
||||
from fqbm.matrix import four_quadrant_matrix, four_quadrant_summary, cross_sector_consistency_check
|
||||
|
||||
state = FQBMState(B=100, R=50, C=20, Loans=800, Deposits=700, E_cb=30, E_b=100)
|
||||
matrix_df = four_quadrant_matrix(state)
|
||||
summary = four_quadrant_summary(state)
|
||||
check = cross_sector_consistency_check(state) # consistent, cb_balance, bank_balance, message
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Differential model and stability (Part XIV)
|
||||
|
||||
```python
|
||||
from fqbm.system.differential_model import solve_trajectory, check_stability, DifferentialParams
|
||||
import numpy as np
|
||||
|
||||
params = DifferentialParams()
|
||||
x0 = [100, 50, 20, 800, 700, 30, 100, 1.0, 0.0, 0.02, 1.0, 0.0]
|
||||
t_span = (0, 10)
|
||||
sol = solve_trajectory(x0, t_span, params)
|
||||
stable = check_stability(params)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Empirical regressions (Part X)
|
||||
|
||||
Synthetic data and regression helpers for inflation pass-through, sovereign spread, and capital flow sensitivity:
|
||||
|
||||
```python
|
||||
from fqbm.empirical.regressions import (
|
||||
run_inflation_pass_through,
|
||||
run_sovereign_spread,
|
||||
run_capital_flow_sensitivity,
|
||||
)
|
||||
|
||||
df_inf = run_inflation_pass_through(n=100)
|
||||
df_spread = run_sovereign_spread(n=100)
|
||||
df_cap = run_capital_flow_sensitivity(n=100)
|
||||
```
|
||||
|
||||
Required columns for each model are documented in the [Data dictionary](DATA_DICTIONARY.md) and in the module docstrings.
|
||||
|
||||
---
|
||||
|
||||
## 9. Optional features
|
||||
|
||||
- **Streamlit dashboard**: `streamlit run scripts/streamlit_dashboard.py`
|
||||
- **CBDC / CCP / repo**: workbook accepts `cbdc_params`, `ccp_params`, `shadow_params`. State has `cbdc_liability` after a CBDC shift; IPSAS presentation shows it. Repo multiplier is always in `result["dashboard"]["repo_multiplier"]` (optional `shadow_params` to customize haircut/rounds).
|
||||
- **Real data**: `from fqbm.data.pipelines import fetch_fed_h41, fetch_bis_series, fetch_imf_series` for Fed H.4.1, BIS bulk CSV (e.g. credit_gap, total_credit), and IMF (optional api_key). Pipelines can be extended (e.g. more series, caching, retries); see [DATA_DICTIONARY.md](DATA_DICTIONARY.md) and [RECOMMENDATIONS.md](RECOMMENDATIONS.md).
|
||||
- **FX parity**: Sheet 4 and `fqbm.sheets.fx_parity` (CIP, UIP, Dornbusch, pass-through).
|
||||
|
||||
For more detail on the API, see [API_REFERENCE.md](API_REFERENCE.md) and [DATA_DICTIONARY.md](DATA_DICTIONARY.md). For additional recommendations (full CCP, FX disclosure, white paper), see [RECOMMENDATIONS.md](RECOMMENDATIONS.md).
|
||||
23
docs/WHITE_PAPER.md
Normal file
23
docs/WHITE_PAPER.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# FQBM White Paper — Placeholder
|
||||
|
||||
This file is a **placeholder** for the canonical Four-Quadrant Balance Sheet Matrix (FQBM) white paper. The full theoretical foundation (Parts I–XVI) is referenced in [framework_summary.md](framework_summary.md) and in the codebase docstrings.
|
||||
|
||||
---
|
||||
|
||||
## Intended content (when published here)
|
||||
|
||||
- **Part I**: Accounting foundation (A = L + E), four-quadrant matrix, open-economy identity.
|
||||
- **Part II**: Closed-economy monetary dynamics (central bank, commercial bank).
|
||||
- **Part III–IV**: Open-economy extension, BoP, parity conditions, capital flows, FX dynamics.
|
||||
- **Part V–VI**: Sovereign risk and CDS; commodity shock channel.
|
||||
- **Part VII–IX**: Shadow banking and leverage; derivatives clearing and CCP; CBDC and digital reserve architecture.
|
||||
- **Part X**: Empirical regression appendix.
|
||||
- **Part XI**: Historical case expansion (1997, 2008, 2020, 2022–23).
|
||||
- **Part XII–XIV**: Quantitative stress tables; Monte Carlo framework; full system differential model.
|
||||
- **Part XV–XVI**: Policy implications; simulation workbook architecture (eight sheets).
|
||||
|
||||
---
|
||||
|
||||
## Versioning
|
||||
|
||||
When the white paper is added to this repository (as Markdown or PDF), it will be versioned with the code and linked from the README and framework_summary. Until then, the framework is implemented and documented in the codebase and in [framework_summary.md](framework_summary.md). For other suggestions (e.g. full CCP balance sheet, FX disclosure), see [RECOMMENDATIONS.md](RECOMMENDATIONS.md).
|
||||
@@ -13,25 +13,25 @@ Every financial asset is someone else’s liability (within or across borders).
|
||||
|
||||
All monetary operations must balance across this structure.
|
||||
|
||||
## Parts of the white paper
|
||||
## Parts of the white paper (one sentence each)
|
||||
|
||||
| Part | Topic |
|
||||
|------|--------|
|
||||
| I | Accounting foundation |
|
||||
| II | Closed-economy monetary dynamics (CB, commercial bank) |
|
||||
| III | Open-economy extension (BoP, parity) |
|
||||
| IV | Capital flows and FX dynamics |
|
||||
| V | Sovereign risk and CDS |
|
||||
| VI | Commodity shock channel |
|
||||
| VII | Shadow banking and leverage |
|
||||
| VIII | Derivatives clearing and CCP |
|
||||
| IX | CBDC and digital reserve architecture |
|
||||
| X | Empirical regression appendix |
|
||||
| XI | Historical case expansion |
|
||||
| XII | Quantitative stress tables |
|
||||
| XIII | Monte Carlo simulation framework |
|
||||
| XIV | Full system differential model |
|
||||
| XV | Policy implications |
|
||||
| XVI | Simulation workbook architecture (eight sheets) |
|
||||
| Part | Topic | Implementation |
|
||||
|------|--------|-----------------|
|
||||
| **I** | Accounting foundation: A = L + E, four-quadrant matrix, open-economy identity. | `fqbm.state`, `fqbm.matrix` (four_quadrant_matrix, cross_sector_consistency_check). |
|
||||
| **II** | Closed-economy monetary dynamics: central bank and commercial bank balance sheets. | `fqbm.sheets.central_bank`, `fqbm.sheets.commercial_bank`; state B, R, C, Loans, Deposits, E_cb, E_b, L_cb. |
|
||||
| **III** | Open-economy extension: BoP, parity conditions. | `open_economy_view()`; state S, K. |
|
||||
| **IV** | Capital flows and FX dynamics: CIP, UIP, Dornbusch, pass-through. | `fqbm.sheets.fx_parity`; Part X regressions (capital flow sensitivity). |
|
||||
| **V** | Sovereign risk and CDS: spread, debt sustainability. | `fqbm.sheets.sovereign_debt`; run_sovereign_spread. |
|
||||
| **VI** | Commodity shock channel: inflation composite, oil/commodity. | `fqbm.sheets.commodity`; state O. |
|
||||
| **VII** | Shadow banking and leverage: repo multiplier, margin spiral. | `fqbm.sheets.shadow_banking`; run_workbook(shadow_params=...); dashboard repo_multiplier. |
|
||||
| **VIII** | Derivatives clearing and CCP: margin flows, default waterfall. | `fqbm.sheets.ccp`; run_workbook(ccp_params=...). Full clearing balance sheet not modeled (see RECOMMENDATIONS.md). |
|
||||
| **IX** | CBDC and digital reserve architecture: deposit shift, funding gap. | `fqbm.sheets.cbdc`; FQBMState.cbdc_liability; run_workbook(cbdc_params=...). |
|
||||
| **X** | Empirical regression appendix: inflation pass-through, sovereign spread, capital flow. | `fqbm.empirical.regressions`; synthetic generators and run_*; required columns in DATA_DICTIONARY. |
|
||||
| **XI** | Historical case expansion: 1997, 2008, 2020, 2022 presets and narrative. | `fqbm.scenarios.presets`; get_case_narrative(name). |
|
||||
| **XII** | Quantitative stress tables: liquidity and capital stress. | `fqbm.sheets.capital_stress`; stress_tables. |
|
||||
| **XIII** | Monte Carlo simulation framework: shock draws, outcome distribution. | `fqbm.sheets.monte_carlo`; run_n_simulations. |
|
||||
| **XIV** | Full system differential model: trajectory and stability. | `fqbm.system.differential_model`; solve_trajectory, check_stability. |
|
||||
| **XV** | Policy implications: discussed in white paper; framework supports policy experiments. | Scenarios and parameters. |
|
||||
| **XVI** | Simulation workbook architecture: eight sheets, dashboard, export. | `fqbm.workbook.runner`; run_workbook. |
|
||||
|
||||
This codebase implements the simulation workbook (Part XVI), Monte Carlo (XIII), differential model (XIV), and empirical regressions (Part X).
|
||||
This codebase implements the simulation workbook (Part XVI), Monte Carlo (XIII), differential model (XIV), empirical regressions (Part X), IPSAS presentation (fqbm.ipsas), scenario presets with get_case_narrative (Part XI), and data pipelines (fqbm.data.pipelines).
|
||||
|
||||
17
src/fqbm/data/__init__.py
Normal file
17
src/fqbm/data/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
||||
"""
|
||||
Real data pipelines for empirical use (Fed H.4.1, BIS, IMF).
|
||||
|
||||
Optional: requires requests for some endpoints; CSV URLs may work with pandas only.
|
||||
"""
|
||||
|
||||
from fqbm.data.pipelines import (
|
||||
fetch_fed_h41,
|
||||
fetch_bis_series,
|
||||
fetch_imf_series,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"fetch_fed_h41",
|
||||
"fetch_bis_series",
|
||||
"fetch_imf_series",
|
||||
]
|
||||
163
src/fqbm/data/pipelines.py
Normal file
163
src/fqbm/data/pipelines.py
Normal file
@@ -0,0 +1,163 @@
|
||||
"""
|
||||
Real data pipelines for empirical use (Fed H.4.1, BIS, IMF).
|
||||
|
||||
Fetch public data for regressions and calibration. Optional API keys may be required
|
||||
for full BIS/IMF access; see docstrings. Uses urllib and pandas; requests optional for some endpoints.
|
||||
"""
|
||||
|
||||
from typing import Optional
|
||||
from urllib.request import urlopen, Request
|
||||
from urllib.error import URLError, HTTPError
|
||||
|
||||
import pandas as pd
|
||||
|
||||
|
||||
# Fed H.4.1: Data Download Program CSV (date range and series in query)
|
||||
# https://www.federalreserve.gov/datadownload/Choose.aspx?rel=H41
|
||||
_FED_H41_CSV_URL = (
|
||||
"https://www.federalreserve.gov/datadownload/Output.aspx?"
|
||||
"rel=H41&series=efce2c1a8744855f2623889dffb2b39a&lastObs=&from=01/01/2020&to=12/31/2024"
|
||||
"&filetype=csv&label=include&layout=seriescolumn"
|
||||
)
|
||||
|
||||
|
||||
def fetch_fed_h41(
|
||||
url: Optional[str] = None,
|
||||
date_col: Optional[str] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
Fetch Federal Reserve H.4.1 (Factors Affecting Reserve Balances) as DataFrame.
|
||||
|
||||
Uses the Fed Data Download Program CSV. If url is None, uses a default URL that may
|
||||
need updating for current dates. Custom url can be built from:
|
||||
https://www.federalreserve.gov/datadownload/Choose.aspx?rel=H41
|
||||
|
||||
Parameters
|
||||
----------
|
||||
url : str, optional
|
||||
Full CSV download URL. If None, uses default _FED_H41_CSV_URL.
|
||||
date_col : str, optional
|
||||
Name of date column for parsing; inferred if possible.
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame
|
||||
H.4.1 series (columns depend on Fed release). Empty DataFrame on error.
|
||||
"""
|
||||
u = url or _FED_H41_CSV_URL
|
||||
try:
|
||||
req = Request(u, headers={"User-Agent": "FQBM/1.0"})
|
||||
with urlopen(req, timeout=30) as resp:
|
||||
df = pd.read_csv(resp, skipinitialspace=True, on_bad_lines="skip")
|
||||
if date_col and date_col in df.columns:
|
||||
df[date_col] = pd.to_datetime(df[date_col], errors="coerce")
|
||||
return df
|
||||
except (URLError, HTTPError, Exception) as e:
|
||||
return pd.DataFrame({"error": [str(e)]})
|
||||
|
||||
|
||||
def fetch_bis_series(
|
||||
dataset: str = "credit_gap",
|
||||
country: Optional[str] = None,
|
||||
api_key: Optional[str] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
Fetch BIS statistics series (e.g. credit gap, property prices, debt service).
|
||||
|
||||
BIS Statistics Warehouse: https://www.bis.org/statistics/
|
||||
For programmatic access, BIS provides CSV export URLs. Some series are available
|
||||
without an API key via published CSV links.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
dataset : str
|
||||
Identifier: "credit_gap", "debt_service", "property", or "total_credit".
|
||||
country : str, optional
|
||||
Country code (e.g. "US", "CN"). Optional filter.
|
||||
api_key : str, optional
|
||||
Not required for public CSV; reserved for future BIS API use.
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame
|
||||
BIS series. Empty DataFrame if fetch fails.
|
||||
"""
|
||||
# BIS bulk download (flat CSV): https://www.bis.org/statistics/full_data_sets.htm
|
||||
urls = {
|
||||
"credit_gap": "https://www.bis.org/static/bulk/WS_CREDIT_GAP_csv_flat.zip",
|
||||
"debt_service": "https://www.bis.org/static/bulk/WS_DSR_csv_flat.zip",
|
||||
"property": "https://www.bis.org/static/bulk/WS_SPP_csv_flat.zip",
|
||||
"total_credit": "https://www.bis.org/static/bulk/WS_TC_csv_flat.zip",
|
||||
"cb_assets": "https://www.bis.org/static/bulk/WS_CBTA_csv_flat.zip",
|
||||
}
|
||||
u = urls.get(dataset, urls["credit_gap"])
|
||||
try:
|
||||
req = Request(u, headers={"User-Agent": "FQBM/1.0"})
|
||||
with urlopen(req, timeout=90) as resp:
|
||||
df = pd.read_csv(resp, compression="zip", on_bad_lines="skip", nrows=10000)
|
||||
# Optional country filter (column name may vary)
|
||||
for col in ("Reference area", "REF_AREA", "COUNTRY"):
|
||||
if country and col in df.columns:
|
||||
df = df[df[col].astype(str).str.upper() == country.upper()].copy()
|
||||
break
|
||||
return df
|
||||
except (URLError, HTTPError, Exception):
|
||||
return pd.DataFrame()
|
||||
|
||||
|
||||
def fetch_imf_series(
|
||||
database_id: str = "IFS",
|
||||
indicator: Optional[str] = None,
|
||||
country: Optional[str] = None,
|
||||
api_key: Optional[str] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
Fetch IMF data (e.g. IFS, GFS, WEO). Uses IMF Data API when api_key is provided;
|
||||
otherwise returns empty DataFrame with instructions.
|
||||
|
||||
IMF Data API: https://data.imf.org/
|
||||
API key (optional): https://www.imf.org/external/data.htm
|
||||
|
||||
Parameters
|
||||
----------
|
||||
database_id : str
|
||||
e.g. "IFS" (International Financial Statistics), "GFS", "WEO".
|
||||
indicator : str, optional
|
||||
Series code (e.g. "FITB_PA" for reserves).
|
||||
country : str, optional
|
||||
Country code (e.g. "US").
|
||||
api_key : str, optional
|
||||
IMF API key for programmatic access.
|
||||
|
||||
Returns
|
||||
-------
|
||||
pd.DataFrame
|
||||
IMF series. Empty DataFrame if no api_key or fetch fails.
|
||||
"""
|
||||
if not api_key:
|
||||
return pd.DataFrame({"note": ["IMF Data API requires registration; pass api_key for programmatic fetch. See https://data.imf.org/"]})
|
||||
try:
|
||||
import urllib.parse
|
||||
# IMF Data API v2 (REST) example
|
||||
base = "https://api.imf.org/v2"
|
||||
params = {"series": indicator or "FITB_PA", "country": country or "US"}
|
||||
q = urllib.parse.urlencode({k: v for k, v in params.items() if v})
|
||||
url = f"{base}/data/{database_id}?{q}"
|
||||
req = Request(url, headers={"User-Agent": "FQBM/1.0", "Accept": "application/json"})
|
||||
with urlopen(req, timeout=30) as resp:
|
||||
import json
|
||||
data = json.loads(resp.read().decode())
|
||||
# Normalize to DataFrame (structure depends on API response)
|
||||
if isinstance(data, list):
|
||||
return pd.DataFrame(data)
|
||||
if isinstance(data, dict) and "CompactData" in data:
|
||||
dataset = data.get("CompactData", {}).get("Dataset", [{}])
|
||||
series = dataset[0].get("Series", []) if dataset else []
|
||||
rows = []
|
||||
for s in series:
|
||||
for obs in s.get("Obs", []):
|
||||
rows.append({"time": obs.get("@TIME_PERIOD"), "value": obs.get("@OBS_VALUE")})
|
||||
return pd.DataFrame(rows)
|
||||
return pd.DataFrame(list(data.items()) if isinstance(data, dict) else [])
|
||||
except Exception:
|
||||
return pd.DataFrame()
|
||||
@@ -14,7 +14,7 @@ import statsmodels.api as sm
|
||||
|
||||
|
||||
def generate_synthetic_inflation(n: int = 100, seed: Optional[int] = None) -> pd.DataFrame:
|
||||
"""Synthetic data for Model 1. Columns: pi, dS, output_gap."""
|
||||
"""Part X: Synthetic data for Model 1 (inflation pass-through). Required columns: pi, dS, output_gap."""
|
||||
rng = np.random.default_rng(seed)
|
||||
dS = rng.normal(0, 0.05, n)
|
||||
output_gap = rng.normal(0, 0.02, n)
|
||||
@@ -26,8 +26,8 @@ def run_inflation_pass_through(
|
||||
data: Optional[pd.DataFrame] = None,
|
||||
) -> sm.regression.linear_model.RegressionResultsWrapper:
|
||||
"""
|
||||
Model 1: π_t = α + β ΔS_t + γ OutputGap_t + ε_t.
|
||||
Data must have columns: pi, dS, output_gap.
|
||||
Model 1 (Part X): π_t = α + β ΔS_t + γ OutputGap_t + ε_t.
|
||||
Required columns: pi, dS, output_gap.
|
||||
"""
|
||||
if data is None:
|
||||
data = generate_synthetic_inflation()
|
||||
@@ -37,7 +37,7 @@ def run_inflation_pass_through(
|
||||
|
||||
|
||||
def generate_synthetic_spread(n: int = 100, seed: Optional[int] = None) -> pd.DataFrame:
|
||||
"""Synthetic data for Model 2. Columns: spread, debt_gdp, reserves_gdp, fx_vol."""
|
||||
"""Part X: Synthetic data for Model 2 (sovereign spread). Required columns: spread, debt_gdp, reserves_gdp, fx_vol."""
|
||||
rng = np.random.default_rng(seed)
|
||||
debt_gdp = rng.uniform(0.3, 1.0, n)
|
||||
reserves_gdp = rng.uniform(0.05, 0.4, n)
|
||||
@@ -52,7 +52,8 @@ def run_sovereign_spread(
|
||||
data: Optional[pd.DataFrame] = None,
|
||||
) -> sm.regression.linear_model.RegressionResultsWrapper:
|
||||
"""
|
||||
Model 2: Spread_t = α + β (Debt/GDP)_t + γ Reserves/GDP_t + δ FXVol_t + ε_t.
|
||||
Model 2 (Part X): Spread_t = α + β (Debt/GDP)_t + γ Reserves/GDP_t + δ FXVol_t + ε_t.
|
||||
Required columns: spread, debt_gdp, reserves_gdp, fx_vol.
|
||||
"""
|
||||
if data is None:
|
||||
data = generate_synthetic_spread()
|
||||
@@ -62,7 +63,7 @@ def run_sovereign_spread(
|
||||
|
||||
|
||||
def generate_synthetic_capital_flow(n: int = 100, seed: Optional[int] = None) -> pd.DataFrame:
|
||||
"""Synthetic data for Model 3. Columns: dK, rate_diff, risk_premium."""
|
||||
"""Part X: Synthetic data for Model 3 (capital flow sensitivity). Required columns: dK, rate_diff, risk_premium."""
|
||||
rng = np.random.default_rng(seed)
|
||||
rate_diff = rng.normal(0.02, 0.01, n)
|
||||
risk_premium = rng.uniform(0, 0.05, n)
|
||||
@@ -74,8 +75,8 @@ def run_capital_flow_sensitivity(
|
||||
data: Optional[pd.DataFrame] = None,
|
||||
) -> sm.regression.linear_model.RegressionResultsWrapper:
|
||||
"""
|
||||
Model 3: ΔK_t = θ (i_d - i_f)_t − ω RiskPremium_t + ε_t.
|
||||
Data columns: dK, rate_diff, risk_premium.
|
||||
Model 3 (Part X): ΔK_t = θ (i_d - i_f)_t − ω RiskPremium_t + ε_t.
|
||||
Required columns: dK, rate_diff, risk_premium.
|
||||
"""
|
||||
if data is None:
|
||||
data = generate_synthetic_capital_flow()
|
||||
|
||||
@@ -8,6 +8,7 @@ IPSAS 2 (cash flow statement structure), IPSAS 24 (budget vs actual). See docs/I
|
||||
from fqbm.ipsas.presentation import (
|
||||
statement_of_financial_position,
|
||||
budget_vs_actual_structure,
|
||||
budget_actual_from_state,
|
||||
cash_flow_statement_structure,
|
||||
statement_of_financial_performance_structure,
|
||||
statement_of_changes_in_net_assets_structure,
|
||||
@@ -16,11 +17,27 @@ from fqbm.ipsas.presentation import (
|
||||
notes_to_financial_statements_structure,
|
||||
statement_of_financial_position_comparative,
|
||||
maturity_risk_disclosure_structure,
|
||||
accounting_policies_structure,
|
||||
borrowing_costs_structure,
|
||||
revenue_recognition_structure,
|
||||
hyperinflation_restatement_structure,
|
||||
events_after_reporting_date_structure,
|
||||
provisions_contingencies_structure,
|
||||
related_party_disclosure_structure,
|
||||
revenue_non_exchange_structure,
|
||||
financial_instruments_measurement_structure,
|
||||
interests_in_other_entities_structure,
|
||||
measurement_basis_structure,
|
||||
transfer_expenses_structure,
|
||||
cash_basis_statement_structure,
|
||||
fs_discussion_and_analysis_structure,
|
||||
functional_presentation_currency_structure,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"statement_of_financial_position",
|
||||
"budget_vs_actual_structure",
|
||||
"budget_actual_from_state",
|
||||
"cash_flow_statement_structure",
|
||||
"statement_of_financial_performance_structure",
|
||||
"statement_of_changes_in_net_assets_structure",
|
||||
@@ -29,4 +46,19 @@ __all__ = [
|
||||
"notes_to_financial_statements_structure",
|
||||
"statement_of_financial_position_comparative",
|
||||
"maturity_risk_disclosure_structure",
|
||||
"accounting_policies_structure",
|
||||
"borrowing_costs_structure",
|
||||
"revenue_recognition_structure",
|
||||
"hyperinflation_restatement_structure",
|
||||
"events_after_reporting_date_structure",
|
||||
"provisions_contingencies_structure",
|
||||
"related_party_disclosure_structure",
|
||||
"revenue_non_exchange_structure",
|
||||
"financial_instruments_measurement_structure",
|
||||
"interests_in_other_entities_structure",
|
||||
"measurement_basis_structure",
|
||||
"transfer_expenses_structure",
|
||||
"cash_basis_statement_structure",
|
||||
"fs_discussion_and_analysis_structure",
|
||||
"functional_presentation_currency_structure",
|
||||
]
|
||||
|
||||
@@ -31,22 +31,26 @@ def statement_of_financial_position(
|
||||
reporting_label = reporting_date or getattr(state, "reporting_date", None) or "Reporting date"
|
||||
|
||||
if entity == "central_bank":
|
||||
# Identity: B + L_cb = R + C + E_cb. Assets = B, L_cb; Liabilities = R, C; Net assets = E_cb.
|
||||
# Identity: B + L_cb = R + C + E_cb (+ cbdc_liability if Part IX). Assets = B, L_cb; Liabilities = R, C, cbdc_liability; Net assets = E_cb.
|
||||
L_cb_val = getattr(state, "L_cb", 0.0)
|
||||
cbdc_liab = getattr(state, "cbdc_liability", 0.0)
|
||||
rows.append(("Non-current assets", "", ""))
|
||||
rows.append(("Financial assets – government securities", "B", state.B))
|
||||
rows.append(("Financial assets – loans to banks (L_cb)", "L_cb", getattr(state, "L_cb", 0.0)))
|
||||
rows.append(("Total non-current assets", "", state.B + getattr(state, "L_cb", 0.0)))
|
||||
rows.append(("Financial assets – loans to banks (L_cb)", "L_cb", L_cb_val))
|
||||
rows.append(("Total non-current assets", "", state.B + L_cb_val))
|
||||
rows.append(("Current assets", "", ""))
|
||||
rows.append(("(Other current assets)", "", 0.0))
|
||||
rows.append(("Total current assets", "", 0.0))
|
||||
rows.append(("TOTAL ASSETS", "", state.B + getattr(state, "L_cb", 0.0)))
|
||||
rows.append(("TOTAL ASSETS", "", state.B + L_cb_val))
|
||||
rows.append(("", "", ""))
|
||||
rows.append(("Current liabilities", "", ""))
|
||||
rows.append(("Currency in circulation", "C", state.C))
|
||||
rows.append(("Reserve balances (deposits of banks)", "R", state.R))
|
||||
rows.append(("Total current liabilities", "", state.C + state.R))
|
||||
if cbdc_liab != 0:
|
||||
rows.append(("Digital currency in circulation (CBDC)", "cbdc_liability", cbdc_liab))
|
||||
rows.append(("Total current liabilities", "", state.C + state.R + cbdc_liab))
|
||||
rows.append(("Net assets / Equity", "E_cb", state.E_cb))
|
||||
rows.append(("TOTAL LIABILITIES AND NET ASSETS", "", state.C + state.R + state.E_cb)) # = B + L_cb
|
||||
rows.append(("TOTAL LIABILITIES AND NET ASSETS", "", state.C + state.R + cbdc_liab + state.E_cb))
|
||||
|
||||
elif entity == "commercial_bank":
|
||||
rows.append(("Current assets", "", ""))
|
||||
@@ -61,6 +65,7 @@ def statement_of_financial_position(
|
||||
rows.append(("TOTAL LIABILITIES AND NET ASSETS", "", state.Deposits + state.E_b))
|
||||
|
||||
else: # consolidated
|
||||
cbdc_liab = getattr(state, "cbdc_liability", 0.0)
|
||||
rows.append(("Non-current assets", "", ""))
|
||||
rows.append(("Financial assets – government securities", "B", state.B))
|
||||
rows.append(("Total non-current assets", "", state.B))
|
||||
@@ -73,9 +78,11 @@ def statement_of_financial_position(
|
||||
rows.append(("Current liabilities", "", ""))
|
||||
rows.append(("Currency in circulation", "C", state.C))
|
||||
rows.append(("Deposits", "Deposits", state.Deposits))
|
||||
rows.append(("Total current liabilities", "", state.C + state.Deposits))
|
||||
if cbdc_liab != 0:
|
||||
rows.append(("Digital currency (CBDC)", "cbdc_liability", cbdc_liab))
|
||||
rows.append(("Total current liabilities", "", state.C + state.Deposits + cbdc_liab))
|
||||
rows.append(("Net assets / Equity (E_cb + E_b)", "", state.E_cb + state.E_b))
|
||||
rows.append(("TOTAL LIABILITIES AND NET ASSETS", "", state.C + state.Deposits + state.E_cb + state.E_b))
|
||||
rows.append(("TOTAL LIABILITIES AND NET ASSETS", "", state.C + state.Deposits + cbdc_liab + state.E_cb + state.E_b))
|
||||
|
||||
df = pd.DataFrame(rows, columns=["Line item", "FQBM code", "Amount"])
|
||||
df.attrs["entity"] = entity
|
||||
@@ -328,3 +335,387 @@ def maturity_risk_disclosure_structure(
|
||||
})
|
||||
df.attrs["maturity_risk_disclosure"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 3: Accounting policies, prior-period adjustments, error correction ---
|
||||
|
||||
|
||||
def accounting_policies_structure(
|
||||
policies: Optional[list[tuple[str, str]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 3: Summary of significant accounting policies and prior-period/error correction.
|
||||
Columns: Policy area, Description, Prior-period adjustment (Y/N), Error correction (Y/N).
|
||||
"""
|
||||
default = [
|
||||
("Basis of preparation", "Accrual basis / cash basis", None, None),
|
||||
("Measurement basis", "Historical cost / fair value where applicable", None, None),
|
||||
("Prior-period comparative", "Restated for prior-period adjustments", None, None),
|
||||
("Error correction", "Material errors corrected retrospectively", None, None),
|
||||
]
|
||||
items = policies or default
|
||||
df = pd.DataFrame(
|
||||
items,
|
||||
columns=["Policy area", "Description", "Prior-period adjustment (Y/N)", "Error correction (Y/N)"],
|
||||
)
|
||||
df.attrs["ipsas_3"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 5: Borrowing costs ---
|
||||
|
||||
|
||||
def borrowing_costs_structure(
|
||||
line_items: Optional[list[tuple[str, Optional[float], Optional[float]]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 5: Borrowing costs – capitalised vs expense.
|
||||
Columns: Line item, Capitalised, Expensed, Total.
|
||||
"""
|
||||
default = [
|
||||
("Borrowing costs on qualifying assets", None, None, None),
|
||||
("Borrowing costs expensed", None, None, None),
|
||||
("Total borrowing costs", None, None, None),
|
||||
]
|
||||
items = line_items or default
|
||||
if items and len(items[0]) == 3:
|
||||
items = [(r[0], r[1], r[2], None) for r in items]
|
||||
df = pd.DataFrame(items, columns=["Line item", "Capitalised", "Expensed", "Total"])
|
||||
df.attrs["ipsas_5"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 9 / 47: Revenue recognition ---
|
||||
|
||||
|
||||
def revenue_recognition_structure(
|
||||
line_items: Optional[list[tuple[str, Optional[float]]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 9/47: Revenue from exchange transactions – recognition and measurement.
|
||||
Columns: Revenue type, Amount, Recognition policy.
|
||||
"""
|
||||
default = [
|
||||
("Revenue from exchange transactions", None, "When performance obligation satisfied"),
|
||||
("Interest revenue", None, "Effective interest method"),
|
||||
("Other revenue", None, "As applicable"),
|
||||
]
|
||||
items = line_items or default
|
||||
df = pd.DataFrame(items, columns=["Revenue type", "Amount", "Recognition policy"])
|
||||
df.attrs["ipsas_9_47"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 10: Hyperinflation restatement ---
|
||||
|
||||
|
||||
def hyperinflation_restatement_structure(
|
||||
line_items: Optional[list[tuple[str, Optional[float], Optional[float], Optional[float]]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 10: Restatement for hyperinflation (historical in nominal, restated in constant).
|
||||
Columns: Line item, Historical (nominal), Restatement factor, Restated (constant).
|
||||
"""
|
||||
default = [
|
||||
("Monetary assets", None, None, None),
|
||||
("Monetary liabilities", None, None, None),
|
||||
("Non-monetary assets", None, None, None),
|
||||
("Net assets", None, None, None),
|
||||
]
|
||||
items = line_items or default
|
||||
df = pd.DataFrame(
|
||||
items,
|
||||
columns=["Line item", "Historical (nominal)", "Restatement factor", "Restated (constant)"],
|
||||
)
|
||||
df.attrs["ipsas_10"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 14: Events after the reporting date ---
|
||||
|
||||
|
||||
def events_after_reporting_date_structure(
|
||||
events: Optional[list[tuple[str, str, Literal["Adjust", "Disclose"]]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 14: Events after the reporting date – adjust vs disclose.
|
||||
Columns: Description, Date, Treatment (Adjust / Disclose).
|
||||
"""
|
||||
default = [
|
||||
("Adjusting event example", "YYYY-MM-DD", "Adjust"),
|
||||
("Non-adjusting event example", "YYYY-MM-DD", "Disclose"),
|
||||
]
|
||||
items = events or default
|
||||
df = pd.DataFrame(items, columns=["Description", "Date", "Treatment"])
|
||||
df.attrs["ipsas_14"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 19: Provisions and contingencies ---
|
||||
|
||||
|
||||
def provisions_contingencies_structure(
|
||||
line_items: Optional[list[tuple[str, Optional[float], Optional[float], str]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 19: Provisions and contingent liabilities/assets.
|
||||
Columns: Line item, Carrying amount, Movement, Nature (provision / contingent liability / contingent asset).
|
||||
"""
|
||||
default = [
|
||||
("Provisions", None, None, "Provision"),
|
||||
("Contingent liabilities", None, None, "Contingent liability"),
|
||||
("Contingent assets", None, None, "Contingent asset"),
|
||||
]
|
||||
items = line_items or default
|
||||
df = pd.DataFrame(items, columns=["Line item", "Carrying amount", "Movement", "Nature"])
|
||||
df.attrs["ipsas_19"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 20: Related party disclosure ---
|
||||
|
||||
|
||||
def related_party_disclosure_structure(
|
||||
parties: Optional[list[tuple[str, str, Optional[float], str]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 20: Related party identification and disclosure.
|
||||
Columns: Related party, Relationship, Amount / transaction, Nature.
|
||||
"""
|
||||
default = [
|
||||
("Government", "Controlling entity", None, "Funding / appropriations"),
|
||||
("Other related entities", "Description", None, "Nature of transaction"),
|
||||
]
|
||||
items = parties or default
|
||||
df = pd.DataFrame(items, columns=["Related party", "Relationship", "Amount", "Nature"])
|
||||
df.attrs["ipsas_20"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 23: Revenue from non-exchange ---
|
||||
|
||||
|
||||
def revenue_non_exchange_structure(
|
||||
line_items: Optional[list[tuple[str, Optional[float], str]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 23: Revenue from non-exchange transactions (taxes, transfers, grants).
|
||||
Columns: Revenue type, Amount, Recognition (e.g. when received / when entitlement arises).
|
||||
"""
|
||||
default = [
|
||||
("Tax revenue", None, "When taxable event occurs"),
|
||||
("Grants and transfers received", None, "When entitlement is virtually certain"),
|
||||
("Other non-exchange revenue", None, "As per IPSAS 23"),
|
||||
]
|
||||
items = line_items or default
|
||||
df = pd.DataFrame(items, columns=["Revenue type", "Amount", "Recognition"])
|
||||
df.attrs["ipsas_23"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 29 / 41: Financial instrument measurement and ECL ---
|
||||
|
||||
|
||||
def financial_instruments_measurement_structure(
|
||||
line_items: Optional[list[tuple[str, str, Optional[float], Optional[float], Optional[float]]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 29/41: Classification, measurement basis, and ECL disclosure.
|
||||
Columns: Instrument, Measurement (AC/FVOCI/FVPL), Carrying amount, ECL, ECL stage.
|
||||
"""
|
||||
default = [
|
||||
("Financial assets at amortised cost", "AC", None, None, None),
|
||||
("Financial assets at FVOCI", "FVOCI", None, None, None),
|
||||
("Financial assets at FVPL", "FVPL", None, None, None),
|
||||
("Financial liabilities", "AC/FVPL", None, None, None),
|
||||
]
|
||||
items = line_items or default
|
||||
df = pd.DataFrame(
|
||||
items,
|
||||
columns=["Instrument", "Measurement", "Carrying amount", "ECL", "ECL stage"],
|
||||
)
|
||||
df.attrs["ipsas_29_41"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 38: Interests in other entities ---
|
||||
|
||||
|
||||
def interests_in_other_entities_structure(
|
||||
entities: Optional[list[tuple[str, str, Optional[float]]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 38: Disclosure of interests in other entities (subsidiaries, associates, JVs).
|
||||
Columns: Entity, Type (subsidiary/associate/JV), Carrying amount.
|
||||
"""
|
||||
default = [
|
||||
("Subsidiary 1", "Subsidiary", None),
|
||||
("Associate 1", "Associate", None),
|
||||
("Joint venture 1", "Joint venture", None),
|
||||
]
|
||||
items = entities or default
|
||||
df = pd.DataFrame(items, columns=["Entity", "Type", "Carrying amount"])
|
||||
df.attrs["ipsas_38"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 46: Measurement basis ---
|
||||
|
||||
|
||||
def measurement_basis_structure(
|
||||
items: Optional[list[tuple[str, str]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 46: Measurement basis (historical cost, fair value, etc.) by category.
|
||||
Columns: Category, Measurement basis.
|
||||
"""
|
||||
default = [
|
||||
("Financial assets – hold to collect", "Amortised cost"),
|
||||
("Financial assets – hold to collect and sell", "FVOCI"),
|
||||
("Financial assets – other", "FVPL"),
|
||||
("Financial liabilities", "Amortised cost / FVPL"),
|
||||
("Non-financial assets", "Historical cost / revaluation"),
|
||||
]
|
||||
items = items or default
|
||||
df = pd.DataFrame(items, columns=["Category", "Measurement basis"])
|
||||
df.attrs["ipsas_46"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- IPSAS 48: Transfer expenses ---
|
||||
|
||||
|
||||
def transfer_expenses_structure(
|
||||
line_items: Optional[list[tuple[str, Optional[float], str]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
IPSAS 48: Transfer expense classification (e.g. grants, subsidies, benefits).
|
||||
Columns: Transfer type, Amount, Classification.
|
||||
"""
|
||||
default = [
|
||||
("Grants and subsidies paid", None, "Transfer expense"),
|
||||
("Social benefits", None, "Transfer expense"),
|
||||
("Other transfers", None, "As per IPSAS 48"),
|
||||
]
|
||||
items = line_items or default
|
||||
df = pd.DataFrame(items, columns=["Transfer type", "Amount", "Classification"])
|
||||
df.attrs["ipsas_48"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- Cash-basis statement ---
|
||||
|
||||
|
||||
def cash_basis_statement_structure(
|
||||
line_items: Optional[list[tuple[str, Optional[float]]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
Cash-basis IPSAS: Statement of cash receipts and payments.
|
||||
Columns: Line item, Cash receipts, Cash payments, Net.
|
||||
"""
|
||||
default = [
|
||||
("Cash from operations", None, None, None),
|
||||
("Cash from investing", None, None, None),
|
||||
("Cash from financing", None, None, None),
|
||||
("Net change in cash", None, None, None),
|
||||
]
|
||||
items = line_items or default
|
||||
df = pd.DataFrame(items, columns=["Line item", "Cash receipts", "Cash payments", "Net"])
|
||||
df.attrs["cash_basis"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- RPG 2: Financial Statement Discussion and Analysis ---
|
||||
|
||||
|
||||
def fs_discussion_and_analysis_structure(
|
||||
sections: Optional[list[tuple[str, str]]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
RPG 2: Financial Statement Discussion and Analysis (narrative) – template.
|
||||
Columns: Section, Content (for user fill).
|
||||
"""
|
||||
default = [
|
||||
("Overview", "Summary of financial position and performance"),
|
||||
("Financial position", "Key balance sheet changes and ratios"),
|
||||
("Performance", "Revenue, expense, surplus/deficit analysis"),
|
||||
("Cash flows", "Liquidity and funding"),
|
||||
("Risks and uncertainties", "Key risks and sensitivities"),
|
||||
("Forward-looking information", "Plans and outlook"),
|
||||
]
|
||||
items = sections or default
|
||||
df = pd.DataFrame(items, columns=["Section", "Content"])
|
||||
df.attrs["rpg_2"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- Functional / presentation currency ---
|
||||
|
||||
|
||||
def functional_presentation_currency_structure(
|
||||
functional: str = "LCU",
|
||||
presentation: Optional[str] = None,
|
||||
fx_rates: Optional[dict[str, float]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
Multi-currency reporting: functional currency and presentation currency.
|
||||
Columns: Description, Value. If presentation differs, translation rates can be provided.
|
||||
"""
|
||||
presentation = presentation or functional
|
||||
rows = [
|
||||
("Functional currency", functional),
|
||||
("Presentation currency", presentation),
|
||||
("Translation method", "Closing rate for assets/liabilities" if presentation != functional else "N/A"),
|
||||
]
|
||||
if fx_rates:
|
||||
for k, v in fx_rates.items():
|
||||
rows.append((f"FX rate ({k})", v))
|
||||
df = pd.DataFrame(rows, columns=["Description", "Value"])
|
||||
df.attrs["functional_presentation_currency"] = True
|
||||
return df
|
||||
|
||||
|
||||
# --- Budget / appropriation model (internal representation for IPSAS 24) ---
|
||||
|
||||
|
||||
def budget_actual_from_state(
|
||||
state: FQBMState,
|
||||
budget: Optional[dict[str, float]] = None,
|
||||
line_items: Optional[list[str]] = None,
|
||||
) -> pd.DataFrame:
|
||||
"""
|
||||
Build budget vs actual from FQBM state. Actuals are derived from state aggregates;
|
||||
budget columns are filled from the budget dict (e.g. {"Total assets": 1000, "Total liabilities": 600}).
|
||||
Optional line_items: list of keys; default uses Total assets, Total liabilities, Net assets, etc.
|
||||
"""
|
||||
default_items = [
|
||||
"Total revenue",
|
||||
"Total expense",
|
||||
"Net surplus/(deficit)",
|
||||
"Total assets",
|
||||
"Total liabilities",
|
||||
"Net assets",
|
||||
]
|
||||
items = line_items or default_items
|
||||
L_cb_val = getattr(state, "L_cb", 0.0)
|
||||
actual_from_state = {
|
||||
"Total assets": state.B + L_cb_val + state.Loans,
|
||||
"Total liabilities": state.C + state.R + state.Deposits,
|
||||
"Net assets": state.E_cb + state.E_b,
|
||||
}
|
||||
budget = budget or {}
|
||||
rows = []
|
||||
for item in items:
|
||||
actual = actual_from_state.get(item) if item in actual_from_state else budget.get(item)
|
||||
orig = budget.get(f"{item} (original)") or budget.get(item)
|
||||
rows.append({
|
||||
"Line item": item,
|
||||
"Original budget": orig,
|
||||
"Final budget": budget.get(f"{item} (final)") or orig,
|
||||
"Actual": actual,
|
||||
"Variance": (actual - orig) if (actual is not None and orig is not None) else None,
|
||||
"Material (Y/N)": None,
|
||||
})
|
||||
df = pd.DataFrame(rows)
|
||||
df.attrs["ipsas_24_from_state"] = True
|
||||
return df
|
||||
|
||||
@@ -57,3 +57,39 @@ def four_quadrant_summary(state: FQBMState, L_cb: Optional[float] = None) -> dic
|
||||
"total_liabilities_cr": total_liab_cr,
|
||||
"identity_A_eq_L_plus_E": abs((total_assets_dr) - (total_liab_dr + total_liab_cr)) < 1e-6,
|
||||
}
|
||||
|
||||
|
||||
def cross_sector_consistency_check(state: FQBMState, L_cb: Optional[float] = None) -> dict:
|
||||
"""
|
||||
Check that four-quadrant matrix totals equal sectoral (CB + bank) sums.
|
||||
|
||||
Central bank: B + L_cb = R + C + E_cb. Commercial bank: Loans = Deposits + E_b.
|
||||
Consolidated assets (Dr) = B + L_cb + Loans; liabilities (Dr) = C + R + Deposits; equity (Cr) = E_cb + E_b.
|
||||
Returns dict with consistent (bool), cb_balance, bank_balance, matrix_totals, and message.
|
||||
"""
|
||||
L_cb_val = L_cb if L_cb is not None else getattr(state, "L_cb", 0.0)
|
||||
cb_assets = state.B + L_cb_val
|
||||
cb_liab_equity = state.R + state.C + state.E_cb
|
||||
cb_balance = abs(cb_assets - cb_liab_equity) < 1e-6
|
||||
bank_assets = state.Loans
|
||||
bank_liab_equity = state.Deposits + state.E_b
|
||||
bank_balance = abs(bank_assets - bank_liab_equity) < 1e-6
|
||||
total_assets_dr = state.B + L_cb_val + state.Loans
|
||||
total_liab_dr = state.C + state.R + state.Deposits
|
||||
total_liab_cr = state.E_cb + state.E_b
|
||||
matrix_identity = abs(total_assets_dr - (total_liab_dr + total_liab_cr)) < 1e-6
|
||||
consistent = cb_balance and bank_balance and matrix_identity
|
||||
return {
|
||||
"consistent": consistent,
|
||||
"cb_balance": cb_balance,
|
||||
"cb_assets": cb_assets,
|
||||
"cb_liab_equity": cb_liab_equity,
|
||||
"bank_balance": bank_balance,
|
||||
"bank_assets": bank_assets,
|
||||
"bank_liab_equity": bank_liab_equity,
|
||||
"matrix_identity": matrix_identity,
|
||||
"total_assets_dr": total_assets_dr,
|
||||
"total_liabilities_dr": total_liab_dr,
|
||||
"total_liabilities_cr": total_liab_cr,
|
||||
"message": "OK" if consistent else "Sector or matrix identity violation",
|
||||
}
|
||||
|
||||
@@ -160,3 +160,71 @@ def list_scenarios() -> list[str]:
|
||||
def get_scenario(name: str) -> Optional[ScenarioPreset]:
|
||||
"""Return preset by name, or None."""
|
||||
return _build_registry().get(name)
|
||||
|
||||
|
||||
def get_case_narrative(name: str) -> Optional[dict[str, Any]]:
|
||||
"""
|
||||
Part XI: Structured narrative and coded case outputs for a historical scenario.
|
||||
Returns dict with keys: name, description, narrative (paragraph), state_summary (dict),
|
||||
key_drivers (list), suggested_shocks (list), or None if scenario not found.
|
||||
"""
|
||||
preset = get_scenario(name)
|
||||
if preset is None:
|
||||
return None
|
||||
narratives = {
|
||||
"asia_1997": {
|
||||
"narrative": (
|
||||
"Asian Financial Crisis (1997): Fixed exchange rate regimes and heavy short-term "
|
||||
"foreign-currency debt left economies exposed to sudden stops. Reserve depletion "
|
||||
"and liability revaluation led to currency collapse and banking stress. The scenario "
|
||||
"calibrates low reserves (R), high sovereign spread, and deposit outflow / FX volatility shocks."
|
||||
),
|
||||
"key_drivers": ["FX regime", "Reserve adequacy", "Short-term external debt", "Sudden stop"],
|
||||
"suggested_shocks": ["deposit_outflow", "fx_vol", "spread_widening"],
|
||||
},
|
||||
"gfc_2008": {
|
||||
"narrative": (
|
||||
"Global Financial Crisis (2008): Shadow banking and repo-funded leverage amplified "
|
||||
"balance sheet expansion. MBS and structured product losses eroded bank capital; "
|
||||
"central bank QE and liquidity support stabilized the system. The scenario uses "
|
||||
"high bank leverage (Loans >> E_b), QE (d_B), and default/deposit outflow shocks."
|
||||
),
|
||||
"key_drivers": ["Leverage", "Repo and wholesale funding", "Capital erosion", "QE"],
|
||||
"suggested_shocks": ["default_rate", "deposit_outflow"],
|
||||
},
|
||||
"pandemic_2020": {
|
||||
"narrative": (
|
||||
"Pandemic (2020): Massive fiscal expansion and central bank balance sheet expansion "
|
||||
"($4T+ in major jurisdictions), swap lines, and deposit growth. The scenario reflects "
|
||||
"elevated reserves (R), large CB securities (B), and sovereign debt and growth shocks."
|
||||
),
|
||||
"key_drivers": ["Fiscal expansion", "CB balance sheet", "Swap lines", "Deposit growth"],
|
||||
"suggested_shocks": ["growth_differential", "sovereign stress"],
|
||||
},
|
||||
"rate_shock_2022": {
|
||||
"narrative": (
|
||||
"Rate shock (2022–23): Dollar strength, EM stress, and duration losses in advanced "
|
||||
"economies. The scenario sets a stronger dollar (S), higher sovereign spread, and "
|
||||
"FX volatility / spread-widening shocks for stress testing."
|
||||
),
|
||||
"key_drivers": ["Interest rate differential", "Dollar strength", "Duration", "EM stress"],
|
||||
"suggested_shocks": ["fx_vol", "spread_widening"],
|
||||
},
|
||||
}
|
||||
info = narratives.get(preset.name, {"narrative": preset.description, "key_drivers": [], "suggested_shocks": []})
|
||||
state = preset.state
|
||||
L_cb_val = getattr(state, "L_cb", 0.0)
|
||||
state_summary = {
|
||||
"B": state.B, "R": state.R, "C": state.C, "Loans": state.Loans, "Deposits": state.Deposits,
|
||||
"E_cb": state.E_cb, "E_b": state.E_b, "S": state.S, "Spread": state.Spread,
|
||||
"L_cb": L_cb_val,
|
||||
"total_assets": state.B + L_cb_val + state.Loans,
|
||||
}
|
||||
return {
|
||||
"name": preset.name,
|
||||
"description": preset.description,
|
||||
"narrative": info["narrative"],
|
||||
"state_summary": state_summary,
|
||||
"key_drivers": info["key_drivers"],
|
||||
"suggested_shocks": info.get("suggested_shocks", []),
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ def stress_tables(
|
||||
params: Optional[StressParams] = None,
|
||||
) -> dict:
|
||||
"""
|
||||
Compute liquidity stress (deposit run vs RCR) and capital shock table.
|
||||
Part XII: Compute liquidity stress (deposit run vs RCR) and capital shock table.
|
||||
Returns dict with 'liquidity_stress' and 'capital_stress' DataFrames.
|
||||
"""
|
||||
params = params or StressParams()
|
||||
|
||||
@@ -33,6 +33,7 @@ def dashboard_aggregate(
|
||||
"E_cb": state.E_cb, "E_b": state.E_b,
|
||||
"S": state.S, "Spread": state.Spread, "O": state.O,
|
||||
"L_cb": getattr(state, "L_cb", 0),
|
||||
"cbdc_liability": getattr(state, "cbdc_liability", 0),
|
||||
}
|
||||
out = {"state": snapshot, "ratios": ratios}
|
||||
# Part VII: shadow banking leverage ratio (bank)
|
||||
|
||||
@@ -14,6 +14,7 @@ Part XIV state: X = [B, R, C, Loans, Deposits, E_cb, E_b, S, K, Spread, O, L_cb]
|
||||
- Spread: sovereign spread
|
||||
- O: oil/commodity price index
|
||||
- L_cb: central bank loans (Part II identity: B + L_cb = R + C + E_cb)
|
||||
- cbdc_liability: central bank digital currency liability (Part IX; not in numeric vector for diff model)
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
@@ -39,7 +40,10 @@ class FQBMState:
|
||||
Spread: float = 0.0
|
||||
O: float = 1.0
|
||||
L_cb: float = 0.0
|
||||
cbdc_liability: float = 0.0 # Part IX: CBDC liability at central bank (not in to_vector for diff model)
|
||||
reporting_date: Optional[str] = field(default=None, compare=False)
|
||||
functional_currency: Optional[str] = field(default=None, compare=False) # e.g. "USD", "LCU"
|
||||
presentation_currency: Optional[str] = field(default=None, compare=False) # e.g. "USD"; if None, same as functional
|
||||
|
||||
def to_vector(self) -> list[float]:
|
||||
return [
|
||||
@@ -61,7 +65,8 @@ class FQBMState:
|
||||
return FQBMState(
|
||||
B=self.B, R=self.R, C=self.C, Loans=self.Loans, Deposits=self.Deposits,
|
||||
E_cb=self.E_cb, E_b=self.E_b, S=self.S, K=self.K, Spread=self.Spread, O=self.O,
|
||||
L_cb=self.L_cb, reporting_date=self.reporting_date,
|
||||
L_cb=self.L_cb, cbdc_liability=self.cbdc_liability, reporting_date=self.reporting_date,
|
||||
functional_currency=self.functional_currency, presentation_currency=self.presentation_currency,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ def run_workbook(
|
||||
scenario: Optional[str] = None,
|
||||
cbdc_params: Optional[Any] = None,
|
||||
ccp_params: Optional[Any] = None,
|
||||
shadow_params: Optional[Any] = None,
|
||||
) -> dict[str, Any]:
|
||||
"""
|
||||
Run full workbook: Sheet 1 → 2 → 4,5,6 → 3,7 → 8. Optionally export to Excel.
|
||||
@@ -68,7 +69,8 @@ def run_workbook(
|
||||
d = deposit_to_cbdc_shift(p.deposit_shift)
|
||||
state.Deposits += d["d_deposits"]
|
||||
state.R += d["d_reserves"]
|
||||
cbdc_result = {"d_deposits": d["d_deposits"], "d_reserves": d["d_reserves"], "cbdc_liability": d["d_cbdc_liability"]}
|
||||
state.cbdc_liability = getattr(state, "cbdc_liability", 0) + d["d_cbdc_liability"]
|
||||
cbdc_result = {"d_deposits": d["d_deposits"], "d_reserves": d["d_reserves"], "cbdc_liability": state.cbdc_liability}
|
||||
|
||||
stress = stress_tables(state, stress_params)
|
||||
if mc_runs > 0:
|
||||
@@ -78,6 +80,28 @@ def run_workbook(
|
||||
|
||||
dashboard = dashboard_aggregate(state, mc_runs=mc_runs, shock_spec=shock_spec)
|
||||
|
||||
# Part VII: optional repo multiplier (wired into workbook and dashboard)
|
||||
repo_result = None
|
||||
if shadow_params is not None:
|
||||
try:
|
||||
from fqbm.sheets.shadow_banking import repo_multiplier, ShadowBankingParams
|
||||
sp = shadow_params if isinstance(shadow_params, ShadowBankingParams) else None
|
||||
haircut = getattr(shadow_params, "haircut", 0.02)
|
||||
rounds = getattr(shadow_params, "repo_rounds", 3)
|
||||
collateral = state.B + state.Loans # proxy for collateral
|
||||
repo_result = repo_multiplier(collateral, haircut=haircut, rounds=rounds)
|
||||
dashboard["repo_multiplier"] = repo_result
|
||||
except Exception:
|
||||
pass
|
||||
if repo_result is None:
|
||||
try:
|
||||
from fqbm.sheets.shadow_banking import repo_multiplier
|
||||
collateral = state.B + state.Loans
|
||||
repo_result = repo_multiplier(collateral, haircut=0.02, rounds=3)
|
||||
dashboard["repo_multiplier"] = repo_result
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Part VIII: optional CCP metrics (margin identity check)
|
||||
ccp_result = None
|
||||
if ccp_params is not None:
|
||||
@@ -102,6 +126,7 @@ def run_workbook(
|
||||
"dashboard": dashboard,
|
||||
"cbdc": cbdc_result,
|
||||
"ccp": ccp_result,
|
||||
"repo_multiplier": repo_result,
|
||||
}
|
||||
|
||||
if export_path and export_path.endswith((".xlsx", ".xls")):
|
||||
|
||||
Reference in New Issue
Block a user