fix(sec_edgar): print a figure under one million instead of 0 (#1589)

- a USD figure under one million keeps three significant digits in the statement table
This commit is contained in:
Yijia-Xiao
2026-10-27 07:59:01 +00:00
parent 6c23d7551c
commit 50bf38ee92
2 changed files with 25 additions and 1 deletions
+12
View File
@@ -321,3 +321,15 @@ def test_a_row_filed_only_year_to_date_keeps_its_figure_beside_a_row_filed_by_qu
rows = {r.split(",")[0]: r.split(",")[1:] for r in out.splitlines()[3:]}
assert rows["Operating Cash Flow"] == ["", "120"]
assert rows["Capital Expenditure"] == ["10", ""]
@pytest.mark.unit
def test_a_figure_under_a_million_is_not_printed_as_zero(monkeypatch):
facts = {"facts": {"us-gaap": {"Revenues": {"units": {"USD": [
_fact("2025-12-31", 303_300, "2026-02-20", start="2025-01-01"),
_fact("2024-12-31", -25_000, "2025-02-20", start="2024-01-01")]}}}}}
monkeypatch.setattr(sec_edgar, "_fetch_json",
lambda url: TICKER_MAP if "company_tickers" in url else facts)
out = sec_edgar.get_income_statement("AAPL", "annual", "2026-03-01")
assert [r for r in out.splitlines() if r.startswith("Revenue,")] == ["Revenue,-0.0250,0.303"]
+13 -1
View File
@@ -19,6 +19,7 @@ from __future__ import annotations
import json
import logging
import math
import os
import time
from datetime import date, datetime
@@ -232,11 +233,22 @@ def _statement(kind: str, ticker: str, freq: str, as_of_date: str, title: str) -
cells = []
for end, index in periods:
value = values.get((end, index)) if chosen[label].get(end) == index else None
cells.append("" if value is None else f"{value / 1e6:.0f}" if unit == "USD" else f"{value:.2f}")
cells.append("" if value is None else _millions(value) if unit == "USD" else f"{value:.2f}")
rows.append(",".join([name] + cells))
return header + "\n".join(rows) + "\n"
def _millions(value: float) -> str:
"""USD in millions; under a million, three significant digits, so it is not printed as 0.
Plain numbers: a thousands separator would split the CSV field.
"""
millions = value / 1e6
if millions == 0 or abs(millions) >= 1:
return f"{millions:.0f}"
return f"{millions:.{2 - math.floor(math.log10(abs(millions)))}f}"
def get_balance_sheet(ticker: str, freq: str = "quarterly", as_of_date: str | None = None) -> str:
"""Balance sheet as filed on or before ``as_of_date``."""
return _statement("balance_sheet", ticker, freq, as_of_date, "Balance Sheet")