Context
This issue is the next source-ingestion contract after the source-map hardening work in PR #79 / issue #78. The goal is to make the high-value datasets we agreed are economically important for a Brazil low-frequency relative-value model actually live, or to implement the best practical equivalent when a fully live official source is not yet deterministic.
This is not a broad data grab. Implement only the sources listed here. ANBIMA remains intentionally out of scope.
Read first
Before coding, read:
AGENTS.md
docs/PROJECT_PLAN.md
docs/ENGINEERING_GUIDELINES.md
docs/TIMING_AND_AVAILABILITY_POLICY.md
docs/B3_INGESTION_SETUP.md
docs/B3_P1_P2_SOURCE_MAP.md
docs/BCB_SOURCE_MAP.md
docs/CVM_SOURCE_MAP.md
configs/datasets/b3.yaml
configs/datasets/bcb.yaml
configs/datasets/cvm.yaml
- Existing raw/bronze/silver ingestion patterns under
src/bralpha/ingestion/*, src/bralpha/normalization/*, and src/bralpha/derived/*
This issue should be implemented after PR #79 is merged or rebased, because it relies on the source-map statuses and documentation introduced there.
Official documentation / source pages to use
Use official public source pages only:
B3
- Daily bulletin search / report source page:
https://www.b3.com.br/pt_br/market-data-e-indices/servicos-de-dados/market-data/historico/boletins-diarios/pesquisa-por-pregao/pesquisa-por-pregao/
- Historical quote data / COTAHIST documentation page:
https://www.b3.com.br/en_us/market-data-and-indices/data-services/market-data/historical-data/equities/historical-quote-data/
- Ibovespa official page:
https://www.b3.com.br/en_us/market-data-and-indices/indices/broad-indices/ibovespa.htm
- Ibovespa historic statistics page:
https://www.b3.com.br/en_us/market-data-and-indices/indices/broad-indices/indice-ibovespa-ibovespa-historic-statistics.htm
BCB
- Copom calendar page:
https://www.bcb.gov.br/controleinflacao/calendariocopom
- Copom interest-rate history page:
https://www.bcb.gov.br/controleinflacao/historicotaxasjuros
- BCB SGS API already configured in repo:
https://api.bcb.gov.br/dados/serie/bcdata.sgs.{series_id}/dados
- BCB Focus/PTAX OData already configured in repo.
CVM
- Daily fund reports:
https://dados.cvm.gov.br/dataset/fi-doc-inf_diario
- Fund registry:
https://dados.cvm.gov.br/dataset/fi-cad
- CDA fund portfolio holdings:
https://dados.cvm.gov.br/dataset/fi-doc-cda
- IPE metadata:
https://dados.cvm.gov.br/dataset/cia_aberta-doc-ipe
- FII monthly structured reports:
https://dados.cvm.gov.br/dataset/fii-doc-inf_mensal
- FIDC monthly structured reports:
https://dados.cvm.gov.br/dataset/fidc-doc-inf_mensal
Non-goals
Do not implement:
- ANBIMA.
- NLP / tone scoring / LLM text extraction.
- PDF OCR.
- Browser automation.
- Unofficial scraping when an official resource cannot be fixture-verified.
- Model training, labels, backtesting, or portfolio construction.
- Large raw-data commits.
- Any live-network tests.
Design principles
- Make sources live only when deterministic. Official page snapshots are fine, but a live downloader for a data table/file requires fixture-verified URL/resource discovery and schema tests.
- Fail closed. Missing links, changed schemas, non-matching resource names, or unknown file structures should fail clearly and/or write failed manifest records. Do not silently use an unrelated resource.
- Keep raw/bronze/silver layering. Downloaders write immutable raw files and manifests; parsers create bronze; normalizers create source-specific silver; derived/model features come later unless explicitly requested below as simple aggregate source panels.
- Point-in-time metadata is required. Preserve source URL, source page, resource name/id, first-seen/download timestamp, HTTP last-modified/resource modified metadata when available, and official reference dates.
- Prefer low-dimensional, model-usable aggregates from high-dimensional sources. CDA, IPE, FII, and FIDC can be huge. Implement raw/bronze auditability, but also source-specific aggregated silver panels when appropriate so the first model has usable inputs without exploding the feature universe.
A. B3 daily bulletin live downloader and selected report parsers
Motivation
B3 daily bulletin files are the cleanest route to important sources that are not replaceable by current live data:
b3_reference_rates: not just another DI curve; it can include B3 primitive risk factors, swap market rates, government-security reference prices, FX traded rates, and risk/scenario files.
b3_traded_securities: COTAHIST gives historical quotes, not a true point-in-time security/tradability master.
b3_indexes_historical_data: IND/WIN futures are tradable equity beta, but spot index data are required for futures basis and clean equity-state features.
- daily price/index updates: annual COTAHIST is fine for historical backfill, but daily bulletin
PriceReport / IndexReport can support current incremental updates.
Required implementation
Create a source-specific B3 daily bulletin discovery/downloader. Do not build a generic web-scraping framework.
Suggested modules:
src/bralpha/ingestion/b3/daily_bulletin.py
src/bralpha/parsing/b3_daily_bulletin.py
src/bralpha/normalization/b3_daily_bulletin.py or source-specific normalizers such as normalization/b3_index_report.py, normalization/b3_traded_securities.py, etc.
The downloader should:
- Fetch/store the official daily bulletin search page for a requested
ref_date.
- Discover report resources by exact configured report-section names.
- Store raw files separately by
dataset_id, report_section, and ref_date.
- Preserve in the manifest:
report_section
ref_date
- official source page URL
- discovered resource URL
- discovered resource file name
- content type
- HTTP last-modified if available
- download timestamp
- discovery mode
- Fail closed if the requested report section is absent or ambiguous.
- Avoid OCR and avoid PDF parsing. If a report is only PDF, record source-map metadata but do not parse it in this issue.
B3 report sections to target first
Implement live download/discovery and fixture-backed parsing for as many of these as deterministic. Prioritize in this order:
-
BVBG.087.01 IndexReport
- Purpose: make spot B3 index data live for Ibovespa and eventually other indices.
- Output target:
b3_index_daily or an equivalent index_daily silver table with ref_date, index_id, open/high/low/close or official index value fields if present, volume/liquidity fields if present, available_date, and source provenance.
- Do not treat IND/WIN futures as a replacement for spot index data after this is live.
-
BVBG.086.01 PriceReport and/or BVBG.186.01 Simplified Price Report - Equities
- Purpose: daily current update path for listed-market prices, complementing annual COTAHIST.
- Output target: either append-compatible with
b3_cotahist_yearly normalized market-daily schema or a separate b3_price_report_daily table with explicit source family.
- Must not silently mix with annual COTAHIST if fields differ.
-
BVBG.028.02 Instruments File, BVBG.029.02 Instruments File, and Tradable Security List
- Purpose: make
b3_traded_securities live.
- Output target: security/reference table with at least
ref_date, symbol, isin if present, market/type/group identifiers, tradability/status fields if present, and source provenance.
- Use this to improve universe hygiene; do not backfill security status prior to the file’s actual availability.
-
Primitive Risk Factors, Derivatives Market - Swap Market Rates, Derivatives Market - Economic Indicators, Securities Market - Government Securities Reference Prices, FX Market - Traded Rates, Opening Parameters and Contracted Transactions, and Scenario and risk-matrix files
- Purpose: make
b3_reference_rates and B3 official risk/reference controls live.
- Output target: one or more source-specific long tables, e.g.
b3_reference_rate_daily, b3_risk_factor_daily, b3_fx_reference_daily, with ref_date, source_report_section, instrument_or_curve_id, tenor_or_bucket, value_name, value, unit, available_date, and provenance.
- Keep these separate from settlement-derived DI curves. They are controls/reference data, not replacements.
B3 investor / foreign-flow data
Foreign/investor-flow data is required for the model and is not replaceable by COTAHIST total volume, CVM fund flows, or BCB balance-of-payments flows.
Create a dedicated B3 investor-flow discovery implementation path:
- Search/verify official B3 public pages or daily-bulletin reports for:
- foreign investor cash-equities flow / balance if available;
- investor participation by investor class;
- market-segment buy/sell/net values if available;
- derivatives participation/positioning if a stable public file exists.
- Do not invent endpoints.
- If only an official page is stable, store raw-page snapshots and leave parser disabled until a direct resource is fixture-verified.
- If a file/resource is deterministic, implement live download and a normalized long panel.
Suggested dataset IDs if deterministic official sources are found:
b3_equities_investor_participation
b3_foreign_investor_movement
b3_derivatives_investor_participation only if official structured data exists.
Minimum useful output schema:
ref_date
market_segment
investor_type or residency_type
buy_value if present
sell_value if present
net_flow if present or derivable from buy/sell
trading_value_share if present or derivable with same-source denominators
unit
available_date
source_report_section
source_version / provenance
If no deterministic official source is found in this issue, document that explicitly and create source-map-only dataset entries with official page URLs and a recommended manual official-source workflow. Do not mark it live without fixture-backed discovery.
B3 tests required
- Mocked official page fixture with multiple report links and exact report-section matching.
- Ambiguous/missing report link failures.
- Raw file manifest metadata includes discovered URL/resource/report section.
- Parser fixture for each report section promoted to live.
- Quality tests for primary keys and required columns.
- A test proving daily bulletin-derived
b3_reference_rates does not overwrite settlement-derived DI curves.
- A test proving current portfolio/security-master files are not backfilled before their
ref_date/availability.
B. BCB Copom structured calendar and decisions
Motivation
SGS Selic target gives the policy-rate time series, but it does not provide clean event metadata. The model needs event-time awareness around Copom meetings and decisions.
Required implementation
Implement structured Copom event tables from official BCB pages or, if the official pages are not machine-readable enough, from a project-maintained official-source manual YAML file.
Suggested datasets:
bcb_copom_calendar
bcb_copom_decisions
Acceptable implementation modes:
- Preferred: fixture-verified parser for official BCB calendar and rate-history pages or an official underlying endpoint discovered from those pages.
- Fallback: manual YAML under
configs/manual/bcb_copom_calendar.yaml and configs/manual/bcb_copom_decisions.yaml, with source URL, source access date, and explicit provenance for each year/decision.
Do not use NLP and do not parse PDFs.
Minimum output schemas
bcb_copom_calendar
meeting_id
meeting_number if available
meeting_year
meeting_start_date if available
decision_date
event_type
source_url
available_date
source_version
bcb_copom_decisions
decision_date
target_selic_percent_pa
previous_target_selic_percent_pa
target_change_bp
decision_direction = hike / cut / hold
meeting_id if joinable
source_url
available_date
source_version
Cross-check decisions against configured SGS selic_target where possible, but do not use the SGS series as the only event source.
Derived helper panel allowed in this issue
It is acceptable to add a simple source-specific event feature panel, not a full modeling feature set:
days_to_next_copom
days_since_last_copom
is_copom_decision_day
is_copom_window_t_minus_1, t_minus_2, t_minus_5, t_plus_1
Keep this in source/derived code, not model preprocessing.
BCB tests required
- Parser/manual YAML validation fixtures.
- No duplicate meeting IDs or decision dates.
- Decision target changes reconcile with consecutive decision rows.
- Event windows do not leak future decision outcomes; pre-decision days may know the scheduled decision date, not the decision value.
C. CVM CDA fund portfolio holdings
Motivation
CDA is the best free source for fund holdings/crowding. It is critical for Brazil RV because it can identify crowding into public bonds, private credit, fund quotas, swaps, foreign assets, and other asset blocks, especially when combined with CVM daily fund flows.
Official page: https://dados.cvm.gov.br/dataset/fi-doc-cda
Required implementation
Make cvm_fund_portfolio_cda live, but implement it carefully.
Suggested modules:
src/bralpha/ingestion/cvm/cda.py
src/bralpha/parsing/cvm_cda.py
src/bralpha/normalization/cvm_cda.py
src/bralpha/derived/cvm/cda_aggregates.py
Downloader requirements:
- Discover CDA resources from the official CVM dataset page / stable CVM data directory.
- Support current rolling monthly files and historical files if official deterministic paths exist.
- Preserve file period, resource name, resource URL, confidentiality indicator if inferable, download timestamp, and HTTP/resource metadata.
- Do not parse or expose confidential individual holdings before the official confidentiality restriction expires.
- Fail closed on unknown file naming/layout.
Parser requirements:
CVM CDA files have multiple asset blocks. Parse blocks separately and normalize to a common long shape where possible. At minimum, detect and preserve:
- public bonds / SELIC block;
- fund quota block;
- swaps block;
- coded assets block;
- deposits / financial-institution titles block;
- agro/private-credit titles block;
- foreign-investment block;
- uncoded assets block;
- confidential/consolidated block if present.
Do not force all fields into one lossy schema. It is acceptable to emit:
- raw block-specific bronze tables;
- a common normalized long table with core fields and
extra_json for block-specific fields.
Minimum normalized core fields:
ref_date
fund_id
fund_class_id if available or joinable later
asset_block
asset_id / isin / ticker / issuer_id where available
asset_description
quantity
market_value
cost_value if available
maturity_date if available
indexer if available
asset_type
confidentiality_status
available_date
source_file
source_version
Aggregate source-specific panel required:
Create practical model-ready source-specific aggregates without making a huge feature explosion:
- by
ref_date, fund_class, asset_block;
- by public bond indexer/maturity bucket when fields permit;
- by private-credit type when fields permit;
- by foreign-asset bucket when fields permit;
- shares of total portfolio value;
- rolling changes in aggregate exposure;
- count of funds reporting by bucket;
- concentration/crowding measures such as top-N holder share if tractable.
Join with cvm_fund_daily_reports and registry/class data when available, but do not require perfect joins for raw ingestion.
CVM CDA tests required
- Resource discovery fixture for monthly/current and historical file names.
- Parser fixtures for at least two asset blocks plus confidential/consolidated behavior.
- Primary key / duplicate tests.
- Confidentiality tests proving restricted details are not marked available before their official availability.
- Aggregate tests for fund-class/block exposure shares.
- Memory/streaming test or chunked parser design for large files.
D. CVM IPE metadata, FII reports, and FIDC reports
D1. CVM IPE metadata
Official page: https://dados.cvm.gov.br/dataset/cia_aberta-doc-ipe
Implement metadata-only ingestion. Do not parse document bodies.
Minimum output fields:
ref_date / delivery date
company_id
company_name
document_id
document_category
document_type
subject / title if structured metadata provides it
version
source_url
available_date
source_version
Useful aggregate/event panel:
- event counts by category and company/sector;
- flags for relevant facts, market announcements, public offerings, recovery/liquidation, debenture deeds/amendments, corporate events, insider/securities-held reports if categories are present;
- rolling 5/21/63 business-day event counts.
Keep all text-body/NLP work out of scope.
D2. FII monthly reports
Official page: https://dados.cvm.gov.br/dataset/fii-doc-inf_mensal
Implement structured monthly report ingestion if deterministic CSV/ZIP resources are available.
Use cases:
- real-estate / yield-product stress;
- FII NAV/equity value and income/distribution proxies if structured fields exist;
- fund-type exposure and market stress after joining with B3 listed FII tickers.
Minimum requirements:
- raw/bronze download and manifest;
- normalized monthly source-specific table;
- no PDF parsing;
- parser fixtures for official CSV layouts.
D3. FIDC monthly reports
Official page: https://dados.cvm.gov.br/dataset/fidc-doc-inf_mensal
Implement structured monthly report ingestion if deterministic CSV/ZIP resources are available.
Use cases:
- private-credit stress;
- FIDC NAV/equity/subordination/tranche metrics if present;
- delinquency/default/overdue metrics if present;
- growth/crowding in private credit.
Minimum requirements:
- raw/bronze download and manifest;
- normalized monthly source-specific table;
- no PDF parsing;
- parser fixtures for current and at least one historical layout if layout changed over time.
CVM IPE/FII/FIDC tests required
- Official resource discovery fixtures.
- Parser fixtures for each live resource.
- Metadata-only guarantee for IPE: no document-body parsing.
- Quality checks and duplicate primary-key tests.
- Source docs updated with known file-history/layout limitations.
Config/docs updates required
Update the relevant YAML configs:
configs/datasets/b3.yaml
configs/datasets/bcb.yaml
configs/datasets/cvm.yaml
configs/sources/b3.yaml if present or create only if it naturally fits existing source config patterns.
configs/sources/bcb.yaml if present or create only if natural.
configs/sources/cvm.yaml
Update docs:
docs/B3_P1_P2_SOURCE_MAP.md
docs/BCB_SOURCE_MAP.md
docs/CVM_SOURCE_MAP.md
docs/TIMING_AND_AVAILABILITY_POLICY.md only if you add source-specific availability rules.
Each live dataset must document:
- official source page/API URL;
- raw format;
- discovery mode;
- expected frequency;
- primary keys;
- known file-layout limitations;
- availability policy;
- whether it is model-usable immediately or reference-only.
CLI / pipeline integration
Add or extend pipeline entry points naturally. Do not overload b3_ingest.py with all unrelated sources unless existing style suggests it.
Expected additions may include:
src/bralpha/pipelines/b3_daily_bulletin_ingest.py
src/bralpha/pipelines/bcb_copom_ingest.py
src/bralpha/pipelines/cvm_cda_ingest.py
src/bralpha/pipelines/cvm_reports_ingest.py
Each pipeline should support:
--dataset
--start / --end when relevant
--report-section or equivalent where relevant
--repo-root
- no live network calls in tests.
Acceptance criteria
This issue is complete when:
- At least one B3 daily-bulletin report family is live with fixture-backed discovery and parsing. Preferred first target is
BVBG.087.01 IndexReport; if unavailable, implement the most deterministic of the prioritized sections and document why.
- B3 investor/foreign-flow official-source investigation is complete and either live with fixtures or explicitly source-map-only with official pages and a manual-source workflow. Do not leave it ambiguous.
b3_traded_securities is live if the Instruments/Tradable Security List reports can be fixture-verified; otherwise it remains explicitly source-map-only with documented blocker.
b3_reference_rates has at least one live fixture-backed B3 reference/risk/rate report if deterministic; otherwise the blocker is documented and settlement-derived DI remains the canonical curve.
- BCB Copom calendar and decisions produce structured source-specific tables, via official parser or manual official-source YAML.
- CVM CDA is live or, if the file layout/resource discovery proves too large for one PR, the PR must at least implement deterministic discovery and one fixture-backed parser for a representative CDA block, with the remaining block parser backlog documented.
- CVM IPE metadata is live metadata-only if deterministic official resources are available.
- FII and FIDC monthly report ingestion are either live with structured parser fixtures or explicitly source-map-only with exact official blocker documented.
- All new live datasets have raw manifests, bronze outputs where appropriate, silver/source-specific outputs where appropriate, and quality tests.
- No ANBIMA work is included.
- Full test suite passes with mocked fixtures and no live-network tests.
Suggested implementation order
- BCB Copom manual/parser tables. This is small and immediately model-useful.
- B3 daily-bulletin discovery framework plus IndexReport or Instruments File as first live report.
- B3 investor/foreign-flow source investigation and implementation if deterministic.
- CVM CDA discovery and parser foundation.
- CVM IPE metadata.
- FII/FIDC structured reports.
Follow-up issues expected
This issue may create follow-up issues for:
- Additional B3 daily-bulletin report parsers after the first deterministic parser lands.
- CDA block parsers not finished in the first CDA PR.
- Text/NLP over BCB/CVM documents, explicitly out of scope here.
- Model feature engineering from the newly live source-specific panels.
Context
This issue is the next source-ingestion contract after the source-map hardening work in PR #79 / issue #78. The goal is to make the high-value datasets we agreed are economically important for a Brazil low-frequency relative-value model actually live, or to implement the best practical equivalent when a fully live official source is not yet deterministic.
This is not a broad data grab. Implement only the sources listed here. ANBIMA remains intentionally out of scope.
Read first
Before coding, read:
AGENTS.mddocs/PROJECT_PLAN.mddocs/ENGINEERING_GUIDELINES.mddocs/TIMING_AND_AVAILABILITY_POLICY.mddocs/B3_INGESTION_SETUP.mddocs/B3_P1_P2_SOURCE_MAP.mddocs/BCB_SOURCE_MAP.mddocs/CVM_SOURCE_MAP.mdconfigs/datasets/b3.yamlconfigs/datasets/bcb.yamlconfigs/datasets/cvm.yamlsrc/bralpha/ingestion/*,src/bralpha/normalization/*, andsrc/bralpha/derived/*This issue should be implemented after PR #79 is merged or rebased, because it relies on the source-map statuses and documentation introduced there.
Official documentation / source pages to use
Use official public source pages only:
B3
https://www.b3.com.br/pt_br/market-data-e-indices/servicos-de-dados/market-data/historico/boletins-diarios/pesquisa-por-pregao/pesquisa-por-pregao/https://www.b3.com.br/en_us/market-data-and-indices/data-services/market-data/historical-data/equities/historical-quote-data/https://www.b3.com.br/en_us/market-data-and-indices/indices/broad-indices/ibovespa.htmhttps://www.b3.com.br/en_us/market-data-and-indices/indices/broad-indices/indice-ibovespa-ibovespa-historic-statistics.htmBCB
https://www.bcb.gov.br/controleinflacao/calendariocopomhttps://www.bcb.gov.br/controleinflacao/historicotaxasjuroshttps://api.bcb.gov.br/dados/serie/bcdata.sgs.{series_id}/dadosCVM
https://dados.cvm.gov.br/dataset/fi-doc-inf_diariohttps://dados.cvm.gov.br/dataset/fi-cadhttps://dados.cvm.gov.br/dataset/fi-doc-cdahttps://dados.cvm.gov.br/dataset/cia_aberta-doc-ipehttps://dados.cvm.gov.br/dataset/fii-doc-inf_mensalhttps://dados.cvm.gov.br/dataset/fidc-doc-inf_mensalNon-goals
Do not implement:
Design principles
A. B3 daily bulletin live downloader and selected report parsers
Motivation
B3 daily bulletin files are the cleanest route to important sources that are not replaceable by current live data:
b3_reference_rates: not just another DI curve; it can include B3 primitive risk factors, swap market rates, government-security reference prices, FX traded rates, and risk/scenario files.b3_traded_securities: COTAHIST gives historical quotes, not a true point-in-time security/tradability master.b3_indexes_historical_data: IND/WIN futures are tradable equity beta, but spot index data are required for futures basis and clean equity-state features.PriceReport/IndexReportcan support current incremental updates.Required implementation
Create a source-specific B3 daily bulletin discovery/downloader. Do not build a generic web-scraping framework.
Suggested modules:
src/bralpha/ingestion/b3/daily_bulletin.pysrc/bralpha/parsing/b3_daily_bulletin.pysrc/bralpha/normalization/b3_daily_bulletin.pyor source-specific normalizers such asnormalization/b3_index_report.py,normalization/b3_traded_securities.py, etc.The downloader should:
ref_date.dataset_id,report_section, andref_date.report_sectionref_dateB3 report sections to target first
Implement live download/discovery and fixture-backed parsing for as many of these as deterministic. Prioritize in this order:
BVBG.087.01 IndexReportb3_index_dailyor an equivalentindex_dailysilver table withref_date,index_id, open/high/low/close or official index value fields if present, volume/liquidity fields if present,available_date, and source provenance.BVBG.086.01 PriceReportand/orBVBG.186.01 Simplified Price Report - Equitiesb3_cotahist_yearlynormalized market-daily schema or a separateb3_price_report_dailytable with explicit source family.BVBG.028.02 Instruments File,BVBG.029.02 Instruments File, andTradable Security Listb3_traded_securitieslive.ref_date,symbol,isinif present, market/type/group identifiers, tradability/status fields if present, and source provenance.Primitive Risk Factors,Derivatives Market - Swap Market Rates,Derivatives Market - Economic Indicators,Securities Market - Government Securities Reference Prices,FX Market - Traded Rates, Opening Parameters and Contracted Transactions, andScenario and risk-matrix filesb3_reference_ratesand B3 official risk/reference controls live.b3_reference_rate_daily,b3_risk_factor_daily,b3_fx_reference_daily, withref_date,source_report_section,instrument_or_curve_id,tenor_or_bucket,value_name,value,unit,available_date, and provenance.B3 investor / foreign-flow data
Foreign/investor-flow data is required for the model and is not replaceable by COTAHIST total volume, CVM fund flows, or BCB balance-of-payments flows.
Create a dedicated B3 investor-flow discovery implementation path:
Suggested dataset IDs if deterministic official sources are found:
b3_equities_investor_participationb3_foreign_investor_movementb3_derivatives_investor_participationonly if official structured data exists.Minimum useful output schema:
ref_datemarket_segmentinvestor_typeorresidency_typebuy_valueif presentsell_valueif presentnet_flowif present or derivable from buy/selltrading_value_shareif present or derivable with same-source denominatorsunitavailable_datesource_report_sectionsource_version/ provenanceIf no deterministic official source is found in this issue, document that explicitly and create source-map-only dataset entries with official page URLs and a recommended manual official-source workflow. Do not mark it live without fixture-backed discovery.
B3 tests required
b3_reference_ratesdoes not overwrite settlement-derived DI curves.ref_date/availability.B. BCB Copom structured calendar and decisions
Motivation
SGS Selic target gives the policy-rate time series, but it does not provide clean event metadata. The model needs event-time awareness around Copom meetings and decisions.
Required implementation
Implement structured Copom event tables from official BCB pages or, if the official pages are not machine-readable enough, from a project-maintained official-source manual YAML file.
Suggested datasets:
bcb_copom_calendarbcb_copom_decisionsAcceptable implementation modes:
configs/manual/bcb_copom_calendar.yamlandconfigs/manual/bcb_copom_decisions.yaml, with source URL, source access date, and explicit provenance for each year/decision.Do not use NLP and do not parse PDFs.
Minimum output schemas
bcb_copom_calendarmeeting_idmeeting_numberif availablemeeting_yearmeeting_start_dateif availabledecision_dateevent_typesource_urlavailable_datesource_versionbcb_copom_decisionsdecision_datetarget_selic_percent_paprevious_target_selic_percent_patarget_change_bpdecision_direction= hike / cut / holdmeeting_idif joinablesource_urlavailable_datesource_versionCross-check decisions against configured SGS
selic_targetwhere possible, but do not use the SGS series as the only event source.Derived helper panel allowed in this issue
It is acceptable to add a simple source-specific event feature panel, not a full modeling feature set:
days_to_next_copomdays_since_last_copomis_copom_decision_dayis_copom_window_t_minus_1,t_minus_2,t_minus_5,t_plus_1Keep this in source/derived code, not model preprocessing.
BCB tests required
C. CVM CDA fund portfolio holdings
Motivation
CDA is the best free source for fund holdings/crowding. It is critical for Brazil RV because it can identify crowding into public bonds, private credit, fund quotas, swaps, foreign assets, and other asset blocks, especially when combined with CVM daily fund flows.
Official page:
https://dados.cvm.gov.br/dataset/fi-doc-cdaRequired implementation
Make
cvm_fund_portfolio_cdalive, but implement it carefully.Suggested modules:
src/bralpha/ingestion/cvm/cda.pysrc/bralpha/parsing/cvm_cda.pysrc/bralpha/normalization/cvm_cda.pysrc/bralpha/derived/cvm/cda_aggregates.pyDownloader requirements:
Parser requirements:
CVM CDA files have multiple asset blocks. Parse blocks separately and normalize to a common long shape where possible. At minimum, detect and preserve:
Do not force all fields into one lossy schema. It is acceptable to emit:
extra_jsonfor block-specific fields.Minimum normalized core fields:
ref_datefund_idfund_class_idif available or joinable laterasset_blockasset_id/isin/ticker/issuer_idwhere availableasset_descriptionquantitymarket_valuecost_valueif availablematurity_dateif availableindexerif availableasset_typeconfidentiality_statusavailable_datesource_filesource_versionAggregate source-specific panel required:
Create practical model-ready source-specific aggregates without making a huge feature explosion:
ref_date,fund_class,asset_block;Join with
cvm_fund_daily_reportsand registry/class data when available, but do not require perfect joins for raw ingestion.CVM CDA tests required
D. CVM IPE metadata, FII reports, and FIDC reports
D1. CVM IPE metadata
Official page:
https://dados.cvm.gov.br/dataset/cia_aberta-doc-ipeImplement metadata-only ingestion. Do not parse document bodies.
Minimum output fields:
ref_date/ delivery datecompany_idcompany_namedocument_iddocument_categorydocument_typesubject/ title if structured metadata provides itversionsource_urlavailable_datesource_versionUseful aggregate/event panel:
Keep all text-body/NLP work out of scope.
D2. FII monthly reports
Official page:
https://dados.cvm.gov.br/dataset/fii-doc-inf_mensalImplement structured monthly report ingestion if deterministic CSV/ZIP resources are available.
Use cases:
Minimum requirements:
D3. FIDC monthly reports
Official page:
https://dados.cvm.gov.br/dataset/fidc-doc-inf_mensalImplement structured monthly report ingestion if deterministic CSV/ZIP resources are available.
Use cases:
Minimum requirements:
CVM IPE/FII/FIDC tests required
Config/docs updates required
Update the relevant YAML configs:
configs/datasets/b3.yamlconfigs/datasets/bcb.yamlconfigs/datasets/cvm.yamlconfigs/sources/b3.yamlif present or create only if it naturally fits existing source config patterns.configs/sources/bcb.yamlif present or create only if natural.configs/sources/cvm.yamlUpdate docs:
docs/B3_P1_P2_SOURCE_MAP.mddocs/BCB_SOURCE_MAP.mddocs/CVM_SOURCE_MAP.mddocs/TIMING_AND_AVAILABILITY_POLICY.mdonly if you add source-specific availability rules.Each live dataset must document:
CLI / pipeline integration
Add or extend pipeline entry points naturally. Do not overload
b3_ingest.pywith all unrelated sources unless existing style suggests it.Expected additions may include:
src/bralpha/pipelines/b3_daily_bulletin_ingest.pysrc/bralpha/pipelines/bcb_copom_ingest.pysrc/bralpha/pipelines/cvm_cda_ingest.pysrc/bralpha/pipelines/cvm_reports_ingest.pyEach pipeline should support:
--dataset--start/--endwhen relevant--report-sectionor equivalent where relevant--repo-rootAcceptance criteria
This issue is complete when:
BVBG.087.01 IndexReport; if unavailable, implement the most deterministic of the prioritized sections and document why.b3_traded_securitiesis live if the Instruments/Tradable Security List reports can be fixture-verified; otherwise it remains explicitly source-map-only with documented blocker.b3_reference_rateshas at least one live fixture-backed B3 reference/risk/rate report if deterministic; otherwise the blocker is documented and settlement-derived DI remains the canonical curve.Suggested implementation order
Follow-up issues expected
This issue may create follow-up issues for: