pyield 0.48.4__tar.gz → 0.48.5__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.
Files changed (70) hide show
  1. {pyield-0.48.4 → pyield-0.48.5}/PKG-INFO +1 -1
  2. pyield-0.48.5/pyield/__about__.py +1 -0
  3. {pyield-0.48.4 → pyield-0.48.5}/pyield/b3/di_over.py +40 -26
  4. {pyield-0.48.4 → pyield-0.48.5}/pyield/bc/__init__.py +1 -5
  5. pyield-0.48.4/pyield/bc/taxas.py → pyield-0.48.5/pyield/bc/selic.py +48 -99
  6. pyield-0.48.4/pyield/__about__.py +0 -1
  7. {pyield-0.48.4 → pyield-0.48.5}/.gitignore +0 -0
  8. {pyield-0.48.4 → pyield-0.48.5}/LICENSE +0 -0
  9. {pyield-0.48.4 → pyield-0.48.5}/README.md +0 -0
  10. {pyield-0.48.4 → pyield-0.48.5}/pyield/__init__.py +0 -0
  11. {pyield-0.48.4 → pyield-0.48.5}/pyield/_internal/__init__.py +0 -0
  12. {pyield-0.48.4 → pyield-0.48.5}/pyield/_internal/br_numbers.py +0 -0
  13. {pyield-0.48.4 → pyield-0.48.5}/pyield/_internal/cache.py +0 -0
  14. {pyield-0.48.4 → pyield-0.48.5}/pyield/_internal/converters.py +0 -0
  15. {pyield-0.48.4 → pyield-0.48.5}/pyield/_internal/data_cache.py +0 -0
  16. {pyield-0.48.4 → pyield-0.48.5}/pyield/_internal/retry.py +0 -0
  17. {pyield-0.48.4 → pyield-0.48.5}/pyield/_internal/types.py +0 -0
  18. {pyield-0.48.4 → pyield-0.48.5}/pyield/anbima/__init__.py +0 -0
  19. {pyield-0.48.4 → pyield-0.48.5}/pyield/anbima/ettj_intradia.py +0 -0
  20. {pyield-0.48.4 → pyield-0.48.5}/pyield/anbima/ettj_ultima.py +0 -0
  21. {pyield-0.48.4 → pyield-0.48.5}/pyield/anbima/ima_ultimo.py +0 -0
  22. {pyield-0.48.4 → pyield-0.48.5}/pyield/anbima/imaq.py +0 -0
  23. {pyield-0.48.4 → pyield-0.48.5}/pyield/anbima/tpf.py +0 -0
  24. {pyield-0.48.4 → pyield-0.48.5}/pyield/b3/__init__.py +0 -0
  25. {pyield-0.48.4 → pyield-0.48.5}/pyield/b3/_contratos.py +0 -0
  26. {pyield-0.48.4 → pyield-0.48.5}/pyield/b3/_validar_pregao.py +0 -0
  27. {pyield-0.48.4 → pyield-0.48.5}/pyield/b3/boletim.py +0 -0
  28. {pyield-0.48.4 → pyield-0.48.5}/pyield/b3/derivativos_intradia.py +0 -0
  29. {pyield-0.48.4 → pyield-0.48.5}/pyield/b3/di1.py +0 -0
  30. {pyield-0.48.4 → pyield-0.48.5}/pyield/b3/futuro/__init__.py +0 -0
  31. {pyield-0.48.4 → pyield-0.48.5}/pyield/b3/futuro/contratos.py +0 -0
  32. {pyield-0.48.4 → pyield-0.48.5}/pyield/b3/futuro/historico.py +0 -0
  33. {pyield-0.48.4 → pyield-0.48.5}/pyield/b3/futuro/intradia.py +0 -0
  34. {pyield-0.48.4 → pyield-0.48.5}/pyield/bc/compromissada.py +0 -0
  35. {pyield-0.48.4 → pyield-0.48.5}/pyield/bc/copom.py +0 -0
  36. {pyield-0.48.4 → pyield-0.48.5}/pyield/bc/leiloes.py +0 -0
  37. {pyield-0.48.4 → pyield-0.48.5}/pyield/bc/ptax.py +0 -0
  38. {pyield-0.48.4 → pyield-0.48.5}/pyield/bc/tpf_intradia.py +0 -0
  39. {pyield-0.48.4 → pyield-0.48.5}/pyield/bc/tpf_mensal.py +0 -0
  40. {pyield-0.48.4 → pyield-0.48.5}/pyield/bc/vna.py +0 -0
  41. {pyield-0.48.4 → pyield-0.48.5}/pyield/du/__init__.py +0 -0
  42. {pyield-0.48.4 → pyield-0.48.5}/pyield/du/core.py +0 -0
  43. {pyield-0.48.4 → pyield-0.48.5}/pyield/du/feriados/__init__.py +0 -0
  44. {pyield-0.48.4 → pyield-0.48.5}/pyield/du/feriados/feriados_antigos_br.txt +0 -0
  45. {pyield-0.48.4 → pyield-0.48.5}/pyield/du/feriados/feriados_br.py +0 -0
  46. {pyield-0.48.4 → pyield-0.48.5}/pyield/du/feriados/feriados_novos_br.txt +0 -0
  47. {pyield-0.48.4 → pyield-0.48.5}/pyield/fwd.py +0 -0
  48. {pyield-0.48.4 → pyield-0.48.5}/pyield/interpolador.py +0 -0
  49. {pyield-0.48.4 → pyield-0.48.5}/pyield/ipca/__init__.py +0 -0
  50. {pyield-0.48.4 → pyield-0.48.5}/pyield/ipca/historico.py +0 -0
  51. {pyield-0.48.4 → pyield-0.48.5}/pyield/ipca/projetado.py +0 -0
  52. {pyield-0.48.4 → pyield-0.48.5}/pyield/py.typed +0 -0
  53. {pyield-0.48.4 → pyield-0.48.5}/pyield/relogio.py +0 -0
  54. {pyield-0.48.4 → pyield-0.48.5}/pyield/selic/__init__.py +0 -0
  55. {pyield-0.48.4 → pyield-0.48.5}/pyield/selic/cpm.py +0 -0
  56. {pyield-0.48.4 → pyield-0.48.5}/pyield/selic/probabilities.py +0 -0
  57. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/__init__.py +0 -0
  58. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/benchmark.py +0 -0
  59. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/leiloes.py +0 -0
  60. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/lft.py +0 -0
  61. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/ltn.py +0 -0
  62. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/ntnb.py +0 -0
  63. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/ntnb1.py +0 -0
  64. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/ntnbprinc.py +0 -0
  65. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/ntnc.py +0 -0
  66. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/ntnf.py +0 -0
  67. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/pre.py +0 -0
  68. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/rmd.py +0 -0
  69. {pyield-0.48.4 → pyield-0.48.5}/pyield/tn/utils.py +0 -0
  70. {pyield-0.48.4 → pyield-0.48.5}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyield
3
- Version: 0.48.4
3
+ Version: 0.48.5
4
4
  Summary: A Python library for analysis of fixed income instruments in Brazil
5
5
  Project-URL: Homepage, https://github.com/crdcj/PYield
6
6
  Project-URL: Documentation, https://crdcj.github.io/PYield
@@ -0,0 +1 @@
1
+ __version__ = "0.48.5"
@@ -9,46 +9,29 @@ Formato do arquivo (ex.: 20250228.txt):
9
9
  Notas de implementação:
10
10
  - O valor "00001315" representa 1315 / 10^4 = 0.1315 (13,15% a.a.).
11
11
  - Arquivos ausentes (feriados/fins de semana) retornam erro FTP 550.
12
+ - Série disponível a partir de 20/08/2012 (primeiro arquivo no FTP).
12
13
  """
13
14
 
15
+ import datetime as dt
14
16
  import ftplib
15
17
  import logging
16
18
 
19
+ from pyield._internal.cache import ttl_cache
17
20
  from pyield._internal.converters import converter_datas
18
21
  from pyield._internal.types import DateLike, any_is_empty
19
22
 
20
23
  registro = logging.getLogger(__name__)
21
24
 
25
+ # Primeiro arquivo disponível no FTP da CETIP
26
+ DATA_INICIO = dt.date(2012, 8, 20)
27
+
22
28
  # 4 casas decimais na taxa = 2 casas decimais em percentual
23
29
  CASAS_DECIMAIS_DI_OVER = 4
24
30
 
25
31
 
26
- def di_over(data: DateLike) -> float:
27
- """Obtém a taxa DI over via FTP da B3/CETIP.
28
-
29
- Busca o arquivo de taxa DI (Depósito Interfinanceiro) no servidor
30
- FTP da CETIP para a data informada.
31
-
32
- Args:
33
- data: data da consulta para buscar a taxa DI.
34
-
35
- Returns:
36
- Taxa DI para a data especificada (ex: 0.1315 para 13,15%).
37
- Retorna ``nan`` se a data for feriado ou fim de semana.
38
-
39
- Examples:
40
- >>> di_over("28/02/2025")
41
- 0.1315
42
- >>> di_over("01/01/2025") # Feriado
43
- nan
44
- """
45
- if any_is_empty(data):
46
- return float("nan")
47
-
48
- # Converte a data para o formato esperado do arquivo: YYYYMMDD.txt
49
- data_ref = converter_datas(data)
50
- nome_arquivo = data_ref.strftime("%Y%m%d.txt")
51
-
32
+ @ttl_cache()
33
+ def _buscar_taxa(nome_arquivo: str) -> float:
34
+ """Busca a taxa DI no FTP da CETIP para o arquivo informado."""
52
35
  try:
53
36
  with ftplib.FTP("ftp.cetip.com.br", timeout=10) as ftp:
54
37
  ftp.login()
@@ -75,3 +58,34 @@ def di_over(data: DateLike) -> float:
75
58
  except ftplib.all_errors as e:
76
59
  registro.error("Erro de conexão ou transferência FTP: %s", e)
77
60
  raise ConnectionError(f"Falha ao buscar taxa DI via FTP: {e}") from e
61
+
62
+
63
+ def di_over(data: DateLike) -> float:
64
+ """Obtém a taxa DI over via FTP da B3/CETIP.
65
+
66
+ Busca o arquivo de taxa DI (Depósito Interfinanceiro) no servidor
67
+ FTP da CETIP para a data informada.
68
+
69
+ Args:
70
+ data: data da consulta para buscar a taxa DI.
71
+
72
+ Returns:
73
+ Taxa DI para a data especificada (ex: 0.1315 para 13,15%).
74
+ Retorna ``nan`` se a data for feriado, fim de semana ou
75
+ anterior a 20/08/2012 (início da série no FTP).
76
+
77
+ Examples:
78
+ >>> di_over("28/02/2025")
79
+ 0.1315
80
+ >>> di_over("01/01/2025") # Feriado
81
+ nan
82
+ """
83
+ if any_is_empty(data):
84
+ return float("nan")
85
+
86
+ data_ref = converter_datas(data)
87
+ if data_ref < DATA_INICIO:
88
+ return float("nan")
89
+
90
+ nome_arquivo = data_ref.strftime("%Y%m%d.txt")
91
+ return _buscar_taxa(nome_arquivo)
@@ -2,9 +2,7 @@ from pyield.bc import compromissada, copom
2
2
  from pyield.bc.compromissada import compromissadas
3
3
  from pyield.bc.leiloes import leiloes
4
4
  from pyield.bc.ptax import ptax, ptax_serie
5
- from pyield.bc.taxas import (
6
- di_over,
7
- di_over_serie,
5
+ from pyield.bc.selic import (
8
6
  selic_meta,
9
7
  selic_meta_serie,
10
8
  selic_over,
@@ -17,8 +15,6 @@ from pyield.bc.vna import vna_lft
17
15
  __all__ = [
18
16
  "copom",
19
17
  "compromissada",
20
- "di_over",
21
- "di_over_serie",
22
18
  "leiloes",
23
19
  "ptax_serie",
24
20
  "compromissadas",
@@ -3,10 +3,10 @@
3
3
  Séries disponíveis:
4
4
  - SELIC Over (SGS 1178)
5
5
  - SELIC Meta (SGS 432)
6
- - DI Over (SGS 11)
7
6
 
8
- Exemplo de chamada à API:
7
+ Exemplos de chamada à API:
9
8
  https://api.bcb.gov.br/dados/serie/bcdata.sgs.1178/dados?formato=json&dataInicial=29/01/2025&dataFinal=31/01/2025
9
+ https://api.bcb.gov.br/dados/serie/bcdata.sgs.1178/dados/ultimos/5?formato=json
10
10
 
11
11
  Exemplo de resposta JSON da API do BCB (valores em percentual):
12
12
  [{"data":"29/01/2025","valor":"12.15"},
@@ -16,7 +16,6 @@ Exemplo de resposta JSON da API do BCB (valores em percentual):
16
16
  Notas de implementação:
17
17
  - Valores percentuais são convertidos para decimal (divididos por 100).
18
18
  - SELIC Over e Meta: arredondadas para 4 casas decimais.
19
- - DI Over diária: 8 casas decimais; anualizada: 4 casas decimais.
20
19
  - Intervalos > 10 anos são divididos automaticamente em blocos.
21
20
  """
22
21
 
@@ -42,7 +41,6 @@ def _extrair_taxa(df: pl.DataFrame) -> float:
42
41
 
43
42
  URL_BASE = "https://api.bcb.gov.br/dados/serie/bcdata.sgs."
44
43
  CASAS_DECIMAIS_ANUALIZADA = 4 # 2 casas no formato percentual
45
- CASAS_DECIMAIS_DIARIA = 8 # 6 casas no formato percentual
46
44
 
47
45
  # Limite de segurança em dias, correspondendo a ~9.5 anos.
48
46
  # Evita a complexidade do cálculo exato de 10 anos-calendário.
@@ -54,7 +52,6 @@ class SerieBC(Enum):
54
52
 
55
53
  SELIC_OVER = 1178
56
54
  SELIC_META = 432
57
- DI_OVER = 11
58
55
 
59
56
 
60
57
  @ttl_cache()
@@ -65,7 +62,7 @@ def _chamar_api(url_api: str) -> list[dict[str, str]]:
65
62
  return resposta.json()
66
63
 
67
64
 
68
- def _montar_url_download(
65
+ def _montar_url_intervalo(
69
66
  serie: SerieBC, inicio: dt.date, fim: dt.date | None = None
70
67
  ) -> str:
71
68
  inicio_str = inicio.strftime("%d/%m/%Y")
@@ -75,29 +72,33 @@ def _montar_url_download(
75
72
  return url
76
73
 
77
74
 
78
- def _buscar_requisicao(
79
- serie: SerieBC,
80
- inicio: dt.date,
81
- fim: dt.date | None,
82
- ) -> pl.DataFrame:
83
- """Busca dados da API para um intervalo."""
84
- esquema_esperado = {"data": pl.Date, "taxa": pl.Float64}
85
- url_api = _montar_url_download(serie, inicio, fim)
75
+ def _montar_url_ultimos(serie: SerieBC, n: int) -> str:
76
+ return f"{URL_BASE}{serie.value}/dados/ultimos/{n}?formato=json"
77
+
78
+
79
+ def _buscar_api(url_api: str) -> pl.DataFrame:
80
+ """Busca dados da API e converte em DataFrame."""
81
+ esquema = {"data": pl.Date, "taxa": pl.Float64}
86
82
 
87
83
  try:
88
84
  dados = _chamar_api(url_api)
89
85
  except requests.exceptions.HTTPError as e:
90
86
  if e.response.status_code == 404: # noqa
91
- return pl.DataFrame(schema=esquema_esperado)
87
+ return pl.DataFrame(schema=esquema)
92
88
  raise
93
89
 
94
90
  if not dados:
95
- return pl.DataFrame(schema=esquema_esperado)
91
+ return pl.DataFrame(schema=esquema)
96
92
 
97
- return pl.from_dicts(dados).select(
93
+ df = pl.from_dicts(dados).select(
98
94
  pl.col("data").str.to_date("%d/%m/%Y"),
99
- taxa=pl.col("valor").cast(pl.Float64) / 100,
95
+ pl.col("valor")
96
+ .cast(pl.Float64)
97
+ .truediv(100)
98
+ .round(CASAS_DECIMAIS_ANUALIZADA)
99
+ .alias("taxa"),
100
100
  )
101
+ return df
101
102
 
102
103
 
103
104
  def _buscar_dados_url(
@@ -110,12 +111,15 @@ def _buscar_dados_url(
110
111
  data_fim = converter_datas(fim) if fim else relogio.hoje()
111
112
 
112
113
  if (data_fim - data_inicio).days < LIMITE_DIAS_SEGURO:
113
- return _buscar_requisicao(serie, data_inicio, data_fim)
114
+ return _buscar_api(_montar_url_intervalo(serie, data_inicio, data_fim))
114
115
 
115
116
  inicios = pl.date_range(start=data_inicio, end=data_fim, interval="10y", eager=True)
116
117
  fins = inicios.dt.offset_by("10y").clip(upper_bound=data_fim)
117
118
 
118
- todos_dfs = [_buscar_requisicao(serie, ini, fim) for ini, fim in zip(inicios, fins)]
119
+ todos_dfs = [
120
+ _buscar_api(_montar_url_intervalo(serie, ini, fim))
121
+ for ini, fim in zip(inicios, fins)
122
+ ]
119
123
 
120
124
  todos_dfs = [df for df in todos_dfs if not df.is_empty()]
121
125
 
@@ -126,8 +130,10 @@ def _buscar_dados_url(
126
130
 
127
131
 
128
132
  def selic_over_serie(
129
- inicio: DateLike,
133
+ inicio: DateLike | None = None,
130
134
  fim: DateLike | None = None,
135
+ *,
136
+ ultimos: int | None = None,
131
137
  ) -> pl.DataFrame:
132
138
  """Taxa SELIC Over (série SGS 1178).
133
139
 
@@ -137,6 +143,8 @@ def selic_over_serie(
137
143
  Args:
138
144
  inicio: Data inicial.
139
145
  fim: Data final. Se ``None``, usa a data mais recente.
146
+ ultimos: Número de registros mais recentes a retornar.
147
+ Mutuamente exclusivo com ``inicio``/``fim``.
140
148
 
141
149
  Returns:
142
150
  DataFrame com colunas data e taxa, ou DataFrame vazio.
@@ -171,10 +179,13 @@ def selic_over_serie(
171
179
  │ 2025-09-17 ┆ 0.149 │
172
180
  └────────────┴───────┘
173
181
  """
174
- if any_is_empty(inicio):
175
- return pl.DataFrame()
176
- df = _buscar_dados_url(SerieBC.SELIC_OVER, inicio, fim)
177
- return df.with_columns(pl.col("taxa").round(CASAS_DECIMAIS_ANUALIZADA))
182
+ if ultimos is not None:
183
+ df = _buscar_api(_montar_url_ultimos(SerieBC.SELIC_OVER, ultimos))
184
+ elif inicio is not None:
185
+ df = _buscar_dados_url(SerieBC.SELIC_OVER, inicio, fim)
186
+ else:
187
+ raise ValueError("Informe 'inicio' ou 'ultimos'.")
188
+ return df
178
189
 
179
190
 
180
191
  def selic_over(data: DateLike) -> float:
@@ -197,8 +208,10 @@ def selic_over(data: DateLike) -> float:
197
208
 
198
209
 
199
210
  def selic_meta_serie(
200
- inicio: DateLike,
211
+ inicio: DateLike | None = None,
201
212
  fim: DateLike | None = None,
213
+ *,
214
+ ultimos: int | None = None,
202
215
  ) -> pl.DataFrame:
203
216
  """Taxa SELIC Meta (série SGS 432).
204
217
 
@@ -207,6 +220,8 @@ def selic_meta_serie(
207
220
  Args:
208
221
  inicio: Data inicial.
209
222
  fim: Data final. Se ``None``, usa a data mais recente.
223
+ ultimos: Número de registros mais recentes a retornar.
224
+ Mutuamente exclusivo com ``inicio``/``fim``.
210
225
 
211
226
  Returns:
212
227
  DataFrame com colunas data e taxa, ou DataFrame vazio.
@@ -223,10 +238,13 @@ def selic_meta_serie(
223
238
  │ 2024-05-31 ┆ 0.105 │
224
239
  └────────────┴───────┘
225
240
  """
226
- if any_is_empty(inicio):
227
- return pl.DataFrame()
228
- df = _buscar_dados_url(SerieBC.SELIC_META, inicio, fim)
229
- return df.with_columns(pl.col("taxa").round(CASAS_DECIMAIS_ANUALIZADA))
241
+ if ultimos is not None:
242
+ df = _buscar_api(_montar_url_ultimos(SerieBC.SELIC_META, ultimos))
243
+ elif inicio is not None:
244
+ df = _buscar_dados_url(SerieBC.SELIC_META, inicio, fim)
245
+ else:
246
+ raise ValueError("Informe 'inicio' ou 'ultimos'.")
247
+ return df
230
248
 
231
249
 
232
250
  def selic_meta(data: DateLike) -> float:
@@ -246,72 +264,3 @@ def selic_meta(data: DateLike) -> float:
246
264
  if any_is_empty(data):
247
265
  return float("nan")
248
266
  return _extrair_taxa(selic_meta_serie(data, data))
249
-
250
-
251
- def di_over_serie(
252
- inicio: DateLike,
253
- fim: DateLike | None = None,
254
- anualizada: bool = True,
255
- ) -> pl.DataFrame:
256
- """Taxa DI Over (série SGS 11).
257
-
258
- Taxa de juros média dos empréstimos interbancários.
259
-
260
- Args:
261
- inicio: Data inicial.
262
- fim: Data final. Se ``None``, usa a data mais recente.
263
- anualizada: Se ``True``, retorna a taxa anualizada (base
264
- 252 d.u.). Caso contrário, retorna a taxa diária.
265
-
266
- Returns:
267
- DataFrame com colunas data e taxa, ou DataFrame vazio.
268
-
269
- Examples:
270
- >>> from pyield import bc
271
- >>> # Retorna todos os dados desde 29-01-2025
272
- >>> bc.di_over_serie("29-01-2025").head(5) # Primeiras 5 linhas
273
- shape: (5, 2)
274
- ┌────────────┬────────┐
275
- │ data ┆ taxa │
276
- │ --- ┆ --- │
277
- │ date ┆ f64 │
278
- ╞════════════╪════════╡
279
- │ 2025-01-29 ┆ 0.1215 │
280
- │ 2025-01-30 ┆ 0.1315 │
281
- │ 2025-01-31 ┆ 0.1315 │
282
- │ 2025-02-03 ┆ 0.1315 │
283
- │ 2025-02-04 ┆ 0.1315 │
284
- └────────────┴────────┘
285
- """
286
- if any_is_empty(inicio):
287
- return pl.DataFrame()
288
- df = _buscar_dados_url(SerieBC.DI_OVER, inicio, fim)
289
- if anualizada:
290
- return df.with_columns(
291
- taxa=(((pl.col("taxa") + 1).pow(252)) - 1).round(CASAS_DECIMAIS_ANUALIZADA)
292
- )
293
- return df.with_columns(taxa=pl.col("taxa").round(CASAS_DECIMAIS_DIARIA))
294
-
295
-
296
- def di_over(data: DateLike, anualizada: bool = True) -> float:
297
- """Taxa DI Over para uma data específica.
298
-
299
- Args:
300
- data: Data da consulta.
301
- anualizada: Se ``True``, retorna a taxa anualizada (base
302
- 252 d.u.). Caso contrário, retorna a taxa diária.
303
-
304
- Returns:
305
- Taxa DI Over ou ``nan`` se não disponível.
306
-
307
- Examples:
308
- >>> from pyield import bc
309
- >>> bc.di_over("31-05-2024")
310
- 0.104
311
-
312
- >>> bc.di_over("28-01-2025", anualizada=False)
313
- 0.00045513
314
- """
315
- if any_is_empty(data):
316
- return float("nan")
317
- return _extrair_taxa(di_over_serie(data, data, anualizada))
@@ -1 +0,0 @@
1
- __version__ = "0.48.4"
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