onetick-py 1.169.0__py3-none-any.whl → 1.171.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.
- onetick/py/__init__.py +8 -2
- onetick/py/_version.py +1 -1
- onetick/py/aggregations/functions.py +1 -1
- onetick/py/aggregations/order_book.py +15 -0
- onetick/py/cache.py +3 -3
- onetick/py/callback/callbacks.py +1 -1
- onetick/py/configuration.py +35 -9
- onetick/py/core/_internal/_state_objects.py +11 -6
- onetick/py/core/_internal/_state_vars.py +8 -2
- onetick/py/core/_source/source_methods/joins.py +1 -1
- onetick/py/core/_source/source_methods/misc.py +1 -1
- onetick/py/core/column_operations/accessors/str_accessor.py +3 -3
- onetick/py/core/column_operations/base.py +9 -9
- onetick/py/core/eval_query.py +3 -3
- onetick/py/core/per_tick_script.py +2 -0
- onetick/py/db/_inspection.py +82 -49
- onetick/py/math.py +265 -386
- onetick/py/misc.py +70 -38
- onetick/py/otq.py +18 -12
- onetick/py/run.py +75 -5
- onetick/py/sources/data_source.py +14 -8
- onetick/py/sources/order_book.py +33 -3
- onetick/py/sources/symbols.py +10 -1
- onetick/py/sources/ticks.py +1 -1
- onetick/py/state.py +14 -20
- {onetick_py-1.169.0.dist-info → onetick_py-1.171.0.dist-info}/METADATA +1 -1
- {onetick_py-1.169.0.dist-info → onetick_py-1.171.0.dist-info}/RECORD +31 -31
- {onetick_py-1.169.0.dist-info → onetick_py-1.171.0.dist-info}/WHEEL +0 -0
- {onetick_py-1.169.0.dist-info → onetick_py-1.171.0.dist-info}/entry_points.txt +0 -0
- {onetick_py-1.169.0.dist-info → onetick_py-1.171.0.dist-info}/licenses/LICENSE +0 -0
- {onetick_py-1.169.0.dist-info → onetick_py-1.171.0.dist-info}/top_level.txt +0 -0
onetick/py/misc.py
CHANGED
|
@@ -3,19 +3,6 @@ from onetick.py.core.column_operations.base import _Operation
|
|
|
3
3
|
from onetick.py.types import value2str, string
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class _BitAndOperator(_Operation):
|
|
7
|
-
def __init__(self, value1, value2):
|
|
8
|
-
super().__init__(dtype=int)
|
|
9
|
-
|
|
10
|
-
def _repr(_value1, _value2):
|
|
11
|
-
return f'BIT_AND({str(_value1)}, {str(_value2)})'
|
|
12
|
-
|
|
13
|
-
self._repr = _repr(value1, value2)
|
|
14
|
-
|
|
15
|
-
def __str__(self):
|
|
16
|
-
return self._repr
|
|
17
|
-
|
|
18
|
-
|
|
19
6
|
def bit_and(value1, value2):
|
|
20
7
|
"""
|
|
21
8
|
Performs the logical AND operation on each pair of corresponding bits of the parameters.
|
|
@@ -55,20 +42,10 @@ def bit_and(value1, value2):
|
|
|
55
42
|
Time A AND
|
|
56
43
|
0 2003-12-01 1 2
|
|
57
44
|
"""
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def __init__(self, value1, value2):
|
|
63
|
-
super().__init__(dtype=int)
|
|
64
|
-
|
|
65
|
-
def _repr(_value1, _value2):
|
|
66
|
-
return f'BIT_OR({str(_value1)}, {str(_value2)})'
|
|
67
|
-
|
|
68
|
-
self._repr = _repr(value1, value2)
|
|
69
|
-
|
|
70
|
-
def __str__(self):
|
|
71
|
-
return self._repr
|
|
45
|
+
return _Operation(
|
|
46
|
+
op_func=lambda v1, v2: (f'BIT_AND({value2str(v1)}, {value2str(v2)})', int),
|
|
47
|
+
op_params=[value1, value2],
|
|
48
|
+
)
|
|
72
49
|
|
|
73
50
|
|
|
74
51
|
def bit_or(value1, value2):
|
|
@@ -110,7 +87,10 @@ def bit_or(value1, value2):
|
|
|
110
87
|
Time A OR
|
|
111
88
|
0 2003-12-01 1 3
|
|
112
89
|
"""
|
|
113
|
-
return
|
|
90
|
+
return _Operation(
|
|
91
|
+
op_func=lambda v1, v2: (f'BIT_OR({value2str(v1)}, {value2str(v2)})', int),
|
|
92
|
+
op_params=[value1, value2],
|
|
93
|
+
)
|
|
114
94
|
|
|
115
95
|
|
|
116
96
|
def bit_xor(value1, value2):
|
|
@@ -152,7 +132,10 @@ def bit_xor(value1, value2):
|
|
|
152
132
|
Time A XOR
|
|
153
133
|
0 2003-12-01 1 1
|
|
154
134
|
"""
|
|
155
|
-
return _Operation(
|
|
135
|
+
return _Operation(
|
|
136
|
+
op_func=lambda v1, v2: (f'BIT_XOR({value2str(v1)}, {value2str(v2)})', int),
|
|
137
|
+
op_params=[value1, value2],
|
|
138
|
+
)
|
|
156
139
|
|
|
157
140
|
|
|
158
141
|
def bit_not(value):
|
|
@@ -193,7 +176,10 @@ def bit_not(value):
|
|
|
193
176
|
Time A NOT
|
|
194
177
|
0 2003-12-01 1 -3
|
|
195
178
|
"""
|
|
196
|
-
return _Operation(
|
|
179
|
+
return _Operation(
|
|
180
|
+
op_func=lambda v: (f'BIT_NOT({value2str(v)})', int),
|
|
181
|
+
op_params=[value],
|
|
182
|
+
)
|
|
197
183
|
|
|
198
184
|
|
|
199
185
|
def bit_at(value, index):
|
|
@@ -235,7 +221,10 @@ def bit_at(value, index):
|
|
|
235
221
|
Time A AT
|
|
236
222
|
0 2003-12-01 1 0
|
|
237
223
|
"""
|
|
238
|
-
return _Operation(
|
|
224
|
+
return _Operation(
|
|
225
|
+
op_func=lambda v, i: (f'BIT_AT({value2str(v)}, {value2str(i)})', int),
|
|
226
|
+
op_params=[value, index],
|
|
227
|
+
)
|
|
239
228
|
|
|
240
229
|
|
|
241
230
|
class _HashCodeOperator(_Operation):
|
|
@@ -262,18 +251,14 @@ class _HashCodeOperator(_Operation):
|
|
|
262
251
|
|
|
263
252
|
dtype = self.HASH_TYPES[hash_type]
|
|
264
253
|
|
|
265
|
-
super().__init__(dtype=dtype)
|
|
266
|
-
|
|
267
254
|
def _repr(_value, _hash_type):
|
|
268
255
|
_value = value2str(_value)
|
|
269
256
|
_hash_type = value2str(_hash_type.upper())
|
|
270
257
|
|
|
271
|
-
return f'COMPUTE_HASH_CODE_STR({_value}, {_hash_type})'
|
|
272
|
-
|
|
273
|
-
self._repr = _repr(value, hash_type)
|
|
258
|
+
return f'COMPUTE_HASH_CODE_STR({_value}, {_hash_type})', dtype
|
|
274
259
|
|
|
275
|
-
|
|
276
|
-
|
|
260
|
+
super().__init__(op_func=_repr,
|
|
261
|
+
op_params=[value, hash_type])
|
|
277
262
|
|
|
278
263
|
|
|
279
264
|
def hash_code(value, hash_type):
|
|
@@ -436,3 +421,50 @@ def get_symbology_mapping(dest_symbology, src_symbology=None, symbol=None, times
|
|
|
436
421
|
op_params=[dest_symbology, src_symbology, symbol, timestamp],
|
|
437
422
|
dtype=str,
|
|
438
423
|
)
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
def get_onetick_version():
|
|
427
|
+
"""
|
|
428
|
+
Returns the string with the build name of OneTick.
|
|
429
|
+
Build string may have different format depending on OneTick version.
|
|
430
|
+
|
|
431
|
+
Note
|
|
432
|
+
----
|
|
433
|
+
The version is returned from the server where the query executes.
|
|
434
|
+
Usually it's the same server where the database specified in :func:`otp.run <onetick.py.run>` resides.
|
|
435
|
+
|
|
436
|
+
Returns
|
|
437
|
+
-------
|
|
438
|
+
:py:class:`~onetick.py.Operation`
|
|
439
|
+
|
|
440
|
+
Examples
|
|
441
|
+
--------
|
|
442
|
+
>>> data = otp.Tick(VERSION=otp.get_onetick_version())
|
|
443
|
+
>>> otp.run(data, symbols='US_COMP::') # doctest: +SKIP
|
|
444
|
+
Time VERSION
|
|
445
|
+
0 2003-12-01 BUILD_rel_20250727_update2 (20250727120000)
|
|
446
|
+
"""
|
|
447
|
+
return _Operation(
|
|
448
|
+
op_func=lambda: ('FORMATMESSAGE("%1% (%2%)", GET_ONETICK_RELEASE(), GET_ONETICK_VERSION())', str),
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def get_username():
|
|
453
|
+
"""
|
|
454
|
+
Returns the string with the name of the user executing the query
|
|
455
|
+
and authenticated login name of the user.
|
|
456
|
+
|
|
457
|
+
Returns
|
|
458
|
+
-------
|
|
459
|
+
:py:class:`~onetick.py.Operation`
|
|
460
|
+
|
|
461
|
+
Examples
|
|
462
|
+
--------
|
|
463
|
+
>>> data = otp.Tick(USER=otp.get_username())
|
|
464
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
465
|
+
Time USER
|
|
466
|
+
0 2003-12-01 onetick (onetick)
|
|
467
|
+
"""
|
|
468
|
+
return _Operation(
|
|
469
|
+
op_func=lambda: ('FORMATMESSAGE("%1% (%2%)", GETUSER(), GET_AUTHENTICATED_USERNAME())', str),
|
|
470
|
+
)
|
onetick/py/otq.py
CHANGED
|
@@ -160,18 +160,24 @@ elif otp.__webapi__:
|
|
|
160
160
|
if 'https_proxy' not in kwargs:
|
|
161
161
|
kwargs['https_proxy'] = config.https_proxy
|
|
162
162
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
163
|
+
webapi_run_parameters = inspect.signature(__original_run).parameters
|
|
164
|
+
|
|
165
|
+
trusted_certificate_file_arg = kwargs.pop('trusted_certificates_file',
|
|
166
|
+
kwargs.pop('trusted_certificate_file', None))
|
|
167
|
+
trusted_certificate_file_value = (
|
|
168
|
+
trusted_certificate_file_arg if trusted_certificate_file_arg is not None
|
|
169
|
+
else config.trusted_certificates_file
|
|
170
|
+
)
|
|
171
|
+
if trusted_certificate_file_value is not None:
|
|
172
|
+
trusted_certificates_supported = set(webapi_run_parameters).intersection({'trusted_certificates_file',
|
|
173
|
+
'trusted_certificate_file'})
|
|
174
|
+
if not trusted_certificates_supported:
|
|
175
|
+
raise ValueError(
|
|
176
|
+
"Parameter `trusted_certificates_file` was set,"
|
|
177
|
+
" however current version of OneTick doesn't support it."
|
|
178
|
+
)
|
|
179
|
+
trusted_certificates_supported_param = list(trusted_certificates_supported)[0]
|
|
180
|
+
kwargs[trusted_certificates_supported_param] = trusted_certificate_file_value
|
|
175
181
|
|
|
176
182
|
if 'callback' in kwargs and kwargs['callback'] is not None:
|
|
177
183
|
kwargs['output_mode'] = otq.QueryOutputMode.callback
|
onetick/py/run.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import asyncio
|
|
2
2
|
import inspect
|
|
3
3
|
import datetime
|
|
4
4
|
import warnings
|
|
@@ -76,10 +76,11 @@ def run(query: Union[Callable, Dict, otp.Source, otp.MultiOutputSource, # NOSON
|
|
|
76
76
|
``query`` can also be a function that has a symbol object as the first parameter.
|
|
77
77
|
This object can be used to get symbol name and symbol parameters.
|
|
78
78
|
Function must return a :py:class:`Source <onetick.py.Source>`.
|
|
79
|
-
symbols: str, list of str, list of otq.Symbol, :py:class:`onetick.py.Source`,
|
|
80
|
-
Symbol(s) to run the query for passed as a string, a list of strings,
|
|
81
|
-
|
|
82
|
-
symbols query
|
|
79
|
+
symbols: str, list of str, list of otq.Symbol, :py:class:`onetick.py.Source`, :pandas:`pandas.DataFrame`, optional
|
|
80
|
+
Symbol(s) to run the query for passed as a string, a list of strings,
|
|
81
|
+
a :pandas:`pandas.DataFrame` with the ``SYMBOL_NAME`` column,
|
|
82
|
+
or as a "symbols" query which results include the ``SYMBOL_NAME`` column.
|
|
83
|
+
The start/end times for the symbols query will taken from the params below.
|
|
83
84
|
See :ref:`symbols <static/concepts/symbols:Symbols: bound and unbound>` for more details.
|
|
84
85
|
start: :py:class:`datetime.datetime`, :py:class:`otp.datetime <onetick.py.datetime>`,\
|
|
85
86
|
:py:class:`pyomd.timeval_t`, optional
|
|
@@ -610,6 +611,75 @@ def run(query: Union[Callable, Dict, otp.Source, otp.MultiOutputSource, # NOSON
|
|
|
610
611
|
require_dict=require_dict, node_names=node_names)
|
|
611
612
|
|
|
612
613
|
|
|
614
|
+
async def run_async(*args, **kwargs):
|
|
615
|
+
"""
|
|
616
|
+
Asynchronous alternative to :func:`otp.run <onetick.py.run>`.
|
|
617
|
+
|
|
618
|
+
All parameters are the same.
|
|
619
|
+
|
|
620
|
+
This function can be used via built-in python ``await`` syntax
|
|
621
|
+
and standard `asyncio <https://docs.python.org/3/library/asyncio.html>`_ library.
|
|
622
|
+
|
|
623
|
+
Note
|
|
624
|
+
----
|
|
625
|
+
Internally this function is implemented as :func:`otp.run <onetick.py.run>` running in a separate thread.
|
|
626
|
+
|
|
627
|
+
Threads in python are generally not interruptable,
|
|
628
|
+
so some `asyncio` functionality may not work as expected.
|
|
629
|
+
|
|
630
|
+
For example, canceling :func:`otp.run_async <onetick.py.run_async>` task by
|
|
631
|
+
`timeout <https://docs.python.org/3/library/asyncio-task.html#timeouts>`_
|
|
632
|
+
may block the waiting function
|
|
633
|
+
or exiting the python process will block until the task is finished,
|
|
634
|
+
depending on python and `asyncio` back-end implementation.
|
|
635
|
+
|
|
636
|
+
Examples
|
|
637
|
+
--------
|
|
638
|
+
|
|
639
|
+
>>> data = otp.Ticks(A=[1, 2, 3])
|
|
640
|
+
|
|
641
|
+
Calling :func:`otp.run_async <onetick.py.run_async>` will create a "coroutine" object:
|
|
642
|
+
|
|
643
|
+
>>> otp.run_async(data) # doctest: +SKIP
|
|
644
|
+
<coroutine object run_async at ...>
|
|
645
|
+
|
|
646
|
+
Use `asyncio.run <https://docs.python.org/3/library/asyncio-runner.html#asyncio.run>`_
|
|
647
|
+
to run this coroutine and wait for it to finish:
|
|
648
|
+
|
|
649
|
+
>>> asyncio.run(otp.run_async(data))
|
|
650
|
+
Time A
|
|
651
|
+
0 2003-12-01 00:00:00.000 1
|
|
652
|
+
1 2003-12-01 00:00:00.001 2
|
|
653
|
+
2 2003-12-01 00:00:00.002 3
|
|
654
|
+
|
|
655
|
+
You can use standard `asyncio <https://docs.python.org/3/library/asyncio.html>`_
|
|
656
|
+
library functions to create and schedule tasks.
|
|
657
|
+
|
|
658
|
+
In the example below two tasks are executed in parallel,
|
|
659
|
+
so total execution time will be around 3 seconds instead of 6:
|
|
660
|
+
|
|
661
|
+
>>> import asyncio
|
|
662
|
+
>>> import time
|
|
663
|
+
>>> async def parallel_tasks():
|
|
664
|
+
... # pause 1 second on each tick (thus 3 seconds for 3 ticks)
|
|
665
|
+
... task_otp = asyncio.create_task(otp.run_async(data.pause(1000)))
|
|
666
|
+
... # just sleep for 3 seconds
|
|
667
|
+
... task_other = asyncio.create_task(asyncio.sleep(3))
|
|
668
|
+
... otp_result = await task_otp
|
|
669
|
+
... await task_other
|
|
670
|
+
... print(otp_result)
|
|
671
|
+
>>> start_time = time.time()
|
|
672
|
+
>>> asyncio.run(parallel_tasks())
|
|
673
|
+
Time A
|
|
674
|
+
0 2003-12-01 00:00:00.000 1
|
|
675
|
+
1 2003-12-01 00:00:00.001 2
|
|
676
|
+
2 2003-12-01 00:00:00.002 3
|
|
677
|
+
>>> print('Finished in', time.time() - start_time, 'seconds') # doctest: +SKIP
|
|
678
|
+
Finished in 3.0108885765075684 seconds
|
|
679
|
+
"""
|
|
680
|
+
return await asyncio.to_thread(run, *args, **kwargs)
|
|
681
|
+
|
|
682
|
+
|
|
613
683
|
def _filter_returned_map_by_node(result, _node_names):
|
|
614
684
|
"""
|
|
615
685
|
Here, result has the following format: {symbol: {node_name: data}}
|
|
@@ -977,14 +977,7 @@ class DataSource(Source):
|
|
|
977
977
|
src = self._table_schema(src)
|
|
978
978
|
return src
|
|
979
979
|
|
|
980
|
-
def
|
|
981
|
-
self, db, symbol, tick_type, identify_input_ts,
|
|
982
|
-
back_to_first_tick=0, keep_first_tick_timestamp=None,
|
|
983
|
-
presort=utils.adaptive, batch_size=None, concurrency=utils.default,
|
|
984
|
-
max_back_ticks_to_prepend=1,
|
|
985
|
-
where_clause_for_back_ticks=None,
|
|
986
|
-
symbol_date=None,
|
|
987
|
-
):
|
|
980
|
+
def _cross_symbol_convert(self, symbol, symbol_date=None):
|
|
988
981
|
tmp_otq = TmpOtq()
|
|
989
982
|
|
|
990
983
|
if isinstance(symbol, _QueryEvalWrapper):
|
|
@@ -996,6 +989,18 @@ class DataSource(Source):
|
|
|
996
989
|
elif isinstance(symbol, (Source, otq.GraphQuery)):
|
|
997
990
|
symbol = Source._convert_symbol_to_string(symbol, tmp_otq, symbol_date=symbol_date)
|
|
998
991
|
|
|
992
|
+
return symbol, tmp_otq
|
|
993
|
+
|
|
994
|
+
def _base_ep_for_cross_symbol(
|
|
995
|
+
self, db, symbol, tick_type, identify_input_ts,
|
|
996
|
+
back_to_first_tick=0, keep_first_tick_timestamp=None,
|
|
997
|
+
presort=utils.adaptive, batch_size=None, concurrency=utils.default,
|
|
998
|
+
max_back_ticks_to_prepend=1,
|
|
999
|
+
where_clause_for_back_ticks=None,
|
|
1000
|
+
symbol_date=None,
|
|
1001
|
+
):
|
|
1002
|
+
symbol, tmp_otq = self._cross_symbol_convert(symbol, symbol_date)
|
|
1003
|
+
|
|
999
1004
|
self.logger.info(f'symbol={symbol}')
|
|
1000
1005
|
|
|
1001
1006
|
tick_type = convert_tick_type_to_str(tick_type, db)
|
|
@@ -1030,6 +1035,7 @@ class DataSource(Source):
|
|
|
1030
1035
|
src.sink(
|
|
1031
1036
|
otq.Merge(identify_input_ts=identify_input_ts).symbols(symbol).tick_type(tick_type)
|
|
1032
1037
|
)
|
|
1038
|
+
|
|
1033
1039
|
src._tmp_otq.merge(tmp_otq)
|
|
1034
1040
|
|
|
1035
1041
|
src = self._table_schema(src)
|
onetick/py/sources/order_book.py
CHANGED
|
@@ -15,6 +15,7 @@ from ..aggregations.order_book import (
|
|
|
15
15
|
from ..aggregations.functions import (
|
|
16
16
|
ob_snapshot, ob_snapshot_wide, ob_snapshot_flat, ob_summary, ob_size, ob_vwap, ob_num_levels,
|
|
17
17
|
)
|
|
18
|
+
from .. import utils
|
|
18
19
|
|
|
19
20
|
from .data_source import DataSource, DATA_SOURCE_DOC_PARAMS
|
|
20
21
|
|
|
@@ -24,17 +25,43 @@ class _ObSource(DataSource):
|
|
|
24
25
|
OB_AGG_PARAMS: Iterable
|
|
25
26
|
_PROPERTIES = DataSource._PROPERTIES + ['_ob_agg']
|
|
26
27
|
|
|
27
|
-
def __init__(self,
|
|
28
|
-
if self._try_default_constructor(
|
|
28
|
+
def __init__(self, db=None, schema=None, **kwargs):
|
|
29
|
+
if self._try_default_constructor(schema=schema, **kwargs):
|
|
29
30
|
return
|
|
30
31
|
|
|
31
32
|
ob_agg_params = {
|
|
32
33
|
param.name: kwargs.pop(param.name, param.default)
|
|
33
34
|
for _, param in self.OB_AGG_PARAMS
|
|
34
35
|
}
|
|
36
|
+
|
|
37
|
+
symbol_param = kwargs.get('symbol')
|
|
38
|
+
symbols_param = kwargs.get('symbols')
|
|
39
|
+
|
|
40
|
+
if symbol_param and symbols_param:
|
|
41
|
+
raise ValueError(
|
|
42
|
+
'You have set the `symbol` and `symbols` parameters together, it is not allowed. '
|
|
43
|
+
'Please, clarify parameters'
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
symbols = symbol_param if symbol_param else symbols_param
|
|
47
|
+
tmp_otq = None
|
|
48
|
+
|
|
49
|
+
# Use bound symbols only in case, if db not passed
|
|
50
|
+
use_bound_symbols = not db and symbols and symbols is not utils.adaptive
|
|
51
|
+
if use_bound_symbols:
|
|
52
|
+
symbols, tmp_otq = self._cross_symbol_convert(symbols, kwargs.get('symbol_date'))
|
|
53
|
+
|
|
54
|
+
if symbols_param:
|
|
55
|
+
del kwargs['symbols']
|
|
56
|
+
|
|
57
|
+
kwargs['symbol'] = None
|
|
58
|
+
|
|
35
59
|
self._ob_agg = self.__class__.OB_AGG_FUNC(**ob_agg_params)
|
|
36
60
|
|
|
37
|
-
|
|
61
|
+
if use_bound_symbols:
|
|
62
|
+
self._ob_agg.set_bound_symbols(symbols)
|
|
63
|
+
|
|
64
|
+
super().__init__(db=db, schema=schema, **kwargs)
|
|
38
65
|
|
|
39
66
|
ob_agg_output_schema = self._ob_agg._get_output_schema(otp.Empty())
|
|
40
67
|
|
|
@@ -43,6 +70,9 @@ class _ObSource(DataSource):
|
|
|
43
70
|
else:
|
|
44
71
|
self.schema.set(**ob_agg_output_schema)
|
|
45
72
|
|
|
73
|
+
if tmp_otq:
|
|
74
|
+
self._tmp_otq.merge(tmp_otq)
|
|
75
|
+
|
|
46
76
|
def base_ep(self, *args, **kwargs):
|
|
47
77
|
src = super().base_ep(*args, **kwargs)
|
|
48
78
|
return self._ob_agg.apply(src)
|
onetick/py/sources/symbols.py
CHANGED
|
@@ -5,6 +5,8 @@ from onetick.py.otq import otq
|
|
|
5
5
|
|
|
6
6
|
from onetick.py.core.source import Source
|
|
7
7
|
from onetick.py.core.column_operations.base import Raw, OnetickParameter
|
|
8
|
+
from onetick.py.core.eval_query import _QueryEvalWrapper
|
|
9
|
+
from onetick.py.core._source.tmp_otq import TmpOtq
|
|
8
10
|
|
|
9
11
|
from .. import types as ott
|
|
10
12
|
from .. import utils
|
|
@@ -20,7 +22,7 @@ class Symbols(Source):
|
|
|
20
22
|
|
|
21
23
|
Parameters
|
|
22
24
|
----------
|
|
23
|
-
db: str
|
|
25
|
+
db: str, :py:func:`eval query <onetick.py.eval>`
|
|
24
26
|
Name of the database where to search symbols.
|
|
25
27
|
By default the database used by :py:func:`otp.run <onetick.py.run>` will be inherited.
|
|
26
28
|
keep_db: bool
|
|
@@ -276,9 +278,13 @@ class Symbols(Source):
|
|
|
276
278
|
end = date.end
|
|
277
279
|
|
|
278
280
|
_symbol = utils.adaptive
|
|
281
|
+
_tmp_otq = None
|
|
279
282
|
if db:
|
|
280
283
|
if isinstance(db, list):
|
|
281
284
|
_symbol = [f"{str(_db).split(':')[0]}::" for _db in db] # noqa
|
|
285
|
+
elif isinstance(db, _QueryEvalWrapper):
|
|
286
|
+
_tmp_otq = TmpOtq()
|
|
287
|
+
_symbol = db.to_eval_string(tmp_otq=_tmp_otq)
|
|
282
288
|
else:
|
|
283
289
|
_symbol = f"{str(db).split(':')[0]}::" # noqa
|
|
284
290
|
|
|
@@ -336,6 +342,9 @@ class Symbols(Source):
|
|
|
336
342
|
if _find_params['symbology'] and _find_params['show_original_symbols']:
|
|
337
343
|
self.schema['ORIGINAL_SYMBOL_NAME'] = str
|
|
338
344
|
|
|
345
|
+
if _tmp_otq:
|
|
346
|
+
self._tmp_otq.merge(_tmp_otq)
|
|
347
|
+
|
|
339
348
|
def base_ep(self, ep_tick_type, keep_db, **params):
|
|
340
349
|
src = Source(otq.FindDbSymbols(**params))
|
|
341
350
|
|
onetick/py/sources/ticks.py
CHANGED
onetick/py/state.py
CHANGED
|
@@ -75,7 +75,7 @@ def tick_list(default_value=None, scope='query', schema=None) -> TickList:
|
|
|
75
75
|
|
|
76
76
|
Parameters
|
|
77
77
|
----------
|
|
78
|
-
default_value: :py:func:`eval query <onetick.py.eval>`
|
|
78
|
+
default_value: :class:`otp.Source <onetick.py.Source>`, :py:func:`eval query <onetick.py.eval>`
|
|
79
79
|
Evaluated query to initialize tick list from.
|
|
80
80
|
scope: str
|
|
81
81
|
Scope for the state variable.
|
|
@@ -85,14 +85,12 @@ def tick_list(default_value=None, scope='query', schema=None) -> TickList:
|
|
|
85
85
|
if ``default_value`` is not passed as well, schema will contain fields of the main Source object.
|
|
86
86
|
|
|
87
87
|
If schema is passed as a list, it will select only these fields from the schema of ``default_value``
|
|
88
|
-
or main Source object.
|
|
88
|
+
or main :class:`Source <onetick.py.Source>` object.
|
|
89
89
|
|
|
90
90
|
Examples
|
|
91
91
|
--------
|
|
92
|
-
>>> def fsq():
|
|
93
|
-
... return otp.Ticks(B=[1, 2, 3])
|
|
94
92
|
>>> data = otp.Tick(A=1)
|
|
95
|
-
>>> data.state_vars['LIST'] = otp.state.tick_list(otp.
|
|
93
|
+
>>> data.state_vars['LIST'] = otp.state.tick_list(otp.Ticks(B=[1, 2, 3]))
|
|
96
94
|
>>> data = data.state_vars['LIST'].dump()
|
|
97
95
|
>>> otp.run(data)[['B']]
|
|
98
96
|
B
|
|
@@ -115,7 +113,7 @@ def tick_set(insertion_policy, key_fields, default_value=None, scope='query', sc
|
|
|
115
113
|
'latest' makes the last inserted tick overwrite the one with the same keys (if existing).
|
|
116
114
|
key_fields: str, list of str
|
|
117
115
|
The values of the specified fields will be used as keys.
|
|
118
|
-
default_value: :py:func:`eval query <onetick.py.eval>`
|
|
116
|
+
default_value: :class:`otp.Source <onetick.py.Source>`, :py:func:`eval query <onetick.py.eval>`
|
|
119
117
|
Evaluated query to initialize tick set from.
|
|
120
118
|
scope: str
|
|
121
119
|
Scope for the state variable.
|
|
@@ -125,14 +123,12 @@ def tick_set(insertion_policy, key_fields, default_value=None, scope='query', sc
|
|
|
125
123
|
if ``default_value`` is not passed as well, schema will contain fields of the main Source object.
|
|
126
124
|
|
|
127
125
|
If schema is passed as a list, it will select only these fields from the schema of ``default_value``
|
|
128
|
-
or main Source object.
|
|
126
|
+
or main :class:`Source <onetick.py.Source>` object.
|
|
129
127
|
|
|
130
128
|
Examples
|
|
131
129
|
--------
|
|
132
|
-
>>> def fsq():
|
|
133
|
-
... return otp.Ticks(B=[1, 1, 2, 2, 3, 3])
|
|
134
130
|
>>> data = otp.Tick(A=1)
|
|
135
|
-
>>> data.state_vars['SET'] = otp.state.tick_set('oldest', 'B', otp.
|
|
131
|
+
>>> data.state_vars['SET'] = otp.state.tick_set('oldest', 'B', otp.Ticks(B=[1, 1, 2, 2, 3, 3]))
|
|
136
132
|
>>> data = data.state_vars['SET'].dump()
|
|
137
133
|
>>> otp.run(data)[['B']]
|
|
138
134
|
B
|
|
@@ -175,7 +171,7 @@ def tick_set_unordered(insertion_policy,
|
|
|
175
171
|
may be considerably worse than that of normal tick set.
|
|
176
172
|
In particular, **default value of -1 will lead to bad performance and should be avoided**
|
|
177
173
|
|
|
178
|
-
default_value: :py:func:`eval query <onetick.py.eval>`
|
|
174
|
+
default_value: :class:`otp.Source <onetick.py.Source>`, :py:func:`eval query <onetick.py.eval>`
|
|
179
175
|
Evaluated query to initialize unordered tick set from.
|
|
180
176
|
scope: str,
|
|
181
177
|
Scope for the state variable.
|
|
@@ -186,14 +182,14 @@ def tick_set_unordered(insertion_policy,
|
|
|
186
182
|
if ``default_value`` is not passed as well, schema will contain fields of the main Source object.
|
|
187
183
|
|
|
188
184
|
If schema is passed as a list, it will select only these fields from the schema of ``default_value``
|
|
189
|
-
or main Source object.
|
|
185
|
+
or main :class:`Source <onetick.py.Source>` object.
|
|
190
186
|
|
|
191
187
|
Examples
|
|
192
188
|
--------
|
|
193
|
-
>>> def fsq():
|
|
194
|
-
... return otp.Ticks(B=[1, 1, 2, 2, 3, 3])
|
|
195
189
|
>>> data = otp.Tick(A=1)
|
|
196
|
-
>>> data.state_vars['SET'] = otp.state.tick_set_unordered('oldest', 'B',
|
|
190
|
+
>>> data.state_vars['SET'] = otp.state.tick_set_unordered('oldest', 'B',
|
|
191
|
+
... otp.Ticks(B=[1, 1, 2, 2, 3, 3]),
|
|
192
|
+
... max_distinct_keys=5)
|
|
197
193
|
>>> data = data.state_vars['SET'].dump()
|
|
198
194
|
>>> otp.run(data)[['B']]
|
|
199
195
|
B
|
|
@@ -218,7 +214,7 @@ def tick_deque(default_value=None, scope='query', schema=None) -> TickDeque:
|
|
|
218
214
|
|
|
219
215
|
Parameters
|
|
220
216
|
----------
|
|
221
|
-
default_value: :py:func:`eval query <onetick.py.eval>`
|
|
217
|
+
default_value: :class:`otp.Source <onetick.py.Source>`, :py:func:`eval query <onetick.py.eval>`
|
|
222
218
|
Evaluated query to initialize tick deque from.
|
|
223
219
|
scope: str
|
|
224
220
|
Scope for the state variable.
|
|
@@ -228,14 +224,12 @@ def tick_deque(default_value=None, scope='query', schema=None) -> TickDeque:
|
|
|
228
224
|
if ``default_value`` is not passed as well, schema will contain fields of the main Source object.
|
|
229
225
|
|
|
230
226
|
If schema is passed as a list, it will select only these fields from the schema of ``default_value``
|
|
231
|
-
or main Source object.
|
|
227
|
+
or main :class:`Source <onetick.py.Source>` object.
|
|
232
228
|
|
|
233
229
|
Examples
|
|
234
230
|
--------
|
|
235
|
-
>>> def fsq():
|
|
236
|
-
... return otp.Ticks(B=[1, 2, 3])
|
|
237
231
|
>>> data = otp.Tick(A=1)
|
|
238
|
-
>>> data.state_vars['DEQUE'] = otp.state.tick_deque(otp.
|
|
232
|
+
>>> data.state_vars['DEQUE'] = otp.state.tick_deque(otp.Ticks(B=[1, 2, 3]))
|
|
239
233
|
>>> data = data.state_vars['DEQUE'].dump()
|
|
240
234
|
>>> otp.run(data)[['B']]
|
|
241
235
|
B
|