pyield 0.55.0__tar.gz → 0.55.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyield-0.55.0 → pyield-0.55.1}/PKG-INFO +12 -128
- {pyield-0.55.0 → pyield-0.55.1}/README.md +11 -127
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/titulos/_zero_td.py +12 -1
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/titulos/lft.py +8 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/titulos/ltn.py +12 -3
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/titulos/ntnb.py +10 -1
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/titulos/ntnbp.py +13 -3
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/titulos/ntnf.py +54 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyproject.toml +1 -1
- {pyield-0.55.0 → pyield-0.55.1}/pyproject.toml.orig +1 -1
- {pyield-0.55.0 → pyield-0.55.1}/LICENSE +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/_internal/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/_internal/br_numbers.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/_internal/cache.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/_internal/converters.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/_internal/data_cache.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/_internal/excel.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/_internal/numbers.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/_internal/retry.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/_internal/types.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/anbima/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/anbima/imaq.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/anbima/taxas.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/b3/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/b3/_contratos.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/b3/_validar_pregao.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/b3/boletim.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/b3/derivativos_intradia.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/b3/di_over.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/bc/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/bc/_olinda.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/bc/leiloes.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/bc/lft.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/bc/sgs.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/du/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/du/core.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/du/feriados/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/du/feriados/feriados_antigos_br.txt +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/du/feriados/feriados_br.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/du/feriados/feriados_novos_br.txt +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/futuro/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/futuro/contratos.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/futuro/di1.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/futuro/historico.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/futuro/intradia.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/fwd.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/interpolador.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/ipca/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/ipca/historico.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/ipca/projetado.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/py.typed +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/relogio.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/selic/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/selic/compromissada.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/selic/copom.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/selic/cpm.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/selic/probabilities.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/_taxas.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/benchmark.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/dealers.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/leiloes.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/rmd/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/rmd/_aba_1_3.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/rmd/_aba_2_1.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/rmd/_common.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/rmd/_download.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/secundario/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/secundario/_intradia.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/secundario/_mensal.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/titulos/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/titulos/_utils.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/titulos/ntnb1.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/titulos/ntnc.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/titulos/pre.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/vna/__init__.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/vna/_download.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/vna/_utils.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/vna/ntnb.py +0 -0
- {pyield-0.55.0 → pyield-0.55.1}/pyield/tpf/vna/ntnc.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyield
|
|
3
|
-
Version: 0.55.
|
|
3
|
+
Version: 0.55.1
|
|
4
4
|
Summary: Polars-powered toolkit for Brazilian fixed income analysis
|
|
5
5
|
Keywords: fixed-income,brazil,finance,analysis,bonds
|
|
6
6
|
Author: Carlos Carvalho
|
|
@@ -306,136 +306,20 @@ yd.ptax("25-12-2025") # -> nan
|
|
|
306
306
|
|
|
307
307
|
Documentação completa: [crdcj.github.io/PYield](https://crdcj.github.io/PYield/)
|
|
308
308
|
|
|
309
|
-
##
|
|
310
|
-
|
|
311
|
-
Quebras acumuladas por versão desde a v0.52.0.
|
|
312
|
-
|
|
313
|
-
### v0.55.0
|
|
314
|
-
|
|
315
|
-
- `yd.lft.vna(...)`, `yd.lft.cotacao(...)`, `yd.lft.pu(...)`, `yd.ltn.pu(...)`,
|
|
316
|
-
`yd.ntnb.vna(...)`, `yd.ntnb.vna_projetado(...)`, `yd.ntnb.cotacao(...)`,
|
|
317
|
-
`yd.ntnb.pu(...)`, `yd.ntnbp.cotacao(...)`, `yd.ntnbp.pu(...)`,
|
|
318
|
-
`yd.ntnb1.cotacao(...)`, `yd.ntnb1.pu(...)`, `yd.ntnc.vna(...)`,
|
|
319
|
-
`yd.ntnc.vna_projetado(...)`, `yd.ntnc.cotacao(...)`, `yd.ntnc.pu(...)` e
|
|
320
|
-
`yd.ntnf.pu(...)` retornam `Decimal`, preservando exatamente os valores com
|
|
321
|
-
seis casas definidos pela fonte ou pela metodologia. Entradas numéricas
|
|
322
|
-
aceitam `float` ou `Decimal`.
|
|
323
|
-
|
|
324
|
-
### v0.54.5
|
|
325
|
-
|
|
326
|
-
- `yd.ntnf.fluxos_caixa(...)` não aceita mais `ajustar_datas_pagamento`. Os
|
|
327
|
-
cronogramas públicos de NTN-B, NTN-B1, NTN-C e NTN-F usam datas contratuais,
|
|
328
|
-
sem ajuste para dias úteis. Para obter datas efetivas de processamento, use
|
|
329
|
-
`yd.du.deslocar(..., 0)`.
|
|
330
|
-
|
|
331
|
-
### v0.54.2
|
|
332
|
-
|
|
333
|
-
- `yd.tpf.taxas_historicas(...)` foi adicionado para consultas por período ou
|
|
334
|
-
de todo o histórico disponível de taxas indicativas.
|
|
335
|
-
- `yd.tpf.taxas(..., completo=True)` foi removido. `yd.tpf.taxas(...)` mantém
|
|
336
|
-
a visão estável de TPF; para acessar todas as colunas processadas da fonte,
|
|
337
|
-
use `pyield.anbima.taxas.buscar(data)` ou `pyield.anbima.taxas.ler(fonte)`.
|
|
338
|
-
|
|
339
|
-
### v0.54.0
|
|
340
|
-
|
|
341
|
-
- LFT, NTN-B, NTN-C e NTN-B1 passaram a expor **cotação e valores de fluxo em
|
|
342
|
-
base 1** (fator decimal), em vez de base 100 (escala percentual da ANBIMA).
|
|
343
|
-
A precisão numérica é preservada: o truncamento de 4 casas na escala ANBIMA
|
|
344
|
-
equivale a 6 casas em base 1.
|
|
345
|
-
|
|
346
|
-
```python
|
|
347
|
-
# Antes
|
|
348
|
-
yd.ntnb.cotacao("31-05-2024", "15-05-2035", 0.061490) # -> 99.3651
|
|
349
|
-
yd.lft.pu(15785.324502, 99.9291) # -> 15774.132706
|
|
350
|
-
|
|
351
|
-
# Agora
|
|
352
|
-
yd.ntnb.cotacao("31-05-2024", "15-05-2035", 0.061490) # -> Decimal('0.993651')
|
|
353
|
-
yd.lft.pu(15785.324502, 0.999291) # -> Decimal('15774.132706')
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
Também afeta `fluxos_caixa(...)` de NTN-B e NTN-C: o cupom semestral passou
|
|
357
|
-
de `2,956301` para `0,02956301` (NTN-C 6% a.a.) e o pagamento final passou
|
|
358
|
-
de `102,956301` para `1,02956301`. Chamadas a `pu(vna, cotacao)` que
|
|
359
|
-
dividiam por 100 (`cotacao / 100`) devem passar diretamente o fator em
|
|
360
|
-
base 1. O PU final permanece na mesma escala financeira.
|
|
361
|
-
- `yd.ntnbprinc` (e `yd.tpf.ntnbprinc`) foi renomeado para `yd.ntnbp` (e
|
|
362
|
-
`yd.tpf.ntnbp`), alinhando o namespace público aos nomes curtos usados no
|
|
363
|
-
restante da biblioteca (`ntnb`, `ntnb1`, `ntnbp`, `ntnc`, `ntnf`).
|
|
364
|
-
- `yd.tpf.premio_pre` foi renomeado para `yd.tpf.premios_pre`, coerente com o
|
|
365
|
-
retorno tabular (`DataFrame` com múltiplos prêmios).
|
|
366
|
-
- Entradas escalares de data inválidas agora **levantam `ValueError`** em
|
|
367
|
-
qualquer função pública que aceite `DateLike`. Antes, chamadas como
|
|
368
|
-
`yd.du.deslocar("31-02-2024", 1)` retornavam `None` silenciosamente. Em
|
|
369
|
-
operações vetorizadas o parse continua tolerante: elementos inválidos viram
|
|
370
|
-
`null` para preservar o pipeline Polars. Strings vazias ou só com espaços
|
|
371
|
-
continuam sendo tratadas como nulas.
|
|
372
|
-
|
|
373
|
-
### v0.53.0
|
|
374
|
-
|
|
375
|
-
- As funções secundárias de TPF migraram do `yd.tpf` para o namespace dedicado
|
|
376
|
-
`yd.tpf.secundario`:
|
|
377
|
-
|
|
378
|
-
- `yd.tpf.secundario_intradia(...)` → `yd.tpf.secundario.intradia(...)`
|
|
379
|
-
- `yd.tpf.secundario_mensal(...)` → `yd.tpf.secundario.mensal(...)`
|
|
380
|
-
|
|
381
|
-
### v0.52.0
|
|
382
|
-
|
|
383
|
-
- `Interpolador(...)` e `Interpolador.interpolar(...)` agora aceitam **apenas
|
|
384
|
-
inteiro escalar**. Chamadas com lista/`pl.Series` (`interp([30, 60])`),
|
|
385
|
-
antes suportadas via sobrecarga vetorial, agora levantam `TypeError`.
|
|
386
|
-
Substitua por `Interpolador.interpolar_expr` em pipelines Polars ou pela
|
|
387
|
-
função top-level `yd.interpolar(...)` (curva única ou multi-curva).
|
|
388
|
-
- `yd.interpolar(...)` passou a usar `extrapolar=False` como padrão, alinhado
|
|
389
|
-
com `Interpolador`. Antes era `True`. Chamadas que dependiam da
|
|
390
|
-
extrapolação implícita na ponta longa precisam passar `extrapolar=True`
|
|
391
|
-
explicitamente.
|
|
392
|
-
- As funções `dv01(...)` dos títulos públicos agora recebem `pu` como argumento
|
|
393
|
-
explícito. Chamadas antigas que passavam apenas data, vencimento e taxa, ou
|
|
394
|
-
que passavam VNA no caso da NTN-B, precisam ser atualizadas.
|
|
395
|
-
- `ntnf.taxas_zero(...)` mudou os nomes dos parâmetros de curva para o padrão
|
|
396
|
-
`vencimentos_*` / `taxas_*`. Chamadas por posição continuam com a mesma
|
|
397
|
-
ordem; chamadas por keyword precisam usar os novos nomes.
|
|
398
|
-
|
|
399
|
-
#### `Interpolador(...)` não aceita mais lista/Series
|
|
400
|
-
|
|
401
|
-
O ``__call__`` e o método ``interpolar`` da classe agora são estritamente
|
|
402
|
-
escalares. O caminho vetorial foi dividido em duas APIs com semântica clara:
|
|
309
|
+
## Compatibilidade e mudanças da API
|
|
403
310
|
|
|
404
|
-
|
|
405
|
-
# Antes (v0.51.x)
|
|
406
|
-
interp = yd.Interpolador(dus, taxas, metodo="flat_forward")
|
|
407
|
-
interp([15, 45, 75]) # pl.Series
|
|
408
|
-
|
|
409
|
-
# Agora, dentro de um pipeline Polars
|
|
410
|
-
df.with_columns(taxa=interp.interpolar_expr("du"))
|
|
411
|
-
|
|
412
|
-
# Agora, ad-hoc (curva única ou multi-curva)
|
|
413
|
-
yd.interpolar(
|
|
414
|
-
dus_alvo=pl.Series([15, 45, 75]),
|
|
415
|
-
dus_curva=pl.Series(dus),
|
|
416
|
-
taxas_curva=pl.Series(taxas),
|
|
417
|
-
)
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
#### `dv01(...)` agora recebe PU
|
|
421
|
-
|
|
422
|
-
As funções `dv01(...)` dos títulos públicos recebem o PU usado como base para o
|
|
423
|
-
cálculo, não mais o VNA ou apenas a taxa. Se necessário, calcule o PU antes:
|
|
424
|
-
|
|
425
|
-
```python
|
|
426
|
-
pu = yd.ntnb.pu(vna, yd.ntnb.cotacao(data, vencimento, taxa))
|
|
427
|
-
dv01 = yd.ntnb.dv01(data, vencimento, taxa, pu)
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
#### `ntnf.taxas_zero(...)` usa nomes por conceito
|
|
311
|
+
A versão atual é `v0.55.0`. As mudanças abaixo exigem atualização de código:
|
|
431
312
|
|
|
432
|
-
|
|
433
|
-
|
|
313
|
+
| Versão | Mudança principal |
|
|
314
|
+
|---|---|
|
|
315
|
+
| `v0.55.0` | Funções de PU, cotação e VNA dos títulos passaram a retornar `Decimal` com seis casas. Entradas numéricas aceitam `float` ou `Decimal`. |
|
|
316
|
+
| `v0.54.5` | `fluxos_caixa` não aceita mais `ajustar_datas_pagamento`; os cronogramas usam datas contratuais. |
|
|
317
|
+
| `v0.54.2` | `taxas_historicas` foi adicionada e `tpf.taxas(completo=True)` foi removida. |
|
|
318
|
+
| `v0.54.0` | Cotações e fluxos de LFT, NTN-B, NTN-C e NTN-B1 passaram de base 100 para base 1; `ntnbprinc` virou `ntnbp`; `premio_pre` virou `premios_pre`; datas escalares inválidas passaram a levantar `ValueError`. |
|
|
319
|
+
| `v0.53.0` | O mercado secundário de TPF passou para `yd.tpf.secundario.intradia` e `yd.tpf.secundario.mensal`. |
|
|
320
|
+
| `v0.52.0` | `Interpolador` passou a ser escalar; use `interpolar_expr` ou `yd.interpolar` para vetores. `dv01` passou a exigir `pu` e `ntnf.taxas_zero` adotou nomes `vencimentos_*` / `taxas_*`. |
|
|
434
321
|
|
|
435
|
-
|
|
436
|
-
- `ltn_taxas` → `taxas_ltn`
|
|
437
|
-
- `ntnf_vencimentos` → `vencimentos_ntnf`
|
|
438
|
-
- `ntnf_taxas` → `taxas_ntnf`
|
|
322
|
+
O histórico completo está disponível nas [releases do GitHub](https://github.com/crdcj/PYield/releases).
|
|
439
323
|
|
|
440
324
|
## Testes
|
|
441
325
|
|
|
@@ -281,136 +281,20 @@ yd.ptax("25-12-2025") # -> nan
|
|
|
281
281
|
|
|
282
282
|
Documentação completa: [crdcj.github.io/PYield](https://crdcj.github.io/PYield/)
|
|
283
283
|
|
|
284
|
-
##
|
|
285
|
-
|
|
286
|
-
Quebras acumuladas por versão desde a v0.52.0.
|
|
287
|
-
|
|
288
|
-
### v0.55.0
|
|
289
|
-
|
|
290
|
-
- `yd.lft.vna(...)`, `yd.lft.cotacao(...)`, `yd.lft.pu(...)`, `yd.ltn.pu(...)`,
|
|
291
|
-
`yd.ntnb.vna(...)`, `yd.ntnb.vna_projetado(...)`, `yd.ntnb.cotacao(...)`,
|
|
292
|
-
`yd.ntnb.pu(...)`, `yd.ntnbp.cotacao(...)`, `yd.ntnbp.pu(...)`,
|
|
293
|
-
`yd.ntnb1.cotacao(...)`, `yd.ntnb1.pu(...)`, `yd.ntnc.vna(...)`,
|
|
294
|
-
`yd.ntnc.vna_projetado(...)`, `yd.ntnc.cotacao(...)`, `yd.ntnc.pu(...)` e
|
|
295
|
-
`yd.ntnf.pu(...)` retornam `Decimal`, preservando exatamente os valores com
|
|
296
|
-
seis casas definidos pela fonte ou pela metodologia. Entradas numéricas
|
|
297
|
-
aceitam `float` ou `Decimal`.
|
|
298
|
-
|
|
299
|
-
### v0.54.5
|
|
300
|
-
|
|
301
|
-
- `yd.ntnf.fluxos_caixa(...)` não aceita mais `ajustar_datas_pagamento`. Os
|
|
302
|
-
cronogramas públicos de NTN-B, NTN-B1, NTN-C e NTN-F usam datas contratuais,
|
|
303
|
-
sem ajuste para dias úteis. Para obter datas efetivas de processamento, use
|
|
304
|
-
`yd.du.deslocar(..., 0)`.
|
|
305
|
-
|
|
306
|
-
### v0.54.2
|
|
307
|
-
|
|
308
|
-
- `yd.tpf.taxas_historicas(...)` foi adicionado para consultas por período ou
|
|
309
|
-
de todo o histórico disponível de taxas indicativas.
|
|
310
|
-
- `yd.tpf.taxas(..., completo=True)` foi removido. `yd.tpf.taxas(...)` mantém
|
|
311
|
-
a visão estável de TPF; para acessar todas as colunas processadas da fonte,
|
|
312
|
-
use `pyield.anbima.taxas.buscar(data)` ou `pyield.anbima.taxas.ler(fonte)`.
|
|
313
|
-
|
|
314
|
-
### v0.54.0
|
|
315
|
-
|
|
316
|
-
- LFT, NTN-B, NTN-C e NTN-B1 passaram a expor **cotação e valores de fluxo em
|
|
317
|
-
base 1** (fator decimal), em vez de base 100 (escala percentual da ANBIMA).
|
|
318
|
-
A precisão numérica é preservada: o truncamento de 4 casas na escala ANBIMA
|
|
319
|
-
equivale a 6 casas em base 1.
|
|
320
|
-
|
|
321
|
-
```python
|
|
322
|
-
# Antes
|
|
323
|
-
yd.ntnb.cotacao("31-05-2024", "15-05-2035", 0.061490) # -> 99.3651
|
|
324
|
-
yd.lft.pu(15785.324502, 99.9291) # -> 15774.132706
|
|
325
|
-
|
|
326
|
-
# Agora
|
|
327
|
-
yd.ntnb.cotacao("31-05-2024", "15-05-2035", 0.061490) # -> Decimal('0.993651')
|
|
328
|
-
yd.lft.pu(15785.324502, 0.999291) # -> Decimal('15774.132706')
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
Também afeta `fluxos_caixa(...)` de NTN-B e NTN-C: o cupom semestral passou
|
|
332
|
-
de `2,956301` para `0,02956301` (NTN-C 6% a.a.) e o pagamento final passou
|
|
333
|
-
de `102,956301` para `1,02956301`. Chamadas a `pu(vna, cotacao)` que
|
|
334
|
-
dividiam por 100 (`cotacao / 100`) devem passar diretamente o fator em
|
|
335
|
-
base 1. O PU final permanece na mesma escala financeira.
|
|
336
|
-
- `yd.ntnbprinc` (e `yd.tpf.ntnbprinc`) foi renomeado para `yd.ntnbp` (e
|
|
337
|
-
`yd.tpf.ntnbp`), alinhando o namespace público aos nomes curtos usados no
|
|
338
|
-
restante da biblioteca (`ntnb`, `ntnb1`, `ntnbp`, `ntnc`, `ntnf`).
|
|
339
|
-
- `yd.tpf.premio_pre` foi renomeado para `yd.tpf.premios_pre`, coerente com o
|
|
340
|
-
retorno tabular (`DataFrame` com múltiplos prêmios).
|
|
341
|
-
- Entradas escalares de data inválidas agora **levantam `ValueError`** em
|
|
342
|
-
qualquer função pública que aceite `DateLike`. Antes, chamadas como
|
|
343
|
-
`yd.du.deslocar("31-02-2024", 1)` retornavam `None` silenciosamente. Em
|
|
344
|
-
operações vetorizadas o parse continua tolerante: elementos inválidos viram
|
|
345
|
-
`null` para preservar o pipeline Polars. Strings vazias ou só com espaços
|
|
346
|
-
continuam sendo tratadas como nulas.
|
|
347
|
-
|
|
348
|
-
### v0.53.0
|
|
349
|
-
|
|
350
|
-
- As funções secundárias de TPF migraram do `yd.tpf` para o namespace dedicado
|
|
351
|
-
`yd.tpf.secundario`:
|
|
352
|
-
|
|
353
|
-
- `yd.tpf.secundario_intradia(...)` → `yd.tpf.secundario.intradia(...)`
|
|
354
|
-
- `yd.tpf.secundario_mensal(...)` → `yd.tpf.secundario.mensal(...)`
|
|
355
|
-
|
|
356
|
-
### v0.52.0
|
|
357
|
-
|
|
358
|
-
- `Interpolador(...)` e `Interpolador.interpolar(...)` agora aceitam **apenas
|
|
359
|
-
inteiro escalar**. Chamadas com lista/`pl.Series` (`interp([30, 60])`),
|
|
360
|
-
antes suportadas via sobrecarga vetorial, agora levantam `TypeError`.
|
|
361
|
-
Substitua por `Interpolador.interpolar_expr` em pipelines Polars ou pela
|
|
362
|
-
função top-level `yd.interpolar(...)` (curva única ou multi-curva).
|
|
363
|
-
- `yd.interpolar(...)` passou a usar `extrapolar=False` como padrão, alinhado
|
|
364
|
-
com `Interpolador`. Antes era `True`. Chamadas que dependiam da
|
|
365
|
-
extrapolação implícita na ponta longa precisam passar `extrapolar=True`
|
|
366
|
-
explicitamente.
|
|
367
|
-
- As funções `dv01(...)` dos títulos públicos agora recebem `pu` como argumento
|
|
368
|
-
explícito. Chamadas antigas que passavam apenas data, vencimento e taxa, ou
|
|
369
|
-
que passavam VNA no caso da NTN-B, precisam ser atualizadas.
|
|
370
|
-
- `ntnf.taxas_zero(...)` mudou os nomes dos parâmetros de curva para o padrão
|
|
371
|
-
`vencimentos_*` / `taxas_*`. Chamadas por posição continuam com a mesma
|
|
372
|
-
ordem; chamadas por keyword precisam usar os novos nomes.
|
|
373
|
-
|
|
374
|
-
#### `Interpolador(...)` não aceita mais lista/Series
|
|
375
|
-
|
|
376
|
-
O ``__call__`` e o método ``interpolar`` da classe agora são estritamente
|
|
377
|
-
escalares. O caminho vetorial foi dividido em duas APIs com semântica clara:
|
|
284
|
+
## Compatibilidade e mudanças da API
|
|
378
285
|
|
|
379
|
-
|
|
380
|
-
# Antes (v0.51.x)
|
|
381
|
-
interp = yd.Interpolador(dus, taxas, metodo="flat_forward")
|
|
382
|
-
interp([15, 45, 75]) # pl.Series
|
|
383
|
-
|
|
384
|
-
# Agora, dentro de um pipeline Polars
|
|
385
|
-
df.with_columns(taxa=interp.interpolar_expr("du"))
|
|
386
|
-
|
|
387
|
-
# Agora, ad-hoc (curva única ou multi-curva)
|
|
388
|
-
yd.interpolar(
|
|
389
|
-
dus_alvo=pl.Series([15, 45, 75]),
|
|
390
|
-
dus_curva=pl.Series(dus),
|
|
391
|
-
taxas_curva=pl.Series(taxas),
|
|
392
|
-
)
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
#### `dv01(...)` agora recebe PU
|
|
396
|
-
|
|
397
|
-
As funções `dv01(...)` dos títulos públicos recebem o PU usado como base para o
|
|
398
|
-
cálculo, não mais o VNA ou apenas a taxa. Se necessário, calcule o PU antes:
|
|
399
|
-
|
|
400
|
-
```python
|
|
401
|
-
pu = yd.ntnb.pu(vna, yd.ntnb.cotacao(data, vencimento, taxa))
|
|
402
|
-
dv01 = yd.ntnb.dv01(data, vencimento, taxa, pu)
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
#### `ntnf.taxas_zero(...)` usa nomes por conceito
|
|
286
|
+
A versão atual é `v0.55.0`. As mudanças abaixo exigem atualização de código:
|
|
406
287
|
|
|
407
|
-
|
|
408
|
-
|
|
288
|
+
| Versão | Mudança principal |
|
|
289
|
+
|---|---|
|
|
290
|
+
| `v0.55.0` | Funções de PU, cotação e VNA dos títulos passaram a retornar `Decimal` com seis casas. Entradas numéricas aceitam `float` ou `Decimal`. |
|
|
291
|
+
| `v0.54.5` | `fluxos_caixa` não aceita mais `ajustar_datas_pagamento`; os cronogramas usam datas contratuais. |
|
|
292
|
+
| `v0.54.2` | `taxas_historicas` foi adicionada e `tpf.taxas(completo=True)` foi removida. |
|
|
293
|
+
| `v0.54.0` | Cotações e fluxos de LFT, NTN-B, NTN-C e NTN-B1 passaram de base 100 para base 1; `ntnbprinc` virou `ntnbp`; `premio_pre` virou `premios_pre`; datas escalares inválidas passaram a levantar `ValueError`. |
|
|
294
|
+
| `v0.53.0` | O mercado secundário de TPF passou para `yd.tpf.secundario.intradia` e `yd.tpf.secundario.mensal`. |
|
|
295
|
+
| `v0.52.0` | `Interpolador` passou a ser escalar; use `interpolar_expr` ou `yd.interpolar` para vetores. `dv01` passou a exigir `pu` e `ntnf.taxas_zero` adotou nomes `vencimentos_*` / `taxas_*`. |
|
|
409
296
|
|
|
410
|
-
|
|
411
|
-
- `ltn_taxas` → `taxas_ltn`
|
|
412
|
-
- `ntnf_vencimentos` → `vencimentos_ntnf`
|
|
413
|
-
- `ntnf_taxas` → `taxas_ntnf`
|
|
297
|
+
O histórico completo está disponível nas [releases do GitHub](https://github.com/crdcj/PYield/releases).
|
|
414
298
|
|
|
415
299
|
## Testes
|
|
416
300
|
|
|
@@ -210,7 +210,8 @@ def taxas_zero(
|
|
|
210
210
|
Padrão False, retornando apenas os vencimentos informados.
|
|
211
211
|
|
|
212
212
|
Returns:
|
|
213
|
-
pl.DataFrame: Curva zero calibrada pelo método TD.
|
|
213
|
+
pl.DataFrame: Curva zero calibrada pelo método TD. Retorna vazio quando
|
|
214
|
+
não restarem vencimentos posteriores à liquidação.
|
|
214
215
|
|
|
215
216
|
Output Columns:
|
|
216
217
|
- data_vencimento (Date): Data do vértice da curva.
|
|
@@ -228,6 +229,16 @@ def taxas_zero(
|
|
|
228
229
|
liquidacao, vencimentos, taxas = _validar_entradas_taxas_zero(
|
|
229
230
|
data_liquidacao, vencimentos, taxas
|
|
230
231
|
)
|
|
232
|
+
if vencimentos.is_empty():
|
|
233
|
+
return pl.DataFrame(
|
|
234
|
+
schema={
|
|
235
|
+
"data_vencimento": pl.Date,
|
|
236
|
+
"dias_uteis": pl.Int64,
|
|
237
|
+
"taxa_zero": pl.Float64,
|
|
238
|
+
"taxa_forward": pl.Float64,
|
|
239
|
+
}
|
|
240
|
+
)
|
|
241
|
+
|
|
231
242
|
titulos = pl.DataFrame({"data_vencimento": vencimentos, "taxa_tir": taxas}).sort(
|
|
232
243
|
"data_vencimento"
|
|
233
244
|
)
|
|
@@ -122,6 +122,8 @@ def cotacao(
|
|
|
122
122
|
|
|
123
123
|
Returns:
|
|
124
124
|
Decimal: Fator de cotação em base 1, truncado em 6 casas decimais.
|
|
125
|
+
Retorna ``Decimal("NaN")`` quando o prazo até o vencimento não é
|
|
126
|
+
positivo.
|
|
125
127
|
|
|
126
128
|
Notes:
|
|
127
129
|
A STN apresenta a cotação na escala percentual (base 100). Esta
|
|
@@ -152,6 +154,8 @@ def cotacao(
|
|
|
152
154
|
taxa = utils.normalizar_taxa_precificacao(taxa)
|
|
153
155
|
# Número de dias úteis entre liquidação (inclusivo) e vencimento (exclusivo)
|
|
154
156
|
dias_uteis = du.contar(data_liquidacao, data_vencimento)
|
|
157
|
+
if dias_uteis <= 0:
|
|
158
|
+
return Decimal("NaN")
|
|
155
159
|
|
|
156
160
|
# Número de períodos truncado conforme regras da STN
|
|
157
161
|
anos_truncados = utils.truncar(dias_uteis / 252, 14)
|
|
@@ -201,6 +205,10 @@ def taxa(
|
|
|
201
205
|
if pu_float <= 0:
|
|
202
206
|
return float("nan")
|
|
203
207
|
|
|
208
|
+
dias_uteis = du.contar(data_liquidacao, data_vencimento)
|
|
209
|
+
if dias_uteis <= 0:
|
|
210
|
+
return float("nan")
|
|
211
|
+
|
|
204
212
|
def diferenca_preco(taxa: float) -> float:
|
|
205
213
|
preco = _calcular_pu(vna, cotacao(data_liquidacao, data_vencimento, taxa))
|
|
206
214
|
return float(preco) - pu_float
|
|
@@ -128,7 +128,8 @@ def pu(
|
|
|
128
128
|
taxa: Taxa de desconto (YTM) do título em formato decimal.
|
|
129
129
|
|
|
130
130
|
Returns:
|
|
131
|
-
Decimal: PU da LTN truncado em seis casas decimais.
|
|
131
|
+
Decimal: PU da LTN truncado em seis casas decimais. Retorna
|
|
132
|
+
``Decimal("NaN")`` quando o prazo até o vencimento não é positivo.
|
|
132
133
|
|
|
133
134
|
References:
|
|
134
135
|
- Secretaria do Tesouro Nacional. Metodologia de Cálculo dos Títulos
|
|
@@ -148,6 +149,8 @@ def pu(
|
|
|
148
149
|
taxa = utils.normalizar_taxa_precificacao(taxa)
|
|
149
150
|
# Calcula dias úteis entre liquidação e vencimento
|
|
150
151
|
dias_uteis = du.contar(data_liquidacao, data_vencimento)
|
|
152
|
+
if dias_uteis <= 0:
|
|
153
|
+
return Decimal("NaN")
|
|
151
154
|
|
|
152
155
|
# Calcula anos úteis truncados conforme a STN
|
|
153
156
|
anos_truncados = utils.truncar(dias_uteis / 252, 14)
|
|
@@ -196,6 +199,8 @@ def taxa(
|
|
|
196
199
|
return float("nan")
|
|
197
200
|
|
|
198
201
|
dias_uteis = du.contar(data_liquidacao, data_vencimento)
|
|
202
|
+
if dias_uteis <= 0:
|
|
203
|
+
return float("nan")
|
|
199
204
|
anos_truncados = utils.truncar(dias_uteis / 252, 14)
|
|
200
205
|
taxa_calculada = (VALOR_FACE / preco_float) ** (1 / anos_truncados) - 1
|
|
201
206
|
return utils.truncar(taxa_calculada, 8)
|
|
@@ -271,7 +276,8 @@ def dv01(
|
|
|
271
276
|
pu: PU usado como base para o cálculo.
|
|
272
277
|
|
|
273
278
|
Returns:
|
|
274
|
-
float: DV01, variação de preço para 1 bp.
|
|
279
|
+
float: DV01, variação de preço para 1 bp. Retorna ``NaN`` quando o
|
|
280
|
+
prazo até o vencimento não é positivo.
|
|
275
281
|
|
|
276
282
|
Examples:
|
|
277
283
|
>>> from pyield import ltn
|
|
@@ -285,6 +291,8 @@ def dv01(
|
|
|
285
291
|
taxa = utils.normalizar_taxa_precificacao(taxa)
|
|
286
292
|
taxa_mais_1bp = round(taxa + 0.0001, 8)
|
|
287
293
|
dias_uteis = du.contar(data_liquidacao, data_vencimento)
|
|
294
|
+
if dias_uteis <= 0:
|
|
295
|
+
return float("nan")
|
|
288
296
|
anos_truncados = utils.truncar(dias_uteis / 252, 14)
|
|
289
297
|
preco_1 = utils.truncar(VALOR_FACE / (1 + taxa) ** anos_truncados, 6)
|
|
290
298
|
preco_2 = utils.truncar(
|
|
@@ -308,7 +316,8 @@ def duration_expr(
|
|
|
308
316
|
Returns:
|
|
309
317
|
pl.Expr: Expressão sem alias com a duration em anos úteis.
|
|
310
318
|
"""
|
|
311
|
-
|
|
319
|
+
dias_uteis = du.contar_expr(data_liquidacao, data_vencimento)
|
|
320
|
+
return pl.when(dias_uteis > 0).then(dias_uteis / 252).otherwise(float("nan"))
|
|
312
321
|
|
|
313
322
|
|
|
314
323
|
def dv01_expr(
|
|
@@ -484,7 +484,8 @@ def taxas_zero(
|
|
|
484
484
|
Padrão False.
|
|
485
485
|
|
|
486
486
|
Returns:
|
|
487
|
-
pl.DataFrame: DataFrame com as taxas zero.
|
|
487
|
+
pl.DataFrame: DataFrame com as taxas zero. Retorna vazio quando não
|
|
488
|
+
restarem vencimentos posteriores à liquidação.
|
|
488
489
|
|
|
489
490
|
Output Columns:
|
|
490
491
|
- data_vencimento (Date): Data de vencimento.
|
|
@@ -561,6 +562,14 @@ def taxas_zero(
|
|
|
561
562
|
data_liquidacao, vencimentos, taxas = _validar_entradas_taxas_zero(
|
|
562
563
|
data_liquidacao, vencimentos, taxas
|
|
563
564
|
)
|
|
565
|
+
if vencimentos.is_empty():
|
|
566
|
+
return pl.DataFrame(
|
|
567
|
+
schema={
|
|
568
|
+
"data_vencimento": pl.Date,
|
|
569
|
+
"dias_uteis": pl.Int64,
|
|
570
|
+
"taxa_zero": pl.Float64,
|
|
571
|
+
}
|
|
572
|
+
)
|
|
564
573
|
|
|
565
574
|
df = _criar_df_bootstrap(data_liquidacao, taxas, vencimentos)
|
|
566
575
|
|
|
@@ -27,7 +27,8 @@ def cotacao(
|
|
|
27
27
|
taxa_tir: Taxa interna de retorno anualizada do título.
|
|
28
28
|
|
|
29
29
|
Returns:
|
|
30
|
-
Decimal: Cotação em base 1, truncada em 6 casas decimais.
|
|
30
|
+
Decimal: Cotação em base 1, truncada em 6 casas decimais. Retorna
|
|
31
|
+
``Decimal("NaN")`` se a liquidação for igual ou posterior ao vencimento.
|
|
31
32
|
|
|
32
33
|
Examples:
|
|
33
34
|
>>> from pyield import ntnbp
|
|
@@ -38,6 +39,8 @@ def cotacao(
|
|
|
38
39
|
return Decimal("NaN")
|
|
39
40
|
|
|
40
41
|
dias_uteis = du.contar(data_liquidacao, data_vencimento)
|
|
42
|
+
if dias_uteis <= 0:
|
|
43
|
+
return Decimal("NaN")
|
|
41
44
|
anos_uteis = utils.truncar(dias_uteis / 252, 14)
|
|
42
45
|
fator_desconto = 1 / (1 + float(taxa_tir)) ** anos_uteis
|
|
43
46
|
return truncar_decimal(fator_desconto, 6)
|
|
@@ -108,12 +111,16 @@ def taxa(
|
|
|
108
111
|
|
|
109
112
|
Returns:
|
|
110
113
|
float: TIR de mercado anualizada, arredondada em quatro casas decimais.
|
|
114
|
+
Retorna ``NaN`` se a liquidação for igual ou posterior ao vencimento.
|
|
111
115
|
"""
|
|
112
116
|
if any_is_empty(data_liquidacao, data_vencimento):
|
|
113
117
|
return float("nan")
|
|
114
118
|
|
|
115
|
-
curva = _normalizar_curva_zero(curva_zero)
|
|
116
119
|
dias_uteis = du.contar(data_liquidacao, data_vencimento)
|
|
120
|
+
if dias_uteis <= 0:
|
|
121
|
+
return float("nan")
|
|
122
|
+
|
|
123
|
+
curva = _normalizar_curva_zero(curva_zero)
|
|
117
124
|
taxa_zero = interpolador.Interpolador(
|
|
118
125
|
curva["dias_uteis"],
|
|
119
126
|
curva["taxa_zero"],
|
|
@@ -141,7 +148,8 @@ def dv01(
|
|
|
141
148
|
pu: PU usado como base para o cálculo.
|
|
142
149
|
|
|
143
150
|
Returns:
|
|
144
|
-
float: DV01 (Dollar Value of 01), variação de preço para 1 bp.
|
|
151
|
+
float: DV01 (Dollar Value of 01), variação de preço para 1 bp. Retorna
|
|
152
|
+
``NaN`` se a liquidação for igual ou posterior ao vencimento.
|
|
145
153
|
|
|
146
154
|
Examples:
|
|
147
155
|
>>> from pyield import ntnbp as bp
|
|
@@ -154,6 +162,8 @@ def dv01(
|
|
|
154
162
|
return float("nan")
|
|
155
163
|
|
|
156
164
|
dias_uteis = du.contar(data_liquidacao, data_vencimento)
|
|
165
|
+
if dias_uteis <= 0:
|
|
166
|
+
return float("nan")
|
|
157
167
|
anos_uteis = utils.truncar(dias_uteis / 252, 14)
|
|
158
168
|
fator_preco = (1 + taxa_tir) ** anos_uteis
|
|
159
169
|
fator_preco_1bp = (1 + taxa_tir + 0.0001) ** anos_uteis
|
|
@@ -346,6 +346,35 @@ def pu(
|
|
|
346
346
|
return truncar_decimal(_calcular_pu(data_liquidacao, data_vencimento, taxa), 6)
|
|
347
347
|
|
|
348
348
|
|
|
349
|
+
def _filtrar_vertices_futuros(
|
|
350
|
+
liquidacao: dt.date,
|
|
351
|
+
vencimentos: pl.Series,
|
|
352
|
+
taxas: pl.Series,
|
|
353
|
+
nome_curva: str,
|
|
354
|
+
) -> tuple[pl.Series, pl.Series]:
|
|
355
|
+
"""Remove vértices sem prazo preservando o alinhamento com as taxas."""
|
|
356
|
+
if len(vencimentos) != len(taxas):
|
|
357
|
+
raise ValueError(
|
|
358
|
+
f"Vencimentos e taxas de {nome_curva} devem ter o mesmo tamanho."
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
df = pl.DataFrame(
|
|
362
|
+
{"data_vencimento": vencimentos, "taxa": taxas},
|
|
363
|
+
schema={"data_vencimento": pl.Date, "taxa": pl.Float64},
|
|
364
|
+
).filter(pl.col("data_vencimento") > liquidacao)
|
|
365
|
+
|
|
366
|
+
removidos = len(vencimentos) - df.height
|
|
367
|
+
if removidos > 0:
|
|
368
|
+
logger.warning(
|
|
369
|
+
"Vencimentos de %s menores ou iguais à liquidação foram ignorados: "
|
|
370
|
+
"%s removidos.",
|
|
371
|
+
nome_curva,
|
|
372
|
+
removidos,
|
|
373
|
+
)
|
|
374
|
+
|
|
375
|
+
return df["data_vencimento"], df["taxa"]
|
|
376
|
+
|
|
377
|
+
|
|
349
378
|
def taxas_zero( # noqa
|
|
350
379
|
data_liquidacao: DateLike,
|
|
351
380
|
vencimentos_ltn: DatesLike,
|
|
@@ -385,6 +414,10 @@ def taxas_zero( # noqa
|
|
|
385
414
|
- dias_uteis (Int64): Dias úteis entre liquidação e vencimento.
|
|
386
415
|
- taxa_zero (Float64): Taxa zero (zero cupom).
|
|
387
416
|
|
|
417
|
+
Notes:
|
|
418
|
+
Vencimentos menores ou iguais à liquidação são ignorados antes da
|
|
419
|
+
construção dos interpoladores.
|
|
420
|
+
|
|
388
421
|
Examples:
|
|
389
422
|
>>> from pyield import ntnf, ltn
|
|
390
423
|
>>> df_ltn = ltn.dados("03-09-2024")
|
|
@@ -431,6 +464,27 @@ def taxas_zero( # noqa
|
|
|
431
464
|
else:
|
|
432
465
|
serie_ntnf_taxas = taxas_ntnf
|
|
433
466
|
|
|
467
|
+
vencimentos_ltn, serie_ltn_taxas = _filtrar_vertices_futuros(
|
|
468
|
+
liquidacao,
|
|
469
|
+
vencimentos_ltn,
|
|
470
|
+
serie_ltn_taxas,
|
|
471
|
+
"LTN",
|
|
472
|
+
)
|
|
473
|
+
vencimentos_ntnf, serie_ntnf_taxas = _filtrar_vertices_futuros(
|
|
474
|
+
liquidacao,
|
|
475
|
+
vencimentos_ntnf,
|
|
476
|
+
serie_ntnf_taxas,
|
|
477
|
+
"NTN-F",
|
|
478
|
+
)
|
|
479
|
+
if vencimentos_ltn.is_empty() or vencimentos_ntnf.is_empty():
|
|
480
|
+
return pl.DataFrame(
|
|
481
|
+
schema={
|
|
482
|
+
"data_vencimento": pl.Date,
|
|
483
|
+
"dias_uteis": pl.Int64,
|
|
484
|
+
"taxa_zero": pl.Float64,
|
|
485
|
+
}
|
|
486
|
+
)
|
|
487
|
+
|
|
434
488
|
# 2. Criar interpoladores (aceitam pl.Series diretamente)
|
|
435
489
|
interpolador_ltn = ip.Interpolador(
|
|
436
490
|
dias_uteis=du.contar(liquidacao, vencimentos_ltn),
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|