Emerging-Market Sovereign Debt Auction Monitor - Brazil DPMFi
Pricing
from $20.00 / 1,000 new auctions
Emerging-Market Sovereign Debt Auction Monitor - Brazil DPMFi
Delta-tracks Brazil's National Treasury domestic bond auction results (LTN, LFT, NTN-B, NTN-F) for new auctions, marginal-rate threshold breaches, and coverage-ratio anomalies. Sourced from the official Tesouro Transparente open-data portal. Financial-grade basis-point precision. Pay-per-event.
Pricing
from $20.00 / 1,000 new auctions
Rating
0.0
(0)
Developer
Stefano Seggio
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Emerging-Market Sovereign Debt Auction Monitor — Brazil DPMFi
Delta-tracks Brazil's National Treasury domestic bond auction results (LTN, LFT, NTN-B, NTN-F) for new auctions, marginal-rate threshold breaches, and coverage-ratio anomalies. Sourced from the official Tesouro Transparente open-data portal (ODbL licensed), a real CKAN instance — confirmed live through Sept 15, 2026, one day before this actor's build date. Part of Delta Registry, a pay-per-event regulatory/compliance data fleet.
Why this exists
Real, live-verified market context: emerging-market sovereign debt is a genuinely under-served Apify Store category (this session's own earlier market-intelligence research found only 2-3 solo trackers worldwide, all developed-market/Asia-focused, zero real LatAm coverage) — confirmed again at this actor's build date via a direct Store API search: zero real competitors exist for Brazil Treasury auction monitoring specifically.
Two real findings that reshaped this actor mid-build
This actor was corrected twice during its own construction, based on live testing against the real source — not shipped on the first design that looked reasonable on paper:
- The record identity key was wrong until live data proved it. A first version keyed each
auction by bond type + maturity + auction date + round. A from-scratch baseline run against
the real 2026 file showed 22 auctions misclassified as revisions of each other with no
explanation — investigation found a real 2026-03-16 LTN auction running a genuine "Extra
Compra" (extraordinary purchase) and a separate "Extra Venda" (extraordinary sale) for the
same bond, maturity, date, and round: two real, independent Treasury operations, not a
duplicate.
auctionTypeis now part of the key; verified against 2,850 real rows across three full years with zero collisions. - File-level caching was planned, tested, and dropped. This server (unlike Actor #2's UK
registry) returns HTTP 405 for
HEAD/Rangerequests, so a plan to at least cache the responseETagto skip parsing was tested directly — three consecutiveGETs of the byte-identical file returned three different ETags. It's not a content signal on this server. Rather than ship a cache that silently never hits, this actor always downloads and parses every selected year; the zero-cost guarantee lives at the per-record fingerprint level instead (see ARCHITECTURE.md).
Quickstart
cURL
curl "https://api.apify.com/v2/acts/stefano_seggio~emerging-market-sovereign-debt-auction-monitor/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"years": ["2026"],"bondTypeFilter": ["LTN", "NTN-F"],"yieldChangeThresholdBps": 10,"maxItems": 100}'
Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("stefano_seggio/emerging-market-sovereign-debt-auction-monitor").call(run_input={"years": ["2026"],"bondTypeFilter": ["LTN", "NTN-F"],"yieldChangeThresholdBps": 10,"maxItems": 100,})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(f"{item['event_type']}: {item['bond_type']} {item['benchmark']} - {item['accepted_rate_decimal']*100:.4f}% ({item['rate_change_bps']} bps)")
Node.js
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('stefano_seggio/emerging-market-sovereign-debt-auction-monitor').call({years: ['2026'],bondTypeFilter: ['LTN', 'NTN-F'],yieldChangeThresholdBps: 10,maxItems: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();items.forEach((item) => console.log(`${item.event_type}: ${item.bond_type} ${item.benchmark} - ${(item.accepted_rate_decimal * 100).toFixed(4)}% (${item.rate_change_bps} bps)`));
Pricing (pay-per-event)
| Event | Price | When it fires |
|---|---|---|
new-auction | $0.02 | An auction (bond type + auction type + maturity + date + round) never seen before appears, after this year's baseline is established. |
auction-result-revised | $0.01 | A previously-seen auction's published figures changed — a real, plausible government data correction. |
AUCTION_UNCHANGED / BASELINE_SNAPSHOT | Never billed | First-run baseline observations and confirmed-unchanged auctions are always free. |
Pricing above is live — this actor is published on Apify Store, and these are the exact,
currently-active Pay-Per-Event prices configured in the Apify Console's monetization settings, not
a proposal. apify-actor-start is retained (the first 5 seconds of platform compute is waived on
every run) and apify-default-dataset-item is removed (no automatic per-write dataset charge), so
the "unchanged auctions cost nothing" guarantee above is enforced at both the application layer
and the Console billing layer.
Input reference
See .actor/input_schema.json for the full, authoritative schema.
| Field | Type | Default | Notes |
|---|---|---|---|
years | array | ["2026"] | Registry years 2000-2027; every selected year is fully downloaded and parsed every run (see "Two real findings" above). |
bondTypeFilter | array | [] (all) | Real, currently-issued types: LTN, LFT, NTN-B, NTN-F. |
auctionTypeFilter | array | [] (all) | Real values from the source's own legend: Venda, Troca, Compra, Extra Compra, Extra Venda. |
yieldChangeThresholdBps | integer | 10 | Notification-only threshold on the marginal (accepted/cutoff) rate, in basis points, versus the bond's own last observed rate. |
coverageRatioFloor | number | 0.5 | Notification-only floor on the coverage ratio (see below). |
maxItems | integer | 50 | This actor's own per-run push cap. |
deltaStateName / resetState / onlyNew | — | fleet defaults | Same convention as the rest of this fleet. |
webhookUrl / slackWebhookUrl / teamsWebhookUrl | string | — | See Alerting below. |
A note on two metrics this README will not overclaim
- No ISIN/CUSIP. Brazilian domestic Treasury securities settle through Brazil's own SELIC system and are identified by bond type + maturity date, not an international security identifier — there is none in this source to extract.
coverage_ratiois not a bid-to-cover ratio. It'squantity_accepted / quantity_offered— a real, useful take-up signal, but this source does not publish total market demand (bids submitted, accepted or not), which a genuine bid-to-cover ratio requires. Labeled honestly as "coverage ratio" throughout this actor, not relabeled to match the term more buyers search for.
Output record
{"@type": "schema:FinancialProduct","event_id": "7a0c07a8...","event_type": "BASELINE_SNAPSHOT","record_id": "LFT-Venda-2032-03-01-2026-01-06-1.ª volta","auction_date": "2026-01-06","bond_type": "LFT","auction_type": "Venda","round": "1.ª volta","settlement_date": "2026-01-07","maturity_date": "2032-03-01","benchmark": "LFT 6 anos","quantity_offered": 750000,"quantity_accepted": 750000,"coverage_ratio": 1,"average_rate_decimal": 0.001065,"average_rate_bps": 11,"accepted_rate_decimal": 0.001065,"accepted_rate_bps": 11,"rate_change_bps": null,"total_amount_accepted": 13506269547.68,"total_amount_accepted_currency": "BRL","quantity_to_central_bank": 500000,"total_amount_to_central_bank": 9004179698.5,"yield_threshold_breached": false,"coverage_threshold_breached": false,"status_fingerprint": "3b5531174d1a...","content_fingerprint": "eb78037a5cd5...","is_new": true,"scraped_at": "2026-09-17T00:16:14.091Z"}
This is a real record from this actor's own live verification run against the actual 2026
auction file — not a fabricated example. Note quantity_to_central_bank: 500000 — a real,
observed market detail: a meaningful share of this auction's volume went directly to Brazil's
central bank rather than the primary dealer market.
event_id is a SHA-1 idempotency key over
(record_id, event_type, status_fingerprint, content_fingerprint)record_id is a 5-component compound key
(bondType-auctionType-maturityDate-auctionDate-round) — see Two real findings above for
why all five components are required.
Alerting
Both channels fire on the same real, quantitative trigger: a brand-new auction always alerts; a
revised auction alerts only when it actually breaches the yieldChangeThresholdBps or
coverageRatioFloor you configured — not merely because something about the record changed.
Slack
Create the webhook via a Slack App (Slack's own current, documented method — not the older
"legacy custom integrations" path). Paste the URL into slackWebhookUrl.
Microsoft Teams
Same real 2026 correction as Actor #2: Microsoft retired the classic Teams "Incoming Webhook"
connector in a May 2026 cutover. Use a Workflows webhook URL (Teams channel → Workflows →
"When a Teams webhook request is received") in teamsWebhookUrl. This actor posts a standard
Adaptive Card; a Power Automate flow's exact trigger schema is user-configurable per flow, so
adjust your flow's parsing step to this actor's payload if needed (documented in
src/notifier.ts).
Architecture
Full spec in ARCHITECTURE.md. Summary:
Actor input ──▶ src/main.ts (migrating/aborting-safe state flush,one KV store, two independently-managed record keys:fingerprints + benchmark rate history)│▼src/routes.ts: for each selected registry year│▼src/dataSource.ts: GET (no HEAD/Range support, no stableETag - always a full download), XLSX parse (real header-row content search, not a hardcoded index), manual UTC-safeExcel-serial-to-date conversion│▼src/quantEngine.ts: decimal rate -> basis points, coverageratio, rate-change bps, threshold breach detection│▼src/deltaEngine.ts: normalize -> canonicalize -> SHA-256-> classify (NEW_AUCTION / AUCTION_RESULT_REVISED /AUCTION_UNCHANGED / BASELINE_SNAPSHOT)│▼src/state.ts: Key-Value Store persistence (per-auctionfingerprints + per-year baseline flag under one record key,per-instrument rate history under a second, independentlyloaded/saved record key - one store, not two)│▼Apify Dataset (pay-per-event push)+ src/notifier.ts (webhook / Slack / Teams, fired onlyon a real threshold breach or a brand-new auction)
Testing
$npm test
112 real, passing tests across eight files:
- tests/quantEngine.test.ts — unit and property-based (via
fast-check) tests for basis-point conversion, coverage ratio, and threshold breach detection, including linearity, monotonicity, homogeneity, and antitonicity properties checked across generated input ranges, not just hand-picked examples. - tests/deltaEngine.test.ts — canonicalization, SHA-256 fingerprint
behavior, Excel-serial-to-date conversion against real observed values, and the full
classify/shouldDeliver state machine, including a regression test for the real
auctionTypecollision found live. - tests/dataSource.test.ts — real XLSX parsing (via an in-memory
workbook built with the same
xlsxlibrary, matching the source's confirmed live layout), HTTP retry/backoff/timeout (including a genuine network-level rejection, not just a bad-status response), 404 handling, non-retryable-4xx handling, and per-year file-extension resolution. - tests/notifier.test.ts — payload-shape and escaping tests for all three channels.
- tests/state.test.ts — Key-Value Store round-tripping for both
independently-managed keys (
STATEandBENCHMARK_RATES) within the shared state store. - tests/routes.test.ts — unit tests for the pure per-row logic.
- tests/integration.test.ts — a full multi-run auction lifecycle
simulation (baseline → unchanged → a real government data revision below threshold → a new
auction and a threshold-breaching revision in the same run) verifying every delta trigger fires
correctly, plus regression tests for maxItems-truncation safety, multi-year independence,
per-year failure isolation, the
eventChargeLimitReachedstop condition, delivery-filtered rows still being tracked in state, and the not-yet-published-year (404) branch. - tests/main.test.ts — shutdown-safety wiring: the
migrating/abortinghandlers actually flush both state stores when invoked, a flush failure never crashes the shutdown path, state is saved even whenrun()fails, andActor.exit()is correctly never called on that failure path.
CI/CD
.github/workflows/deploy.yml: every push and pull request runs
lint, type-check/build, and the full test suite; a push to main that passes all three then
deploys via the Apify CLI using an APIFY_TOKEN repository secret.
What this actor deliberately does not do
- No ISIN/CUSIP tracking — this source doesn't publish them (see above).
- No true bid-to-cover ratio — this source doesn't publish total market demand (see above).
- No forward-looking auction calendar — Brazil's real quarterly auction calendar is a PDF press release, not a structured feed; mixing unreliable PDF-scraping into a "zero-defect, financial-grade" actor would undermine the actual reliability guarantee. See ARCHITECTURE.md#3-three-mandate-assumptions-corrected-against-this-real-source.
- No file-level change-avoidance — this server's ETag isn't a real content signal (see above); every run fully downloads and parses every selected year.
- No classic Microsoft Teams connector support — retired, see Alerting above.
This actor is part of Delta Registry — pay-per-event regulatory & compliance data infrastructure built and operated by Stefano Seggio. For the rest of the fleet, see github.com/stefanoseggio.