Skip to content

Commit 4f21372

Browse files
committed
Fix rendering of per share values
1 parent da7e602 commit 4f21372

2 files changed

Lines changed: 45 additions & 12 deletions

File tree

edgar/xbrl/rendering.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,17 @@ def _format_comparison(pct_change: float, comparison_type: str) -> str:
379379
'us-gaap_WeightedAverageNumberOfSharesOutstandingBasic',
380380
'us-gaap_WeightedAverageNumberOfSharesOutstandingDiluted',
381381
'us-gaap_WeightedAverageNumberOfDilutedSharesOutstanding',
382-
'us-gaap_CommonStockSharesIssued'
382+
'us-gaap_CommonStockSharesIssued',
383+
]
384+
385+
eps_concepts = [
386+
'us-gaap_EarningsPerShareBasic',
387+
'us-gaap_EarningsPerShareDiluted',
388+
'us-gaap_EarningsPerShareBasicAndDiluted',
389+
'us-gaap_IncomeLossFromContinuingOperationsPerBasicShare',
390+
'us-gaap_IncomeLossFromContinuingOperationsPerDilutedShare',
391+
'us-gaap_IncomeLossFromDiscontinuedOperationsNetOfTaxPerBasicShare',
392+
'us-gaap_IncomeLossFromDiscontinuedOperationsNetOfTaxPerDilutedShare'
383393
]
384394

385395

@@ -803,9 +813,9 @@ def _create_units_note(
803813

804814
# Construct appropriate units note
805815
if monetary_scale_text and shares_scale_text and shares_scale != dominant_scale:
806-
return f"[italic](In {monetary_scale_text}, except shares in {shares_scale_text})[/italic]"
816+
return f"[italic](In {monetary_scale_text}, except shares in {shares_scale_text} and per share data)[/italic]"
807817
elif monetary_scale_text:
808-
return f"[italic](In {monetary_scale_text}, except per share data)[/italic]"
818+
return f"[italic](In {monetary_scale_text}, except shares and per share data)[/italic]"
809819
else:
810820
return ""
811821

@@ -846,14 +856,13 @@ def _format_value_for_display_as_string(
846856
# Extract only needed metadata
847857
concept = item.get('concept', '')
848858

849-
# Fast check for common share concepts (avoid dict lookup when possible)
859+
# Fast check for common share and EPS concepts
850860
is_share_value = concept in share_concepts
861+
is_eps_value = concept in eps_concepts
851862

852863
# Only perform expensive label operations if needed for monetary determination
853864
is_monetary = is_monetary_statement
854-
if concept in ('us-gaap_EarningsPerShareBasic', 'us-gaap_EarningsPerShareDiluted'):
855-
is_monetary = False
856-
elif is_share_value:
865+
if is_eps_value or is_share_value:
857866
is_monetary = False
858867
elif not is_monetary:
859868
# Skip label checks entirely if we already know it's not monetary
@@ -873,8 +882,24 @@ def _format_value_for_display_as_string(
873882

874883
# Format numeric values efficiently
875884
if value_type in (int, float):
885+
# Handle EPS values with decimal precision
886+
if is_eps_value:
887+
# EPS values should show 2-3 decimal places and not be scaled
888+
if abs(value) >= 1000:
889+
# For very large EPS values, use thousands separator
890+
return f"{value:,.2f}"
891+
elif abs(value) >= 10:
892+
# For EPS values >= 10, use 2 decimal places
893+
return f"{value:.2f}"
894+
else:
895+
# For typical EPS values < 10, use up to 3 decimal places but remove trailing zeros
896+
formatted = f"{value:.3f}".rstrip('0').rstrip('.')
897+
# Ensure at least 2 decimal places for EPS
898+
if '.' not in formatted or len(formatted.split('.')[1]) < 2:
899+
return f"{value:.2f}"
900+
return formatted
876901
# Handle share values with a specialized path
877-
if is_share_value:
902+
elif is_share_value:
878903
if fact_decimals <= -3:
879904
# Efficiently apply scaling
880905
scale_factor = 10 ** (-fact_decimals)

gists/QueryingXBRL.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,28 @@
1111
# Query by concept
1212
results = xb.query().by_concept("us-gaap:PaymentsToAcquireAvailableForSaleSecuritiesDebt")
1313
print(results)
14-
print(type(results))
14+
15+
results = xb.query().by_concept("PaymentsToAcquireAvailableForSaleSecuritiesDebt")
16+
print(results)
17+
18+
results = xb.query().by_concept("us-gaap_PaymentsToAcquireAvailableForSaleSecuritiesDebt")
19+
print(results)
20+
21+
results = xb.query().by_concept("RevenueFrom")
22+
print(results)
1523

1624
#
1725
revenue_query = xb.query().by_label("Revenue")
1826
print(revenue_query)
1927

20-
revenue_query = xb.query().by_label("Revenue", exact=True)
28+
revenue_query = xb.query().by_label("Total deferred revenue")
2129
print(revenue_query)
2230

31+
"""
2332
income_facts = xb.query().by_statement_type("IncomeStatement")
2433
2534
print(income_facts)
2635
2736
sorted_query = xb.query().sort_by('value', ascending=False)
2837
print(sorted_query.limit(10))
29-
30-
stats = xb.query().by_statement_type("IncomeStatement").stats()
38+
"""

0 commit comments

Comments
 (0)