Does foreign money move the Brazilian market?
The "foreign flow" chart almost never runs alone in the news: it comes with the causal reading attached — "foreigners are back, the market goes up". This page measures what can be measured from a source that holds up, and publishes the whole result, including the part that undoes the reading.
Before the number: what is being measured
This is not B3's chart. That one is the non-resident buy/sell balance on the exchange floor. This is capital crossing the border, from the Central Bank's balance-of-payments foreign exchange records. They correlate and tell similar stories; they are not the same number.
Why we don't use B3's: as of 16/08/2026 that was seven paths tested without finding a stable, machine-readable public source. The last one was the Daily Bulletin (BDI) — a JavaScript-rendered application whose output is PDF, and whose own site warns that bulletins older than 20 days live only in the archive. A scraper on top of that would break without warning on every layout change, and the history would have to be rebuilt from PDFs. That is the opposite of what this database sets out to be.
The two series
| Flow | foreign portfolio investment in equities, monthly net, US$ millions — methodology |
| Market | total return of our market index, dividends reinvested — methodology |
The monthly return uses the last index point in each month and is computed in logs, which is what adds up over time and keeps a +50% followed by a −33% symmetric.
Why in two currencies
The flow is in dollars; the index, in reais. A year of +20% in reais with the dollar up 25% is a loss for whoever brought dollars in — and it is the dollar result that decides whether that capital stays. Publishing only the local-currency version would answer, with a correct number, a question that is not the foreign investor's.
The exchange rate is the daily USD sell rate (SGS series 1, identified by name in the Central Bank's open-data catalogue). We store the daily series and define month-end ourselves rather than using the ready-made monthly one: the return that matters is the index level on the last trading day of the month converted at that day's rate. A monthly average answers a different question, and the gap between the two shows up precisely in months of sharp turns — the months that matter most in a flow analysis.
The conversion happens on the level, before dividing, never on the finished return. The two routes give close but different numbers, and the wrong one goes unnoticed because it stays plausible. Invariant I-X07 locks this.
The result
Snapshot of 16/08/2026, with 122 months (2016-05 to 2026-06). The figures below are a frozen copy, for citation. The table that recomputes every month lives at /macro/fluxo-e-mercado, and that one governs — this page describes the METHOD. (One of our own comparison pages aged silently because it carried hand-typed numbers; the date above exists because of that.)
| Lag | Reading | In R$ (Pearson · Spearman) | In US$ (Pearson · Spearman) | Months |
|---|---|---|---|---|
| -3 | return → flow +3m | +0.02 · +0.03 | -0.01 · -0.03 | 119 |
| -2 | return → flow +2m | -0.07 · -0.11 | -0.09 · -0.13 | 120 |
| -1 | return → flow +1m | +0.14 · +0.10 | +0.20 · +0.16 | 121 |
| 0 | same month | +0.47 · +0.38 | +0.51 · +0.46 | 122 |
| +1 | flow → return +1m | +0.03 · -0.06 | +0.05 · -0.03 | 123 |
| +2 | flow → return +2m | -0.14 · -0.16 | -0.07 · -0.11 | 124 |
| +3 | flow → return +3m | -0.05 · -0.04 | +0.01 · +0.02 | 124 |
Pearson measures a linear relationship; Spearman measures the same thing over ranks, and it runs alongside on purpose: one panic month (March 2020) dominates Pearson by itself, and any divergence between the two is the information that the result rests on few months.
How to read it (valid while the order of magnitude holds)
Same month: +0.47 (R$) and +0.51 (US$). Strong — and almost mechanical. Money arrives while the market is rising, and the buying itself pushes prices. This number says nothing about prediction, which is exactly how the news chart is usually read.
Flow first, return next month: +0.03. Essentially zero — and on ranks it turns slightly negative. Across these 123 months, knowing that foreigners came in was worth nothing for the month ahead.
Return first, flow next month: +0.14 (R$) and +0.20 (US$). Larger than the other direction, in both currencies and both measures. What the data looks like is money following the market rather than leading it.
The asymmetry between −1 and +1 is this page's finding, and it inverts the headline: the foreign investor looks more like someone who arrives after the rally than someone who causes it.
Limits, plainly
- Correlation is not cause. Flow and returns both answer to US rates, commodity prices and political risk. A third thing moving both is the ordinary case, not the exception.
- One country, one regime, ~10 years. The market index starts in 2016 and that is what bounds the window. Enough to refuse a claim; not enough to establish a rule.
- We do not test statistical significance, and publish no p-value. On an autocorrelated time series the naive p-value is far too optimistic, and it would lend false authority to numbers that are already small here.
- This is a descriptive map, not a decision rule. Money that came in is not a buy signal.
Invariants
| id | what it locks |
|---|---|
| I-X05 | every FX quote is positive and inside a possible range |
| I-X06 | no FX jump above 15% between neighbouring trading days |
| I-X07 | return in US$ = return in R$ − change in the exchange rate |
| I-X08 | every published correlation carries its own n, and n is never small enough to be noise |
| I-X09 | the same-month correlation is the largest of all |
I-X09 is not a guess about the market: it is an assembly test. Flow and return in the same month share the cause, so lag zero has to dominate. If a distant lag comes out larger, the date alignment is off — a shifted month, a reference period read as the next one, an exchange rate matched to the wrong month. It is the same class of error that produced "Technology +2809% in a week" in the sector index, and that was only caught because someone asked whether the number was possible.
I-X08 exists because a correlation is the easiest number to publish without context: |0.5| over 8 months and |0.5| over 120 months are different results and print identically. If the sample shrinks, the row disappears from the page instead of shipping with an asterisk.