onetick-py 1.177.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/__init__.py +0 -0
- locator_parser/acl.py +73 -0
- locator_parser/actions.py +262 -0
- locator_parser/common.py +368 -0
- locator_parser/io.py +43 -0
- locator_parser/locator.py +150 -0
- onetick/__init__.py +101 -0
- onetick/doc_utilities/__init__.py +3 -0
- onetick/doc_utilities/napoleon.py +40 -0
- onetick/doc_utilities/ot_doctest.py +140 -0
- onetick/doc_utilities/snippets.py +279 -0
- onetick/lib/__init__.py +4 -0
- onetick/lib/instance.py +141 -0
- onetick/py/__init__.py +293 -0
- onetick/py/_stack_info.py +89 -0
- onetick/py/_version.py +2 -0
- onetick/py/aggregations/__init__.py +11 -0
- onetick/py/aggregations/_base.py +648 -0
- onetick/py/aggregations/_docs.py +948 -0
- onetick/py/aggregations/compute.py +286 -0
- onetick/py/aggregations/functions.py +2216 -0
- onetick/py/aggregations/generic.py +104 -0
- onetick/py/aggregations/high_low.py +80 -0
- onetick/py/aggregations/num_distinct.py +83 -0
- onetick/py/aggregations/order_book.py +501 -0
- onetick/py/aggregations/other.py +1014 -0
- onetick/py/backports.py +26 -0
- onetick/py/cache.py +374 -0
- onetick/py/callback/__init__.py +5 -0
- onetick/py/callback/callback.py +276 -0
- onetick/py/callback/callbacks.py +131 -0
- onetick/py/compatibility.py +798 -0
- onetick/py/configuration.py +771 -0
- onetick/py/core/__init__.py +0 -0
- onetick/py/core/_csv_inspector.py +93 -0
- onetick/py/core/_internal/__init__.py +0 -0
- onetick/py/core/_internal/_manually_bound_value.py +6 -0
- onetick/py/core/_internal/_nodes_history.py +250 -0
- onetick/py/core/_internal/_op_utils/__init__.py +0 -0
- onetick/py/core/_internal/_op_utils/every_operand.py +9 -0
- onetick/py/core/_internal/_op_utils/is_const.py +10 -0
- onetick/py/core/_internal/_per_tick_scripts/tick_list_sort_template.script +121 -0
- onetick/py/core/_internal/_proxy_node.py +140 -0
- onetick/py/core/_internal/_state_objects.py +2312 -0
- onetick/py/core/_internal/_state_vars.py +93 -0
- onetick/py/core/_source/__init__.py +0 -0
- onetick/py/core/_source/_symbol_param.py +95 -0
- onetick/py/core/_source/schema.py +97 -0
- onetick/py/core/_source/source_methods/__init__.py +0 -0
- onetick/py/core/_source/source_methods/aggregations.py +809 -0
- onetick/py/core/_source/source_methods/applyers.py +296 -0
- onetick/py/core/_source/source_methods/columns.py +141 -0
- onetick/py/core/_source/source_methods/data_quality.py +301 -0
- onetick/py/core/_source/source_methods/debugs.py +272 -0
- onetick/py/core/_source/source_methods/drops.py +120 -0
- onetick/py/core/_source/source_methods/fields.py +619 -0
- onetick/py/core/_source/source_methods/filters.py +1002 -0
- onetick/py/core/_source/source_methods/joins.py +1413 -0
- onetick/py/core/_source/source_methods/merges.py +605 -0
- onetick/py/core/_source/source_methods/misc.py +1455 -0
- onetick/py/core/_source/source_methods/pandases.py +155 -0
- onetick/py/core/_source/source_methods/renames.py +356 -0
- onetick/py/core/_source/source_methods/sorts.py +183 -0
- onetick/py/core/_source/source_methods/switches.py +142 -0
- onetick/py/core/_source/source_methods/symbols.py +117 -0
- onetick/py/core/_source/source_methods/times.py +627 -0
- onetick/py/core/_source/source_methods/writes.py +986 -0
- onetick/py/core/_source/symbol.py +205 -0
- onetick/py/core/_source/tmp_otq.py +222 -0
- onetick/py/core/column.py +209 -0
- onetick/py/core/column_operations/__init__.py +0 -0
- onetick/py/core/column_operations/_methods/__init__.py +4 -0
- onetick/py/core/column_operations/_methods/_internal.py +28 -0
- onetick/py/core/column_operations/_methods/conversions.py +216 -0
- onetick/py/core/column_operations/_methods/methods.py +292 -0
- onetick/py/core/column_operations/_methods/op_types.py +160 -0
- onetick/py/core/column_operations/accessors/__init__.py +0 -0
- onetick/py/core/column_operations/accessors/_accessor.py +28 -0
- onetick/py/core/column_operations/accessors/decimal_accessor.py +104 -0
- onetick/py/core/column_operations/accessors/dt_accessor.py +537 -0
- onetick/py/core/column_operations/accessors/float_accessor.py +184 -0
- onetick/py/core/column_operations/accessors/str_accessor.py +1367 -0
- onetick/py/core/column_operations/base.py +1121 -0
- onetick/py/core/cut_builder.py +150 -0
- onetick/py/core/db_constants.py +20 -0
- onetick/py/core/eval_query.py +245 -0
- onetick/py/core/lambda_object.py +441 -0
- onetick/py/core/multi_output_source.py +232 -0
- onetick/py/core/per_tick_script.py +2256 -0
- onetick/py/core/query_inspector.py +464 -0
- onetick/py/core/source.py +1744 -0
- onetick/py/db/__init__.py +2 -0
- onetick/py/db/_inspection.py +1128 -0
- onetick/py/db/db.py +1327 -0
- onetick/py/db/utils.py +64 -0
- onetick/py/docs/__init__.py +0 -0
- onetick/py/docs/docstring_parser.py +112 -0
- onetick/py/docs/utils.py +81 -0
- onetick/py/functions.py +2398 -0
- onetick/py/license.py +190 -0
- onetick/py/log.py +88 -0
- onetick/py/math.py +935 -0
- onetick/py/misc.py +470 -0
- onetick/py/oqd/__init__.py +22 -0
- onetick/py/oqd/eps.py +1195 -0
- onetick/py/oqd/sources.py +325 -0
- onetick/py/otq.py +216 -0
- onetick/py/pyomd_mock.py +47 -0
- onetick/py/run.py +916 -0
- onetick/py/servers.py +173 -0
- onetick/py/session.py +1347 -0
- onetick/py/sources/__init__.py +19 -0
- onetick/py/sources/cache.py +167 -0
- onetick/py/sources/common.py +128 -0
- onetick/py/sources/csv.py +642 -0
- onetick/py/sources/custom.py +85 -0
- onetick/py/sources/data_file.py +305 -0
- onetick/py/sources/data_source.py +1045 -0
- onetick/py/sources/empty.py +94 -0
- onetick/py/sources/odbc.py +337 -0
- onetick/py/sources/order_book.py +271 -0
- onetick/py/sources/parquet.py +168 -0
- onetick/py/sources/pit.py +191 -0
- onetick/py/sources/query.py +495 -0
- onetick/py/sources/snapshots.py +419 -0
- onetick/py/sources/split_query_output_by_symbol.py +198 -0
- onetick/py/sources/symbology_mapping.py +123 -0
- onetick/py/sources/symbols.py +374 -0
- onetick/py/sources/ticks.py +825 -0
- onetick/py/sql.py +70 -0
- onetick/py/state.py +251 -0
- onetick/py/types.py +2131 -0
- onetick/py/utils/__init__.py +70 -0
- onetick/py/utils/acl.py +93 -0
- onetick/py/utils/config.py +186 -0
- onetick/py/utils/default.py +49 -0
- onetick/py/utils/file.py +38 -0
- onetick/py/utils/helpers.py +76 -0
- onetick/py/utils/locator.py +94 -0
- onetick/py/utils/perf.py +498 -0
- onetick/py/utils/query.py +49 -0
- onetick/py/utils/render.py +1374 -0
- onetick/py/utils/script.py +244 -0
- onetick/py/utils/temp.py +471 -0
- onetick/py/utils/types.py +120 -0
- onetick/py/utils/tz.py +84 -0
- onetick_py-1.177.0.dist-info/METADATA +137 -0
- onetick_py-1.177.0.dist-info/RECORD +152 -0
- onetick_py-1.177.0.dist-info/WHEEL +5 -0
- onetick_py-1.177.0.dist-info/entry_points.txt +2 -0
- onetick_py-1.177.0.dist-info/licenses/LICENSE +21 -0
- onetick_py-1.177.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import datetime as dt
|
|
2
|
+
|
|
3
|
+
import onetick.py as otp
|
|
4
|
+
from onetick.py.otq import otq
|
|
5
|
+
|
|
6
|
+
import onetick.py.core._source
|
|
7
|
+
import onetick.py.functions
|
|
8
|
+
import onetick.py.db._inspection
|
|
9
|
+
from onetick.py.core.source import Source
|
|
10
|
+
|
|
11
|
+
from .. import utils, configuration
|
|
12
|
+
|
|
13
|
+
from .common import update_node_tick_type
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Empty(Source):
|
|
17
|
+
"""
|
|
18
|
+
Empty data source
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
db: str
|
|
23
|
+
Name of the database from which to take schema.
|
|
24
|
+
symbol: str, list of str, :class:`Source`, :class:`query`, :py:func:`eval query <onetick.py.eval>`
|
|
25
|
+
Symbol(s) from which data should be taken.
|
|
26
|
+
tick_type: str,
|
|
27
|
+
Name of the tick_type from which to take schema.
|
|
28
|
+
start, end: :py:class:`datetime.datetime`, :py:class:`otp.datetime <onetick.py.datetime>`, \
|
|
29
|
+
:py:class:`onetick.py.adaptive`
|
|
30
|
+
Time interval from which the data should be taken.
|
|
31
|
+
schema: dict
|
|
32
|
+
Schema to use in case db and/or tick_type are not set.
|
|
33
|
+
kwargs:
|
|
34
|
+
Deprecated. Use ``schema`` instead.
|
|
35
|
+
Schema to use in case db and/or tick_type are not set.
|
|
36
|
+
|
|
37
|
+
Examples
|
|
38
|
+
--------
|
|
39
|
+
We can define schema:
|
|
40
|
+
|
|
41
|
+
>>> data = otp.Empty(schema={'A': str, 'B': int})
|
|
42
|
+
>>> otp.run(data)
|
|
43
|
+
Empty DataFrame
|
|
44
|
+
Columns: [A, B, Time]
|
|
45
|
+
Index: []
|
|
46
|
+
>>> data.schema
|
|
47
|
+
{'A': <class 'str'>, 'B': <class 'int'>}
|
|
48
|
+
|
|
49
|
+
Or we can get schema from the database:
|
|
50
|
+
|
|
51
|
+
>>> data = otp.Empty(db='SOME_DB', tick_type='TT')
|
|
52
|
+
>>> data.schema
|
|
53
|
+
{'X': <class 'int'>}
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def __init__(
|
|
57
|
+
self,
|
|
58
|
+
db=utils.adaptive_to_default,
|
|
59
|
+
symbol=utils.adaptive_to_default,
|
|
60
|
+
tick_type=utils.adaptive,
|
|
61
|
+
start=utils.adaptive,
|
|
62
|
+
end=utils.adaptive,
|
|
63
|
+
schema=None,
|
|
64
|
+
**kwargs,
|
|
65
|
+
):
|
|
66
|
+
if self._try_default_constructor(schema=schema, **kwargs):
|
|
67
|
+
return
|
|
68
|
+
|
|
69
|
+
schema = self._select_schema(schema, kwargs)
|
|
70
|
+
|
|
71
|
+
columns = {}
|
|
72
|
+
|
|
73
|
+
if (tick_type is not utils.adaptive and
|
|
74
|
+
db != configuration.config.get('default_db') and db is not utils.adaptive_to_default):
|
|
75
|
+
try:
|
|
76
|
+
db_obj = onetick.py.db._inspection.DB(db)
|
|
77
|
+
params = {'tick_type': tick_type}
|
|
78
|
+
if end is not utils.adaptive:
|
|
79
|
+
params['end'] = end
|
|
80
|
+
columns = db_obj.schema(**params)
|
|
81
|
+
except Exception:
|
|
82
|
+
pass # do not raise an exception if no data found, because it is empty _source and does not matter
|
|
83
|
+
|
|
84
|
+
else:
|
|
85
|
+
columns = schema
|
|
86
|
+
|
|
87
|
+
super().__init__(
|
|
88
|
+
_symbols=symbol, _start=start, _end=end, _base_ep_func=lambda: self.base_ep(db), schema=columns,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
def base_ep(self, db):
|
|
92
|
+
src = Source(otq.TickGenerator(fields="long ___NOTHING___=0"))
|
|
93
|
+
update_node_tick_type(src, 'TICK_GENERATOR', db)
|
|
94
|
+
return src
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
from typing import Optional, List
|
|
2
|
+
|
|
3
|
+
import onetick.py as otp
|
|
4
|
+
from onetick.py.otq import otq
|
|
5
|
+
|
|
6
|
+
import onetick.py.db._inspection
|
|
7
|
+
from onetick.py.core.source import Source
|
|
8
|
+
|
|
9
|
+
from .. import utils, configuration
|
|
10
|
+
from ..core.column_operations.base import _Operation
|
|
11
|
+
from ..compatibility import is_odbc_query_supported
|
|
12
|
+
|
|
13
|
+
from .common import update_node_tick_type
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ODBC(Source):
|
|
17
|
+
|
|
18
|
+
_PROPERTIES = Source._PROPERTIES + [
|
|
19
|
+
'_dsn',
|
|
20
|
+
'_connection_string',
|
|
21
|
+
'_authentication_type',
|
|
22
|
+
'_user',
|
|
23
|
+
'_password',
|
|
24
|
+
'_sql',
|
|
25
|
+
'_symbology',
|
|
26
|
+
'_allow_unordered_ticks',
|
|
27
|
+
'_tz',
|
|
28
|
+
'_start_expr',
|
|
29
|
+
'_end_expr',
|
|
30
|
+
'_apply_symbol_name_history',
|
|
31
|
+
'_numeric_scale',
|
|
32
|
+
'_preserve_unicode_fields',
|
|
33
|
+
'_db',
|
|
34
|
+
'_tick_type',
|
|
35
|
+
'_symbols',
|
|
36
|
+
'_presort',
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
dsn: Optional[str] = None,
|
|
42
|
+
connection_string: Optional[str] = None,
|
|
43
|
+
authentication_type: str = 'credentials',
|
|
44
|
+
user: Optional[str] = None,
|
|
45
|
+
password: Optional[str] = None,
|
|
46
|
+
sql: Optional[str] = None,
|
|
47
|
+
start_expr: Optional[_Operation] = None,
|
|
48
|
+
end_expr: Optional[_Operation] = None,
|
|
49
|
+
tz=None,
|
|
50
|
+
allow_unordered_ticks=False,
|
|
51
|
+
numeric_scale=8,
|
|
52
|
+
preserve_unicode_fields: Optional[List[str]] = None,
|
|
53
|
+
symbology='',
|
|
54
|
+
apply_symbol_name_history=False,
|
|
55
|
+
start=utils.adaptive,
|
|
56
|
+
end=utils.adaptive,
|
|
57
|
+
db=utils.adaptive,
|
|
58
|
+
tick_type=utils.adaptive,
|
|
59
|
+
symbols=utils.adaptive_to_default,
|
|
60
|
+
presort=False,
|
|
61
|
+
schema=None,
|
|
62
|
+
**kwargs,
|
|
63
|
+
):
|
|
64
|
+
"""
|
|
65
|
+
Read from ODBC-compatible database and propagate the resulting data as a time series of ticks.
|
|
66
|
+
|
|
67
|
+
A time series is generated for every symbol of the query and the symbol name can be passed down to SQL query.
|
|
68
|
+
|
|
69
|
+
If an attribute with the name *TIMESTAMP* is present in the database schema,
|
|
70
|
+
it is assumed to be of either SQL DATE or SQL TIMESTAMP type, in which case output tick timestamps
|
|
71
|
+
will carry values of that field and the field itself will not be propagated.
|
|
72
|
+
If such a field is absent, output tick timestamps will be equal to query end time.
|
|
73
|
+
|
|
74
|
+
ODBC source supported only on OneTick versions starting from release 1.24
|
|
75
|
+
(or from development build 20231108-0)
|
|
76
|
+
|
|
77
|
+
Note
|
|
78
|
+
----
|
|
79
|
+
|
|
80
|
+
To be able to use this class, you need to have a ODBC driver manager available on your machine
|
|
81
|
+
(comes with Windows OS; **unixodbc** package may need to be installed on UNIX OS).
|
|
82
|
+
|
|
83
|
+
Also, the following entry needs to be added to the main configuration file::
|
|
84
|
+
|
|
85
|
+
LOAD_ODBC_UDF=true
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
dsn: str
|
|
90
|
+
Target database's source name registered in ODBC configuration.
|
|
91
|
+
connection_string: str
|
|
92
|
+
ODBC connection string. The format depends on the database you are trying to connect.
|
|
93
|
+
Example for SQLite database::
|
|
94
|
+
|
|
95
|
+
DRIVER={SQLite3};Database=/path/to/the/database.db
|
|
96
|
+
|
|
97
|
+
This parameter is mutually exclusive
|
|
98
|
+
with parameters ``dsn``, ``user``, ``password`` and ``authentication_type``.
|
|
99
|
+
authentication_type: str ('system' or 'credentials')
|
|
100
|
+
|
|
101
|
+
- **system**: in this case a trusted connection to the database will be used.
|
|
102
|
+
If authentication is enabled in the server configuration file
|
|
103
|
+
(see the OneTick Installation and Administration Guide for details),
|
|
104
|
+
the client will be authenticated and the client's credentials will be used for connection;
|
|
105
|
+
otherwise, server credentials will be used.
|
|
106
|
+
- **credentials**: username and password specified with parameter ``connection_string``
|
|
107
|
+
or with parameters ``user`` and ``password`` will be used to connect to the database.
|
|
108
|
+
|
|
109
|
+
user: str, optional
|
|
110
|
+
The connection user name.
|
|
111
|
+
|
|
112
|
+
Ignored if ``authentication_type`` is **system**.
|
|
113
|
+
password: str, optional
|
|
114
|
+
The connection password.
|
|
115
|
+
|
|
116
|
+
Ignored if ``authentication_type`` is **system**.
|
|
117
|
+
sql: str
|
|
118
|
+
A query in SQL language, which may optionally contain parameter placeholders.
|
|
119
|
+
|
|
120
|
+
There are 3 types of placeholders: **<_SYMBOL_NAME>**, **<_START_TIME>**, and **<_END_TIME>**.
|
|
121
|
+
|
|
122
|
+
**<_SYMBOL_NAME>** will be replaced by the pure symbol name part of the query.
|
|
123
|
+
|
|
124
|
+
**<_START_TIME>** and **<_END_TIME>** will be replaced by values of parameters
|
|
125
|
+
``start_expr`` and ``end_expr`` or, if they are not set, with values taken from query start and end times.
|
|
126
|
+
|
|
127
|
+
These timestamps will be inserted in the format ``YYYY-MM-DD HH:MM:SS.sss TIMEZONE``.
|
|
128
|
+
|
|
129
|
+
start_expr: str or :py:class:`~onetick.py.Operation`
|
|
130
|
+
A constant string expression used to replace the **<_START_TIME>** placeholder in an ``sql`` query.
|
|
131
|
+
Tick-dependent columns can't be used in this expression, only meta fields such as
|
|
132
|
+
*TIMESTAMP*, *_START_TIME*, and *_END_TIME* are allowed.
|
|
133
|
+
end_expr: str or :py:class:`~onetick.py.Operation`
|
|
134
|
+
A constant string expression used to replace the **<_END_TIME>** placeholder in an ``sql`` query.
|
|
135
|
+
Tick-dependent columns can't be used in this expression, only meta fields such as
|
|
136
|
+
*TIMESTAMP*, *_START_TIME*, and *_END_TIME* are allowed.
|
|
137
|
+
tz: str
|
|
138
|
+
The timezone used to interpret *TIMESTAMP* and other datetime columns in the database.
|
|
139
|
+
By default :py:attr:`tz<onetick.py.configuration.Config.tz>` is used.
|
|
140
|
+
|
|
141
|
+
allow_unordered_ticks: bool
|
|
142
|
+
If set to False, this class will raise an exception when unordered ticks will be encountered.
|
|
143
|
+
|
|
144
|
+
If set to True, processing ticks unordered by timestamp will be allowed
|
|
145
|
+
(exception may still be raised by other EPs of the graph that require ticks to be ordered).
|
|
146
|
+
|
|
147
|
+
numeric_scale: int
|
|
148
|
+
Number of digits after the decimal point for SQL_NUMERIC and SQL_DECIMAL data types.
|
|
149
|
+
Precision (maximum number of digits) is always set to 34.
|
|
150
|
+
preserve_unicode_fields: list of str
|
|
151
|
+
By default ODBC queries all data as ANSI,
|
|
152
|
+
ODBC Driver Manager then tries to convert Unicode characters to ANSI.
|
|
153
|
+
|
|
154
|
+
This parameter is a list of fields, which have Unicode types in the data source
|
|
155
|
+
and will be propagated without conversion.
|
|
156
|
+
|
|
157
|
+
UNICODE_CHAR_TYPE field property will be set to UCS-2 for these fields.
|
|
158
|
+
|
|
159
|
+
symbology: str
|
|
160
|
+
If specified, **<_SYMBOL_NAME>** placeholder in ``sql`` query will be replaced with
|
|
161
|
+
the mapping of the symbol name of the query for provided symbology.
|
|
162
|
+
|
|
163
|
+
apply_symbol_name_history: bool
|
|
164
|
+
If set to False, ODBC will not take into account the symbol name history
|
|
165
|
+
when substituting the SQL query with actual symbol names.
|
|
166
|
+
|
|
167
|
+
If set to True, ODBC will resolve symbol name changes according to the reference data
|
|
168
|
+
by substituting the SQL query accordingly,
|
|
169
|
+
provided the symbol date is specified in :py:func:`otp.run <onetick.py.run>` when running the query and
|
|
170
|
+
the SQL query contains all three placeholders **<_SYMBOL_NAME>**, **<_START_TIME>**, **<_END_TIME>**.
|
|
171
|
+
|
|
172
|
+
Note that ODBC data source needs to support "UNION ALL" syntax for this functionality to work.
|
|
173
|
+
|
|
174
|
+
start:
|
|
175
|
+
Custom start time of the query.
|
|
176
|
+
By default the start time used by :py:func:`otp.run <onetick.py.run>` will be inherited.
|
|
177
|
+
end:
|
|
178
|
+
Custom end time of the query.
|
|
179
|
+
By default the start time used by :py:func:`otp.run <onetick.py.run>` will be inherited.
|
|
180
|
+
db: str
|
|
181
|
+
Custom database name for the node of the graph.
|
|
182
|
+
By default the database used by :py:func:`otp.run <onetick.py.run>` will be inherited.
|
|
183
|
+
tick_type: str
|
|
184
|
+
Custom tick type for the node of the graph.
|
|
185
|
+
By default "ANY" tick type will be set.
|
|
186
|
+
symbols: str or list of str
|
|
187
|
+
Custom symbol name for the node of the graph or list of symbols.
|
|
188
|
+
If list of symbols is specified, ticks from different symbols will be merged into one source.
|
|
189
|
+
|
|
190
|
+
Separate ODBC connection will be created for each processed symbol.
|
|
191
|
+
To avoid this and have a single connection per thread, ``presort`` parameter can be specified.
|
|
192
|
+
|
|
193
|
+
By default the symbol name used by :py:func:`otp.run <onetick.py.run>` will be inherited.
|
|
194
|
+
presort: bool
|
|
195
|
+
Adds **PRESORT** EP before merging bound symbols specified in ``symbols``.
|
|
196
|
+
That make ODBC use single connection for all symbols.
|
|
197
|
+
schema: dict
|
|
198
|
+
Set the schema of the python :py:class:`~onetick.py.Source` object of this class.
|
|
199
|
+
|
|
200
|
+
Schema can't be taken automatically from the database, so it should be set manually
|
|
201
|
+
for python-level type checking to work.
|
|
202
|
+
kwargs:
|
|
203
|
+
Deprecated. Use ``schema`` instead.
|
|
204
|
+
Set the schema of the python :py:class:`~onetick.py.Source` object of this class.
|
|
205
|
+
|
|
206
|
+
See also
|
|
207
|
+
--------
|
|
208
|
+
**ODBC_QUERY** OneTick event processor
|
|
209
|
+
|
|
210
|
+
Examples
|
|
211
|
+
--------
|
|
212
|
+
|
|
213
|
+
Connect with database's ``dsn``, manually set schema, get all data from TEST_TABLE:
|
|
214
|
+
|
|
215
|
+
>>> data = otp.ODBC(dsn='testdb_dsn', sql='select * from TEST_TABLE',
|
|
216
|
+
... schema={'A': str, 'B': int, 'C': float, 'D': otp.nsectime}) # doctest: +SKIP
|
|
217
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
218
|
+
Time A B C D
|
|
219
|
+
0 2003-12-04 A1 1975 8.12345 2022-01-01 12:13:14.111
|
|
220
|
+
1 2003-12-04 A2 1971 7.98765 2022-01-02 22:23:24.222
|
|
221
|
+
|
|
222
|
+
Connect using ``connection_string`` parameter:
|
|
223
|
+
|
|
224
|
+
>>> data = otp.ODBC(connection_string='DRIVER={SQLite3};Database=/path/to/the/database',
|
|
225
|
+
... sql='select * from TEST_TABLE') # doctest: +SKIP
|
|
226
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
227
|
+
Time A B C D
|
|
228
|
+
0 2003-12-04 A1 1975 8.12345 2022-01-01 12:13:14.111
|
|
229
|
+
1 2003-12-04 A2 1971 7.98765 2022-01-02 22:23:24.222
|
|
230
|
+
|
|
231
|
+
Substitute start time placeholder with ``start_expr`` parameter:
|
|
232
|
+
|
|
233
|
+
>>> data = otp.ODBC(
|
|
234
|
+
... dsn='testdb_dsn',
|
|
235
|
+
... sql='select * from TEST_TIMESTAMP where TIMESTAMP >= "<_START_TIME>"',
|
|
236
|
+
... start_expr=(otp.meta_fields['START_TIME'] + otp.Day(1)).dt.strftime('%Y-%m-%d %H:%M:%S.%q')
|
|
237
|
+
... ) # doctest: +SKIP
|
|
238
|
+
>>> otp.run(data, start=otp.dt(2022, 1, 1), end=otp.dt(2022, 1, 3)) # doctest: +SKIP
|
|
239
|
+
Time A
|
|
240
|
+
0 2022-01-02 22:23:24.222 2
|
|
241
|
+
|
|
242
|
+
Use parameter ``allow_unordered_ticks`` if needed:
|
|
243
|
+
|
|
244
|
+
>>> data = otp.ODBC(dsn='testdb_dsn',
|
|
245
|
+
... sql='select * from TEST_UNORDERED',
|
|
246
|
+
... allow_unordered_ticks=True) # doctest: +SKIP
|
|
247
|
+
>>> otp.run(data, start=otp.dt(2022, 1, 1), end=otp.dt(2022, 1, 3)) # doctest: +SKIP
|
|
248
|
+
Time A
|
|
249
|
+
0 2022-01-02 22:23:24.222 2
|
|
250
|
+
1 2022-01-01 12:13:14.111 1
|
|
251
|
+
"""
|
|
252
|
+
if self._try_default_constructor(schema=schema, **kwargs):
|
|
253
|
+
return
|
|
254
|
+
|
|
255
|
+
if not is_odbc_query_supported():
|
|
256
|
+
raise RuntimeError("ODBC source is not supported in this version of OneTick, "
|
|
257
|
+
"it is available starting from release 1.24 (or development build 20231108)")
|
|
258
|
+
|
|
259
|
+
if not dsn and not connection_string:
|
|
260
|
+
raise ValueError("One of the parameters 'dsn' or 'connection_string' must be specified")
|
|
261
|
+
|
|
262
|
+
if authentication_type not in {'system', 'credentials'}:
|
|
263
|
+
raise ValueError(f"Unknown value for parameter 'authentication_type': {authentication_type}")
|
|
264
|
+
|
|
265
|
+
if connection_string and any([dsn, user, password, authentication_type == 'system']):
|
|
266
|
+
raise ValueError("Parameter 'connection_string' is used instead of parameters"
|
|
267
|
+
" 'dsn', 'user', 'password' and 'authentication_type'")
|
|
268
|
+
|
|
269
|
+
if not sql:
|
|
270
|
+
raise ValueError("Parameter 'sql' must be set")
|
|
271
|
+
|
|
272
|
+
if not isinstance(numeric_scale, int) or not 0 <= numeric_scale <= 34:
|
|
273
|
+
raise ValueError("Unsupported value for parameter 'numeric_scale'")
|
|
274
|
+
|
|
275
|
+
self._dsn = dsn
|
|
276
|
+
self._connection_string = connection_string
|
|
277
|
+
self._authentication_type = authentication_type
|
|
278
|
+
self._user = user
|
|
279
|
+
self._password = password
|
|
280
|
+
self._sql = sql
|
|
281
|
+
self._symbology = symbology
|
|
282
|
+
self._allow_unordered_ticks = allow_unordered_ticks
|
|
283
|
+
self._apply_symbol_name_history = apply_symbol_name_history
|
|
284
|
+
self._numeric_scale = numeric_scale
|
|
285
|
+
self._preserve_unicode_fields = preserve_unicode_fields
|
|
286
|
+
self._tz = tz
|
|
287
|
+
self._start_expr = start_expr
|
|
288
|
+
self._end_expr = end_expr
|
|
289
|
+
self._db = db
|
|
290
|
+
self._tick_type = tick_type
|
|
291
|
+
self._symbols = symbols
|
|
292
|
+
self._presort = presort
|
|
293
|
+
|
|
294
|
+
# if we have a list of symbols, they will be merged in self.base_ep()
|
|
295
|
+
if isinstance(symbols, list):
|
|
296
|
+
symbols = None
|
|
297
|
+
|
|
298
|
+
super().__init__(
|
|
299
|
+
_symbols=symbols, _start=start, _end=end, _base_ep_func=lambda: self.base_ep(schema=schema, **kwargs),
|
|
300
|
+
schema=schema, **kwargs,
|
|
301
|
+
)
|
|
302
|
+
|
|
303
|
+
def base_ep(self, schema=None, **kwargs):
|
|
304
|
+
|
|
305
|
+
src = Source(
|
|
306
|
+
otq.Omd_odbcQuery(
|
|
307
|
+
dsn=self._dsn or '',
|
|
308
|
+
connection_string=self._connection_string or '',
|
|
309
|
+
authentication_type='System' if self._authentication_type == 'system' else 'Username/Password',
|
|
310
|
+
user=self._user or '',
|
|
311
|
+
password=self._password or '',
|
|
312
|
+
sql=self._sql,
|
|
313
|
+
symbology=self._symbology or '',
|
|
314
|
+
allow_unordered_ticks=self._allow_unordered_ticks,
|
|
315
|
+
apply_symbol_name_history=self._apply_symbol_name_history,
|
|
316
|
+
numeric_scale=self._numeric_scale,
|
|
317
|
+
preserve_unicode_fields=','.join(self._preserve_unicode_fields or []),
|
|
318
|
+
tz=self._tz or configuration.config.get('tz') or '',
|
|
319
|
+
start_time_expr=str(self._start_expr) if self._start_expr is not None else '',
|
|
320
|
+
end_time_expr=str(self._end_expr) if self._end_expr is not None else '',
|
|
321
|
+
),
|
|
322
|
+
schema=schema,
|
|
323
|
+
**kwargs,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
db = self._db
|
|
327
|
+
|
|
328
|
+
if isinstance(self._symbols, list):
|
|
329
|
+
if self._presort:
|
|
330
|
+
src.sink(otq.Presort().symbols(self._symbols))
|
|
331
|
+
src.sink(otq.Merge(identify_input_ts=False))
|
|
332
|
+
else:
|
|
333
|
+
src.sink(otq.Merge(identify_input_ts=False).symbols(self._symbols))
|
|
334
|
+
|
|
335
|
+
update_node_tick_type(src, self._tick_type, db)
|
|
336
|
+
|
|
337
|
+
return src
|