Standardized __str__ format and id format
This commit is contained in:
parent
a610cfe07c
commit
6a995d6406
|
@ -1,6 +1,19 @@
|
|||
"""# Finance Definitions.
|
||||
|
||||
Python library defining base types for financial processing.
|
||||
|
||||
Defines a base `Asset` type, and various subtypes, for universal representation
|
||||
of these assets.
|
||||
|
||||
Defined hierarchy:
|
||||
|
||||
* `Asset`
|
||||
- `Currency`
|
||||
+ `FiatCurrency`
|
||||
+ `CryptoCurrency`
|
||||
- `Stock`
|
||||
- `Index`
|
||||
- `Commodity`
|
||||
"""
|
||||
|
||||
import dataclasses
|
||||
|
@ -22,7 +35,16 @@ RE_CRYPTO_TICKER_FORMAT = r'^\S+$'
|
|||
@enforce_typing.enforce_types
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
class StockExchange:
|
||||
"""Unified Stock Exchange identifiers."""
|
||||
"""Unified Stock Exchange identifiers.
|
||||
|
||||
Fields:
|
||||
- `name`: Human-readable name.
|
||||
- `mic`: Official MIC identifier.
|
||||
- `bloomberg_id`: Identifier for lookup on Bloomberg.
|
||||
- `crunchbase_id`: Identifier for lookup on Crunchbase.
|
||||
- `yahoo_id`: Identifier for lookup on Yahoo! Finance.
|
||||
- `eod_id`: Identifier for lookup on EOD.
|
||||
"""
|
||||
|
||||
name: str
|
||||
mic: str
|
||||
|
@ -42,6 +64,7 @@ class Asset:
|
|||
"""
|
||||
|
||||
def names(self) -> list[str]:
|
||||
"""Returns a list of human readable names for this `Asset`."""
|
||||
return COMMON_NAMES.get(self, [])
|
||||
|
||||
def to_polygon_id(self) -> str:
|
||||
|
@ -85,13 +108,15 @@ class Asset:
|
|||
def to_string_id(self) -> str:
|
||||
"""Formats the asset id using the fin_defs asset format."""
|
||||
if isinstance(self, Stock):
|
||||
return f'stock:{self}'
|
||||
return f'stock:{self.ticker}.{self.exchange.mic}'
|
||||
if isinstance(self, FiatCurrency):
|
||||
return f'fiat:{self}'
|
||||
return f'fiat:{self.iso_code}'
|
||||
if isinstance(self, CryptoCurrency):
|
||||
return f'crypto:{self}'
|
||||
return f'crypto:{self.ccxt_symbol}'
|
||||
if isinstance(self, Index):
|
||||
return f'index:{self}'
|
||||
return f'index:{self.ticker}'
|
||||
if isinstance(self, Commodity):
|
||||
return f'commodity:{self.alpha_vantage_id}'
|
||||
|
||||
raise NotImplementedError('Unsupported asset type: ' + str(self))
|
||||
|
||||
|
@ -122,6 +147,9 @@ class Asset:
|
|||
msg = f'Unsupported asset format: {asset_id}'
|
||||
raise NotImplementedError(msg)
|
||||
|
||||
def __str__(self):
|
||||
return self.to_string_id()
|
||||
|
||||
|
||||
@enforce_typing.enforce_types
|
||||
@dataclasses.dataclass(frozen=True)
|
||||
|
@ -139,9 +167,6 @@ class FiatCurrency(Currency):
|
|||
msg = f'iso_code was not in correct format: {self.iso_code}'
|
||||
raise ValueError(msg)
|
||||
|
||||
def __str__(self):
|
||||
return self.iso_code
|
||||
|
||||
|
||||
@enforce_typing.enforce_types
|
||||
@dataclasses.dataclass(frozen=True, eq=True)
|
||||
|
@ -156,10 +181,6 @@ class CryptoCurrency(Currency):
|
|||
raise ValueError(msg)
|
||||
"""
|
||||
|
||||
def __str__(self):
|
||||
return self.ccxt_symbol
|
||||
|
||||
|
||||
@enforce_typing.enforce_types
|
||||
@dataclasses.dataclass(frozen=True, eq=True)
|
||||
class Stock(Asset):
|
||||
|
@ -172,9 +193,6 @@ class Stock(Asset):
|
|||
msg = f'ticker was not in correct format: {self.ticker}'
|
||||
raise ValueError(msg)
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.ticker}.{self.exchange.mic}'
|
||||
|
||||
@staticmethod
|
||||
def from_polygon_id(polygon_id: str, stock_exchange: StockExchange) -> 'Stock':
|
||||
return Stock(polygon_id, stock_exchange)
|
||||
|
@ -190,9 +208,6 @@ class Index(Asset):
|
|||
msg = f'ticker was not in correct format: {self.ticker}'
|
||||
raise ValueError(msg)
|
||||
|
||||
def __str__(self):
|
||||
return self.ticker
|
||||
|
||||
|
||||
@enforce_typing.enforce_types
|
||||
@dataclasses.dataclass(frozen=True, eq=True)
|
||||
|
@ -204,9 +219,6 @@ class Commodity(Asset):
|
|||
msg = f'alpha_vantage_id was not in correct format: {self.alpha_vantage_id}'
|
||||
raise ValueError(msg)
|
||||
|
||||
def __str__(self):
|
||||
return self.alpha_vantage_id
|
||||
|
||||
|
||||
Commodity.CRUDE_OIL_WTI = Commodity('WTI')
|
||||
Commodity.CRUDE_OIL_BRENT = Commodity('BRENT')
|
||||
|
@ -227,7 +239,7 @@ BTC = CryptoCurrency('BTC', coingecko_id='bitcoin')
|
|||
MPC = CryptoCurrency('MPC', coingecko_id='partisia-blockchain')
|
||||
SPX = Index('SPX')
|
||||
NDX = Index('NDX')
|
||||
USDT = CryptoCurrency('USDT', 'tether')
|
||||
USDT = CryptoCurrency('USDT', coingecko_id='tether')
|
||||
|
||||
COMMON_NAMES: dict[Asset, list[str]] = {
|
||||
FiatCurrency('USD'): ['U.S. Dollar'],
|
||||
|
@ -246,15 +258,15 @@ COMMON_NAMES: dict[Asset, list[str]] = {
|
|||
NDX: ['Nasdaq 100'],
|
||||
BTC: ['Bitcoin BTC'],
|
||||
MPC: ['Partisia Blockchain MPC Token'],
|
||||
CryptoCurrency('ETH', 'ethereum'): ['Ethereum Ether'],
|
||||
CryptoCurrency('DOGE', 'dogecoin'): ['Dogecoin'],
|
||||
CryptoCurrency('SOL', 'solana'): ['Solana SOL'],
|
||||
CryptoCurrency('ADA', 'cardano'): ['Cardano ADA'],
|
||||
CryptoCurrency('BNB', 'bnb'): ['Binance BNB'],
|
||||
CryptoCurrency('MATIC', 'polygon'): ['Polygon MATIC'],
|
||||
CryptoCurrency('ETH', coingecko_id='ethereum'): ['Ethereum Ether'],
|
||||
CryptoCurrency('DOGE', coingecko_id='dogecoin'): ['Dogecoin'],
|
||||
CryptoCurrency('SOL', coingecko_id='solana'): ['Solana SOL'],
|
||||
CryptoCurrency('ADA', coingecko_id='cardano'): ['Cardano ADA'],
|
||||
CryptoCurrency('BNB', coingecko_id='bnb'): ['Binance BNB'],
|
||||
CryptoCurrency('MATIC', coingecko_id='polygon'): ['Polygon MATIC'],
|
||||
# Stable-coins
|
||||
CryptoCurrency('DAI', 'dai'): ['DAI'],
|
||||
CryptoCurrency('USDC', 'usdc'): ['USD Coin'],
|
||||
CryptoCurrency('DAI', coingecko_id='dai'): ['DAI'],
|
||||
CryptoCurrency('USDC', coingecko_id='usdc'): ['USD Coin'],
|
||||
USDT: ['Tether USDT'],
|
||||
}
|
||||
|
||||
|
@ -384,7 +396,12 @@ class AssetInformation:
|
|||
@enforce_typing.enforce_types
|
||||
@dataclasses.dataclass(frozen=True, eq=True, slots=True)
|
||||
class AssetAmount:
|
||||
"""Decimal with associated asset unit."""
|
||||
"""Decimal with associated asset unit.
|
||||
|
||||
Fields:
|
||||
- `asset`: Asset unit of amount.
|
||||
- `amount`: Amount of given asset.
|
||||
"""
|
||||
|
||||
asset: Asset
|
||||
amount: Decimal
|
||||
|
@ -447,6 +464,7 @@ class ExchangeRateSample(Asset):
|
|||
"""Single exchange rate sample with a timestamp and various stats."""
|
||||
|
||||
timestamp: datetime.date | datetime.datetime
|
||||
base_asset: Asset
|
||||
_average: Decimal | None = None
|
||||
last: Decimal | None = None
|
||||
open: Decimal | None = None
|
||||
|
|
12
test/test_ids.py
Normal file
12
test/test_ids.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
import pytest
|
||||
|
||||
import fin_defs
|
||||
|
||||
@pytest.mark.parametrize('asset', fin_defs.WELL_KNOWN_SYMBOLS.values())
|
||||
def test_to_from_string_id(asset: fin_defs.Asset):
|
||||
assert fin_defs.Asset.from_string_id(asset.to_string_id()) == asset
|
||||
import fin_defs
|
||||
|
||||
@pytest.mark.parametrize('asset', fin_defs.WELL_KNOWN_SYMBOLS.values())
|
||||
def test_to_from_polygon_id(asset: fin_defs.Asset):
|
||||
assert fin_defs.Asset.from_polygon_id(asset.to_polygon_id()) == asset
|
Loading…
Reference in New Issue
Block a user