Implement `MktPair.from_msg()` constructor

Handle case where `'dst'` field is just a `str` (in which case delegate to
`.from_fqme()`) as well as do `Asset` loading and use our
`Struct.copy()` to enforce type-casting to (for eg. `Decimal`s) such
that we'll now capture typing errors despite IPC transport.

Change `Symbol.tick_size` and `.lot_tick_size` defaults to decimal
for proper casting and type `MktPair.atype: str` since `msgspec` can't
cast to `AssetTypeName` without special handling..
pre_overruns_ctxcancelled
Tyler Goodlet 2023-03-21 13:59:06 -04:00
parent 901562cb6b
commit 98d8b4a0e8
1 changed files with 19 additions and 6 deletions

View File

@ -111,7 +111,7 @@ class Asset(Struct, frozen=True):
'''
name: str
atype: AssetTypeName
atype: str # AssetTypeName
# minimum transaction size / precision.
# eg. for buttcoin this is a "satoshi".
@ -223,7 +223,7 @@ class MktPair(Struct, frozen=True):
@classmethod
def from_msg(
self,
cls,
msg: dict[str, Any],
) -> MktPair:
@ -231,7 +231,17 @@ class MktPair(Struct, frozen=True):
Constructor for a received msg-dict normally received over IPC.
'''
raise NotImplementedError
dst_asset_msg = msg.pop('dst')
if isinstance(dst_asset_msg, str):
return cls.from_fqme(
dst_asset_msg,
**msg,
)
# NOTE: we call `.copy()` here to ensure
# type casting!
dst = Asset(**dst_asset_msg).copy()
return cls(dst=dst, **msg).copy()
@property
def resolved(self) -> bool:
@ -264,7 +274,7 @@ class MktPair(Struct, frozen=True):
broker=broker,
**kwargs,
)
).copy()
@property
def key(self) -> str:
@ -425,8 +435,11 @@ class Symbol(Struct):
'''
key: str
tick_size: Decimal = 0.01
lot_tick_size: Decimal = 0.0 # "volume" precision as min step value
# precision descriptors for price and vlm
tick_size: Decimal = Decimal('0.01')
lot_tick_size: Decimal = Decimal('0.0')
suffix: str = ''
broker_info: dict[str, dict[str, Any]] = {}