Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion edgar/xbrl/currency.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
usd_revenue = converter.to_usd(dkk_revenue, 2024, rate_type='average')
"""

import re
from collections import Counter
from dataclasses import dataclass, field
from datetime import date, datetime
Expand All @@ -47,7 +48,26 @@ def _extract_year(value) -> Optional[int]:
return value.year
return None

__all__ = ['CurrencyConverter', 'ExchangeRate']
__all__ = ['CurrencyConverter', 'ExchangeRate', 'normalize_currency_unit']


def normalize_currency_unit(raw: Optional[str]) -> Optional[str]:
"""Extract an ISO 4217 code from common XBRL currency unit identifiers."""
if not raw:
return raw

if re.fullmatch(r"[A-Z]{3}", raw):
return raw

match = re.search(r"iso4217:([A-Z]{3})", raw, flags=re.IGNORECASE)
if match:
return match.group(1).upper()

match = re.search(r"UNIT_STANDARD_([A-Z]{3})(?:_|$)", raw)
if match:
return match.group(1)

return raw


@dataclass
Expand Down
2 changes: 2 additions & 0 deletions edgar/xbrl/facts.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

from edgar.richtools import repr_rich
from edgar.xbrl.core import STANDARD_LABEL, parse_date
from edgar.xbrl.currency import normalize_currency_unit
from edgar.xbrl.models import select_display_label


Expand Down Expand Up @@ -1014,6 +1015,7 @@ def get_facts(self) -> List[Dict[str, Any]]:
'context_ref': fact.context_ref,
'value': fact.value,
'unit_ref': fact.unit_ref,
'currency': normalize_currency_unit(fact.unit_ref),
'decimals': fact.decimals,
'numeric_value': fact.numeric_value
}
Expand Down
21 changes: 21 additions & 0 deletions tests/xbrl/test_currency_unit_normalization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from edgar.xbrl.currency import normalize_currency_unit


def test_normalize_currency_unit_returns_clean_iso_code():
assert normalize_currency_unit("USD") == "USD"


def test_normalize_currency_unit_extracts_iso4217_measure():
assert normalize_currency_unit("iso4217:USD") == "USD"


def test_normalize_currency_unit_extracts_standard_unit_identifier():
raw = "UNIT_STANDARD_HKD_MNUSOXGRF0O9R60JINVDUQ"

assert normalize_currency_unit(raw) == "HKD"


def test_normalize_currency_unit_preserves_unknown_format():
raw = "shares"

assert normalize_currency_unit(raw) == raw