Improved price parsing
This commit is contained in:
parent
5c29ea63da
commit
79b9edc5d6
|
@ -214,16 +214,17 @@ class FiatCurrency(Currency):
|
|||
|
||||
@staticmethod
|
||||
def from_currency_symbol(symbol: str) -> 'Currency | None':
|
||||
for currency, currency_symbol in CURRENCY_SYMBOLS.items():
|
||||
if currency_symbol == symbol:
|
||||
for currency, currency_display in ASSET_DISPLAY.items():
|
||||
if currency_display.symbol == symbol:
|
||||
return currency
|
||||
return None
|
||||
|
||||
def to_currency_symbol(self) -> str:
|
||||
return CURRENCY_SYMBOLS[self]
|
||||
return ASSET_DISPLAY[self].symbol
|
||||
|
||||
|
||||
FiatCurrency.DKK = FiatCurrency('DKK')
|
||||
FiatCurrency.SEK = FiatCurrency('SEK')
|
||||
FiatCurrency.NOK = FiatCurrency('NOK')
|
||||
FiatCurrency.USD = FiatCurrency('USD')
|
||||
FiatCurrency.EUR = FiatCurrency('EUR')
|
||||
|
@ -353,6 +354,7 @@ CURRENCY_CODES = {
|
|||
'CHF',
|
||||
'ZAR',
|
||||
'CZK',
|
||||
'SEK',
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -364,15 +366,25 @@ WELL_KNOWN_SYMBOLS = (
|
|||
| {'SPX500': SPX, 'SP500': SPX, 'Nasdaq 100': NDX}
|
||||
)
|
||||
|
||||
CURRENCY_SYMBOLS: dict[Currency, str] = {
|
||||
USD: '$',
|
||||
EUR: '€',
|
||||
FiatCurrency.GBP: '£',
|
||||
BTC: '₿',
|
||||
FiatCurrency.JPY: '¥',
|
||||
}
|
||||
|
||||
ASSET_PREFIX: dict[Asset, str] = CURRENCY_SYMBOLS # TODO: Remove at some point.
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class AssetDisplay:
|
||||
symbol: str | None
|
||||
prefix: str | None
|
||||
suffix: str | None
|
||||
|
||||
UNKNOWN_ASSET_DISPLAY = AssetDisplay(None,None,None)
|
||||
|
||||
ASSET_DISPLAY: dict[Asset, AssetDisplay] = {
|
||||
USD: AssetDisplay('$','$', None),
|
||||
EUR: AssetDisplay('€','€', None),
|
||||
FiatCurrency.GBP: AssetDisplay('£','£', None),
|
||||
BTC: AssetDisplay('₿','₿',None),
|
||||
FiatCurrency.JPY: AssetDisplay('¥','¥', None),
|
||||
FiatCurrency.DKK: AssetDisplay(None,None, 'kr.'),
|
||||
FiatCurrency.SEK: AssetDisplay(None,None, 'kr.'),
|
||||
FiatCurrency.NOK: AssetDisplay(None,None, 'kr.'),
|
||||
}
|
||||
|
||||
EXCHANGES = [
|
||||
NYSE,
|
||||
|
@ -501,10 +513,11 @@ class AssetAmount:
|
|||
elif abs_amount >= THREE_DECIMALS_UNDER_THIS_AMOUNT:
|
||||
specificity = '2'
|
||||
|
||||
prefix = ASSET_PREFIX.get(self.asset, '')
|
||||
return ('{sign}{prefix}{amount:.' + specificity + 'f} {name}').format(
|
||||
display = ASSET_DISPLAY.get(self.asset, UNKNOWN_ASSET_DISPLAY)
|
||||
return ('{sign}{prefix}{amount:.' + specificity + 'f}{suffix} {name}').format(
|
||||
sign='-' if (self.amount == self.amount and self.amount < 0) else '',
|
||||
prefix=prefix,
|
||||
prefix=display.prefix or '',
|
||||
suffix=f' {display.suffix}' if display.suffix else '',
|
||||
amount=abs_amount,
|
||||
name=self.asset.raw_short_name(),
|
||||
)
|
||||
|
|
|
@ -4,7 +4,7 @@ from decimal import Decimal
|
|||
|
||||
from .data import (
|
||||
CURRENCY_CODES,
|
||||
CURRENCY_SYMBOLS,
|
||||
ASSET_DISPLAY,
|
||||
Asset,
|
||||
AssetAmount,
|
||||
FiatCurrency,
|
||||
|
@ -30,7 +30,7 @@ def parse_amount(price: str) -> Decimal:
|
|||
RE_CURRENCY_CODES = '(?P<code>' + '|'.join(re.escape(c) for c in CURRENCY_CODES) + ')'
|
||||
|
||||
RE_CURRENCY_SYMBOLS = (
|
||||
r'(?P<sym>[' + ''.join(re.escape(c) for c in CURRENCY_SYMBOLS.values()) + '])'
|
||||
r'(?P<sym>[' + ''.join(re.escape(c.symbol) for c in ASSET_DISPLAY.values() if c.symbol) + '])'
|
||||
)
|
||||
|
||||
RE_SYM_AMOUNT_CODE = re.compile(
|
||||
|
@ -77,6 +77,8 @@ RE_AMOUNT_SUFFIX_KR = re.compile(
|
|||
|
||||
VARIANTS_OF_FREE = frozenset(['free', 'gratis', 'gives væk'])
|
||||
|
||||
KRONER_USING_ASSETS = {k for k,c in ASSET_DISPLAY.items() if c.suffix == 'kr.'}
|
||||
|
||||
|
||||
def parse_price(text: str, default_currency: Asset) -> AssetAmount | None:
|
||||
"""
|
||||
|
@ -94,6 +96,7 @@ def parse_price(text: str, default_currency: Asset) -> AssetAmount | None:
|
|||
return AssetAmount(default_currency, Decimal(0))
|
||||
|
||||
code, sym, amount_text = None, None, None
|
||||
currency = None
|
||||
|
||||
if m := RE_SYM_AMOUNT_CODE.fullmatch(text):
|
||||
code, sym, amount_text = m.group('code'), m.group('sym'), m.group('amount')
|
||||
|
@ -104,11 +107,13 @@ def parse_price(text: str, default_currency: Asset) -> AssetAmount | None:
|
|||
elif m := RE_AMOUNT_CODE.fullmatch(text):
|
||||
code, amount_text = m.group('code'), m.group('amount')
|
||||
elif m := (RE_KR_AMOUNT.fullmatch(text) or RE_AMOUNT_SUFFIX_KR.fullmatch(text)):
|
||||
code, amount_text = 'DKK', m.group('amount')
|
||||
amount_text = m.group('amount')
|
||||
currency = default_currency if default_currency in KRONER_USING_ASSETS else FiatCurrency.DKK
|
||||
else:
|
||||
logger.debug('Unknown format: %s', text)
|
||||
return None
|
||||
|
||||
if currency is None:
|
||||
currency = (
|
||||
CURRENCY_CODES[code.upper()] if code else FiatCurrency.from_currency_symbol(sym)
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user