Simplify `Symbol` extend `MktPair`, add `Asset`
Drop everything we can in terms of methods and attrs from `Symbol`: - kill `.tokens()`, `.front_feed()`, `.tokens()`, `.nearest_tick()`, `.front_fqsn()`, instead moving logic from these methods into dependents (and obviously removing any usage from rest of code base, coming in follow up commits). - rename `.quantize_size()` -> `.quantize()`. - re-implement `.brokers`, `.lot_size_digits`, `.tick_size_digits` as `@property` methods; for the latter two, allows us to minimize to only accepting min tick decimal values on alternative constructor class methods and to drop the equivalent instance vars. - map `_fqsn` related variable names to new and preferred `_fqme`. We also juggle around some utility functions, moving limited precision related `decimal.Decimal` routines to the top of module and soon-to-be legacy `fqsn` related routines to the bottom. `MktPair` draft type extensions: - drop requirements for `src_type`, and offer the optional `.dst_type` field as either a `str` or (new `typing.Literal`) `AssetTypeName`. - define an equivalent `.quantize()` as (re)defined in `Symbol` but with `quantity_type: str` field which specifies whether to use the price or the size precision. - add a lot more docs, a `.key` property for the "symbol" name, draft property for a `.fqme: str` - allow `.src` and `.dst` to be of type `str | Asset` Add a new `Asset` to capture "things which can be used in markets and/or transactions" XD - defines a `.name`, `.atype: AssetTypeName` a financial category tag, `tx_tick: Decimal` the precision limit for transactions and of course a `.quantime()` method for doing accounting arithmetic on a given tech stack. - define the `atype: AssetTypeName` type as a finite set of `str`s expected to be used in various ways for default settings in other parts of the data and order control layers..pre_overruns_ctxcancelled
							parent
							
								
									c0a3c6dff7
								
							
						
					
					
						commit
						e9cedc6613
					
				| 
						 | 
					@ -34,34 +34,169 @@ from decimal import (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from typing import (
 | 
					from typing import (
 | 
				
			||||||
    Any,
 | 
					    Any,
 | 
				
			||||||
 | 
					    Literal,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..data.types import Struct
 | 
					from ..data.types import Struct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_underlyings: list[str] = [
 | 
				
			||||||
 | 
					    'stock',
 | 
				
			||||||
 | 
					    'bond',
 | 
				
			||||||
 | 
					    'crypto_currency',
 | 
				
			||||||
 | 
					    'fiat_currency',
 | 
				
			||||||
 | 
					    'commodity',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_derivs: list[str] = [
 | 
				
			||||||
 | 
					    'swap',
 | 
				
			||||||
 | 
					    'future',
 | 
				
			||||||
 | 
					    'continuous_future',
 | 
				
			||||||
 | 
					    'option',
 | 
				
			||||||
 | 
					    'futures_option',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# NOTE: a tag for other subsystems to try
 | 
				
			||||||
 | 
					# and do default settings for certain things:
 | 
				
			||||||
 | 
					# - allocator does unit vs. dolla size limiting.
 | 
				
			||||||
 | 
					AssetTypeName: Literal[
 | 
				
			||||||
 | 
					    _underlyings
 | 
				
			||||||
 | 
					    +
 | 
				
			||||||
 | 
					    _derivs
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# egs. stock, futer, option, bond etc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def float_digits(
 | 
				
			||||||
 | 
					    value: float,
 | 
				
			||||||
 | 
					) -> int:
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    Return the number of precision digits read from a decimal or float
 | 
				
			||||||
 | 
					    value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    if value == 0:
 | 
				
			||||||
 | 
					        return 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return int(
 | 
				
			||||||
 | 
					        -Decimal(str(value)).as_tuple().exponent
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def digits_to_dec(
 | 
				
			||||||
 | 
					    ndigits: int,
 | 
				
			||||||
 | 
					) -> Decimal:
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    Return the minimum float value for an input integer value.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    eg. 3 -> 0.001
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    if ndigits == 0:
 | 
				
			||||||
 | 
					        return Decimal('0')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return Decimal('0.' + '0'*(ndigits-1) + '1')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Asset(Struct, frozen=True):
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    Container type describing any transactable asset's technology.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    name: str
 | 
				
			||||||
 | 
					    atype: AssetTypeName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # minimum transaction size / precision.
 | 
				
			||||||
 | 
					    # eg. for buttcoin this is a "satoshi".
 | 
				
			||||||
 | 
					    tx_tick: Decimal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # NOTE: additional info optionally packed in by the backend, but
 | 
				
			||||||
 | 
					    # should not be explicitly required in our generic API.
 | 
				
			||||||
 | 
					    info: dict = {}  # make it frozen?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __str__(self) -> str:
 | 
				
			||||||
 | 
					        return self.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def quantize(
 | 
				
			||||||
 | 
					        self,
 | 
				
			||||||
 | 
					        size: float,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ) -> Decimal:
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        Truncate input ``size: float`` using ``Decimal``
 | 
				
			||||||
 | 
					        quantized form of the digit precision defined
 | 
				
			||||||
 | 
					        by ``self.lot_tick_size``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        digits = float_digits(self.tx_tick)
 | 
				
			||||||
 | 
					        return Decimal(size).quantize(
 | 
				
			||||||
 | 
					            Decimal(f'1.{"0".ljust(digits, "0")}'),
 | 
				
			||||||
 | 
					            rounding=ROUND_HALF_EVEN
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MktPair(Struct, frozen=True):
 | 
					class MktPair(Struct, frozen=True):
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    Market description for a pair of assets which are tradeable:
 | 
				
			||||||
 | 
					    a market which enables transactions of the form,
 | 
				
			||||||
 | 
					        buy: source asset -> destination asset
 | 
				
			||||||
 | 
					        sell: destination asset -> source asset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    src: str  # source asset name being used to buy
 | 
					    The main intention of this type is for a cross-asset, venue, broker
 | 
				
			||||||
    src_type: str  # source asset's financial type/classification name
 | 
					    normalized descriptive data type from which all market-auctions can
 | 
				
			||||||
    # ^ specifies a "class" of financial instrument
 | 
					    be mapped, simply.
 | 
				
			||||||
    # egs. stock, futer, option, bond etc.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dst: str  # destination asset name being bought
 | 
					    '''
 | 
				
			||||||
    dst_type: str  # destination asset's financial type/classification name
 | 
					    # "source asset" (name) used to buy *from*
 | 
				
			||||||
 | 
					    # (or used to sell *to*)
 | 
				
			||||||
 | 
					    src: str | Asset
 | 
				
			||||||
 | 
					    # "destination asset" (name) used to buy *to*
 | 
				
			||||||
 | 
					    # (or used to sell *from*)
 | 
				
			||||||
 | 
					    dst: str | Asset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    price_tick: float  # minimum price increment value increment
 | 
					 | 
				
			||||||
    price_tick_digits: int  # required decimal digits for above
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    size_tick: float  # minimum size (aka vlm) increment value increment
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # size_tick_digits: int  # required decimal digits for above
 | 
					 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def size_tick_digits(self) -> int:
 | 
					    def key(self) -> str:
 | 
				
			||||||
        return self.size_tick
 | 
					        '''
 | 
				
			||||||
 | 
					        The "endpoint key" for this market.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        In most other tina platforms this is referred to as the
 | 
				
			||||||
 | 
					        "symbol".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        return f'{self.src}{self.dst}'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # the tick size is the number describing the smallest step in value
 | 
				
			||||||
 | 
					    # available in this market between the source and destination
 | 
				
			||||||
 | 
					    # assets.
 | 
				
			||||||
 | 
					    # https://en.wikipedia.org/wiki/Tick_size
 | 
				
			||||||
 | 
					    # https://en.wikipedia.org/wiki/Commodity_tick
 | 
				
			||||||
 | 
					    # https://en.wikipedia.org/wiki/Percentage_in_point
 | 
				
			||||||
 | 
					    price_tick: Decimal  # minimum price increment value increment
 | 
				
			||||||
 | 
					    size_tick: Decimal  # minimum size (aka vlm) increment value increment
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # @property
 | 
				
			||||||
 | 
					    # def size_tick_digits(self) -> int:
 | 
				
			||||||
 | 
					    #     return float_digits(self.size_tick)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    broker: str | None = None  # the middle man giving access
 | 
				
			||||||
    venue: str | None = None  # market venue provider name
 | 
					    venue: str | None = None  # market venue provider name
 | 
				
			||||||
    expiry: str | None = None  # for derivs, expiry datetime parseable str
 | 
					    expiry: str | None = None  # for derivs, expiry datetime parseable str
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # destination asset's financial type/classification name
 | 
				
			||||||
 | 
					    # NOTE: this is required for the order size allocator system,
 | 
				
			||||||
 | 
					    # since we use different default settings based on the type
 | 
				
			||||||
 | 
					    # of the destination asset, eg. futes use a units limits vs.
 | 
				
			||||||
 | 
					    # equities a $limit.
 | 
				
			||||||
 | 
					    dst_type: AssetTypeName | None = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # source asset's financial type/classification name
 | 
				
			||||||
 | 
					    # TODO: is a src type required for trading?
 | 
				
			||||||
 | 
					    # there's no reason to need any more then the one-way alloc-limiter
 | 
				
			||||||
 | 
					    # config right?
 | 
				
			||||||
 | 
					    # src_type: AssetTypeName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # for derivs, info describing contract, egs.
 | 
					    # for derivs, info describing contract, egs.
 | 
				
			||||||
    # strike price, call or put, swap type, exercise model, etc.
 | 
					    # strike price, call or put, swap type, exercise model, etc.
 | 
				
			||||||
    contract_info: str | None = None
 | 
					    contract_info: str | None = None
 | 
				
			||||||
| 
						 | 
					@ -81,13 +216,53 @@ class MktPair(Struct, frozen=True):
 | 
				
			||||||
    # fqa, fqma, .. etc. see issue:
 | 
					    # fqa, fqma, .. etc. see issue:
 | 
				
			||||||
    # https://github.com/pikers/piker/issues/467
 | 
					    # https://github.com/pikers/piker/issues/467
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def fqsn(self) -> str:
 | 
					    def fqme(self) -> str:
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        Return the fully qualified market (endpoint) name for the
 | 
					        Return the fully qualified market endpoint-address for the
 | 
				
			||||||
        pair of transacting assets.
 | 
					        pair of transacting assets.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Yes, you can pronounce it colloquially as "f#$%-me"..
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        ...
 | 
					
 | 
				
			||||||
 | 
					    # fqsn = fqme
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def quantize(
 | 
				
			||||||
 | 
					        self,
 | 
				
			||||||
 | 
					        size: float,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        quantity_type: Literal['price', 'size'] = 'size',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ) -> Decimal:
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        Truncate input ``size: float`` using ``Decimal``
 | 
				
			||||||
 | 
					        and ``.size_tick``'s # of digits.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        match quantity_type:
 | 
				
			||||||
 | 
					            case 'price':
 | 
				
			||||||
 | 
					                digits = float_digits(self.price_tick)
 | 
				
			||||||
 | 
					            case 'size':
 | 
				
			||||||
 | 
					                digits = float_digits(self.size_tick)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Decimal(size).quantize(
 | 
				
			||||||
 | 
					            Decimal(f'1.{"0".ljust(digits, "0")}'),
 | 
				
			||||||
 | 
					            rounding=ROUND_HALF_EVEN
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # TODO: remove this?
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def type_key(self) -> str:
 | 
				
			||||||
 | 
					        return list(self.broker_info.values())[0]['asset_type']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # @classmethod
 | 
				
			||||||
 | 
					    # def from_fqme(
 | 
				
			||||||
 | 
					    #     cls,
 | 
				
			||||||
 | 
					    #     fqme: str,
 | 
				
			||||||
 | 
					    #     **kwargs,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # ) -> MktPair:
 | 
				
			||||||
 | 
					    #     broker, key, suffix = unpack_fqme(fqme)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def mk_fqsn(
 | 
					def mk_fqsn(
 | 
				
			||||||
| 
						 | 
					@ -103,34 +278,6 @@ def mk_fqsn(
 | 
				
			||||||
    return '.'.join([symbol, provider]).lower()
 | 
					    return '.'.join([symbol, provider]).lower()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def float_digits(
 | 
					 | 
				
			||||||
    value: float,
 | 
					 | 
				
			||||||
) -> int:
 | 
					 | 
				
			||||||
    '''
 | 
					 | 
				
			||||||
    Return the number of precision digits read from a float value.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    '''
 | 
					 | 
				
			||||||
    if value == 0:
 | 
					 | 
				
			||||||
        return 0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return int(-Decimal(str(value)).as_tuple().exponent)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def digits_to_dec(
 | 
					 | 
				
			||||||
    ndigits: int,
 | 
					 | 
				
			||||||
) -> Decimal:
 | 
					 | 
				
			||||||
    '''
 | 
					 | 
				
			||||||
    Return the minimum float value for an input integer value.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    eg. 3 -> 0.001
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    '''
 | 
					 | 
				
			||||||
    if ndigits == 0:
 | 
					 | 
				
			||||||
        return Decimal('0')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return Decimal('0.' + '0'*(ndigits-1) + '1')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def unpack_fqsn(fqsn: str) -> tuple[str, str, str]:
 | 
					def unpack_fqsn(fqsn: str) -> tuple[str, str, str]:
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
    Unpack a fully-qualified-symbol-name to ``tuple``.
 | 
					    Unpack a fully-qualified-symbol-name to ``tuple``.
 | 
				
			||||||
| 
						 | 
					@ -164,6 +311,10 @@ def unpack_fqsn(fqsn: str) -> tuple[str, str, str]:
 | 
				
			||||||
        suffix,
 | 
					        suffix,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unpack_fqme = unpack_fqsn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# TODO: rework the below `Symbol` (which was originally inspired and
 | 
					# TODO: rework the below `Symbol` (which was originally inspired and
 | 
				
			||||||
# derived from stuff in quantdom) into a simpler, ipc msg ready, market
 | 
					# derived from stuff in quantdom) into a simpler, ipc msg ready, market
 | 
				
			||||||
# endpoint meta-data container type as per the drafted interace above.
 | 
					# endpoint meta-data container type as per the drafted interace above.
 | 
				
			||||||
| 
						 | 
					@ -176,37 +327,9 @@ class Symbol(Struct):
 | 
				
			||||||
    key: str
 | 
					    key: str
 | 
				
			||||||
    tick_size: float = 0.01
 | 
					    tick_size: float = 0.01
 | 
				
			||||||
    lot_tick_size: float = 0.0  # "volume" precision as min step value
 | 
					    lot_tick_size: float = 0.0  # "volume" precision as min step value
 | 
				
			||||||
    tick_size_digits: int = 2
 | 
					 | 
				
			||||||
    lot_size_digits: int = 0
 | 
					 | 
				
			||||||
    suffix: str = ''
 | 
					    suffix: str = ''
 | 
				
			||||||
    broker_info: dict[str, dict[str, Any]] = {}
 | 
					    broker_info: dict[str, dict[str, Any]] = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					 | 
				
			||||||
    def from_broker_info(
 | 
					 | 
				
			||||||
        cls,
 | 
					 | 
				
			||||||
        broker: str,
 | 
					 | 
				
			||||||
        symbol: str,
 | 
					 | 
				
			||||||
        info: dict[str, Any],
 | 
					 | 
				
			||||||
        suffix: str = '',
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    ) -> Symbol:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        tick_size = info.get('price_tick_size', 0.01)
 | 
					 | 
				
			||||||
        lot_size = info.get('lot_tick_size', 0.0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return Symbol(
 | 
					 | 
				
			||||||
            key=symbol,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            tick_size=tick_size,
 | 
					 | 
				
			||||||
            lot_tick_size=lot_size,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            tick_size_digits=float_digits(tick_size),
 | 
					 | 
				
			||||||
            lot_size_digits=float_digits(lot_size),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            suffix=suffix,
 | 
					 | 
				
			||||||
            broker_info={broker: info},
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def from_fqsn(
 | 
					    def from_fqsn(
 | 
				
			||||||
        cls,
 | 
					        cls,
 | 
				
			||||||
| 
						 | 
					@ -215,13 +338,25 @@ class Symbol(Struct):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ) -> Symbol:
 | 
					    ) -> Symbol:
 | 
				
			||||||
        broker, key, suffix = unpack_fqsn(fqsn)
 | 
					        broker, key, suffix = unpack_fqsn(fqsn)
 | 
				
			||||||
        return cls.from_broker_info(
 | 
					        tick_size = info.get('price_tick_size', 0.01)
 | 
				
			||||||
            broker,
 | 
					        lot_size = info.get('lot_tick_size', 0.0)
 | 
				
			||||||
            key,
 | 
					
 | 
				
			||||||
            info=info,
 | 
					        return Symbol(
 | 
				
			||||||
 | 
					            key=key,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            tick_size=tick_size,
 | 
				
			||||||
 | 
					            lot_tick_size=lot_size,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # tick_size_digits=float_digits(tick_size),
 | 
				
			||||||
 | 
					            # lot_size_digits=float_digits(lot_size),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            suffix=suffix,
 | 
					            suffix=suffix,
 | 
				
			||||||
 | 
					            broker_info={broker: info},
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # compat name mapping
 | 
				
			||||||
 | 
					    from_fqme = from_fqsn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def type_key(self) -> str:
 | 
					    def type_key(self) -> str:
 | 
				
			||||||
        return list(self.broker_info.values())[0]['asset_type']
 | 
					        return list(self.broker_info.values())[0]['asset_type']
 | 
				
			||||||
| 
						 | 
					@ -230,38 +365,20 @@ class Symbol(Struct):
 | 
				
			||||||
    def brokers(self) -> list[str]:
 | 
					    def brokers(self) -> list[str]:
 | 
				
			||||||
        return list(self.broker_info.keys())
 | 
					        return list(self.broker_info.keys())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def nearest_tick(self, value: float) -> float:
 | 
					    @property
 | 
				
			||||||
        '''
 | 
					    def tick_size_digits(self) -> int:
 | 
				
			||||||
        Return the nearest tick value based on mininum increment.
 | 
					        return float_digits(self.lot_tick_size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        '''
 | 
					    @property
 | 
				
			||||||
        mult = 1 / self.tick_size
 | 
					    def lot_size_digits(self) -> int:
 | 
				
			||||||
        return round(value * mult) / mult
 | 
					        return float_digits(self.lot_tick_size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def front_feed(self) -> tuple[str, str]:
 | 
					    @property
 | 
				
			||||||
        '''
 | 
					    def broker(self) -> str:
 | 
				
			||||||
        Return the "current" feed key for this symbol.
 | 
					        return list(self.broker_info.keys())[0]
 | 
				
			||||||
 | 
					 | 
				
			||||||
        (i.e. the broker + symbol key in a tuple).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        '''
 | 
					 | 
				
			||||||
        return (
 | 
					 | 
				
			||||||
            list(self.broker_info.keys())[0],
 | 
					 | 
				
			||||||
            self.key,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def tokens(self) -> tuple[str]:
 | 
					 | 
				
			||||||
        broker, key = self.front_feed()
 | 
					 | 
				
			||||||
        if self.suffix:
 | 
					 | 
				
			||||||
            return (key, self.suffix, broker)
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            return (key, broker)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def fqsn(self) -> str:
 | 
					    def fqsn(self) -> str:
 | 
				
			||||||
        return '.'.join(self.tokens()).lower()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def front_fqsn(self) -> str:
 | 
					 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        fqsn = "fully qualified symbol name"
 | 
					        fqsn = "fully qualified symbol name"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -279,24 +396,30 @@ class Symbol(Struct):
 | 
				
			||||||
        <broker>.<venue>.<instrumentname>.<suffixwithmetadata>
 | 
					        <broker>.<venue>.<instrumentname>.<suffixwithmetadata>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        tokens = self.tokens()
 | 
					        broker = self.broker
 | 
				
			||||||
        fqsn = '.'.join(map(str.lower, tokens))
 | 
					        key = self.key
 | 
				
			||||||
        return fqsn
 | 
					        if self.suffix:
 | 
				
			||||||
 | 
					            tokens = (key, self.suffix, broker)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            tokens = (key, broker)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def quantize_size(
 | 
					        return '.'.join(tokens).lower()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fqme = fqsn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def quantize(
 | 
				
			||||||
        self,
 | 
					        self,
 | 
				
			||||||
        size: float,
 | 
					        size: float,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ) -> Decimal:
 | 
					    ) -> Decimal:
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        Truncate input ``size: float`` using ``Decimal``
 | 
					        Truncate input ``size: float`` using ``Decimal``
 | 
				
			||||||
        and ``.lot_size_digits``.
 | 
					        quantized form of the digit precision defined
 | 
				
			||||||
 | 
					        by ``self.lot_tick_size``.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        '''
 | 
					        '''
 | 
				
			||||||
        digits = self.lot_size_digits
 | 
					        digits = float_digits(self.lot_tick_size)
 | 
				
			||||||
        return Decimal(size).quantize(
 | 
					        return Decimal(size).quantize(
 | 
				
			||||||
            Decimal(f'1.{"0".ljust(digits, "0")}'),
 | 
					            Decimal(f'1.{"0".ljust(digits, "0")}'),
 | 
				
			||||||
            rounding=ROUND_HALF_EVEN
 | 
					            rounding=ROUND_HALF_EVEN
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue