# Latin America Economic Stress Monitor (`malmon/latam-economic-stress-monitor`) Actor

Rules-based stress monitor for 7 Latin American economies. FX momentum, inflation, and commodity terms-of-trade signals produce a transparent verdict: stable, watch, elevated, or stress. Covers Argentina, Brazil, Mexico, Colombia, Chile, Peru, Uruguay.

- **URL**: https://apify.com/malmon/latam-economic-stress-monitor.md
- **Developed by:** [Simon M](https://apify.com/malmon) (community)
- **Categories:** Agents, Developer tools, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / crisis scan

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## LatAm Economic Stress Monitor

A cross-signal economic stress monitor for **7 Latin American economies**. It combines FX, inflation, **export-weighted** commodity, **real-interest-rate**, and **official-reserve** data into a **transparent, rules-based stress verdict** plus a continuous **0–100 stress score** — and a **second gauge** for slow-moving **structural vulnerability** (sovereign debt, fiscal balance, banking-sector health, external-buffer adequacy, currency valuation, and political/institutional risk). Each record also carries **sovereign credit ratings** (S&P, Moody's, Fitch) with recent rating actions as an independent external benchmark. Never a black box: every verdict shows exactly which signals fired and why, and each run reports **what changed since the last one**.

> **Delayed data.** Verdicts are computed from delayed official sources (central-bank FX, national CPI, World Bank commodity prices, central-bank policy rates, World Bank reserves, World Bank debt & external-sector statistics), never real-time feeds.

---

### Modes

| Mode | Input | Output | Price |
|---|---|---|---|
| `crisis-scan` (default) | none | all 7 countries, ranked by stress | **$1.50** flat / run |
| `country-snapshot` | `country` (ISO alpha-2) | full profile + verdict for one country | **$0.50** / country |

---

### Notion integration (optional)

Each run can write a summary row per country to a Notion database using [Apify MCP Connectors](https://docs.apify.com/platform/integrations/mcp-connectors/use-in-actors) — no API key stored in the actor.

**Setup (once):**
1. In Apify Console → Settings → API & Integrations, create a Notion MCP connector and authenticate it with your Notion workspace.
2. Share the target database with your Notion integration.
3. Set the two optional input fields when running the actor:

| Input field | What to put |
|---|---|
| `notionConnector` | The connector ID shown in Apify Console (select from the picker) |
| `notionDatabaseId` | The 32-char hex ID from your Notion database URL (`notion.so/workspace/<id>?v=…`) |

Both fields are optional — omit them and the actor runs normally without touching Notion.

**What gets written:** one database row per country per run, mapped to these property types:

| Notion property | Type | Content |
|---|---|---|
| Country | title | Country name (e.g. "Brazil") |
| Verdict | select | `stable` / `watch` / `elevated` / `stress` / `insufficient-data` |
| Stress Score | number | Continuous 0–100 score (omitted when null) |
| Vulnerability Level | select | `low` / `moderate` / `high` / `unavailable` |
| Fired Signals | text | Comma-separated signal names, both gauges (e.g. `fxMomentum, debtDistress`) |
| Coverage Level | select | `full` / `partial` / `minimal` / `none` |
| Last Updated | date | Run timestamp (ISO 8601) |
| Actor Run URL | url | Direct link to the Apify run log |

A Notion write failure is non-fatal — the actor run completes normally and logs a warning.

---

### The verdict

**Gauge 1 — acute stress.** Five fast-moving signals, each `fired` / `not-fired` / `unavailable`:

| Signal | Fires when |
|---|---|
| **FX momentum** | currency depreciates >5% over 30 days, or >15% over 90 days |
| **Inflation level** | YoY CPI >20%, or >10% and accelerating month-on-month |
| **Commodity shock** | the country's primary-export commodity move, **weighted by how much the country depends on it**, implies a terms-of-trade hit of **≥5 percentage points of export value** (`price YoY% × commodity's share of the country's exports`). A global price fall is no longer the same signal for every producer — oil −40% is a −12pp hit for Colombia (oil ≈30% of exports) but negligible for Brazil (manufacturing dominates; oil ≈11%). *(Where no export-share figure exists, falls back to a volatility-tiered price threshold: 10% gold/platinum · 20% copper/soybeans/coffee · 25% crude/coal/wheat.)* |
| **Real interest rate** | policy rate − inflation YoY is **deeply negative (< −3pp)** — savings erosion / capital-flight / financial-repression risk. Available where both a central-bank policy rate and CPI are published (currently 5 of 7 — see coverage table). |
| **Reserve drawdown** | official FX reserves fall **>12.5% over 6 months, or >20% YoY** — the classic FX-crisis predictor (a central bank burning reserves to defend the currency / cover external gaps). Rising reserves never fire. |

Verdict from the count of **fired** signals: `0 → stable · 1 → watch · 2 → elevated · 3+ → stress`.

**Stress score (0–100).** Alongside the categorical verdict, each record carries a continuous, z-aware `stressScore` — a weighted blend of how far each signal is past its threshold *and* how unusual the move is versus the country's own history. It differentiates countries the coarse verdict lumps together, and it is the ranking key for `crisis-scan`. Weights: FX 0.28 · reserves 0.20 · inflation 0.22 · real rate 0.16 · commodity 0.14 (lowest — it's an exogenous global price; the two external-account signals FX + reserves carry the most). `stressScoreBasis` shows each signal's contribution.

**Gauge 2 — structural vulnerability.** Alongside the acute read, each record carries a *separate* **`vulnerabilityScore` (0–100)** and **`vulnerabilityLevel`** (`low`/`moderate`/`high`) — *how fragile the country is underneath*, distinct from *how much stress it's under right now*. Six slow-moving structural signals feed it:

| Structural signal | Fires when |
|---|---|
| **Debt distress** | external debt **>60% of GNI**, or debt service **>25% of exports**, or short-term debt **>100% of reserves** (Guidotti-Greenspan) |
| **External adequacy** | reserve buffer **<3 months of imports**, or a current-account deficit **wider than 8% of GDP** |
| **Fiscal solvency** | fiscal **deficit wider than 6% of GDP**, or government debt **>70% of GDP** — the flow that builds the debt overhang |
| **REER misalignment** | the real effective exchange rate sits **>15% above the country's own multi-year average** — an overvalued currency, a devaluation risk |
| **Financial stress** | bank **nonperforming loans >10%** of gross loans (banking asset quality), or a **credit-to-GDP boom** — private credit **>9 percentage points of GDP above its own recent trend** (the BIS / Schularick-Taylor early-warning indicator) |
| **Political stability** | World Bank **WGI** governance — **Political Stability & Absence of Violence** below **−1.0**, or **Rule of Law** below **−1.0** (estimate −2.5…+2.5; a low reading = elevated political / event risk, the trigger that turns latent vulnerability into crisis) |

These never touch the acute verdict or stressScore — a country can be calm today yet structurally fragile (or the reverse). The headline alarm is when **both gauges are hot**: the cross-gauge `acute_stress_x_high_vulnerability` compound flag fires when an `elevated`/`stress` verdict meets `high` vulnerability — the setup Argentina has repeatedly been in ahead of its debt crises. *(World Bank data is annual and CC-BY licensed; these are slow-moving ratios — external-debt/GNI moves only ~3–5pp a year — so a ~2-year-old vintage is representative. Each value carries its `dataYear`; anything older than ~3 years is dropped per metric.)*

**z-score.** Each signal reports a `zScore` — how unusual the current move is against that country's *own* history (a 4% depreciation means more for a managed peg like Argentina's exchange controls than a free float like Brazil's). It feeds the stress score and the reason text but, by design, never flips the categorical fire/not-fire (which stays on the same documented absolute rule everywhere).

**Trend & compound flags.** Each signal reports a `trend` (`deteriorating`/`improving`/`stable`); and `compoundFlags` surfaces reinforcing combinations — `twin_external_pressure` (FX + commodity), `fx_inflation_spiral`, `stagflation_risk` (inflation + negative real rate), `reserve_defence` (FX depreciating *while* reserves are drawn down — defending the currency by burning reserves), and the cross-gauge `acute_stress_x_high_vulnerability` (acute stress meeting high structural fragility). These are context; they don't change the fired count.

**What changed (`delta`).** Each record diffs against the previous run: `verdictChange`, `stressScoreDelta`, `firedCountDelta`, and per-signal status changes. `null` on the first ever run. The diff is only as meaningful as the interval between runs — **schedule the actor (daily or weekly)** so the comparison spans a real period; two runs minutes apart will show `sinceRunAgeDays: 0` and little movement. `sinceRunAgeDays` is always reported so you can see the window the delta covers, and the underlying official data refreshes on its own cadence (FX daily → CPI/commodity monthly), so a weekly schedule is a sensible default.

**Staleness:** each signal has a freshness cutoff (FX 7 days, inflation 90 days, commodity 45 days, reserves 180 days). Beyond it the signal is `unavailable` — stale data never drives a verdict. Reserves are an **end-of-period stock**, so the latest figure is aged from the **last day of its month**, the correct convention for stock data.

**Sovereign credit ratings (external benchmark).** Each record carries `creditRatings` — the current long-term foreign-currency grade and outlook from **S&P, Moody's, and Fitch**, sourced from countryeconomy.com. This is a **standalone external-validation field**; it does not feed `stressScore` or `vulnerabilityScore`. `recentActions` surfaces all rating changes and outlook shifts in the trailing **24 months** (newest first), each with a plain-language `sentence` (e.g. *"S&P downgraded to BB- (Stable) on 2026-04-08"*). Useful as an independent cross-check: a model `vulnerabilityLevel: high` with three investment-grade ratings, or a `stable` verdict with a recent downgrade, are both worth flagging.

**Honesty rules:**
- If fewer than 2 signals are computable for a country, the verdict is **`insufficient-data`** (and `stressScore` is `null`) — never a falsely reassuring "stable". "Stable" always means *we checked and nothing fired*, not *we couldn't look*.
- Every record carries `coverageLevel` (`full`/`partial`/`minimal`/`none`), a **`dataCoherence`** flag (`fresh` = computable signals within 45 days of each other · `mixed` = 45–90 days apart · `stale` = >90 days apart), and a per-signal breakdown with the numbers, the threshold, the trend, and a plain-language reason.

---

### Coverage (verified 2026-06-12)

The commodity signal is a **weighted export basket** (each country's main Pink-Sheet-priced exports × their share of total exports), so a global price move becomes a country-specific terms-of-trade impact. Export-share data from OEC 2023.

| Country | FX | Inflation | Commodity basket | Real rate | Reserves | Signals wired\* |
|---|---|---|---|---|---|---|
| Argentina (AR) | ✅ BCRA | ✅ INDEC | ✅ soy meal · soy oil · soybeans · corn · oil · beef | — (policy tool abolished) | ✅ WB | **4** |
| Brazil (BR) | ✅ BCB | ✅ IBGE SIDRA | ✅ soybeans · iron ore · oil · soy meal · sugar · beef | ✅ BCB Selic | ✅ WB | **5** |
| Chile (CL) | ✅ Mindicador | ✅ IMF | ✅ copper · lithium | ✅ BCCh TPM | ✅ WB | **5** |
| Colombia (CO) | ✅ TRM Colombia | ✅ IMF | ✅ crude oil · coal · coffee · gold | ✅ BanRep (BIS) | ✅ WB | **5** |
| Mexico (MX) | ✅ Banxico† | ✅ IMF | ✅ crude oil | ✅ Banxico (BIS) | ✅ WB | **5** |
| Peru (PE) | ✅ BCRP | ✅ IMF | ✅ copper · gold · zinc · lead · silver | ✅ BCRP (BIS) | ✅ WB | **5** |
| Uruguay (UY) | ⚠️ BCU (TCP-blocked) | ✅ IMF | ✅ beef · soybeans · wheat | ⚠️ BCU (TCP-blocked; 180d cache) | ✅ WB | **3–4** |

\* **"Signals wired" is the potential** — sources with a feed connected. The live `computableCount` per run is the truth. Treat this column as the ceiling, not a promise.

† **Mexico (MX)** requires a `BANXICO_TOKEN` actor secret (Banxico SIE API token). Set it once in Apify Console → Actor → Secrets. Without it, Mexico's FX signal is unavailable and the real-rate signal cannot be computed.

**Notes.** *Inflation:* Argentina (INDEC CPI) and Brazil (IBGE SIDRA IPCA) are covered by national databases; Chile, Colombia, Mexico, Peru and Uruguay are gap-filled from the IMF CPI dataflow (attributed; derived YoY/MoM). *Policy rates:* Brazil's Selic rate is fetched from BCB's open-data JSON API; Chile's TPM from mindicador.cl (which aggregates Banco Central de Chile data); Colombia, Mexico and Peru from the Bank for International Settlements WS_CBPOL dataflow (daily central-bank rates, BIS public use); Uruguay's BCU COPOM decision page is TCP-blocked from Apify datacenter IPs (see Known limitations). Argentina's BCRA formally abolished its Selic-equivalent policy tool under the Milei administration (2023–), so `realRate` is `unavailable` for AR. *Commodity:* Mexico's commodity signal is limited — manufacturing dominates its export mix and crude oil is only ~6% of exports; a global oil move has a smaller macro impact here than in Colombia or Peru. Chile's basket includes lithium (13% of exports, OEC 2023) but the BCCh BDE price fetcher is not yet implemented — Chile runs on copper alone currently. *Reserves:* **currently unavailable for all 7 countries** — the World Bank FI.RES.TOTL.CD annual series is ~528 days old (2024 year-end), well past the 180-day freshness cutoff. The signal is correctly `unavailable` rather than serving stale data. Monthly central-bank reserve data is the fix path; see Known limitations.

---

### Output (one record per country)

```jsonc
{
  "schemaVersion": 15,
  "country": "CO",
  "countryName": "Colombia",

  // ── Gauge 1 — acute stress (fast signals). CO has a full basket (oil/coal/coffee/gold)
  //    and BanRep policy rate via BIS WS_CBPOL. Inflation gap-filled from IMF CPI. ──
  "verdict": "watch",
  "stressScore": 31.2,
  "stressScoreBasis": [ { "signal": "fxMomentum", "weight": 0.28, "subScore": 0.7 }, { "signal": "inflationLevel", "weight": 0.22, "subScore": 0.1 }, { "signal": "commodityShock", "weight": 0.14, "subScore": 0.0 }, { "signal": "realRate", "weight": 0.16, "subScore": 0.0 }, { "signal": "reserveDrawdown", "weight": 0.20, "subScore": 0.0 } ],
  "coverageLevel": "full",
  "dataCoherence": "fresh",
  "firedCount": 1,
  "computableCount": 5,
  "asOf": "2026-06-05",
  "signals": {
    "fxMomentum":      { "status": "fired",     "reason": "USD/COP 30d +6.1% ...; +2.0σ vs own history", "value": 6.1, "threshold": ">5% over 30d, or >15% over 90d", "trend": "deteriorating", "zScore": 2.0 },
    "inflationLevel":  { "status": "not-fired",  "reason": "YoY 4.9%, MoM steady (2026-04)", "value": 4.9, "threshold": "YoY >20%, or >10% and MoM accelerating", "trend": "improving", "zScore": -0.8 },
    "commodityShock":  { "status": "not-fired",  "reason": "Export basket +0.5pp terms-of-trade impact [oil ..., coal ..., coffee ...]", "value": 0.5, "threshold": "basket terms-of-trade impact ≤ −5pp", "trend": "stable", "zScore": -0.2 },
    "realRate":        { "status": "not-fired",  "reason": "Real rate +6.35pp = policy 11.25% − inflation 4.9%", "value": 6.35, "threshold": "real rate < −3pp", "trend": "stable", "zScore": null },
    "reserveDrawdown": { "status": "not-fired",  "reason": "Reserves stable YoY +1.2% (World Bank 2024, annual fallback)", "value": 1.2, "threshold": "reserves down >20% YoY, or >12.5% over 6m", "trend": "stable", "zScore": null }
  },

  // ── Gauge 2 — structural vulnerability ──
  "vulnerabilityScore": 41.0,
  "vulnerabilityLevel": "moderate",
  "vulnerabilitySignals": {
    "debtDistress":       { "status": "not-fired", ... },
    "externalAdequacy":   { "status": "fired",     "reason": "CA deficit 3.8% of GDP (2024, annual)", ... },
    "fiscalSolvency":     { "status": "not-fired", ... },
    "reerMisalignment":   { "status": "not-fired", ... },
    "financialStress":    { "status": "not-fired", ... },
    "politicalStability": { "status": "not-fired", ... }
  },

  "compoundFlags": [],

  // ── Narrative patterns (schema 14). Empty when no pattern fires. ──
  "narrativeFlags": [],
  // Possible values: "masked_fragility" (acute calm + structural high vulnerability),
  // "compounding_risk" (both gauges elevated), "improving_from_extreme:<signal>"
  // (signal fires on absolute threshold but z < −1 vs own history — extreme but easing).

  // ── Company signals (schema 13): listed companies affected by an active commodity signal. ──
  "companySignals": [],
  // Empty when no commodity signal is active. Each entry: { name, ticker, exchange,
  // signalCount, commoditySignals[{ commodityCode, direction, exportImpactPct, ... }] }

  // ── Underlying delayed values ──
  "fx":        { "pair": "USD/COP", "latest": 4310, "asOf": "2026-06-05", "change30dPct": 6.1, ... },
  "inflation": { "period": "2026-04", "yoyPct": 4.9, "momPct": -0.1, "accelerating": false, ... },
  "commodity": { "period": "2026-04", "basketSharePct": 53, "exportImpactPct": 0.5, "components": [ ... ], ... },
  "realRate":  { "policyRatePct": 11.25, "inflationYoyPct": 4.9, "realRatePct": 6.35, "asOf": "2026-06-01", ... },
  "reserves":  { "period": "2024-12", "latestUsd": 58900000000, "changeYoyPct": 1.2, ... },
  "debtDistress": { "extDebtGniPct": 52.1, "debtServiceExportsPct": 18.3, "shortTermDebtReservesPct": 34.2, "dataYear": 2023, ... },
  "externalAdequacy": { "importCoverMonths": 4.2, "currentAccountGdpPct": -3.8, "dataYear": 2024, ... },
  "fiscalSolvency": { "fiscalBalanceGdpPct": -4.1, "govtDebtGdpPct": null, "dataYear": 2023, ... },
  "reerMisalignment": { "reerIndex": 98.4, "trailingAvg": 97.1, "overvaluationPct": 1.3, "latestYear": 2023, ... },
  "financialStress": { "nplPct": 4.1, "creditGdpPct": 51.2, "creditGdpGapPp": 2.1, "dataYear": 2023, ... },
  "politicalStability": { "politicalStabilityEst": -0.3, "ruleOfLawEst": -0.1, "dataYear": 2023, ... },

  // ── schema 15 — sovereign credit ratings (external benchmark, does not feed scores) ──
  "creditRatings": {
    "sp":     { "grade": "BB-",  "outlook": "Stable",   "asOf": "2026-04-08" },
    "moodys": { "grade": "Baa3", "outlook": "Stable",   "asOf": "2025-06-26" },
    "fitch":  { "grade": "BB+",  "outlook": "Stable",   "asOf": "2021-07-01" },
    "recentActions": [
      { "agency": "sp",     "date": "2026-04-08", "grade": "BB-",  "outlook": "Stable",   "change": "downgrade",      "sentence": "S&P downgraded to BB- (Stable) on 2026-04-08" },
      { "agency": "moodys", "date": "2025-06-26", "grade": "Baa3", "outlook": "Stable",   "change": "downgrade",      "sentence": "Moody's downgraded to Baa3 (Stable) on 2025-06-26" },
      { "agency": "sp",     "date": "2025-06-26", "grade": "BB",   "outlook": "Negative", "change": "downgrade",      "sentence": "S&P downgraded to BB (Negative) on 2025-06-26" },
      { "agency": "moodys", "date": "2024-06-27", "grade": "Baa2", "outlook": "Negative", "change": "outlook-change", "sentence": "Moody's changed to Baa2 (Negative) on 2024-06-27" }
    ],
    "dataAsOf": "2026-06-13",
    "source": { "name": "countryeconomy.com", "url": "https://countryeconomy.com/ratings/colombia" }
  },

  "delta":    { "sinceISO": "2026-06-05T...", "sinceRunAgeDays": 7, "verdictChange": null, "stressScoreDelta": 1.5, "firedCountDelta": 0, "signalChanges": [] },
  "warnings": []
}
````

`crisis-scan` returns the 7 records sorted by `stressScore`, most-stressed first (`insufficient-data` last).

***

### Known limitations / structural ceilings

- **Uruguay BCU TCP-blocked.** Banco Central del Uruguay's COPOM decision page is blocked at the TCP level from Apify datacenter IPs (the connection itself is refused, not an HTTP 403). This affects Uruguay's FX and policy-rate signals. A 180-day cache warms from the first run where the source is reachable (e.g. a local/residential run); the last-known rate is served within that window and disclosed in the rate's `licenseNote`. Beyond 180 days the signal goes `unavailable`. The BIS WS\_CBPOL dataflow does not cover Uruguay.
- **Argentina — no policy rate.** BCRA abolished its formal Selic-equivalent policy tool under the Milei administration (2023–); no single machine-readable rate exists. `realRate` is `unavailable` for AR; the signal is added when a stable equivalent emerges.
- **Mexico requires a Banxico API token.** Set `BANXICO_TOKEN` as an actor secret in Apify Console. Without it, Mexico's FX signal and real-rate signal are both unavailable. The BIS WS\_CBPOL policy-rate feed (used for Mexico's real-rate numerator) does **not** require the token — only the FX source (Banxico SIE) does.
- **⚠️ reserveDrawdown is currently unavailable for all 7 LatAm countries.** The World Bank FI.RES.TOTL.CD series (the fallback since the IMF SDMX IL dataflow returned empty responses as of 2026-06-12) publishes annual year-end values with a ~1.5 year lag. As of mid-2026, the latest vintage is 2024-12-31 — which is ~528 days old, well past the 180-day freshness cutoff. The signal is correctly marked `unavailable` rather than serving stale data as live. The fix requires fresher sources: LatAm central banks (BCB, BanRep, BCRP, Banxico, etc.) publish monthly international reserves on their own sites — wiring those is the next step for this signal. Until that work is done, `reserveDrawdown` is structurally dark across the region. `coverageLevel` reflects this honestly (`partial` rather than `full`).
- **Mexico's commodity signal is limited.** Manufacturing accounts for ~80% of Mexico's exports; crude oil is ~6%. A global oil shock has a smaller terms-of-trade impact here than in Colombia or Peru. The signal is wired but will fire only on extreme moves.
- **Chile's lithium component is currently null.** The Pink Sheet does not carry a lithium price series. The plan is to fetch BCCh BDE series F019.PPB.PRE.37.D ($/kg daily, LME-benchmarked), but that fetcher is not yet implemented. Chile's commodity signal runs on copper alone until it is.
- **Commodity dependence is a structural weight, not a live figure.** The export-share percentages (OEC 2023) are slow-moving structural ratios surfaced with their `dataYear`, not a real-time datum. The commodity *price* is live; the *weight* is structural.
- **One computable signal is never a verdict.** A country with only one usable signal is `insufficient-data` (and `stressScore: null`) regardless of whether that signal fired — a single axis is not enough to call macro stress.
- **`dataCoherence` and `compoundFlags` are context, not overrides.** They never change the categorical fired count or verdict.
- **Chile, Colombia, Mexico, Peru, Uruguay have no national CPI source** in this actor — inflation is gap-filled from the IMF CPI dataflow (attributed, derived YoY/MoM).

***

### Sources & licensing

This actor aggregates official sources, each attributed on every record:

- **FX** — national central banks: BCRA (AR), BCB (BR), Banco Central de Chile via mindicador.cl (CL), TRM Colombia / SFC (CO), Banxico (MX), BCRP (PE), BCU (UY). All open government data.
- **Inflation** — INDEC (AR), IBGE SIDRA IPCA (BR); IMF CPI dataflow for CL, CO, MX, PE, UY (attributed; derived YoY/MoM — not bulk redistribution).
- **Commodity** — World Bank Commodity Price Data (Pink Sheet), CC BY 4.0. Export-dependence weights from the Observatory of Economic Complexity (OEC 2023). Chile lithium (BCCh BDE) is defined in the basket but the fetcher is not yet implemented — Chile runs on copper alone currently.
- **Policy rates** — BCB SGS series 432 / Selic (BR), mindicador.cl TPM (CL), BIS WS\_CBPOL (CO, MX, PE — public use), BCU COPOM (UY — cache). AR not covered (tool abolished).
- **Official reserves** — World Bank FI.RES.TOTL.CD (total reserves including gold, annual, CC BY 4.0). Currently unavailable for signal computation (data is ~528 days old, beyond the 180-day cutoff). Next step: wire monthly central-bank reserve publications directly.
- **Structural vulnerability** — World Bank World Development Indicators (CC BY 4.0): external debt, debt service, import cover, current account, fiscal balance, government debt, NPL ratio, domestic credit, REER. World Bank WGI (CC BY 4.0): Political Stability & Absence of Violence, Rule of Law.

Data is **delayed** and presented with attribution. It is analysis built on public official data, not a redistribution product.

***

### Notes

- **Not investment advice.** A transparent screening tool; the signals and thresholds are documented judgements, not a forecast.
- **No residential proxy needed for most sources.** All LatAm central-bank FX endpoints are reachable from Apify datacenter IPs — except BCU Uruguay (TCP-blocked at the firewall level). A residential proxy would restore UY but is not required for the other 6 countries.
- **Schedule** weekly or monthly; the underlying data refreshes daily (FX) to monthly (CPI/commodity).
- Shared scraping/parsing logic is imported from the internal `fx-core` / `inflation-core` / `commodity-core` libraries (no actor-to-actor calls).

# Actor input Schema

## `mode` (type: `string`):

country-snapshot returns one country's economic profile and stress verdict (requires a country code). crisis-scan scans all covered countries and returns them ranked by stress level.

## `country` (type: `string`):

ISO 3166-1 alpha-2 code, required in country-snapshot mode. Covered: AR, BR, CL, CO, MX, PE, UY.

## `notionConnector` (type: `string`):

Connector ID from your authenticated Notion MCP connector. When provided together with notionDatabaseId, each run appends a summary page to your Notion database.

## `notionDatabaseId` (type: `string`):

ID of the Notion database to write run summaries into. Required when notionConnector is set.

## `backfillRunId` (type: `string`):

Apify run ID of a past crisis-scan run. When set, skips data collection and sends that run's saved snapshots to Notion. Requires notionConnector and notionDatabaseId.

## Actor input object example

```json
{
  "mode": "crisis-scan",
  "country": "BR"
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("malmon/latam-economic-stress-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("malmon/latam-economic-stress-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call malmon/latam-economic-stress-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=malmon/latam-economic-stress-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Latin America Economic Stress Monitor",
        "description": "Rules-based stress monitor for 7 Latin American economies. FX momentum, inflation, and commodity terms-of-trade signals produce a transparent verdict: stable, watch, elevated, or stress. Covers Argentina, Brazil, Mexico, Colombia, Chile, Peru, Uruguay.",
        "version": "0.3",
        "x-build-id": "PF9gaX51AhrCiGxRh"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/malmon~latam-economic-stress-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-malmon-latam-economic-stress-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/malmon~latam-economic-stress-monitor/runs": {
            "post": {
                "operationId": "runs-sync-malmon-latam-economic-stress-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/malmon~latam-economic-stress-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-malmon-latam-economic-stress-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "country-snapshot",
                            "crisis-scan"
                        ],
                        "type": "string",
                        "description": "country-snapshot returns one country's economic profile and stress verdict (requires a country code). crisis-scan scans all covered countries and returns them ranked by stress level.",
                        "default": "crisis-scan"
                    },
                    "country": {
                        "title": "Country (country-snapshot mode)",
                        "pattern": "^[A-Za-z]{2}$",
                        "type": "string",
                        "description": "ISO 3166-1 alpha-2 code, required in country-snapshot mode. Covered: AR, BR, CL, CO, MX, PE, UY."
                    },
                    "notionConnector": {
                        "title": "Notion connector (optional)",
                        "type": "string",
                        "description": "Connector ID from your authenticated Notion MCP connector. When provided together with notionDatabaseId, each run appends a summary page to your Notion database."
                    },
                    "notionDatabaseId": {
                        "title": "Notion database ID (optional)",
                        "pattern": "^[0-9a-f-]{32,36}$",
                        "type": "string",
                        "description": "ID of the Notion database to write run summaries into. Required when notionConnector is set."
                    },
                    "backfillRunId": {
                        "title": "Backfill from past run (optional)",
                        "type": "string",
                        "description": "Apify run ID of a past crisis-scan run. When set, skips data collection and sends that run's saved snapshots to Notion. Requires notionConnector and notionDatabaseId."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
