Compute symbol digits at creation time

Add a new factory func `mk_symbol()` to create the initial
instance at feed creation time.
fsp_feeds
Tyler Goodlet 2021-08-18 10:08:57 -04:00
parent 6744f59c58
commit dfb9c55944
5 changed files with 40 additions and 24 deletions

View File

@ -62,6 +62,9 @@ tf_in_1m = {
def float_digits(
value: float,
) -> int:
if value == 0:
return 0
return int(-decimal.Decimal(str(value)).as_tuple().exponent)
@ -82,28 +85,20 @@ class Symbol(BaseModel):
Yah, i guess dats what it izz.
"""
key: str
tick_size: float = 0.01
lot_tick_size: float = 0.01 # "volume" precision as min step value
type_key: str # {'stock', 'forex', 'future', ... etc.}
tick_size: float
lot_tick_size: float # "volume" precision as min step value
tick_size_digits: int
lot_size_digits: int
broker_info: Dict[str, Dict[str, Any]] = {}
# specifies a "class" of financial instrument
# ex. stock, futer, option, bond etc.
type_key: str
@property
def brokers(self) -> List[str]:
return list(self.broker_info.keys())
def digits(self) -> int:
"""Return the trailing number of digits specified by the min
tick size for the instrument.
"""
return float_digits(self.tick_size)
def lot_digits(self) -> int:
return float_digits(self.lot_tick_size)
def nearest_tick(self, value: float) -> float:
"""Return the nearest tick value based on mininum increment.
@ -112,6 +107,30 @@ class Symbol(BaseModel):
return round(value * mult) / mult
def mk_symbol(
key: str,
type_key: str,
tick_size: float = 0.01,
lot_tick_size: float = 0,
broker_info: dict[str, Any] = {},
) -> Symbol:
'''Create and return an instrument description for the
"symbol" named as ``key``.
'''
return Symbol(
key=key,
type_key=type_key,
tick_size=tick_size,
lot_tick_size=lot_tick_size,
tick_size_digits=float_digits(tick_size),
lot_size_digits=float_digits(lot_tick_size),
broker_info=broker_info,
)
def from_df(
df: pd.DataFrame,
source=None,

View File

@ -49,7 +49,7 @@ from ._sharedmem import (
ShmArray,
)
from .ingest import get_ingestormod
from ._source import base_iohlc_dtype, Symbol
from ._source import base_iohlc_dtype, mk_symbol, Symbol
from ..ui import _search
from ._sampling import (
_shms,
@ -535,7 +535,7 @@ async def open_feed(
si = data['symbol_info']
ohlc_sample_rates.append(data['sample_rate'])
symbol = Symbol(
symbol = mk_symbol(
key=sym,
type_key=si.get('asset_type', 'forex'),
tick_size=si.get('price_tick_size', 0.01),

View File

@ -371,7 +371,7 @@ class LinkedSplits(QWidget):
# add crosshairs
self.cursor = Cursor(
linkedsplits=self,
digits=symbol.digits(),
digits=symbol.tick_size_digits,
)
self.chart = self.add_plot(
@ -882,7 +882,7 @@ class ChartPlotWidget(pg.PlotWidget):
# use the tick size precision for display
sym = self.linked.symbol
if name == sym.key:
digits = sym.digits()
digits = sym.tick_size_digits
else:
digits = 2
@ -1144,8 +1144,8 @@ async def chart_from_quotes(
l1 = L1Labels(
chart,
# determine precision/decimal lengths
digits=symbol.digits(),
size_digits=symbol.lot_digits(),
digits=symbol.tick_size_digits,
size_digits=symbol.lot_size_digits,
)
chart._l1_labels = l1

View File

@ -169,7 +169,7 @@ def mk_alloc(
'''
tracker = self._position
pp_size = tracker.live_pp.size
ld = symbol.lot_digits()
ld = symbol.lot_size_digits
if (
action == 'buy' and pp_size > 0 or
@ -289,7 +289,7 @@ class PositionTracker:
)
pp_label.render()
nsize = self.chart.linked.symbol.lot_digits()
nsize = self.chart.linked.symbol.lot_size_digits
self.size_label = size_label = Label(
view=view,

View File

@ -116,12 +116,9 @@ class OrderMode:
# TODO: convert these values into human-readable form
# (i.e. with k, m, M, B) type embedded suffixes
level=order.price,
# level_digits=symbol.digits(),
action=order.action,
size=order.size,
# TODO: we need truncation checks in the EMS for this?
# size_digits=min(symbol.lot_digits(), 3),
color=self._colors[order.action],
dotted=True if (