onetick-py 1.162.2__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.
Files changed (152) hide show
  1. locator_parser/__init__.py +0 -0
  2. locator_parser/acl.py +73 -0
  3. locator_parser/actions.py +266 -0
  4. locator_parser/common.py +365 -0
  5. locator_parser/io.py +41 -0
  6. locator_parser/locator.py +150 -0
  7. onetick/__init__.py +101 -0
  8. onetick/doc_utilities/__init__.py +3 -0
  9. onetick/doc_utilities/napoleon.py +40 -0
  10. onetick/doc_utilities/ot_doctest.py +140 -0
  11. onetick/doc_utilities/snippets.py +280 -0
  12. onetick/lib/__init__.py +4 -0
  13. onetick/lib/instance.py +138 -0
  14. onetick/py/__init__.py +290 -0
  15. onetick/py/_stack_info.py +89 -0
  16. onetick/py/_version.py +2 -0
  17. onetick/py/aggregations/__init__.py +11 -0
  18. onetick/py/aggregations/_base.py +645 -0
  19. onetick/py/aggregations/_docs.py +912 -0
  20. onetick/py/aggregations/compute.py +286 -0
  21. onetick/py/aggregations/functions.py +2216 -0
  22. onetick/py/aggregations/generic.py +104 -0
  23. onetick/py/aggregations/high_low.py +80 -0
  24. onetick/py/aggregations/num_distinct.py +83 -0
  25. onetick/py/aggregations/order_book.py +427 -0
  26. onetick/py/aggregations/other.py +1014 -0
  27. onetick/py/backports.py +26 -0
  28. onetick/py/cache.py +373 -0
  29. onetick/py/callback/__init__.py +5 -0
  30. onetick/py/callback/callback.py +275 -0
  31. onetick/py/callback/callbacks.py +131 -0
  32. onetick/py/compatibility.py +752 -0
  33. onetick/py/configuration.py +736 -0
  34. onetick/py/core/__init__.py +0 -0
  35. onetick/py/core/_csv_inspector.py +93 -0
  36. onetick/py/core/_internal/__init__.py +0 -0
  37. onetick/py/core/_internal/_manually_bound_value.py +6 -0
  38. onetick/py/core/_internal/_nodes_history.py +250 -0
  39. onetick/py/core/_internal/_op_utils/__init__.py +0 -0
  40. onetick/py/core/_internal/_op_utils/every_operand.py +9 -0
  41. onetick/py/core/_internal/_op_utils/is_const.py +10 -0
  42. onetick/py/core/_internal/_per_tick_scripts/tick_list_sort_template.script +121 -0
  43. onetick/py/core/_internal/_proxy_node.py +140 -0
  44. onetick/py/core/_internal/_state_objects.py +2307 -0
  45. onetick/py/core/_internal/_state_vars.py +87 -0
  46. onetick/py/core/_source/__init__.py +0 -0
  47. onetick/py/core/_source/_symbol_param.py +95 -0
  48. onetick/py/core/_source/schema.py +97 -0
  49. onetick/py/core/_source/source_methods/__init__.py +0 -0
  50. onetick/py/core/_source/source_methods/aggregations.py +810 -0
  51. onetick/py/core/_source/source_methods/applyers.py +296 -0
  52. onetick/py/core/_source/source_methods/columns.py +141 -0
  53. onetick/py/core/_source/source_methods/data_quality.py +301 -0
  54. onetick/py/core/_source/source_methods/debugs.py +270 -0
  55. onetick/py/core/_source/source_methods/drops.py +120 -0
  56. onetick/py/core/_source/source_methods/fields.py +619 -0
  57. onetick/py/core/_source/source_methods/filters.py +1001 -0
  58. onetick/py/core/_source/source_methods/joins.py +1393 -0
  59. onetick/py/core/_source/source_methods/merges.py +566 -0
  60. onetick/py/core/_source/source_methods/misc.py +1325 -0
  61. onetick/py/core/_source/source_methods/pandases.py +155 -0
  62. onetick/py/core/_source/source_methods/renames.py +356 -0
  63. onetick/py/core/_source/source_methods/sorts.py +183 -0
  64. onetick/py/core/_source/source_methods/switches.py +142 -0
  65. onetick/py/core/_source/source_methods/symbols.py +117 -0
  66. onetick/py/core/_source/source_methods/times.py +627 -0
  67. onetick/py/core/_source/source_methods/writes.py +702 -0
  68. onetick/py/core/_source/symbol.py +202 -0
  69. onetick/py/core/_source/tmp_otq.py +222 -0
  70. onetick/py/core/column.py +209 -0
  71. onetick/py/core/column_operations/__init__.py +0 -0
  72. onetick/py/core/column_operations/_methods/__init__.py +4 -0
  73. onetick/py/core/column_operations/_methods/_internal.py +28 -0
  74. onetick/py/core/column_operations/_methods/conversions.py +215 -0
  75. onetick/py/core/column_operations/_methods/methods.py +294 -0
  76. onetick/py/core/column_operations/_methods/op_types.py +150 -0
  77. onetick/py/core/column_operations/accessors/__init__.py +0 -0
  78. onetick/py/core/column_operations/accessors/_accessor.py +30 -0
  79. onetick/py/core/column_operations/accessors/decimal_accessor.py +92 -0
  80. onetick/py/core/column_operations/accessors/dt_accessor.py +464 -0
  81. onetick/py/core/column_operations/accessors/float_accessor.py +160 -0
  82. onetick/py/core/column_operations/accessors/str_accessor.py +1374 -0
  83. onetick/py/core/column_operations/base.py +1061 -0
  84. onetick/py/core/cut_builder.py +149 -0
  85. onetick/py/core/db_constants.py +20 -0
  86. onetick/py/core/eval_query.py +244 -0
  87. onetick/py/core/lambda_object.py +442 -0
  88. onetick/py/core/multi_output_source.py +193 -0
  89. onetick/py/core/per_tick_script.py +2253 -0
  90. onetick/py/core/query_inspector.py +465 -0
  91. onetick/py/core/source.py +1663 -0
  92. onetick/py/db/__init__.py +2 -0
  93. onetick/py/db/_inspection.py +1042 -0
  94. onetick/py/db/db.py +1423 -0
  95. onetick/py/db/utils.py +64 -0
  96. onetick/py/docs/__init__.py +0 -0
  97. onetick/py/docs/docstring_parser.py +112 -0
  98. onetick/py/docs/utils.py +81 -0
  99. onetick/py/functions.py +2354 -0
  100. onetick/py/license.py +188 -0
  101. onetick/py/log.py +88 -0
  102. onetick/py/math.py +947 -0
  103. onetick/py/misc.py +437 -0
  104. onetick/py/oqd/__init__.py +22 -0
  105. onetick/py/oqd/eps.py +1195 -0
  106. onetick/py/oqd/sources.py +325 -0
  107. onetick/py/otq.py +211 -0
  108. onetick/py/pyomd_mock.py +47 -0
  109. onetick/py/run.py +841 -0
  110. onetick/py/servers.py +173 -0
  111. onetick/py/session.py +1342 -0
  112. onetick/py/sources/__init__.py +19 -0
  113. onetick/py/sources/cache.py +167 -0
  114. onetick/py/sources/common.py +126 -0
  115. onetick/py/sources/csv.py +642 -0
  116. onetick/py/sources/custom.py +85 -0
  117. onetick/py/sources/data_file.py +305 -0
  118. onetick/py/sources/data_source.py +1049 -0
  119. onetick/py/sources/empty.py +94 -0
  120. onetick/py/sources/odbc.py +337 -0
  121. onetick/py/sources/order_book.py +238 -0
  122. onetick/py/sources/parquet.py +168 -0
  123. onetick/py/sources/pit.py +191 -0
  124. onetick/py/sources/query.py +495 -0
  125. onetick/py/sources/snapshots.py +419 -0
  126. onetick/py/sources/split_query_output_by_symbol.py +198 -0
  127. onetick/py/sources/symbology_mapping.py +123 -0
  128. onetick/py/sources/symbols.py +357 -0
  129. onetick/py/sources/ticks.py +825 -0
  130. onetick/py/sql.py +70 -0
  131. onetick/py/state.py +256 -0
  132. onetick/py/types.py +2056 -0
  133. onetick/py/utils/__init__.py +70 -0
  134. onetick/py/utils/acl.py +93 -0
  135. onetick/py/utils/config.py +186 -0
  136. onetick/py/utils/default.py +49 -0
  137. onetick/py/utils/file.py +38 -0
  138. onetick/py/utils/helpers.py +76 -0
  139. onetick/py/utils/locator.py +94 -0
  140. onetick/py/utils/perf.py +499 -0
  141. onetick/py/utils/query.py +49 -0
  142. onetick/py/utils/render.py +1139 -0
  143. onetick/py/utils/script.py +244 -0
  144. onetick/py/utils/temp.py +471 -0
  145. onetick/py/utils/types.py +118 -0
  146. onetick/py/utils/tz.py +82 -0
  147. onetick_py-1.162.2.dist-info/METADATA +148 -0
  148. onetick_py-1.162.2.dist-info/RECORD +152 -0
  149. onetick_py-1.162.2.dist-info/WHEEL +5 -0
  150. onetick_py-1.162.2.dist-info/entry_points.txt +2 -0
  151. onetick_py-1.162.2.dist-info/licenses/LICENSE +21 -0
  152. onetick_py-1.162.2.dist-info/top_level.txt +2 -0
@@ -0,0 +1,325 @@
1
+ from functools import partial
2
+
3
+ import pandas as pd
4
+
5
+ import onetick.py as otp
6
+ from onetick.py.otq import otq
7
+
8
+ from onetick.py import utils
9
+ from onetick.py.sources.data_source import _start_doc, _end_doc, _symbol_doc
10
+ from onetick.py.docs.utils import docstring, param_doc
11
+
12
+
13
+ COMMON_SOURCE_DOC_PARAMS = [_start_doc, _end_doc, _symbol_doc]
14
+ OQD_TICK_TYPE = 'OQD::*'
15
+
16
+
17
+ def _modify_query_times(src):
18
+ src.sink(otq.ModifyQueryTimes(
19
+ start_time=('parse_time("%Y%m%d %H:%M:%S.%q", '
20
+ 'time_format("%Y%m%d", _START_TIME, _TIMEZONE) + " 00:00:00.000", "GMT")'),
21
+ end_time=('parse_time("%Y%m%d %H:%M:%S.%q", '
22
+ 'time_format("%Y%m%d", _END_TIME, _TIMEZONE) + " 24:00:00.000", "GMT")'),
23
+ output_timestamp='min(max(TIMESTAMP,_START_TIME),_END_TIME)'
24
+ ))
25
+
26
+
27
+ _exch_doc = param_doc(
28
+ name='exch',
29
+ desc="""
30
+ The OneQuantData exchange code for the desired price series. Possible values:
31
+
32
+ - 'all'
33
+ return data for all exchanges;
34
+
35
+ - 'main'
36
+ return data main pricing exchange;
37
+
38
+ - any other string value will treated as exchange name to filter data.
39
+
40
+ Default: 'all'.
41
+ """,
42
+ str_annotation="str, 'all', 'main'",
43
+ default='all',
44
+ )
45
+
46
+
47
+ class OHLCV(otp.Source):
48
+ @docstring(parameters=[_exch_doc] + COMMON_SOURCE_DOC_PARAMS, add_self=True)
49
+ def __init__(
50
+ self,
51
+ exch='all',
52
+ symbol=utils.adaptive,
53
+ start=utils.adaptive,
54
+ end=utils.adaptive,
55
+ **kwargs
56
+ ):
57
+ """
58
+ OneQuantData™ source to retrieve a time series of unadjusted
59
+ prices for a symbol for one particular pricing exchange of daily OHLCV data.
60
+ Output ticks have fields: OPEN, HIGH, LOW, CLOSE, VOLUME, CURRENCY, EXCH.
61
+
62
+ Examples
63
+ --------
64
+ >>> src = otp.oqd.sources.OHLCV(exch="USPRIM") # doctest: +SKIP
65
+ >>> otp.run(src, # doctest: +SKIP
66
+ ... symbols='BTKR::::GOOGL US',
67
+ ... start=otp.dt(2018, 8, 1),
68
+ ... end=otp.dt(2018, 8, 2),
69
+ ... symbol_date=otp.dt(2018, 8, 1))
70
+ Time OID EXCH CURRENCY OPEN HIGH LOW CLOSE VOLUME
71
+ 0 2018-08-01 00:00:00 74143 USPRIM USD 1242.73 1245.72 1225.00 1232.99 605680.0
72
+ 1 2018-08-01 20:00:00 74143 USPRIM USD 1219.69 1244.25 1218.06 1241.13 596960.0
73
+ """
74
+ if self._try_default_constructor(**kwargs):
75
+ return
76
+
77
+ super().__init__(
78
+ _symbols=symbol,
79
+ _start=start,
80
+ _end=end,
81
+ _base_ep_func=partial(self.build, exch=exch)
82
+ )
83
+
84
+ self.schema.set(OID=str,
85
+ EXCH=str,
86
+ CURRENCY=str,
87
+ OPEN=float,
88
+ HIGH=float,
89
+ LOW=float,
90
+ CLOSE=float,
91
+ VOLUME=float)
92
+
93
+ def build(self, exch):
94
+ ep = None
95
+ if exch == 'all':
96
+ ep = otp.oqd.eps.OqdSourceDprcAll()
97
+ elif exch == 'main':
98
+ ep = otp.oqd.eps.OqdSourceDprcMain()
99
+ else:
100
+ ep = otp.oqd.eps.OqdSourceDprcExch(exch=exch)
101
+
102
+ src = otp.Source(ep)
103
+ src.tick_type(OQD_TICK_TYPE)
104
+ _modify_query_times(src)
105
+ return src
106
+
107
+
108
+ class CorporateActions(otp.Source):
109
+ """
110
+ OneQuantData™ source EP to retrieve a time series of corporate
111
+ actions for a symbol.
112
+
113
+ This source will return all corporate action fields available for a symbol
114
+ with EX-Dates between the query start time and end time. The
115
+ timestamp of the series is equal to the EX-Date of the corporate
116
+ action with a time of 0:00:00 GMT.
117
+
118
+ Examples
119
+ --------
120
+ >>> src = otp.oqd.sources.CorporateActions() # doctest: +SKIP
121
+ >>> otp.run(src, # doctest: +SKIP
122
+ ... symbols='TDEQ::::AAPL',
123
+ ... start=otp.dt(2021, 1, 1),
124
+ ... end=otp.dt(2021, 8, 6),
125
+ ... symbol_date=otp.dt(2021, 2, 18),
126
+ ... timezone='GMT')
127
+ Time OID ACTION_ID ACTION_TYPE ACTION_ADJUST ACTION_CURRENCY ANN_DATE EX_DATE PAY_DATE REC_DATE\
128
+ TERM_NOTE TERM_RECORD_TYPE ACTION_STATUS
129
+ 0 2021-02-05 9706 16799540 CASH_DIVIDEND 0.205 USD 20210127 20210205 20210211 20210208\
130
+ CASH:0.205@USD NORMAL
131
+ 1 2021-05-07 9706 17098817 CASH_DIVIDEND 0.220 USD 20210428 20210507 20210513 20210510\
132
+ CASH:0.22@USD NORMAL
133
+ 2 2021-08-06 9706 17331864 CASH_DIVIDEND 0.220 USD 20210727 20210806 20210812 20210809\
134
+ CASH:0.22@USD NORMAL
135
+
136
+ """
137
+
138
+ @docstring(parameters=COMMON_SOURCE_DOC_PARAMS, add_self=True)
139
+ def __init__(
140
+ self,
141
+ symbol=utils.adaptive,
142
+ start=utils.adaptive,
143
+ end=utils.adaptive,
144
+ **kwargs
145
+ ):
146
+ if self._try_default_constructor(**kwargs):
147
+ return
148
+
149
+ super().__init__(
150
+ _symbols=symbol,
151
+ _start=start,
152
+ _end=end,
153
+ _base_ep_func=partial(self.build)
154
+ )
155
+
156
+ self.schema.set(OID=str,
157
+ ACTION_ID=int,
158
+ ACTION_TYPE=str,
159
+ ACTION_ADJUST=float,
160
+ ACTION_CURRENCY=str,
161
+ ANN_DATE=int,
162
+ EX_DATE=int,
163
+ PAY_DATE=int,
164
+ REC_DATE=int,
165
+ TERM_NOTE=str,
166
+ TERM_RECORD_TYPE=str,
167
+ ACTION_STATUS=str)
168
+
169
+ def build(self):
170
+ ep = otp.oqd.eps.OqdSourceCacs()
171
+ src = otp.Source(ep)
172
+ src.tick_type(OQD_TICK_TYPE)
173
+ _modify_query_times(src)
174
+ return src
175
+
176
+
177
+ class DescriptiveFields(otp.Source):
178
+ """OneQuantData™ source to retrieve a time series of descriptive fields for a symbol.
179
+ There will only be ticks on days when some field in the descriptive data changes.
180
+ Output ticks will have fields:
181
+ OID, END_DATE, COUNTRY, EXCH, NAME,
182
+ ISSUE_DESC, ISSUE_CLASS, ISSUE_TYPE, ISSUE_STATUS,
183
+ SIC_CODE, IDSYM, TICKER, CALENDAR.
184
+
185
+ Note: currently actual fields have 9999 year in END_DATE, but it could not fit the
186
+ nanosecond timestamp, so it is replaced with 2035-01-01 date.
187
+
188
+ Examples
189
+ --------
190
+ >>> src = otp.oqd.sources.DescriptiveFields() # doctest: +SKIP
191
+ >>> otp.run(src, # doctest: +SKIP
192
+ ... symbols='1000001589',
193
+ ... start=otp.dt(2020, 3, 1),
194
+ ... end=otp.dt(2023, 3, 2),
195
+ ... timezone='GMT').iloc[:6]
196
+ Time OID END_DATE COUNTRY EXCH NAME ISSUE_DESC\
197
+ ISSUE_CLASS ISSUE_TYPE ISSUE_STATUS SIC_CODE IDSYM TICKER CALENDAR
198
+ 0 2020-03-01 1000001589 2020-03-23 LUX EL^X INVESTEC GLOBAL ST EUROPEAN HIGH YLD BD INC 2\
199
+ FUND NORMAL B2PT4G9
200
+ 1 2020-03-23 1000001589 2020-04-01 LUX EL^X NINETY ONE LIMITED EUROPEAN HIGH YLD BD INC 2\
201
+ FUND NORMAL B2PT4G9
202
+ 2 2020-04-01 1000001589 2021-01-01 LUX EL^X NINETY ONE LUX S.A EUROPEAN HIGH YLD BD INC 2\
203
+ FUND NORMAL B2PT4G9
204
+ 3 2021-01-01 1000001589 2021-06-18 LUX EL^X NINETY ONE LUX S.A EUROPEAN HIGH YLD BD INC 2\
205
+ FUND NORMAL B2PT4G9
206
+ 4 2021-06-18 1000001589 2022-01-01 LUX EL^X NINETY ONE LUX S.A GSF GBL HIGH YLD A2 EUR DIS\
207
+ FUND NORMAL B2PT4G9
208
+ 5 2022-01-01 1000001589 2022-01-28 LUX EL^X NINETY ONE LUX S.A GSF GBL HIGH YLD A2 EUR DIS\
209
+ FUND NORMAL B2PT4G9
210
+ """
211
+
212
+ @docstring(parameters=COMMON_SOURCE_DOC_PARAMS, add_self=True)
213
+ def __init__(
214
+ self,
215
+ symbol=utils.adaptive,
216
+ start=utils.adaptive,
217
+ end=utils.adaptive,
218
+ **kwargs
219
+ ):
220
+ if self._try_default_constructor(**kwargs):
221
+ return
222
+
223
+ super().__init__(
224
+ _symbols=symbol,
225
+ _start=start,
226
+ _end=end,
227
+ _base_ep_func=partial(self.build)
228
+ )
229
+
230
+ self.schema.set(
231
+ OID=str,
232
+ END_DATE=otp.nsectime,
233
+ COUNTRY=str,
234
+ EXCH=str,
235
+ NAME=str,
236
+ ISSUE_DESC=str,
237
+ ISSUE_CLASS=str,
238
+ ISSUE_TYPE=str,
239
+ ISSUE_STATUS=str,
240
+ SIC_CODE=str,
241
+ IDSYM=str,
242
+ TICKER=str,
243
+ CALENDAR=str,)
244
+
245
+ def build(self):
246
+ ep = otp.oqd.eps.OqdSourceDes()
247
+ src = otp.Source(ep)
248
+ src.tick_type(OQD_TICK_TYPE)
249
+ _modify_query_times(src)
250
+
251
+ # work-around to resolve problem with pandas timestamp out of bounds
252
+ pd_max = pd.Timestamp.max.strftime('%Y%m%d%H%M%S')
253
+ src.sink(otq.UpdateFields(
254
+ set='END_DATE=PARSE_NSECTIME("%Y-%m-%d", "2035-01-01", _TIMEZONE)',
255
+ where=f'AS_YYYYMMDDHHMMSS(END_DATE) > {pd_max}'))
256
+ return src
257
+
258
+
259
+ class SharesOutstanding(otp.Source):
260
+ """
261
+ Logic is implemented in OQD_SOURCE_SHO EP to retrieve a time series of shares
262
+ outstanding for a stock.
263
+
264
+ The source retrieves a time series of shares outstanding
265
+ for a stock. This source only applies to stocks or securities that have
266
+ published shares outstanding data.
267
+
268
+ The series represents total shares outstanding and is not free float
269
+ adjusted.
270
+
271
+ Note: currently actual fields have 9999 year in END_DATE, but it could not fit the
272
+ nanosecond timestamp, so it is replaced with 2035-01-01 date.
273
+
274
+
275
+ Examples
276
+ --------
277
+ >>> src = otp.oqd.sources.SharesOutstanding() # doctest: +SKIP
278
+ >>> otp.run(src, # doctest: +SKIP
279
+ ... symbols='TDEQ::::AAPL',
280
+ ... start=otp.dt(2021, 1, 1),
281
+ ... end=otp.dt(2021, 8, 6),
282
+ ... symbol_date=otp.dt(2021, 2, 18),
283
+ ... timezone='GMT')
284
+ Time OID END_DATE REPORT_MONTH SHARES
285
+ 0 2021-01-01 9706 2021-01-06 202009 1.700180e+10
286
+ 1 2021-01-06 9706 2021-01-29 202009 1.682326e+10
287
+ 2 2021-01-29 9706 2021-05-03 202012 1.678810e+10
288
+ 3 2021-05-03 9706 2021-07-30 202103 1.668763e+10
289
+ 4 2021-07-30 9706 2021-10-29 202106 1.653017e+10
290
+ """
291
+ @docstring(parameters=COMMON_SOURCE_DOC_PARAMS, add_self=True)
292
+ def __init__(
293
+ self,
294
+ symbol=otp.utils.adaptive,
295
+ start=otp.utils.adaptive,
296
+ end=otp.utils.adaptive,
297
+ **kwargs
298
+ ):
299
+ if self._try_default_constructor(**kwargs):
300
+ return
301
+
302
+ super().__init__(
303
+ _symbols=symbol,
304
+ _start=start,
305
+ _end=end,
306
+ _base_ep_func=partial(self.build)
307
+ )
308
+
309
+ self.schema.set(OID=str,
310
+ END_DATE=otp.nsectime,
311
+ REPORT_MONTH=int,
312
+ SHARES=int)
313
+
314
+ def build(self):
315
+ ep = otp.oqd.eps.OqdSourceSho()
316
+ src = otp.Source(ep)
317
+ src.tick_type(OQD_TICK_TYPE)
318
+ _modify_query_times(src)
319
+
320
+ # work-around to resolve problem with pandas timestamp out of bounds
321
+ pd_max = pd.Timestamp.max.strftime('%Y%m%d%H%M%S')
322
+ src.sink(otq.UpdateFields(
323
+ set='END_DATE=PARSE_NSECTIME("%Y-%m-%d", "2035-01-01", _TIMEZONE)',
324
+ where=f'AS_YYYYMMDDHHMMSS(END_DATE) > {pd_max}'))
325
+ return src
onetick/py/otq.py ADDED
@@ -0,0 +1,211 @@
1
+ # This file is used to import the correct query module:
2
+ # onetick.query or onetick.query_webapi
3
+ # based on the environment variable OTP_WEBAPI
4
+ # Re-use this file in your tests to import the correct onetick.query module
5
+ # Also it is override pyomd and OneTickLib classes with mock classes
6
+
7
+ import getpass
8
+ import inspect
9
+ import os
10
+ import tempfile
11
+ import warnings
12
+ import onetick.py as otp
13
+ from onetick.py import configuration
14
+
15
+
16
+ class OneTickLib:
17
+ # mock class for OneTickLib, used for webapi and onetick-query-stubs
18
+ # maybe it is not right to combine this namesake classes (onetick.lib.OneTickLib and pyomd.OneTickLib)
19
+ # but it is done to simplify the code and it is not affecting anything except tests
20
+ LOGGING_LEVEL_MIN = 0
21
+ LOGGING_LEVEL_LOW = 1
22
+ LOGGING_LEVEL_MEDIUM = 2
23
+ LOGGING_LEVEL_MAX = 3
24
+ set_authentication_token = None
25
+
26
+ def __init__(self, *args, **kwargs): # NOSONAR
27
+ pass
28
+
29
+ def set_log_file(self, log_file): # NOSONAR
30
+ pass
31
+
32
+ def cleanup(self): # NOSONAR
33
+ pass
34
+
35
+
36
+ if os.getenv("OTP_SKIP_OTQ_VALIDATION", False):
37
+ import onetick_stubs as otq # noqa: F401
38
+ import pyomd # noqa: F401
39
+
40
+ class ConfigStub:
41
+ API_CONFIG: dict = {}
42
+
43
+ class otli:
44
+ OneTickLib = OneTickLib # NOSONAR
45
+
46
+ for key, value in otq.query.__dict__.items():
47
+ setattr(otq, key, value)
48
+ setattr(otq, 'webapi', False)
49
+ setattr(otq, 'config', ConfigStub)
50
+ setattr(otq, 'graph_components', otq)
51
+
52
+ elif otp.__webapi__:
53
+ import onetick.query_webapi as otq # noqa: F401
54
+ setattr(otq, 'webapi', True)
55
+
56
+ from onetick.py.pyomd_mock import pyomd
57
+
58
+ __original_run = otq.run
59
+
60
+ def run(*args, **kwargs):
61
+ from onetick.py import config # noqa
62
+ from onetick.py.compatibility import is_max_concurrency_with_webapi_supported
63
+
64
+ if not config.http_address and 'http_address' not in kwargs:
65
+ raise ValueError('otp.run() http_address keyword param, '
66
+ 'otp.config.http_address or OTP_HTTP_ADDRESS '
67
+ 'environment variable are required '
68
+ 'when using WebAPI mode.')
69
+
70
+ # TODO WEBAPI review this
71
+ # if file name is not in single quotes, then put it in single quotes
72
+ query_name = None
73
+ query = kwargs.get('query', None)
74
+ if isinstance(query, str):
75
+ if query[0] == "'" and query[-1] == "'":
76
+ query = query.replace("'", "")
77
+ if '::' in query:
78
+ query_name = query.split('::')[-1]
79
+ query = query.replace(f'::{query_name}', '')
80
+ kwargs['query'] = query
81
+ kwargs['query_name'] = query_name
82
+
83
+ del_params = [
84
+ 'start_time_expression',
85
+ 'end_time_expression',
86
+ 'alternative_username',
87
+ 'batch_size',
88
+ 'treat_byte_arrays_as_strings',
89
+ 'output_matrix_per_field',
90
+ 'return_utc_times',
91
+ 'connection',
92
+ 'svg_path',
93
+ 'use_connection_pool',
94
+ 'time_as_nsec',
95
+ 'max_expected_ticks_per_symbol',
96
+ ]
97
+ ignore_deleted_params = [
98
+ 'treat_byte_arrays_as_strings',
99
+ 'time_as_nsec',
100
+ 'alternative_username',
101
+ 'max_expected_ticks_per_symbol'
102
+ ]
103
+ for param in del_params:
104
+ if param in kwargs:
105
+ if kwargs[param] and param not in ignore_deleted_params:
106
+ warnings.warn(f'Parameter {param} is not supported in WebAPI mode and will be ignored.')
107
+ del kwargs[param]
108
+
109
+ from onetick.py import config # noqa
110
+ if 'http_address' not in kwargs:
111
+ kwargs['http_address'] = config.http_address
112
+
113
+ if kwargs.get('username'):
114
+ kwargs['http_username'] = kwargs['username']
115
+ del kwargs['username']
116
+ else:
117
+ kwargs['http_username'] = config.http_username
118
+
119
+ if kwargs.get('password'):
120
+ kwargs['http_password'] = kwargs['password']
121
+ del kwargs['password']
122
+ else:
123
+ kwargs['http_password'] = config.http_password
124
+
125
+ if 'access_token' not in kwargs:
126
+ if config.access_token:
127
+ kwargs['access_token'] = config.access_token
128
+ elif not kwargs['access_token']:
129
+ del kwargs['access_token']
130
+
131
+ access_token_url = kwargs.get('access_token_url', config.access_token_url)
132
+ if access_token_url:
133
+ if not hasattr(otq, 'get_access_token'):
134
+ raise RuntimeError('Current `onetick.query_webapi` version doesn\'t have `get_access_token` function')
135
+
136
+ if kwargs.get('access_token'):
137
+ raise ValueError('Both `access_token` and `access_token_url` set, instead of only one of them.')
138
+
139
+ if 'client_id' in kwargs:
140
+ client_id = kwargs.pop('client_id')
141
+ else:
142
+ client_id = config.client_id
143
+
144
+ if 'client_secret' in kwargs:
145
+ client_secret = kwargs.pop('client_secret')
146
+ else:
147
+ client_secret = config.client_secret
148
+
149
+ for param_name, param_value in zip(['client_id', 'client_secret'], [client_id, client_secret]):
150
+ if not param_value:
151
+ raise ValueError(f'`access_token_url` parameter set, however `{param_name}` parameter missing.')
152
+
153
+ kwargs['access_token'] = otq.get_access_token(access_token_url, client_id, client_secret)
154
+
155
+ if 'access_token_url' in kwargs:
156
+ del kwargs['access_token_url']
157
+
158
+ if 'http_proxy' not in kwargs:
159
+ kwargs['http_proxy'] = config.http_proxy
160
+
161
+ if 'https_proxy' not in kwargs:
162
+ kwargs['https_proxy'] = config.https_proxy
163
+
164
+ is_trusted_certificates_supported = 'trusted_certificates_file' in inspect.signature(otq.run).parameters
165
+
166
+ if (
167
+ ('trusted_certificates_file' in kwargs or config.trusted_certificates_file is not None) and
168
+ not is_trusted_certificates_supported
169
+ ):
170
+ raise ValueError(
171
+ 'Parameter `trusted_certificates_file` was set, however current version of OneTick doesn\'t support it.'
172
+ )
173
+
174
+ if 'trusted_certificates_file' not in kwargs and is_trusted_certificates_supported:
175
+ kwargs['trusted_certificates_file'] = config.trusted_certificates_file
176
+
177
+ if 'callback' in kwargs and kwargs['callback'] is not None:
178
+ kwargs['output_mode'] = otq.QueryOutputMode.callback
179
+
180
+ if 'max_concurrency' in kwargs and not is_max_concurrency_with_webapi_supported():
181
+ kwargs['max_concurrency'] = None
182
+
183
+ return __original_run(*args, **kwargs)
184
+
185
+ otq.run = run
186
+
187
+ otq.OneTickLib = OneTickLib
188
+
189
+ class otli: # type: ignore # noqa: F401
190
+ OneTickLib = otq.OneTickLib # NOSONAR
191
+
192
+ else:
193
+ import onetick.query as otq # type: ignore # noqa: F401
194
+ import pyomd # type: ignore # noqa: F401
195
+ import onetick.lib.instance as otli # type: ignore # noqa: F401
196
+ setattr(otq, 'webapi', False)
197
+
198
+
199
+ def _tmp_otq_path():
200
+ # copied from onetick.test.fixtures _keep_generated_dir() with replacement to /tmp
201
+ # required with OTP_WEBAPI_TEST_MODE to separate otq files from shared dbs+config+locator+acl files
202
+ from onetick.py import utils # noqa
203
+ res = os.path.join(utils.TMP_CONFIGS_DIR(), os.environ.get("ONE_TICK_TMP_DIR", "otqs"))
204
+ res = res.replace(utils.temp.WEBAPI_TEST_MODE_SHARED_CONFIG,
205
+ os.path.join(tempfile.gettempdir(), "test_" + getpass.getuser()))
206
+
207
+ # % and + is some webapi related path bugs, probably would be fixed someday
208
+ return res.replace("%", "_").replace("+", "_")
209
+
210
+
211
+ __all__ = ['otq', 'pyomd', 'otli', '_tmp_otq_path']
@@ -0,0 +1,47 @@
1
+ import datetime
2
+ import onetick.py as otp
3
+
4
+
5
+ if otp.__webapi__:
6
+ try:
7
+ from onetick.query_webapi import QueryProperties # noqa: E0611
8
+ except ImportError as e:
9
+ try:
10
+ import onetick.query_webapi # noqa
11
+ raise RuntimeError("You're trying to use onetick.query_webapi module, "
12
+ "that is not compatible with onetick.py. "
13
+ "Please, use onetick.query module instead (unset OTP_WEBAPI), "
14
+ "or install onetick.query_webapi==1.24.20240715 or newer. "
15
+ "Also, check that your PYTHONPATH doesn't have onetick binary path, "
16
+ "because onetick distribution could have older onetick.query_webapi, "
17
+ "that mirror your pip-installed version.") from e
18
+ except ImportError as e2:
19
+ raise ImportError(
20
+ "OTP_WEBAPI environment variable is set,"
21
+ " but onetick.query_webapi module is not available."
22
+ " Please, install onetick.query_webapi to avoid import errors"
23
+ " or unset OTP_WEBAPI to use onetick.query module instead."
24
+ ) from e2
25
+
26
+ # copied from one_market_data/one_tick/bin/python/onetick/query/_internal_utils.py
27
+ def quoted(str_object):
28
+ if len(str_object) <= 1:
29
+ return str_object
30
+ if str_object[0] == "'" and str_object[-1] == "'" or str_object[0] == '"' and str_object[-1] == '"':
31
+ return str_object
32
+ return f"'{str_object}'"
33
+
34
+ class OT_time_nsec_mock: # NOSONAR
35
+ def __init__(self, number):
36
+ self.number = number
37
+
38
+ def __int__(self):
39
+ return int(self.number / 1e9)
40
+
41
+ class pyomd:
42
+ timeval_t = datetime.datetime # type: ignore
43
+ QueryProperties = QueryProperties # type: ignore # NOSONAR
44
+
45
+ @staticmethod
46
+ def OT_time_nsec(number): # NOSONAR
47
+ return int(number / 1e9)