onetick-py 1.163.0__py3-none-any.whl → 1.165.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- locator_parser/actions.py +10 -14
- locator_parser/common.py +13 -10
- locator_parser/io.py +6 -4
- locator_parser/locator.py +1 -1
- onetick/doc_utilities/ot_doctest.py +1 -1
- onetick/doc_utilities/snippets.py +1 -2
- onetick/lib/instance.py +7 -4
- onetick/py/__init__.py +5 -9
- onetick/py/_version.py +1 -1
- onetick/py/aggregations/_base.py +7 -4
- onetick/py/aggregations/_docs.py +1 -1
- onetick/py/aggregations/other.py +1 -1
- onetick/py/cache.py +1 -0
- onetick/py/callback/callback.py +1 -0
- onetick/py/core/_internal/_proxy_node.py +1 -1
- onetick/py/core/_internal/_state_objects.py +2 -2
- onetick/py/core/_source/source_methods/aggregations.py +8 -9
- onetick/py/core/_source/source_methods/applyers.py +2 -2
- onetick/py/core/_source/source_methods/debugs.py +16 -14
- onetick/py/core/_source/source_methods/drops.py +1 -1
- onetick/py/core/_source/source_methods/fields.py +5 -5
- onetick/py/core/_source/source_methods/filters.py +4 -3
- onetick/py/core/_source/source_methods/joins.py +6 -6
- onetick/py/core/_source/source_methods/misc.py +84 -0
- onetick/py/core/_source/source_methods/renames.py +3 -3
- onetick/py/core/_source/source_methods/switches.py +3 -3
- onetick/py/core/_source/source_methods/writes.py +279 -10
- onetick/py/core/_source/tmp_otq.py +1 -1
- onetick/py/core/column_operations/_methods/_internal.py +1 -1
- onetick/py/core/column_operations/_methods/methods.py +8 -7
- onetick/py/core/column_operations/_methods/op_types.py +1 -0
- onetick/py/core/column_operations/accessors/dt_accessor.py +4 -0
- onetick/py/core/column_operations/base.py +5 -5
- onetick/py/core/cut_builder.py +1 -0
- onetick/py/core/eval_query.py +1 -0
- onetick/py/core/lambda_object.py +2 -3
- onetick/py/core/per_tick_script.py +6 -5
- onetick/py/core/query_inspector.py +6 -7
- onetick/py/core/source.py +82 -9
- onetick/py/db/_inspection.py +4 -8
- onetick/py/db/db.py +4 -100
- onetick/py/docs/docstring_parser.py +1 -1
- onetick/py/functions.py +1 -0
- onetick/py/license.py +2 -0
- onetick/py/math.py +2 -2
- onetick/py/otq.py +1 -2
- onetick/py/run.py +8 -7
- onetick/py/servers.py +2 -2
- onetick/py/session.py +8 -6
- onetick/py/sources/common.py +6 -4
- onetick/py/sources/data_source.py +25 -35
- onetick/py/sources/query.py +7 -7
- onetick/py/sources/symbols.py +1 -1
- onetick/py/sources/ticks.py +3 -3
- onetick/py/state.py +1 -0
- onetick/py/types.py +27 -25
- onetick/py/utils/config.py +2 -2
- onetick/py/utils/perf.py +2 -3
- onetick/py/utils/render.py +12 -3
- onetick/py/utils/temp.py +2 -2
- {onetick_py-1.163.0.dist-info → onetick_py-1.165.0.dist-info}/METADATA +3 -3
- {onetick_py-1.163.0.dist-info → onetick_py-1.165.0.dist-info}/RECORD +66 -66
- {onetick_py-1.163.0.dist-info → onetick_py-1.165.0.dist-info}/WHEEL +0 -0
- {onetick_py-1.163.0.dist-info → onetick_py-1.165.0.dist-info}/entry_points.txt +0 -0
- {onetick_py-1.163.0.dist-info → onetick_py-1.165.0.dist-info}/licenses/LICENSE +0 -0
- {onetick_py-1.163.0.dist-info → onetick_py-1.165.0.dist-info}/top_level.txt +0 -0
onetick/py/core/lambda_object.py
CHANGED
|
@@ -253,7 +253,7 @@ class _EmulateObject(_EmulateInputObject):
|
|
|
253
253
|
|
|
254
254
|
def __setattr__(self, key, value):
|
|
255
255
|
if key in self.__class__.__dict__:
|
|
256
|
-
|
|
256
|
+
super().__setattr__(key, value)
|
|
257
257
|
if key not in self.__dict__ or key in _EmulateObject.NEW_VALUES:
|
|
258
258
|
_EmulateObject.NEW_VALUES[key].append(value)
|
|
259
259
|
if key not in self.__dict__:
|
|
@@ -381,8 +381,7 @@ class _EmulateObject(_EmulateInputObject):
|
|
|
381
381
|
|
|
382
382
|
def _validate_lambda(lambda_f):
|
|
383
383
|
if not (isinstance(lambda_f, types.LambdaType) and lambda_f.__name__ == '<lambda>'
|
|
384
|
-
or isinstance(lambda_f, types.FunctionType)
|
|
385
|
-
or isinstance(lambda_f, types.MethodType)):
|
|
384
|
+
or isinstance(lambda_f, (types.FunctionType, types.MethodType))):
|
|
386
385
|
raise ValueError("It is expected to get a function, method or lambda,"
|
|
387
386
|
f" but got '{lambda_f}' of type '{type(lambda_f)}'")
|
|
388
387
|
|
|
@@ -329,7 +329,7 @@ class Expression:
|
|
|
329
329
|
@property
|
|
330
330
|
def is_dynamic_tick(self) -> bool:
|
|
331
331
|
try:
|
|
332
|
-
return
|
|
332
|
+
return isinstance(self.value, _DynamicTick)
|
|
333
333
|
except ValueError:
|
|
334
334
|
return False
|
|
335
335
|
|
|
@@ -585,7 +585,7 @@ class ExpressionParser:
|
|
|
585
585
|
value = self.fun.emulator if self.fun.emulator is not None else expr.id
|
|
586
586
|
return Expression(value)
|
|
587
587
|
|
|
588
|
-
if
|
|
588
|
+
if not isinstance(expr.ctx, ast.Load):
|
|
589
589
|
# local variable, left-hand side
|
|
590
590
|
return Expression(LocalVariable(expr.id))
|
|
591
591
|
|
|
@@ -603,6 +603,7 @@ class ExpressionParser:
|
|
|
603
603
|
# parameter of the per-tick script function
|
|
604
604
|
return Expression(_Operation(op_str=expr.id, dtype=self.fun.args_annotations[expr.id]))
|
|
605
605
|
|
|
606
|
+
# pylint: disable-next=eval-used
|
|
606
607
|
value = eval(expr.id, self.fun.closure_vars.globals, self.fun.closure_vars.nonlocals) # type: ignore[arg-type]
|
|
607
608
|
return Expression(value)
|
|
608
609
|
|
|
@@ -632,7 +633,7 @@ class ExpressionParser:
|
|
|
632
633
|
val = self.expression(expr.value)
|
|
633
634
|
item = self.expression(expr.slice)
|
|
634
635
|
|
|
635
|
-
if
|
|
636
|
+
if isinstance(expr.ctx, ast.Load):
|
|
636
637
|
v = val.value[item.value]
|
|
637
638
|
return Expression(v)
|
|
638
639
|
|
|
@@ -657,7 +658,7 @@ class ExpressionParser:
|
|
|
657
658
|
val = self.expression(expr.value)
|
|
658
659
|
attr = expr.attr
|
|
659
660
|
|
|
660
|
-
if
|
|
661
|
+
if isinstance(expr.ctx, ast.Load):
|
|
661
662
|
v = getattr(val.value, attr)
|
|
662
663
|
return Expression(v)
|
|
663
664
|
|
|
@@ -1007,7 +1008,7 @@ class CaseExpressionParser(ExpressionParser):
|
|
|
1007
1008
|
def get_if_expr(first, second):
|
|
1008
1009
|
if isinstance(expr.op, ast.Or):
|
|
1009
1010
|
return ast.IfExp(test=first, body=first, orelse=second)
|
|
1010
|
-
|
|
1011
|
+
else:
|
|
1011
1012
|
return ast.IfExp(test=first, body=second, orelse=first)
|
|
1012
1013
|
|
|
1013
1014
|
first = None
|
|
@@ -101,7 +101,7 @@ def get_query_info(otq_path, query_name="", inspected_graphs=None):
|
|
|
101
101
|
stack_info = res.group(1)
|
|
102
102
|
return ep_name, stack_info
|
|
103
103
|
|
|
104
|
-
graph = defaultdict(
|
|
104
|
+
graph = defaultdict(Node)
|
|
105
105
|
|
|
106
106
|
if not os.path.exists(otq_path):
|
|
107
107
|
raise FileNotFoundError(f'otq "{otq_path}" is not found')
|
|
@@ -176,7 +176,7 @@ def get_query_info(otq_path, query_name="", inspected_graphs=None):
|
|
|
176
176
|
graph[num].PARAMETERS[inner_param_name] = inner_param_value
|
|
177
177
|
continue
|
|
178
178
|
|
|
179
|
-
if param
|
|
179
|
+
if param in ("SOURCE", "SINK"):
|
|
180
180
|
sources = []
|
|
181
181
|
|
|
182
182
|
for v in value.split():
|
|
@@ -199,8 +199,6 @@ def get_query_info(otq_path, query_name="", inspected_graphs=None):
|
|
|
199
199
|
else:
|
|
200
200
|
setattr(graph[num], param, value)
|
|
201
201
|
|
|
202
|
-
# with
|
|
203
|
-
|
|
204
202
|
if not found:
|
|
205
203
|
raise QueryNotFoundError(f'Query "{query_name}" is not found in the {otq_path}')
|
|
206
204
|
|
|
@@ -233,6 +231,8 @@ def get_query_info(otq_path, query_name="", inspected_graphs=None):
|
|
|
233
231
|
address = node.PARAMETERS["OTQ_NODE"]
|
|
234
232
|
elif hasattr(node, "PH_PATH"):
|
|
235
233
|
address = node.PH_PATH
|
|
234
|
+
else:
|
|
235
|
+
raise ValueError("Can't get NESTED_OTQ address")
|
|
236
236
|
|
|
237
237
|
node.EP = "NESTED_OTQ " + address
|
|
238
238
|
|
|
@@ -263,7 +263,7 @@ def get_query_info(otq_path, query_name="", inspected_graphs=None):
|
|
|
263
263
|
|
|
264
264
|
def _search_for_bound_sink(self, root, bound_symbol_info):
|
|
265
265
|
if root in bound_symbol_info:
|
|
266
|
-
return
|
|
266
|
+
return
|
|
267
267
|
|
|
268
268
|
if not is_commented_out(self.nodes[root]):
|
|
269
269
|
# A commented node cannot have its own bound symbols, but can have a bound sink
|
|
@@ -419,7 +419,7 @@ def add_pins(otq_path, query_name, specification):
|
|
|
419
419
|
if res:
|
|
420
420
|
for inx, v in enumerate(specification):
|
|
421
421
|
node, pin_flag, pin_name = v
|
|
422
|
-
if node.NUM == num:
|
|
422
|
+
if node.NUM == num: # noqa
|
|
423
423
|
if pin_flag is None:
|
|
424
424
|
continue
|
|
425
425
|
node_name = "NODE_" + str(num)
|
|
@@ -432,7 +432,6 @@ def add_pins(otq_path, query_name, specification):
|
|
|
432
432
|
|
|
433
433
|
# don't use this specification item anymore
|
|
434
434
|
specification[inx] = (node, None, None)
|
|
435
|
-
# with
|
|
436
435
|
|
|
437
436
|
with open(otq_path, "w") as fout:
|
|
438
437
|
fout.write(out.getvalue())
|
onetick/py/core/source.py
CHANGED
|
@@ -24,7 +24,7 @@ from onetick.py.core._source.tmp_otq import TmpOtq
|
|
|
24
24
|
from onetick.py.core.column import _Column
|
|
25
25
|
from onetick.py.core.column_operations.base import _Operation, OnetickParameter
|
|
26
26
|
from onetick.py.core.query_inspector import get_query_parameter_list
|
|
27
|
-
from onetick.py.utils import adaptive, adaptive_to_default, default
|
|
27
|
+
from onetick.py.utils import adaptive, adaptive_to_default, default, render_otq
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
def _is_dict_required(symbols):
|
|
@@ -362,9 +362,9 @@ class Source:
|
|
|
362
362
|
raise KeyError(f'Column name {name} is not in the schema. Please, check that this column '
|
|
363
363
|
'is in the schema or add it using the .schema property')
|
|
364
364
|
|
|
365
|
-
if name
|
|
365
|
+
if name in (0, 1):
|
|
366
366
|
raise ValueError(f"constant {name} are not supported for indexing for now, please use otp.Empty")
|
|
367
|
-
if
|
|
367
|
+
if isinstance(name, (int, float)):
|
|
368
368
|
raise ValueError("integer indexes are not supported")
|
|
369
369
|
self.__dict__[name] = _Column(name, dtype, self)
|
|
370
370
|
else:
|
|
@@ -775,6 +775,7 @@ class Source:
|
|
|
775
775
|
)
|
|
776
776
|
|
|
777
777
|
return mqt_ep
|
|
778
|
+
return None
|
|
778
779
|
|
|
779
780
|
def _set_date_range_and_symbols(self, symbols=None, start=None, end=None):
|
|
780
781
|
# will modify self
|
|
@@ -938,6 +939,76 @@ class Source:
|
|
|
938
939
|
kwargs.setdefault('verbose', True)
|
|
939
940
|
self.to_graph().render(**kwargs)
|
|
940
941
|
|
|
942
|
+
def render_otq(
|
|
943
|
+
self,
|
|
944
|
+
image_path: Optional[str] = None,
|
|
945
|
+
output_format: Optional[str] = None,
|
|
946
|
+
load_external_otqs: bool = True,
|
|
947
|
+
view: bool = False,
|
|
948
|
+
line_limit: Optional[Tuple[int, int]] = (10, 30),
|
|
949
|
+
parse_eval_from_params: bool = False,
|
|
950
|
+
debug: bool = False,
|
|
951
|
+
**kwargs,
|
|
952
|
+
):
|
|
953
|
+
"""
|
|
954
|
+
Render current :py:class:`~onetick.py.Source` graph.
|
|
955
|
+
|
|
956
|
+
Parameters
|
|
957
|
+
----------
|
|
958
|
+
image_path: str, None
|
|
959
|
+
Path for generated image. If omitted, image will be saved in a temp dir
|
|
960
|
+
output_format: str, None
|
|
961
|
+
`Graphviz` rendering format. Default: `png`.
|
|
962
|
+
If `image_path` contains one of next extensions, `output_format` will be set automatically:
|
|
963
|
+
`png`, `svg`, `dot`.
|
|
964
|
+
load_external_otqs: bool
|
|
965
|
+
If set to `True` (default) dependencies from external .otq files (not listed in ``path`` param)
|
|
966
|
+
will be loaded automatically.
|
|
967
|
+
view: bool
|
|
968
|
+
Defines should generated image be shown after render.
|
|
969
|
+
line_limit: Tuple[int, int], None
|
|
970
|
+
Limit for maximum number of lines and length of some EP parameters strings.
|
|
971
|
+
First param is limit of lines, second - limit of characters in each line.
|
|
972
|
+
If set to None limit disabled.
|
|
973
|
+
If one of tuple values set to zero the corresponding limit disabled.
|
|
974
|
+
parse_eval_from_params: bool
|
|
975
|
+
Enable parsing and printing `eval` sub-queries from EP parameters.
|
|
976
|
+
debug: bool
|
|
977
|
+
Allow to print stdout or stderr from `Graphviz` render.
|
|
978
|
+
kwargs:
|
|
979
|
+
Additional arguments to be passed to :py:meth:`onetick.py.Source.to_otq` method (except
|
|
980
|
+
``file_name``, ``file_suffix`` and ``query_name`` parameters)
|
|
981
|
+
|
|
982
|
+
Returns
|
|
983
|
+
-------
|
|
984
|
+
Path to rendered image
|
|
985
|
+
|
|
986
|
+
See also
|
|
987
|
+
--------
|
|
988
|
+
:py:func:`render_otq <onetick.py.utils.render_otq>`
|
|
989
|
+
|
|
990
|
+
Examples
|
|
991
|
+
--------
|
|
992
|
+
|
|
993
|
+
>>> data = otp.DataSource(db='US_COMP', tick_type='TRD', symbols='AAA') # doctest: +SKIP
|
|
994
|
+
>>> data1, data2 = data[(data['PRICE'] > 50)] # doctest: +SKIP
|
|
995
|
+
>>> data = otp.merge([data1, data2]) # doctest: +SKIP
|
|
996
|
+
>>> data.render_otq('./path/to/image.png') # doctest: +SKIP
|
|
997
|
+
|
|
998
|
+
.. image:: ../../static/testing/images/render_otq_3.png
|
|
999
|
+
"""
|
|
1000
|
+
|
|
1001
|
+
if {'file_name', 'file_suffix', 'query_name'} & kwargs.keys():
|
|
1002
|
+
raise ValueError(
|
|
1003
|
+
'It\'s not allowed to pass parameters `file_name`, `file_suffix` and `query_name` as `kwargs` '
|
|
1004
|
+
'in `render_otq` method.'
|
|
1005
|
+
)
|
|
1006
|
+
|
|
1007
|
+
otq_path = self.to_otq(**kwargs)
|
|
1008
|
+
return render_otq(
|
|
1009
|
+
otq_path, image_path, output_format, load_external_otqs, view, line_limit, parse_eval_from_params, debug,
|
|
1010
|
+
)
|
|
1011
|
+
|
|
941
1012
|
def copy(self, ep=None, columns=None, deep=False) -> 'Source':
|
|
942
1013
|
"""
|
|
943
1014
|
Build an object with copied calculation graph.
|
|
@@ -1208,7 +1279,7 @@ class Source:
|
|
|
1208
1279
|
if not (
|
|
1209
1280
|
issubclass(type(ep), otq.graph_components.EpBase)
|
|
1210
1281
|
or issubclass(type(ep), otq.graph_components.EpBase.PinnedEp)
|
|
1211
|
-
or
|
|
1282
|
+
or isinstance(ep, tuple)
|
|
1212
1283
|
):
|
|
1213
1284
|
raise TypeError("sinking is allowed only for EpBase instances")
|
|
1214
1285
|
|
|
@@ -1217,7 +1288,7 @@ class Source:
|
|
|
1217
1288
|
else:
|
|
1218
1289
|
obj = self.copy()
|
|
1219
1290
|
|
|
1220
|
-
if
|
|
1291
|
+
if isinstance(ep, tuple):
|
|
1221
1292
|
# for already existed EP fetched from _ProxyNode
|
|
1222
1293
|
obj.__node.sink(out_pin, *ep)
|
|
1223
1294
|
else:
|
|
@@ -1244,11 +1315,11 @@ class Source:
|
|
|
1244
1315
|
if not (
|
|
1245
1316
|
issubclass(type(ep), otq.graph_components.EpBase)
|
|
1246
1317
|
or issubclass(type(ep), otq.graph_components.EpBase.PinnedEp)
|
|
1247
|
-
or
|
|
1318
|
+
or isinstance(ep, tuple)
|
|
1248
1319
|
):
|
|
1249
1320
|
raise TypeError("sourcing is allowed only for EpBase instances")
|
|
1250
1321
|
|
|
1251
|
-
if
|
|
1322
|
+
if isinstance(ep, tuple):
|
|
1252
1323
|
# for already existed EP fetched from _ProxyNode
|
|
1253
1324
|
return self.__node.source(in_pin, *ep)
|
|
1254
1325
|
else:
|
|
@@ -1259,11 +1330,11 @@ class Source:
|
|
|
1259
1330
|
if not (
|
|
1260
1331
|
issubclass(type(ep), otq.graph_components.EpBase)
|
|
1261
1332
|
or issubclass(type(ep), otq.graph_components.EpBase.PinnedEp)
|
|
1262
|
-
or
|
|
1333
|
+
or isinstance(ep, tuple)
|
|
1263
1334
|
):
|
|
1264
1335
|
raise TypeError("sourcing is allowed only for EpBase instances")
|
|
1265
1336
|
|
|
1266
|
-
if
|
|
1337
|
+
if isinstance(ep, tuple):
|
|
1267
1338
|
# for already existed EP fetched from _ProxyNode
|
|
1268
1339
|
return self.__node.source_by_key(to_key, *ep)
|
|
1269
1340
|
else:
|
|
@@ -1590,6 +1661,7 @@ class Source:
|
|
|
1590
1661
|
write,
|
|
1591
1662
|
write_parquet,
|
|
1592
1663
|
save_snapshot,
|
|
1664
|
+
write_text,
|
|
1593
1665
|
)
|
|
1594
1666
|
from ._source.source_methods.renames import ( # type: ignore[misc]
|
|
1595
1667
|
_add_prefix_and_suffix,
|
|
@@ -1632,6 +1704,7 @@ class Source:
|
|
|
1632
1704
|
from ._source.source_methods.misc import ( # type: ignore[misc]
|
|
1633
1705
|
pause,
|
|
1634
1706
|
insert_tick,
|
|
1707
|
+
insert_at_end,
|
|
1635
1708
|
transpose,
|
|
1636
1709
|
cache,
|
|
1637
1710
|
pnl_realized,
|
onetick/py/db/_inspection.py
CHANGED
|
@@ -278,9 +278,8 @@ class DB:
|
|
|
278
278
|
tz_gmt = gettz('GMT')
|
|
279
279
|
for inx in range(len(result)):
|
|
280
280
|
start_date = result['START_DATE'][inx]
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
start_date = 0
|
|
281
|
+
# On Windows datetime.fromtimestamp throws an OSError for negative values
|
|
282
|
+
start_date = max(start_date, 0)
|
|
284
283
|
start = datetime.fromtimestamp(start_date / 1000, tz=tz_gmt)
|
|
285
284
|
start = start.replace(tzinfo=None)
|
|
286
285
|
try:
|
|
@@ -376,8 +375,7 @@ class DB:
|
|
|
376
375
|
# future is not loaded yet
|
|
377
376
|
if locator_start > today:
|
|
378
377
|
continue
|
|
379
|
-
|
|
380
|
-
locator_end = today
|
|
378
|
+
locator_end = min(locator_end, today)
|
|
381
379
|
|
|
382
380
|
if respect_acl:
|
|
383
381
|
try:
|
|
@@ -627,7 +625,7 @@ class DB:
|
|
|
627
625
|
context=self.context)
|
|
628
626
|
|
|
629
627
|
result = get_schema(use_cache=True)
|
|
630
|
-
if
|
|
628
|
+
if result.empty:
|
|
631
629
|
# in case cache settings in database are bad (e.g. BEXRTS-1220)
|
|
632
630
|
result = get_schema(use_cache=False)
|
|
633
631
|
|
|
@@ -719,8 +717,6 @@ class DB:
|
|
|
719
717
|
>>> us_comp_db.symbols(date=otp.dt(2022, 3, 1), tick_type='TRD', pattern='^AAP.*')
|
|
720
718
|
['AAP', 'AAPL']
|
|
721
719
|
"""
|
|
722
|
-
import onetick.py as otp
|
|
723
|
-
|
|
724
720
|
if date is None:
|
|
725
721
|
date = self.last_date
|
|
726
722
|
if timezone is None:
|
onetick/py/db/db.py
CHANGED
|
@@ -182,7 +182,7 @@ class _DB:
|
|
|
182
182
|
def _format_params(params):
|
|
183
183
|
res = {}
|
|
184
184
|
for key, value in params.items():
|
|
185
|
-
if
|
|
185
|
+
if hasattr(value, 'strftime'):
|
|
186
186
|
res[key] = value.strftime("%Y%m%d%H%M%S")
|
|
187
187
|
else:
|
|
188
188
|
res[key] = str(value)
|
|
@@ -280,6 +280,8 @@ class _DB:
|
|
|
280
280
|
# because before there was no ability to get written ticks
|
|
281
281
|
if kwargs.get('propagate'):
|
|
282
282
|
return res
|
|
283
|
+
else:
|
|
284
|
+
return None
|
|
283
285
|
|
|
284
286
|
@property
|
|
285
287
|
def properties(self):
|
|
@@ -724,105 +726,6 @@ class DB(_DB):
|
|
|
724
726
|
return self._format_params(feed)
|
|
725
727
|
|
|
726
728
|
|
|
727
|
-
"""
|
|
728
|
-
Keep here as example of custom databases that can be defined in client code
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
P_CME = DB(
|
|
732
|
-
name="P_CME",
|
|
733
|
-
db_properties={
|
|
734
|
-
"symbology": "CTA",
|
|
735
|
-
"archive_compression_type": constants.compression_type.NATIVE_PLUS_GZIP,
|
|
736
|
-
"tick_search_max_boundary_offset_sec": 1800,
|
|
737
|
-
"tick_timestamp_type": "NANOS",
|
|
738
|
-
},
|
|
739
|
-
db_locations=[
|
|
740
|
-
{
|
|
741
|
-
"access_method": constants.access_method.SOCKET,
|
|
742
|
-
"location": "192.168.5.63:50025",
|
|
743
|
-
"start_time": datetime(year=2008, month=9, day=1),
|
|
744
|
-
"end_time": constants.DEFAULT_END_DATE,
|
|
745
|
-
}
|
|
746
|
-
],
|
|
747
|
-
)
|
|
748
|
-
|
|
749
|
-
MS127 = DB(
|
|
750
|
-
name="MS127",
|
|
751
|
-
db_properties={
|
|
752
|
-
"symbology": "MSGR",
|
|
753
|
-
"ref_data_db": "REF_DATA_MS127",
|
|
754
|
-
"archive_compression_type": constants.compression_type.NATIVE_PLUS_GZIP,
|
|
755
|
-
"ignore_previous_day_corrections_on_reload": "yes",
|
|
756
|
-
},
|
|
757
|
-
db_locations=[
|
|
758
|
-
{
|
|
759
|
-
"access_method": constants.access_method.SOCKET,
|
|
760
|
-
"location": "192.168.5.63:50025",
|
|
761
|
-
"start_time": datetime(year=2010, month=12, day=31),
|
|
762
|
-
"end_time": constants.DEFAULT_END_DATE,
|
|
763
|
-
}
|
|
764
|
-
],
|
|
765
|
-
)
|
|
766
|
-
|
|
767
|
-
MS44 = DB(
|
|
768
|
-
name="MS44",
|
|
769
|
-
db_properties={
|
|
770
|
-
"symbology": "MSGR",
|
|
771
|
-
"ref_data_db": "REF_DATA_MS44",
|
|
772
|
-
"archive_compression_type": constants.compression_type.NATIVE_PLUS_GZIP,
|
|
773
|
-
"ignore_previous_day_corrections_on_reload": "yes",
|
|
774
|
-
},
|
|
775
|
-
db_locations=[
|
|
776
|
-
{
|
|
777
|
-
"access_method": constants.access_method.SOCKET,
|
|
778
|
-
"location": "192.168.5.63:50025",
|
|
779
|
-
"start_time": datetime(year=2010, month=12, day=31),
|
|
780
|
-
"end_time": constants.DEFAULT_END_DATE,
|
|
781
|
-
}
|
|
782
|
-
],
|
|
783
|
-
)
|
|
784
|
-
|
|
785
|
-
TAQ_NBBO = DB(
|
|
786
|
-
name="TAQ_NBBO",
|
|
787
|
-
db_properties={
|
|
788
|
-
"symbology": "BZX",
|
|
789
|
-
"price_not_key": True,
|
|
790
|
-
"memory_data_max_life_hours": 30,
|
|
791
|
-
"memory_db_dir": "/onetick-tickdata-com/STORAGE_GATEWAY/DEEP_HISTORY/US_TED/NBBO/shmem",
|
|
792
|
-
"mmap_db_compression_type": constants.compression_type.NATIVE_PLUS_GZIP,
|
|
793
|
-
},
|
|
794
|
-
db_locations=[
|
|
795
|
-
{
|
|
796
|
-
"access_method": constants.access_method.FILE,
|
|
797
|
-
"location": "/onetick-tickdata-com/STORAGE_GATEWAY/DEEP_HISTORY/US_TED/NBBO/",
|
|
798
|
-
"start_time": datetime(year=2001, month=1, day=1),
|
|
799
|
-
"end_time": constants.DEFAULT_END_DATE,
|
|
800
|
-
}
|
|
801
|
-
],
|
|
802
|
-
)
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
US_COMP = DB(
|
|
806
|
-
name="US_COMP",
|
|
807
|
-
db_properties={
|
|
808
|
-
"symbology": "BZX",
|
|
809
|
-
"price_not_key": True,
|
|
810
|
-
"memory_data_max_life_hours": 30,
|
|
811
|
-
"memory_db_dir": "/onetick-tickdata-com/STORAGE_GATEWAY/DEEP_HISTORY/US_TED/TAQ/shmem",
|
|
812
|
-
"mmap_db_compression_type": constants.compression_type.NATIVE_PLUS_GZIP,
|
|
813
|
-
},
|
|
814
|
-
db_locations=[
|
|
815
|
-
{
|
|
816
|
-
"access_method": constants.access_method.FILE,
|
|
817
|
-
"location": "/onetick-tickdata-com/STORAGE_GATEWAY/DEEP_HISTORY/US_TED/TAQ/",
|
|
818
|
-
"start_time": datetime(year=2003, month=10, day=1),
|
|
819
|
-
"end_time": constants.DEFAULT_END_DATE,
|
|
820
|
-
}
|
|
821
|
-
],
|
|
822
|
-
)
|
|
823
|
-
"""
|
|
824
|
-
|
|
825
|
-
|
|
826
729
|
class RefDB(DB):
|
|
827
730
|
""" Creates reference database object.
|
|
828
731
|
|
|
@@ -1414,6 +1317,7 @@ class RefDB(DB):
|
|
|
1414
1317
|
},
|
|
1415
1318
|
stdout=subprocess.PIPE,
|
|
1416
1319
|
stderr=subprocess.PIPE,
|
|
1320
|
+
check=False,
|
|
1417
1321
|
)
|
|
1418
1322
|
return p.stdout, p.stderr
|
|
1419
1323
|
|
onetick/py/functions.py
CHANGED
|
@@ -572,6 +572,7 @@ def _add_node_name_prefix_to_columns_in_operation(op, src):
|
|
|
572
572
|
raise ValueError('You set to use name for column prefix, but name is empty')
|
|
573
573
|
name = f'{src.node_name()}.{column.name}'
|
|
574
574
|
return Column(name, column.dtype, column.obj_ref, precision=getattr(column, "_precision", None))
|
|
575
|
+
return None
|
|
575
576
|
|
|
576
577
|
return op._replace_parameters(fun)
|
|
577
578
|
|
onetick/py/license.py
CHANGED
onetick/py/math.py
CHANGED
|
@@ -10,7 +10,7 @@ class _MaxOperator(_Operation):
|
|
|
10
10
|
super().__init__(dtype=get_type_by_objects(objs))
|
|
11
11
|
|
|
12
12
|
def _str_max(l_val, r_val):
|
|
13
|
-
if
|
|
13
|
+
if isinstance(r_val, list):
|
|
14
14
|
if len(r_val) > 1:
|
|
15
15
|
r_val = _str_max(r_val[0], r_val[1:])
|
|
16
16
|
else:
|
|
@@ -55,7 +55,7 @@ class _MinOperator(_Operation):
|
|
|
55
55
|
super().__init__(dtype=get_type_by_objects(objs))
|
|
56
56
|
|
|
57
57
|
def _str_min(l_val, r_val):
|
|
58
|
-
if
|
|
58
|
+
if isinstance(r_val, list):
|
|
59
59
|
if len(r_val) > 1:
|
|
60
60
|
r_val = _str_min(r_val[0], r_val[1:])
|
|
61
61
|
else:
|
onetick/py/otq.py
CHANGED
|
@@ -10,7 +10,6 @@ import os
|
|
|
10
10
|
import tempfile
|
|
11
11
|
import warnings
|
|
12
12
|
import onetick.py as otp
|
|
13
|
-
from onetick.py import configuration
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
class OneTickLib:
|
|
@@ -33,7 +32,7 @@ class OneTickLib:
|
|
|
33
32
|
pass
|
|
34
33
|
|
|
35
34
|
|
|
36
|
-
if os.getenv("OTP_SKIP_OTQ_VALIDATION"
|
|
35
|
+
if os.getenv("OTP_SKIP_OTQ_VALIDATION"):
|
|
37
36
|
import onetick_stubs as otq # noqa: F401
|
|
38
37
|
import pyomd # noqa: F401
|
|
39
38
|
|
onetick/py/run.py
CHANGED
|
@@ -494,7 +494,7 @@ def run(query: Union[Callable, Dict, otp.Source, otp.MultiOutputSource, # NOSON
|
|
|
494
494
|
query = otp.MultiOutputSource(query)
|
|
495
495
|
|
|
496
496
|
params_saved_to_otq = {}
|
|
497
|
-
if isinstance(query, otp.Source
|
|
497
|
+
if isinstance(query, (otp.Source, otp.MultiOutputSource)):
|
|
498
498
|
start = None if start is utils.adaptive else start
|
|
499
499
|
end = None if end is utils.adaptive else end
|
|
500
500
|
params_saved_to_otq = dict(
|
|
@@ -660,9 +660,9 @@ def _form_dict_from_list(data_list, output_structure):
|
|
|
660
660
|
d = defaultdict(list)
|
|
661
661
|
for node, df in lst:
|
|
662
662
|
d[node].append(df)
|
|
663
|
-
for node in d.
|
|
664
|
-
if len(
|
|
665
|
-
d[node] =
|
|
663
|
+
for node, node_list in d.items():
|
|
664
|
+
if len(node_list) == 1:
|
|
665
|
+
d[node] = node_list[0]
|
|
666
666
|
if len(d) == 1:
|
|
667
667
|
d = list(d.values())[0]
|
|
668
668
|
else: # converting defaultdict to regular dict
|
|
@@ -671,7 +671,7 @@ def _form_dict_from_list(data_list, output_structure):
|
|
|
671
671
|
|
|
672
672
|
def get_dataframe(data):
|
|
673
673
|
if output_structure == 'df':
|
|
674
|
-
return pd.DataFrame(
|
|
674
|
+
return pd.DataFrame(dict(data))
|
|
675
675
|
else:
|
|
676
676
|
import polars
|
|
677
677
|
if isinstance(data, polars.DataFrame):
|
|
@@ -749,7 +749,7 @@ def _process_empty_results(result, query_schema, output_structure):
|
|
|
749
749
|
(field, np.array([], dtype=otp.types.type2np(dtype)))
|
|
750
750
|
for field, dtype in {**query_schema, 'Time': otp.nsectime}.items()
|
|
751
751
|
]
|
|
752
|
-
if
|
|
752
|
+
if isinstance(result, otq.SymbolNumpyResultMap):
|
|
753
753
|
empty_data = dict(schema)
|
|
754
754
|
else:
|
|
755
755
|
empty_data = schema
|
|
@@ -758,7 +758,7 @@ def _process_empty_results(result, query_schema, output_structure):
|
|
|
758
758
|
import polars
|
|
759
759
|
empty_data = polars.DataFrame(dict(schema))
|
|
760
760
|
|
|
761
|
-
if
|
|
761
|
+
if isinstance(result, otq.SymbolNumpyResultMap):
|
|
762
762
|
for result_item in result.get_dict().values():
|
|
763
763
|
for node_name, symbol_result in result_item.items():
|
|
764
764
|
if len(symbol_result[0]) == 0:
|
|
@@ -814,6 +814,7 @@ def _get_start_end(start, end, timezone):
|
|
|
814
814
|
|
|
815
815
|
# `isinstance(obj, datetime.date)` is not correct because
|
|
816
816
|
# isinstance(<datetime.datetime object>, datetime.date) = True
|
|
817
|
+
# pylint: disable=unidiomatic-typecheck
|
|
817
818
|
if type(start) is datetime.date:
|
|
818
819
|
start = datetime.datetime(start.year, start.month, start.day)
|
|
819
820
|
if type(end) is datetime.date:
|
onetick/py/servers.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Optional, Union
|
|
1
|
+
from typing import Optional, Union
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
class RemoteTS:
|
|
@@ -96,7 +96,7 @@ class RemoteTS:
|
|
|
96
96
|
return self.__str__()
|
|
97
97
|
|
|
98
98
|
def __str__(self):
|
|
99
|
-
if isinstance(self._host, FaultTolerance
|
|
99
|
+
if isinstance(self._host, (FaultTolerance, LoadBalancing)):
|
|
100
100
|
return str(self._host)
|
|
101
101
|
url = f'{self._host}:{self._port}'
|
|
102
102
|
if self._protocol:
|
onetick/py/session.py
CHANGED
|
@@ -16,7 +16,7 @@ from . import utils
|
|
|
16
16
|
from . import license as _license
|
|
17
17
|
from . import db as _db
|
|
18
18
|
from . import servers as _servers
|
|
19
|
-
from .
|
|
19
|
+
from . import configuration
|
|
20
20
|
from .db._inspection import databases as _databases
|
|
21
21
|
|
|
22
22
|
|
|
@@ -320,6 +320,7 @@ class ACL(_FileHandler):
|
|
|
320
320
|
def reload(self, db=None):
|
|
321
321
|
if self._session_ref is not None:
|
|
322
322
|
return utils.reload_config(db, config_type='ACCESS_LIST')
|
|
323
|
+
return None
|
|
323
324
|
|
|
324
325
|
def _read_dbs(self):
|
|
325
326
|
get_db = GetAll()
|
|
@@ -433,6 +434,7 @@ class Locator(_FileHandler):
|
|
|
433
434
|
def reload(self, db_=None):
|
|
434
435
|
if self._session_ref is not None:
|
|
435
436
|
return utils.reload_config(db_, config_type='LOCATOR')
|
|
437
|
+
return None
|
|
436
438
|
|
|
437
439
|
def _apply_actions(self, actions, print_writer=False):
|
|
438
440
|
writer = PrintWriter() if print_writer else FileWriter(self.path)
|
|
@@ -1300,11 +1302,11 @@ class TestSession(Session):
|
|
|
1300
1302
|
``DEMO_L1`` is the database defined in the default locator generated by onetick.py
|
|
1301
1303
|
and it is also a name of the database commonly used in the OneTick ecosystem, academy courses, etc.
|
|
1302
1304
|
"""
|
|
1303
|
-
config['tz'] = 'EST5EDT'
|
|
1304
|
-
config['default_db'] = 'DEMO_L1'
|
|
1305
|
-
config['default_symbol'] = 'AAPL'
|
|
1306
|
-
config['default_start_time'] = datetime(2003, 12, 1, 0, 0, 0)
|
|
1307
|
-
config['default_end_time'] = datetime(2003, 12, 4, 0, 0, 0)
|
|
1305
|
+
configuration.config['tz'] = 'EST5EDT'
|
|
1306
|
+
configuration.config['default_db'] = 'DEMO_L1'
|
|
1307
|
+
configuration.config['default_symbol'] = 'AAPL'
|
|
1308
|
+
configuration.config['default_start_time'] = datetime(2003, 12, 1, 0, 0, 0)
|
|
1309
|
+
configuration.config['default_end_time'] = datetime(2003, 12, 4, 0, 0, 0)
|
|
1308
1310
|
super().__init__(*args, **kwargs)
|
|
1309
1311
|
|
|
1310
1312
|
|