`.accounting._mktinfo`: better fqme `MktPair` handling
It needed some work.. - Make `unpack_fqme()` always return a 4-tuple handling the venue and suffix parts more generally. - add `Asset.Asset.guess_from_mkt_ep_key()` a like-it-sounds hack at trying to render a `.dst: Asset` for most most purposes throughout the stack. - always try to preprocess the input `fqme: str` with `unpack_fqme()` in `MktPair.from_fqme()` and use the new `Asset` method (above) to make up a `.dst: Asset` pulling as much meta-info we can from the caller. - add `MktPair.bs_fqme` to get the thing without the broker part.. - add an `'unknown'` value to the `_derivs` def. - drop `Symbol.from_fqsn()` and `unpack_fqsn()` more generally (yes BREAKING).rekt_pps
parent
53a41ba93d
commit
d4c8ba19a2
|
@ -54,6 +54,9 @@ _derivs: list[str] = [
|
||||||
'continuous_future',
|
'continuous_future',
|
||||||
'option',
|
'option',
|
||||||
'futures_option',
|
'futures_option',
|
||||||
|
|
||||||
|
# if we can't figure it out, presume the worst XD
|
||||||
|
'unknown',
|
||||||
]
|
]
|
||||||
|
|
||||||
# NOTE: a tag for other subsystems to try
|
# NOTE: a tag for other subsystems to try
|
||||||
|
@ -143,6 +146,39 @@ class Asset(Struct, frozen=True):
|
||||||
rounding=ROUND_HALF_EVEN
|
rounding=ROUND_HALF_EVEN
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def guess_from_mkt_ep_key(
|
||||||
|
cls,
|
||||||
|
mkt_ep_key: str,
|
||||||
|
atype: str | None = None,
|
||||||
|
|
||||||
|
) -> Asset:
|
||||||
|
'''
|
||||||
|
A hacky guess method for presuming a (target) asset's properties
|
||||||
|
based on either the actualy market endpoint key, or config settings
|
||||||
|
from the user.
|
||||||
|
|
||||||
|
'''
|
||||||
|
atype = atype or 'unknown'
|
||||||
|
|
||||||
|
# attempt to strip off any source asset
|
||||||
|
# via presumed syntax of:
|
||||||
|
# - <dst>/<src>
|
||||||
|
# - <dst>.<src>
|
||||||
|
# - etc.
|
||||||
|
for char in ['/', '.']:
|
||||||
|
dst, _, src = mkt_ep_key.partition(char)
|
||||||
|
if src:
|
||||||
|
if not atype:
|
||||||
|
atype = 'fiat'
|
||||||
|
break
|
||||||
|
|
||||||
|
return Asset(
|
||||||
|
name=dst,
|
||||||
|
atype=atype,
|
||||||
|
tx_tick=Decimal('0.01'),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def maybe_cons_tokens(
|
def maybe_cons_tokens(
|
||||||
tokens: list[Any],
|
tokens: list[Any],
|
||||||
|
@ -269,15 +305,28 @@ class MktPair(Struct, frozen=True):
|
||||||
def from_fqme(
|
def from_fqme(
|
||||||
cls,
|
cls,
|
||||||
fqme: str,
|
fqme: str,
|
||||||
|
|
||||||
price_tick: float | str,
|
price_tick: float | str,
|
||||||
size_tick: float | str,
|
size_tick: float | str,
|
||||||
bs_mktid: str,
|
bs_mktid: str,
|
||||||
|
|
||||||
|
broker: str | None = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
|
|
||||||
) -> MktPair:
|
) -> MktPair:
|
||||||
|
|
||||||
broker, key, suffix = unpack_fqme(fqme)
|
_fqme: str = fqme
|
||||||
|
if (
|
||||||
|
broker
|
||||||
|
and broker not in fqme
|
||||||
|
):
|
||||||
|
_fqme = f'{fqme}.{broker}'
|
||||||
|
|
||||||
|
broker, mkt_ep_key, venue, suffix = unpack_fqme(_fqme)
|
||||||
|
dst: Asset = Asset.guess_from_mkt_ep_key(
|
||||||
|
mkt_ep_key,
|
||||||
|
atype=kwargs.get('_atype'),
|
||||||
|
)
|
||||||
|
|
||||||
# XXX: loading from a fqme string will
|
# XXX: loading from a fqme string will
|
||||||
# leave this pair as "un resolved" meaning
|
# leave this pair as "un resolved" meaning
|
||||||
|
@ -285,13 +334,21 @@ class MktPair(Struct, frozen=True):
|
||||||
# which we expect to be filled in by some
|
# which we expect to be filled in by some
|
||||||
# backend client with access to that data-info.
|
# backend client with access to that data-info.
|
||||||
return cls(
|
return cls(
|
||||||
dst=key, # not resolved
|
# XXX: not resolved to ``Asset`` :(
|
||||||
|
dst=dst,
|
||||||
|
|
||||||
|
broker=broker,
|
||||||
|
venue=venue,
|
||||||
|
# XXX NOTE: we presume this token
|
||||||
|
# if the expiry for now!
|
||||||
|
expiry=suffix,
|
||||||
|
|
||||||
price_tick=price_tick,
|
price_tick=price_tick,
|
||||||
size_tick=size_tick,
|
size_tick=size_tick,
|
||||||
bs_mktid=bs_mktid,
|
bs_mktid=bs_mktid,
|
||||||
broker=broker,
|
|
||||||
|
|
||||||
**kwargs,
|
**kwargs,
|
||||||
|
|
||||||
).copy()
|
).copy()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -381,6 +438,14 @@ class MktPair(Struct, frozen=True):
|
||||||
self.broker,
|
self.broker,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bs_fqme(self) -> str:
|
||||||
|
'''
|
||||||
|
FQME sin broker part XD
|
||||||
|
|
||||||
|
'''
|
||||||
|
return self.fqme.rstrip(f'.{self.broker}')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fqsn(self) -> str:
|
def fqsn(self) -> str:
|
||||||
return self.fqme
|
return self.fqme
|
||||||
|
@ -428,7 +493,9 @@ class MktPair(Struct, frozen=True):
|
||||||
def unpack_fqme(
|
def unpack_fqme(
|
||||||
fqme: str,
|
fqme: str,
|
||||||
|
|
||||||
) -> tuple[str, str, str]:
|
broker: str | None = None
|
||||||
|
|
||||||
|
) -> tuple[str, ...]:
|
||||||
'''
|
'''
|
||||||
Unpack a fully-qualified-symbol-name to ``tuple``.
|
Unpack a fully-qualified-symbol-name to ``tuple``.
|
||||||
|
|
||||||
|
@ -442,17 +509,26 @@ def unpack_fqme(
|
||||||
match tokens:
|
match tokens:
|
||||||
case [mkt_ep, broker]:
|
case [mkt_ep, broker]:
|
||||||
# probably crypto
|
# probably crypto
|
||||||
# mkt_ep, broker = tokens
|
|
||||||
return (
|
return (
|
||||||
broker,
|
broker,
|
||||||
mkt_ep,
|
mkt_ep,
|
||||||
'',
|
'',
|
||||||
|
'',
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO: swap venue and suffix/deriv-info here?
|
# TODO: swap venue and suffix/deriv-info here?
|
||||||
case [mkt_ep, venue, suffix, broker]:
|
case [mkt_ep, venue, suffix, broker]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# handle `bs_mktid` + `broker` input case
|
||||||
|
case [
|
||||||
|
mkt_ep, venue, suffix
|
||||||
|
] if (
|
||||||
|
broker
|
||||||
|
and suffix != broker
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
case [mkt_ep, venue, broker]:
|
case [mkt_ep, venue, broker]:
|
||||||
suffix = ''
|
suffix = ''
|
||||||
|
|
||||||
|
@ -461,14 +537,13 @@ def unpack_fqme(
|
||||||
|
|
||||||
return (
|
return (
|
||||||
broker,
|
broker,
|
||||||
'.'.join([mkt_ep, venue]),
|
mkt_ep,
|
||||||
|
venue,
|
||||||
|
# '.'.join([mkt_ep, venue]),
|
||||||
suffix,
|
suffix,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
unpack_fqsn = unpack_fqme
|
|
||||||
|
|
||||||
|
|
||||||
class Symbol(Struct):
|
class Symbol(Struct):
|
||||||
'''
|
'''
|
||||||
I guess this is some kinda container thing for dealing with
|
I guess this is some kinda container thing for dealing with
|
||||||
|
@ -485,27 +560,26 @@ class Symbol(Struct):
|
||||||
broker_info: dict[str, dict[str, Any]] = {}
|
broker_info: dict[str, dict[str, Any]] = {}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_fqsn(
|
def from_fqme(
|
||||||
cls,
|
cls,
|
||||||
fqsn: str,
|
fqsn: str,
|
||||||
info: dict[str, Any],
|
info: dict[str, Any],
|
||||||
|
|
||||||
) -> Symbol:
|
) -> Symbol:
|
||||||
broker, key, suffix = unpack_fqsn(fqsn)
|
broker, mktep, venue, suffix = unpack_fqme(fqsn)
|
||||||
tick_size = info.get('price_tick_size', 0.01)
|
tick_size = info.get('price_tick_size', 0.01)
|
||||||
lot_size = info.get('lot_tick_size', 0.0)
|
lot_size = info.get('lot_tick_size', 0.0)
|
||||||
|
|
||||||
return Symbol(
|
return Symbol(
|
||||||
key=key,
|
broker=broker,
|
||||||
|
key=mktep,
|
||||||
tick_size=tick_size,
|
tick_size=tick_size,
|
||||||
lot_tick_size=lot_size,
|
lot_tick_size=lot_size,
|
||||||
|
venue=venue,
|
||||||
suffix=suffix,
|
suffix=suffix,
|
||||||
broker_info={broker: info},
|
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']
|
||||||
|
|
Loading…
Reference in New Issue