Compute symbol digits at creation time
Add a new factory func `mk_symbol()` to create the initial instance at feed creation time.fsp_feeds
parent
6744f59c58
commit
dfb9c55944
|
@ -62,6 +62,9 @@ tf_in_1m = {
|
||||||
def float_digits(
|
def float_digits(
|
||||||
value: float,
|
value: float,
|
||||||
) -> int:
|
) -> int:
|
||||||
|
if value == 0:
|
||||||
|
return 0
|
||||||
|
|
||||||
return int(-decimal.Decimal(str(value)).as_tuple().exponent)
|
return int(-decimal.Decimal(str(value)).as_tuple().exponent)
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,28 +85,20 @@ class Symbol(BaseModel):
|
||||||
Yah, i guess dats what it izz.
|
Yah, i guess dats what it izz.
|
||||||
"""
|
"""
|
||||||
key: str
|
key: str
|
||||||
tick_size: float = 0.01
|
type_key: str # {'stock', 'forex', 'future', ... etc.}
|
||||||
lot_tick_size: float = 0.01 # "volume" precision as min step value
|
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]] = {}
|
broker_info: Dict[str, Dict[str, Any]] = {}
|
||||||
|
|
||||||
# specifies a "class" of financial instrument
|
# specifies a "class" of financial instrument
|
||||||
# ex. stock, futer, option, bond etc.
|
# ex. stock, futer, option, bond etc.
|
||||||
type_key: str
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def brokers(self) -> List[str]:
|
def brokers(self) -> List[str]:
|
||||||
return list(self.broker_info.keys())
|
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:
|
def nearest_tick(self, value: float) -> float:
|
||||||
"""Return the nearest tick value based on mininum increment.
|
"""Return the nearest tick value based on mininum increment.
|
||||||
|
|
||||||
|
@ -112,6 +107,30 @@ class Symbol(BaseModel):
|
||||||
return round(value * mult) / mult
|
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(
|
def from_df(
|
||||||
df: pd.DataFrame,
|
df: pd.DataFrame,
|
||||||
source=None,
|
source=None,
|
||||||
|
|
|
@ -49,7 +49,7 @@ from ._sharedmem import (
|
||||||
ShmArray,
|
ShmArray,
|
||||||
)
|
)
|
||||||
from .ingest import get_ingestormod
|
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 ..ui import _search
|
||||||
from ._sampling import (
|
from ._sampling import (
|
||||||
_shms,
|
_shms,
|
||||||
|
@ -535,7 +535,7 @@ async def open_feed(
|
||||||
si = data['symbol_info']
|
si = data['symbol_info']
|
||||||
ohlc_sample_rates.append(data['sample_rate'])
|
ohlc_sample_rates.append(data['sample_rate'])
|
||||||
|
|
||||||
symbol = Symbol(
|
symbol = mk_symbol(
|
||||||
key=sym,
|
key=sym,
|
||||||
type_key=si.get('asset_type', 'forex'),
|
type_key=si.get('asset_type', 'forex'),
|
||||||
tick_size=si.get('price_tick_size', 0.01),
|
tick_size=si.get('price_tick_size', 0.01),
|
||||||
|
|
|
@ -371,7 +371,7 @@ class LinkedSplits(QWidget):
|
||||||
# add crosshairs
|
# add crosshairs
|
||||||
self.cursor = Cursor(
|
self.cursor = Cursor(
|
||||||
linkedsplits=self,
|
linkedsplits=self,
|
||||||
digits=symbol.digits(),
|
digits=symbol.tick_size_digits,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.chart = self.add_plot(
|
self.chart = self.add_plot(
|
||||||
|
@ -882,7 +882,7 @@ class ChartPlotWidget(pg.PlotWidget):
|
||||||
# use the tick size precision for display
|
# use the tick size precision for display
|
||||||
sym = self.linked.symbol
|
sym = self.linked.symbol
|
||||||
if name == sym.key:
|
if name == sym.key:
|
||||||
digits = sym.digits()
|
digits = sym.tick_size_digits
|
||||||
else:
|
else:
|
||||||
digits = 2
|
digits = 2
|
||||||
|
|
||||||
|
@ -1144,8 +1144,8 @@ async def chart_from_quotes(
|
||||||
l1 = L1Labels(
|
l1 = L1Labels(
|
||||||
chart,
|
chart,
|
||||||
# determine precision/decimal lengths
|
# determine precision/decimal lengths
|
||||||
digits=symbol.digits(),
|
digits=symbol.tick_size_digits,
|
||||||
size_digits=symbol.lot_digits(),
|
size_digits=symbol.lot_size_digits,
|
||||||
)
|
)
|
||||||
chart._l1_labels = l1
|
chart._l1_labels = l1
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ def mk_alloc(
|
||||||
'''
|
'''
|
||||||
tracker = self._position
|
tracker = self._position
|
||||||
pp_size = tracker.live_pp.size
|
pp_size = tracker.live_pp.size
|
||||||
ld = symbol.lot_digits()
|
ld = symbol.lot_size_digits
|
||||||
|
|
||||||
if (
|
if (
|
||||||
action == 'buy' and pp_size > 0 or
|
action == 'buy' and pp_size > 0 or
|
||||||
|
@ -289,7 +289,7 @@ class PositionTracker:
|
||||||
)
|
)
|
||||||
pp_label.render()
|
pp_label.render()
|
||||||
|
|
||||||
nsize = self.chart.linked.symbol.lot_digits()
|
nsize = self.chart.linked.symbol.lot_size_digits
|
||||||
|
|
||||||
self.size_label = size_label = Label(
|
self.size_label = size_label = Label(
|
||||||
view=view,
|
view=view,
|
||||||
|
|
|
@ -116,12 +116,9 @@ class OrderMode:
|
||||||
# TODO: convert these values into human-readable form
|
# TODO: convert these values into human-readable form
|
||||||
# (i.e. with k, m, M, B) type embedded suffixes
|
# (i.e. with k, m, M, B) type embedded suffixes
|
||||||
level=order.price,
|
level=order.price,
|
||||||
# level_digits=symbol.digits(),
|
|
||||||
action=order.action,
|
action=order.action,
|
||||||
|
|
||||||
size=order.size,
|
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],
|
color=self._colors[order.action],
|
||||||
|
|
||||||
dotted=True if (
|
dotted=True if (
|
||||||
|
|
Loading…
Reference in New Issue