pereirapthiago / cotacao-bcb
Pacote PHP 8.2 para download e parse de cotações de todas as moedas do Banco Central do Brasil
Requires
- php: ^8.2
- ext-curl: *
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.0
- squizlabs/php_codesniffer: ^3.7
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-03 17:39:46 UTC
README
Pacote PHP 8.2 para download e parse das cotações de fechamento de câmbio do Banco Central do Brasil (BCB).
Requisitos
- PHP 8.2+
ext-curl
Instalação
composer require pereirapthiago/cotacao-bcb
Uso básico
use Atlantic\CotacaoBcb\CotacaoBcb; $bcb = new CotacaoBcb(); $resultado = $bcb->buscar(new DateTimeImmutable('2026-04-17')); $resultado->data; // DateTimeImmutable — data efetiva da cotação $resultado->cotacoes; // array<string, CotacaoDto> indexado por sigla $resultado->cotacoes['USD']->taxaCompra; // float $resultado->cotacoes['USD']->taxaVenda; // float $resultado->cotacoes['EUR']->taxaCompra; // float
Regras de negócio
| Situação | Comportamento |
|---|---|
| Sábado ou domingo | Retorna a cotação da sexta-feira anterior |
| Data de hoje ou futura | Retorna a cotação do último dia útil anterior |
| Feriado bancário | Lança CotacaoNaoEncontradaException |
| Data anterior a 17/10/2014 | Lança CotacaoNaoEncontradaException sem consultar o BCB (não há arquivo diário); use buscarHistorico() |
| Falha de conexão / HTTP | Lança BcbIndisponivelException |
Cotações históricas (antes de 17/10/2014)
Os arquivos diários de fechamento só existem a partir de 17/10/2014. Para datas anteriores, buscarHistorico() usa a consulta histórica do PTAX, uma moeda por período:
$cotacoes = $bcb->buscarHistorico(860, new DateTimeImmutable('2010-01-11'), new DateTimeImmutable('2010-01-15')); $cotacoes[0]->data; // DateTimeImmutable — 2010-01-11 $cotacoes[0]->taxaCompra; // 0.038172
| Situação | Comportamento |
|---|---|
| Período com cotações | list<CotacaoDto> em ordem de data; feriados e fins de semana não aparecem |
| Período sem cotação | Lista vazia |
| Moeda sem série histórica (ex.: criada depois de 2014) | Lista vazia, sem consultar o BCB |
$de posterior a $ate |
Lança InvalidArgumentException |
| Falha de conexão / resposta inesperada | Lança BcbIndisponivelException |
Antes de 01/02/1999 (CotacaoBcb::INICIO_TAXA_UNICA) |
Pode haver duas cotações no mesmo dia (câmbio duplo, mercados livre e flutuante). O pacote devolve as duas; a escolha fica com quem consome |
O parâmetro é o código BCB da moeda (o mesmo de CotacaoDto::$codigo). O PTAX usa um identificador interno próprio (ChkMoeda); a conversão é feita pelo pacote em ValueObject/CodigoPtax.
Um dia só ($de == $ate) também funciona: o PTAX recusa esse período, então o pacote consulta até o dia seguinte e filtra.
Tratamento de exceções
use Atlantic\CotacaoBcb\Exception\CotacaoNaoEncontradaException; use Atlantic\CotacaoBcb\Exception\BcbIndisponivelException; try { $resultado = $bcb->buscar(new DateTimeImmutable('2026-01-01')); // Ano Novo } catch (CotacaoNaoEncontradaException $e) { // BCB retornou 404 — feriado ou data sem cotação disponível } catch (BcbIndisponivelException $e) { // Falha de conexão ou erro HTTP inesperado }
Estrutura do retorno
ResultadoCotacaoDto
| Propriedade | Tipo | Descrição |
|---|---|---|
data |
DateTimeImmutable |
Data efetiva da cotação (após ajuste de dia útil) |
cotacoes |
array<string, CotacaoDto> |
Todas as moedas, indexadas pela sigla ISO (ex: 'USD') |
CotacaoDto
| Propriedade | Tipo | Descrição |
|---|---|---|
sigla |
string |
Código ISO da moeda (ex: USD, EUR) |
codigo |
int |
Código numérico do BCB |
tipo |
string |
Tipo de paridade (A ou B) |
taxaCompra |
float |
Taxa de compra em BRL |
taxaVenda |
float |
Taxa de venda em BRL |
paridadeCompra |
float |
Paridade de compra |
paridadeVenda |
float |
Paridade de venda |
data |
DateTimeImmutable |
Data da cotação |
Injeção de dependência
O repositório HTTP pode ser substituído por uma implementação customizada (útil para testes):
use Atlantic\CotacaoBcb\Repository\CotacaoBcbRepositoryInterface; class RepositorioFake implements CotacaoBcbRepositoryInterface { public function buscarCsv(string $dataFormatada): string { return "17/04/2026;220;A;USD;4,96890000;4,96950000;1,00000000;1,00000000\n"; } } $bcb = new CotacaoBcb(new RepositorioFake()); // A consulta histórica tem a sua própria interface, PtaxHistoricoRepositoryInterface: $bcb = new CotacaoBcb(repositorioHistorico: new RepositorioHistoricoFake());
Estrutura do pacote
src/
├── CotacaoBcb.php → fachada principal (entry point)
├── Dto/
│ ├── CotacaoDto.php → cotação de uma moeda (readonly)
│ └── ResultadoCotacaoDto.php → coleção de cotações para uma data (readonly)
├── Factory/
│ └── CotacaoDtoFactory.php → cria CotacaoDto a partir de linha CSV
├── Repository/
│ ├── CotacaoBcbRepository.php → busca CSV diário via HTTP (cURL)
│ ├── CotacaoBcbRepositoryInterface.php → abstração do repositório
│ ├── PtaxHistoricoRepository.php → busca a consulta histórica do PTAX (cURL)
│ └── PtaxHistoricoRepositoryInterface.php
├── Service/
│ ├── BuscadorCotacaoService.php → orquestra lógica de negócio e datas
│ ├── BuscadorHistoricoService.php → cotações de uma moeda num período (PTAX)
│ └── ParserCsvService.php → faz parse do conteúdo CSV
├── ValueObject/
│ ├── DataCotacao.php → value object de data com regra de dia útil
│ └── CodigoPtax.php → código BCB => ChkMoeda do PTAX
└── Exception/
├── CotacaoNaoEncontradaException.php → 404 do BCB
└── BcbIndisponivelException.php → falha de conexão/HTTP
Ferramentas de qualidade
vendor/bin/phpunit # testes unitários vendor/bin/phpstan analyse # análise estática vendor/bin/phpcs # code style PSR-12
Fonte dos dados
- CSV de fechamento do BCB (a partir de 17/10/2014):
https://www4.bcb.gov.br/Download/fechamento/{YYYYMMDD}.csv - Consulta histórica do PTAX:
https://ptax.bcb.gov.br/ptax_internet/consultaBoletim.do?method=gerarCSVFechamentoMoedaNoPeriodo&ChkMoeda={id}&DATAINI={dd/mm/aaaa}&DATAFIM={dd/mm/aaaa}
Licença
MIT