From 50bf38ee928d1c212dc1ffdac31d795b5c820387 Mon Sep 17 00:00:00 2001 From: Yijia-Xiao Date: Tue, 27 Oct 2026 00:52:03 +0000 Subject: [PATCH] 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 --- tests/test_sec_edgar.py | 12 ++++++++++++ tradingagents/dataflows/vendors/sec_edgar.py | 14 +++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/tests/test_sec_edgar.py b/tests/test_sec_edgar.py index be6e007f9..b72d33b4c 100644 --- a/tests/test_sec_edgar.py +++ b/tests/test_sec_edgar.py @@ -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"] diff --git a/tradingagents/dataflows/vendors/sec_edgar.py b/tradingagents/dataflows/vendors/sec_edgar.py index 653cb0a1b..255d501ce 100644 --- a/tradingagents/dataflows/vendors/sec_edgar.py +++ b/tradingagents/dataflows/vendors/sec_edgar.py @@ -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")