Skip to content

About

A Python-based country investment analysis framework that uses official central-bank and macroeconomic data to detect economic regimes, evaluate inflation, growth, interest rates and liquidity, and score assets such as stocks, bonds, gold, currencies and real estate across multiple countries.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Countries Investment Model

An explainable, confidence-aware macro investment framework for comparing 13 investable asset groups across 18 countries.

The model combines official-source observations, explicit provenance, country-aware regime detection, asset scoring, optional valuation inputs, and uncertainty-aware cross-country comparison. It produces terminal, JSON, and self-contained responsive HTML reports.

Research and decision support only. Outputs are model signals, not personalized financial advice or standalone buy/sell instructions.

What changed in version 2.1

The project is now a layered Python package instead of duplicated, thousand-line scripts. investment_dashboard.py is the single root launcher; country selection is handled by the provider registry.

Key improvements:

  • one shared domain model for observations, confidence, regimes, and asset scores;
  • one application pipeline for merge precedence and report generation;
  • isolated country adapters for official-source extraction;
  • strategy objects for generic and Iran-specific economic behavior;
  • shared HTTP retry, parsing, and strict JSON infrastructure;
  • separate terminal and HTML presentation layers;
  • editable HTML template and stylesheet with portable single-file output;
  • regression and architecture tests that protect numerical behavior and dependency direction.
  • 12 additional country providers using explicit central-bank policy settings and comparable World Bank macro observations;
  • instrument-level labels for named FX baskets, sovereign bonds, inflation-linked bonds, and local cash instruments;
  • silver, corporate credit, broad and energy commodities, Bitcoin, and Ether scoring;
  • implementation guidance, risk labels, valuation-input requirements, and evidence-aware assessment statuses for every asset.

See ARCHITECTURE.md for boundaries, design decisions, roles, and the extension contract.

Supported countries

Code Country Currency Primary monetary source
ir Iran IRR Central Bank of Iran
us United States USD Federal Reserve / FRED
cn China CNY People's Bank of China
de Germany EUR Deutsche Bundesbank / Eurosystem
jp Japan JPY Bank of Japan
gb United Kingdom GBP Bank of England
tr Turkey TRY Central Bank of the Republic of Türkiye / World Bank WDI
fr France EUR Banque de France / ECB / World Bank WDI
be Belgium EUR National Bank of Belgium / ECB / World Bank WDI
nl Netherlands EUR De Nederlandsche Bank / ECB / World Bank WDI
es Spain EUR Banco de España / ECB / World Bank WDI
it Italy EUR Banca d'Italia / ECB / World Bank WDI
az Azerbaijan AZN Central Bank of Azerbaijan / World Bank WDI
am Armenia AMD Central Bank of Armenia / World Bank WDI
fi Finland EUR Bank of Finland / ECB / World Bank WDI
se Sweden SEK Sveriges Riksbank / World Bank WDI
ca Canada CAD Bank of Canada / World Bank WDI
br Brazil BRL Banco Central do Brasil / World Bank WDI

The World Bank adapter is intentionally labeled live_official_auxiliary and receives a source quality penalty relative to a current national release. Its annual observations improve international comparability but do not pretend to be higher-frequency national data.

Analysis pipeline

Official source + manual input + seed fallback
                         |
                         v
             manual > live > seed merge
                         |
                         v
          provenance and staleness confidence
                         |
                         v
               normalized macro features
                         |
                         v
          regime detection and asset scoring
                         |
                         v
              optional market valuation
                         |
                         v
       terminal / JSON / responsive HTML report

The model asks which asset classes the current macro environment supports. A high macro score does not mean the asset is attractively priced. Without market inputs, its scope is explicitly reported as MACRO_ONLY.

Installation

Python 3.10 or newer is required.

py -m venv .venv
.venv\Scripts\activate
py -m pip install -e ".[test]"

Optional PDF support for some official publications:

py -m pip install -e ".[pdf]"

Optional Iran spreadsheet and browser extraction support:

py -m pip install -e ".[iran]"
py -m playwright install chromium

On Linux or macOS, use python3 and the platform's virtual-environment activation command.

Usage

Compare every country

py investment_dashboard.py

Equivalent package command:

py -m countries_investment_model

Run deterministically with seed and manual data only:

py investment_dashboard.py --no-web

Export both machine-readable and visual reports:

py investment_dashboard.py --no-web --output report.json --html dashboard.html

Analyze a subset:

py investment_dashboard.py --countries tr,fr,ca,br --no-web

List supported country keys:

py investment_dashboard.py --list-countries

Run one country

Use the same canonical command with one country code:

py investment_dashboard.py --countries ir
py investment_dashboard.py --countries us
py investment_dashboard.py --countries tr

The command accepts:

--no-web          Skip live retrieval
--no-seed         Disable seed fallbacks
--input-json      Supply manual macro observations
--market-json     Supply optional valuation inputs
--output          Write a complete JSON report
--json            Print JSON rather than terminal output
--debug           Print retrieval diagnostics
--http-timeout    Set the per-request timeout

Manual inputs

Simple values are accepted:

{
  "inflation_yoy": 2.7,
  "core_inflation": 2.9,
  "gdp_growth": 1.8,
  "policy_rate": 3.5,
  "money_growth": 4.7
}

Auditable metadata can be provided with a value:

{
  "inflation_yoy": {
    "value": 2.7,
    "unit": "percent",
    "period": "2026-07",
    "release_date": "2026-08-15",
    "frequency": "monthly",
    "source": "Manually verified official release",
    "source_url": "https://example.org/official-release",
    "base_confidence": 0.98
  }
}

For a comparison run, group overrides by country:

{
  "us": {"inflation_yoy": 2.7, "gdp_growth": 1.8},
  "jp": {"inflation_yoy": 2.1, "gdp_growth": 0.9}
}

Inputs must be valid JSON objects. Non-finite values such as NaN and Infinity are rejected.

Optional valuation inputs

Depending on the country strategy, supported inputs can include:

{
  "gold_premium_pct": 2.0,
  "equity_forward_pe": 17.0,
  "housing_price_to_annual_rent": 22.0,
  "government_bond_yield": 4.0,
  "inflation_linked_real_yield": 1.5,
  "corporate_bond_spread_bps": 145,
  "cash_rate": 3.5,
  "local_currency_reer_overvaluation_pct": 5.0,
  "silver_premium_pct": 4.0,
  "broad_commodity_roll_yield_pct": 1.5,
  "energy_commodity_roll_yield_pct": -2.0,
  "bitcoin_mvrv_zscore": 1.2,
  "ether_mvrv_zscore": 1.0
}

When at least one applicable valuation input exists, the affected output is labeled MACRO_PLUS_VALUATION and retains both the raw macro score and valuation adjustment. The valuation_evidence.supported_inputs list is country-specific: for example, generic gold uses gold_premium_pct, while Iran gold uses gold_coin_bubble_pct. Inputs must be finite JSON numbers; unknown fields are retained for auditability and reported as unused.

Asset universe

Every generic-country report evaluates:

  • gold and silver;
  • a named reserve-currency basket versus the country's local currency;
  • listed real estate and broad domestic equities;
  • nominal sovereign, inflation-linked sovereign, and investment-grade corporate bonds;
  • local Treasury bills or insured cash instruments;
  • diversified broad and energy commodities;
  • unleveraged spot Bitcoin and Ether exposure.

Iran uses the same expanded real, commodity, and digital-asset coverage but labels local fixed income explicitly as IRR sovereign sukuk or high-grade fixed-rate debt—never as a “fixed salary.” Each output includes an implementation route, major risks, and the market inputs needed to move beyond macro-only analysis. Digital assets are marked EXTREME risk and include custody, legal, sanctions, protocol, and drawdown warnings.

Confidence and provenance

Every observation retains:

  • value, unit, and frequency;
  • observation period;
  • release date, when the source supplies one;
  • retrieval date for live access;
  • source label and URL;
  • provenance type (live_*, official_auxiliary, manual, or seed);
  • base, staleness, source-quality, estimate, and effective confidence factors.

Release and retrieval dates are deliberately separate. Fetching an old observation today does not make that observation fresh.

Missing weighted indicators contribute zero to overall data confidence and are treated as neutral in scoring. They are never silently converted into observed zero-percent values.

Current source factors are transparent heuristics:

Provenance Factor
Live or manual 1.00
Official auxiliary 0.94
Seed fallback 0.65
Unknown 0.75
Forecast or projection multiplier 0.82

These factors are not calibrated probabilities. Historical backtesting is still required.

Output interpretation

Each country report contains:

model
regime
data_confidence
analysis_confidence
features
observations
market_inputs
assets_ranked
warnings

Each asset record also includes its precise country-specific label, instrument profile, valuation_evidence, and an assessment:

  • DUE_DILIGENCE_CANDIDATE: supportive adjusted score, adequate evidence confidence, and a supplied valuation input;
  • MACRO_WATCHLIST: macro backdrop is supportive, but valuation or other due diligence remains;
  • NEUTRAL / UNFAVORABLE_MACRO: no supportive model signal;
  • INSUFFICIENT_EVIDENCE: analysis confidence is too low for a directional status.

These statuses are research gates, not buy or sell instructions.

The comparison report adds quality coverage, source mix, global opportunities, and confidence- adjusted scores. The adjustment is:

50 + (raw score - 50) * analysis confidence

Low-confidence scores therefore move toward neutral. The shown range is a transparent heuristic sensitivity band, not a statistical confidence interval.

Repository structure

countries-investment-model/
├── countries_investment_model/
│   ├── domain/
│   │   ├── entities.py
│   │   ├── assets.py
│   │   ├── confidence.py
│   │   └── strategies.py
│   ├── application/
│   │   ├── provider.py
│   │   ├── assessment.py
│   │   ├── report_service.py
│   │   └── suite_service.py
│   ├── infrastructure/
│   │   ├── http.py
│   │   ├── parsing.py
│   │   └── json_io.py
│   ├── countries/
│   │   ├── registry.py
│   │   ├── expanded.py
│   │   ├── world_bank.py
│   │   └── <national source adapters>.py
│   └── presentation/
│       ├── country_cli.py
│       ├── dashboard_cli.py
│       ├── console.py
│       ├── html_report.py
│       ├── assets/report.css
│       └── templates/report.html
├── tests/
├── ARCHITECTURE.md
├── pyproject.toml
└── investment_dashboard.py

Development roles

The architecture was reviewed through these responsibilities:

  • macro methodology lead;
  • quantitative model engineer;
  • data integration engineer;
  • application architect;
  • product and visualization designer;
  • QA and reliability engineer;
  • documentation and release owner.

Detailed ownership and review evidence are defined in ARCHITECTURE.md.

Quality checks

Run the test suite:

py -B -m unittest discover -s tests -v

The tests cover:

  • confidence penalties and staleness semantics;
  • neutral handling of missing evidence;
  • all 18 offline country pipelines;
  • preserved numerical regression baselines;
  • the expanded asset universe, precise FX labels, risk profiles, and assessment gates;
  • annual-period staleness and official-auxiliary source penalties;
  • valuation scope changes;
  • cross-country score adjustment and output validation;
  • safe, complete, responsive HTML generation;
  • supported aliases;
  • package dependency direction;
  • one thin canonical root entry point and no duplicate country launchers.

Adding a country

Add a focused adapter under countries_investment_model/countries/, configure its official sources and seed observations, create a CountryProvider, and register it in registry.py. Reuse GenericMacroStrategy when its assumptions fit. Add a dedicated domain strategy when the country's monetary system requires genuinely different economic logic.

Every new adapter should include regression expectations for its regime, confidence, and leading asset score. Full instructions are in ARCHITECTURE.md.

Known limitations and roadmap

The current rules are economically interpretable but not yet historically calibrated. Priority next steps are:

  1. point-in-time historical datasets that preserve publication lags and revisions;
  2. country and asset return backtests without look-ahead bias;
  3. calibrated uncertainty and regime probabilities;
  4. fiscal, sovereign-risk, external-balance, labor, and credit features;
  5. standardized cross-country accessibility, liquidity, tax, and FX-risk adjustments;
  6. automated source-contract fixtures for scraper change detection;
  7. a hosted API and interactive dashboard after model validation.

License

MIT. See LICENSE.

About

A Python-based country investment analysis framework that uses official central-bank and macroeconomic data to detect economic regimes, evaluate inflation, growth, interest rates and liquidity, and score assets such as stocks, bonds, gold, currencies and real estate across multiple countries.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages