onetick-py 1.170.0__py3-none-any.whl → 1.172.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.
Files changed (30) hide show
  1. onetick/py/__init__.py +8 -2
  2. onetick/py/_version.py +1 -1
  3. onetick/py/cache.py +3 -3
  4. onetick/py/callback/callbacks.py +1 -1
  5. onetick/py/configuration.py +35 -9
  6. onetick/py/core/_source/source_methods/misc.py +1 -1
  7. onetick/py/core/_source/source_methods/writes.py +48 -33
  8. onetick/py/core/column_operations/_methods/methods.py +1 -4
  9. onetick/py/core/column_operations/accessors/_accessor.py +4 -6
  10. onetick/py/core/column_operations/accessors/decimal_accessor.py +20 -8
  11. onetick/py/core/column_operations/accessors/dt_accessor.py +137 -68
  12. onetick/py/core/column_operations/accessors/float_accessor.py +35 -15
  13. onetick/py/core/column_operations/accessors/str_accessor.py +0 -7
  14. onetick/py/core/column_operations/base.py +72 -12
  15. onetick/py/core/multi_output_source.py +41 -2
  16. onetick/py/core/per_tick_script.py +2 -0
  17. onetick/py/db/_inspection.py +82 -49
  18. onetick/py/db/db.py +2 -2
  19. onetick/py/functions.py +7 -1
  20. onetick/py/math.py +374 -386
  21. onetick/py/misc.py +70 -38
  22. onetick/py/otq.py +18 -12
  23. onetick/py/run.py +75 -5
  24. onetick/py/sources/ticks.py +1 -1
  25. {onetick_py-1.170.0.dist-info → onetick_py-1.172.0.dist-info}/METADATA +4 -2
  26. {onetick_py-1.170.0.dist-info → onetick_py-1.172.0.dist-info}/RECORD +30 -30
  27. {onetick_py-1.170.0.dist-info → onetick_py-1.172.0.dist-info}/WHEEL +0 -0
  28. {onetick_py-1.170.0.dist-info → onetick_py-1.172.0.dist-info}/entry_points.txt +0 -0
  29. {onetick_py-1.170.0.dist-info → onetick_py-1.172.0.dist-info}/licenses/LICENSE +0 -0
  30. {onetick_py-1.170.0.dist-info → onetick_py-1.172.0.dist-info}/top_level.txt +0 -0
onetick/py/__init__.py CHANGED
@@ -214,9 +214,15 @@ from onetick.py.core.per_tick_script import (
214
214
  )
215
215
  from onetick.py.callback import CallbackBase
216
216
  from onetick.py.sql import SqlQuery
217
- from onetick.py.run import run
217
+ from onetick.py.run import run, run_async
218
218
  from onetick.py.math import rand, now
219
- from onetick.py.misc import bit_and, bit_or, bit_at, bit_xor, bit_not, hash_code, get_symbology_mapping
219
+ from onetick.py.misc import (
220
+ bit_and, bit_or, bit_at, bit_xor, bit_not,
221
+ hash_code,
222
+ get_symbology_mapping,
223
+ get_onetick_version,
224
+ get_username,
225
+ )
220
226
  from onetick.py.core.column import Column
221
227
  from onetick.py.core.column_operations.base import Operation, Expr as expr, Raw as raw, OnetickParameter as param
222
228
  from onetick.py.core.per_tick_script import remote, Once, once, logf, throw_exception
onetick/py/_version.py CHANGED
@@ -1,2 +1,2 @@
1
1
  # This file was generated automatically. DO NOT CHANGE.
2
- VERSION = '1.170.0'
2
+ VERSION = '1.172.0'
onetick/py/cache.py CHANGED
@@ -113,7 +113,7 @@ def create_cache(
113
113
  The cache will be cleared every X seconds, triggering new query executions when data is requested.
114
114
  tick_type: str
115
115
  Tick type.
116
- symbol: str, list of str, list of otq.Symbol, :py:class:`onetick.py.Source`, pd.DataFrame, optional
116
+ symbol: str, list of str, list of otq.Symbol, :py:class:`onetick.py.Source`, :pandas:`pandas.DataFrame`, optional
117
117
  ``symbols`` parameter of ``otp.run()``.
118
118
  db: str
119
119
  Database.
@@ -259,7 +259,7 @@ def delete_cache(
259
259
  :func:`<onetick.py.create_cache>`.
260
260
  tick_type: str
261
261
  Tick type.
262
- symbol: str, list of str, list of otq.Symbol, :py:class:`onetick.py.Source`, pd.DataFrame, optional
262
+ symbol: str, list of str, list of otq.Symbol, :py:class:`onetick.py.Source`, :pandas:`pandas.DataFrame`, optional
263
263
  ``symbols`` parameter of ``otp.run()``.
264
264
  db: str
265
265
  Database.
@@ -329,7 +329,7 @@ def modify_cache_config(
329
329
  New value of configuration parameter. Will be converted to string.
330
330
  tick_type: str
331
331
  Tick type.
332
- symbol: str, list of str, list of otq.Symbol, :py:class:`onetick.py.Source`, pd.DataFrame, optional
332
+ symbol: str, list of str, list of otq.Symbol, :py:class:`onetick.py.Source`, :pandas:`pandas.DataFrame`, optional
333
333
  ``symbols`` parameter of ``otp.run()``.
334
334
  db: str
335
335
  Database.
@@ -18,7 +18,7 @@ class LogCallback(CallbackBase):
18
18
 
19
19
  class ManualDataframeCallback(CallbackBase):
20
20
  """
21
- This callback class can be used to generate the same pandas.DataFrame result as in otp.run.
21
+ This callback class can be used to generate the same :pandas:`pandas.DataFrame` result as in otp.run.
22
22
  Unlike otp.run, here result is constructed manually, one tick at a time.
23
23
  This may lead to lower memory usage in some cases.
24
24
  See task PY-863 for details.
@@ -32,6 +32,28 @@ def parse_datetime(s):
32
32
  )
33
33
 
34
34
 
35
+ def parse_bool(value) -> Optional[bool]:
36
+ str_value = str(value).lower()
37
+ if str_value in ('1', 'true', 'yes'):
38
+ return True
39
+ elif str_value in ('0', 'false', 'no'):
40
+ return False
41
+ else:
42
+ return None
43
+
44
+
45
+ def parse_true(value) -> bool:
46
+ return parse_bool(value) is True
47
+
48
+
49
+ def parse_bool_or_string(value) -> Union[bool, str]:
50
+ parsed_value = parse_bool(value)
51
+ if parsed_value is not None:
52
+ return parsed_value
53
+ else:
54
+ return str(value)
55
+
56
+
35
57
  def _env_func_concurrency(value: str) -> Optional[int]:
36
58
  if not value:
37
59
  return None
@@ -197,7 +219,7 @@ class OtpShowStackInfoProperty(OtpProperty):
197
219
  """
198
220
  @staticmethod
199
221
  def parser(value):
200
- return str(value).lower() in ('1', 'true', 'yes')
222
+ return parse_true(value)
201
223
 
202
224
  def __init__(self, *args, **kwargs):
203
225
  super().__init__(*args, **kwargs)
@@ -492,7 +514,7 @@ class Config:
492
514
  base_default=False,
493
515
  allowed_types=[bool],
494
516
  env_var_name='OTP_PRESORT_FORCE_DEFAULT_CONCURRENCY',
495
- env_var_func=OtpShowStackInfoProperty.parser,
517
+ env_var_func=parse_true,
496
518
  )
497
519
 
498
520
  # default batch size is set to 0, so the number of symbols in batch is not limited
@@ -623,10 +645,14 @@ class Config:
623
645
  )
624
646
 
625
647
  trusted_certificates_file = OtpProperty(
626
- description='Path to the file with list of trusted Certificate Authority certificates for WebAPI requests.',
648
+ description='Either a boolean, in which case it controls whether we verify the server TLS certificate '
649
+ 'or a string with the path to the file with list of '
650
+ 'trusted Certificate Authority certificates for WebAPI requests. '
651
+ 'Default behaviour implies verification is enabled.',
627
652
  base_default=None,
628
- allowed_types=str,
653
+ allowed_types=(bool, str),
629
654
  env_var_name='OTP_SSL_CERT_FILE',
655
+ env_var_func=parse_bool_or_string,
630
656
  )
631
657
 
632
658
  max_expected_ticks_per_symbol = OtpProperty(
@@ -641,7 +667,7 @@ class Config:
641
667
  base_default=False,
642
668
  allowed_types=(str, bool, int),
643
669
  env_var_name='OTP_SHOW_STACK_INFO',
644
- env_var_func=OtpShowStackInfoProperty.parser,
670
+ env_var_func=parse_true,
645
671
  )
646
672
 
647
673
  log_symbol = OtpProperty(
@@ -651,7 +677,7 @@ class Config:
651
677
  base_default=False,
652
678
  allowed_types=(str, bool, int),
653
679
  env_var_name='OTP_LOG_SYMBOL',
654
- env_var_func=OtpShowStackInfoProperty.parser,
680
+ env_var_func=parse_true,
655
681
  )
656
682
 
657
683
  ignore_ticks_in_unentitled_time_range = OtpProperty(
@@ -659,7 +685,7 @@ class Config:
659
685
  base_default=False,
660
686
  env_var_name='OTP_IGNORE_TICKS_IN_UNENTITLED_TIME_RANGE',
661
687
  allowed_types=(str, bool, int),
662
- env_var_func=OtpShowStackInfoProperty.parser,
688
+ env_var_func=parse_true,
663
689
  )
664
690
 
665
691
  main_query_generated_filename = OtpProperty(
@@ -685,7 +711,7 @@ class Config:
685
711
  base_default=False,
686
712
  env_var_name='OTP_OTQ_DEBUG_MODE',
687
713
  allowed_types=(str, bool, int),
688
- env_var_func=OtpShowStackInfoProperty.parser,
714
+ env_var_func=parse_true,
689
715
  )
690
716
 
691
717
  allow_lowercase_in_saved_fields = OtpProperty(
@@ -702,7 +728,7 @@ class Config:
702
728
  base_default=True,
703
729
  env_var_name='OTP_CLEAN_UP_TMP_FILES',
704
730
  allowed_types=(str, bool, int),
705
- env_var_func=OtpShowStackInfoProperty.parser,
731
+ env_var_func=parse_true,
706
732
  )
707
733
 
708
734
  default_schema_policy = OtpProperty(
@@ -514,7 +514,7 @@ def cache(
514
514
  the result data not found in the cache. Otherwise, the cache remains unchanged.
515
515
  tick_type: str
516
516
  Tick type.
517
- symbol: str, list of str, list of otq.Symbol, :py:class:`onetick.py.Source`, pd.DataFrame, optional
517
+ symbol: str, list of str, list of otq.Symbol, :py:class:`onetick.py.Source`, :pandas:`pandas.DataFrame`, optional
518
518
  ``symbols`` parameter of ``otp.run()``.
519
519
  db: str
520
520
  Database.
@@ -23,8 +23,8 @@ def write(
23
23
  symbol: Union[str, 'otp.Column', None] = None,
24
24
  tick_type: Union[str, 'otp.Column', None] = None,
25
25
  date: Union[datetime.date, Type[adaptive], None] = adaptive,
26
- start: Optional[datetime.date] = None,
27
- end: Optional[datetime.date] = None,
26
+ start_date: Optional[datetime.date] = None,
27
+ end_date: Optional[datetime.date] = None,
28
28
  append: bool = False,
29
29
  keep_symbol_and_tick_type: Union[bool, Type[adaptive]] = adaptive,
30
30
  propagate: bool = True,
@@ -72,22 +72,21 @@ def write(
72
72
  date where to save data.
73
73
  Should be set to `None` if writing to accelerator or memory database.
74
74
  By default, it is set to `otp.config.default_date`.
75
- start: :py:class:`otp.datetime <onetick.py.datetime>` or None
75
+ start_date: :py:class:`otp.datetime <onetick.py.datetime>` or None
76
76
  Start date for data to save. It is inclusive.
77
77
  Cannot be used with ``date`` parameter.
78
78
  Also cannot be used with ``inplace`` set to ``True``.
79
79
  Should be set to `None` if writing to accelerator or memory database.
80
80
  By default, None.
81
- end: :py:class:`otp.datetime <onetick.py.datetime>` or None
82
- End date for data to save. It is exclusive, so be sure to set
83
- it to the next day after the last day in data.
81
+ end_date: :py:class:`otp.datetime <onetick.py.datetime>` or None
82
+ End date for data to save. It is inclusive.
84
83
  Cannot be used with ``date`` parameter.
85
84
  Also cannot be used with ``inplace`` set to ``True``.
86
85
  Should be set to `None` if writing to accelerator or memory database.
87
86
  By default, None.
88
87
  append: bool
89
88
  If False - data will be rewritten for this ``date``
90
- or range of dates (from ``start`` to ``end``),
89
+ or range of dates (from ``start_date`` to ``end_date``),
91
90
  otherwise data will be appended: new symbols are added,
92
91
  existing symbols can be modified (append new ticks, modify existing ticks).
93
92
  This option is not valid for accelerator databases.
@@ -100,12 +99,12 @@ def write(
100
99
  propagate: bool
101
100
  Propagate ticks after that event processor or not.
102
101
  out_of_range_tick_action: str
103
- Action to be executed if tick's timestamp's date is not ``date`` or between ``start`` or ``end``:
102
+ Action to be executed if tick's timestamp's date is not ``date`` or between ``start_date`` or ``end_date``:
104
103
 
105
104
  * `exception`: runtime exception will be raised
106
105
  * `ignore`: tick will not be written to the database
107
106
  * `load`: writes tick to the database anyway.
108
- Can be used only with ``date``, not with ``start``+``end``.
107
+ Can be used only with ``date``, not with ``start_date``+``end_date``.
109
108
 
110
109
  Default: `exception`
111
110
  timestamp: Column
@@ -134,7 +133,7 @@ def write(
134
133
  A flag controls whether operation should be applied inplace.
135
134
  If ``inplace=True``, then it returns nothing.
136
135
  Otherwise, method returns a new modified object.
137
- Cannot be ``True`` if ``start`` and ``end`` are set.
136
+ Cannot be ``True`` if ``start_date`` and ``end_date`` are set.
138
137
  kwargs:
139
138
  .. deprecated:: 1.21.0
140
139
 
@@ -176,6 +175,15 @@ def write(
176
175
  warnings.warn("Parameter 'keep_timestamp_field' is deprecated, use 'keep_timestamp'", FutureWarning)
177
176
  keep_timestamp = kwargs.pop('keep_timestamp_field')
178
177
 
178
+ if 'start' in kwargs:
179
+ warnings.warn("Parameter 'start' is deprecated, use 'start_date'", FutureWarning)
180
+ start_date = kwargs.pop('start')
181
+
182
+ if 'end' in kwargs:
183
+ warnings.warn("Parameter 'end' is deprecated, use 'end_date'", FutureWarning)
184
+ # Parameter 'end' was exclusive. Parameter 'end_date' is inclusive.
185
+ end_date = kwargs.pop('end') - otp.Day(1)
186
+
179
187
  if kwargs:
180
188
  raise TypeError(f'write() got unexpected arguments: {list(kwargs)}')
181
189
 
@@ -194,15 +202,18 @@ def write(
194
202
  f'Field "{field_name}" contains lowercase characters and cannot be saved to a Onetick database'
195
203
  )
196
204
 
197
- if date is not adaptive and (start or end):
198
- raise ValueError('date cannot be used with start+end')
205
+ if date is not adaptive and (start_date or end_date):
206
+ raise ValueError('date cannot be used with start_date+end_date')
199
207
 
200
- if date is adaptive and (start and end) and inplace:
208
+ if date is adaptive and (start_date and end_date) and inplace:
201
209
  # join_with_query and merge are used for multiple dates, so inplace is not supported
202
- raise ValueError('cannot run on multiple dates if inplace is True, use one value for date instead of start+end')
210
+ raise ValueError(
211
+ 'cannot run on multiple dates if inplace is True,'
212
+ ' use one value for date instead of start_date+end_date'
213
+ )
203
214
 
204
- if (start and not end) or (not start and end):
205
- raise ValueError('start and end should be both specified or both None')
215
+ if (start_date and not end_date) or (not start_date and end_date):
216
+ raise ValueError('start_date and end_date should be both specified or both None')
206
217
 
207
218
  if date is adaptive:
208
219
  date = configuration.config.default_date
@@ -244,10 +255,10 @@ def write(
244
255
  # let's ignore
245
256
  pass
246
257
  elif out_of_range_tick_action.upper() == 'LOAD':
247
- if start and end:
248
- raise ValueError('LOAD out_of_range_tick_action cannot be used with start+end, use date instead')
258
+ if start_date and end_date:
259
+ raise ValueError('LOAD out_of_range_tick_action cannot be used with start_date+end_date, use date instead')
249
260
  elif out_of_range_tick_action.upper() == 'EXCEPTION':
250
- if start and end:
261
+ if start_date and end_date:
251
262
  # WRITE_TO_ONETICK_DB use DAY_BOUNDARY_TZ and DAY_BOUNDARY_OFFSET
252
263
  # to check tick timestamp is out of range or not
253
264
  # so we mimic it here with THROW event processor
@@ -259,10 +270,12 @@ def write(
259
270
  {'DAY_BOUNDARY_TZ': '__DAY_BOUNDARY_TZ', 'DAY_BOUNDARY_OFFSET': '__DAY_BOUNDARY_OFFSET'}, inplace=True
260
271
  )
261
272
  self = self.join_with_query(src, symbol=f"{str(db)}::DUMMY", caching='per_symbol')
262
- start_formatted = start.strftime('%Y-%m-%d')
263
- end_formatted = end.strftime('%Y-%m-%d')
264
- convert_timestamp = self['TIMESTAMP'].dt.strftime('%Y%m%d%H%M%S.%J', timezone=self['__DAY_BOUNDARY_TZ'])
265
- start_op = otp.dt(start).to_operation(timezone=self['__DAY_BOUNDARY_TZ']) + self['__DAY_BOUNDARY_OFFSET']
273
+ timezone = self['__DAY_BOUNDARY_TZ']
274
+ offset = self['__DAY_BOUNDARY_OFFSET']
275
+ convert_timestamp = self['TIMESTAMP'].dt.strftime('%Y%m%d%H%M%S.%J', timezone=timezone)
276
+
277
+ start_formatted = start_date.strftime('%Y-%m-%d')
278
+ start_op = otp.dt(start_date).to_operation(timezone=timezone) + offset
266
279
  self.throw(
267
280
  where=(self['TIMESTAMP'] < start_op),
268
281
  message=(
@@ -270,11 +283,14 @@ def write(
270
283
  + convert_timestamp
271
284
  + ' of a tick, visible or hidden, '
272
285
  + f'earlier than {start_formatted} in timezone '
273
- + self['__DAY_BOUNDARY_TZ']
286
+ + timezone
274
287
  ),
275
288
  inplace=True,
276
289
  )
277
- end_op = otp.dt(end).to_operation(timezone=self['__DAY_BOUNDARY_TZ']) + self['__DAY_BOUNDARY_OFFSET']
290
+
291
+ end = end_date + otp.Day(1) # end_date is inclusive
292
+ end_formatted = end.strftime('%Y-%m-%d')
293
+ end_op = otp.dt(end).to_operation(timezone=timezone) + offset
278
294
  self.throw(
279
295
  where=(self['TIMESTAMP'] >= end_op),
280
296
  message=(
@@ -282,10 +298,11 @@ def write(
282
298
  + convert_timestamp
283
299
  + ' of a tick, visible or hidden, '
284
300
  + f'later than {end_formatted} in timezone '
285
- + self['__DAY_BOUNDARY_TZ']
301
+ + timezone
286
302
  ),
287
303
  inplace=True,
288
304
  )
305
+ self.drop(['__DAY_BOUNDARY_TZ', '__DAY_BOUNDARY_OFFSET'], inplace=True)
289
306
  else:
290
307
  raise ValueError(
291
308
  f'Unknown out_of_range_tick_action: {out_of_range_tick_action}.'
@@ -303,18 +320,16 @@ def write(
303
320
  use_context_of_query=use_context_of_query,
304
321
  )
305
322
 
306
- if start and end:
307
- days = (end - start).days
323
+ if start_date and end_date:
324
+ days = (end_date - start_date).days
308
325
  if days < 0:
309
- raise ValueError("Parameter 'start' must be less than parameter 'end'")
310
- if days == 0:
311
- raise ValueError("Parameters 'start' and 'end' must specify different dates")
326
+ raise ValueError("Parameter 'start_date' must be less than or equal to parameter 'end_date'")
312
327
  branches = []
313
- for i in range(days):
328
+ for i in range(days + 1):
314
329
  branch = self.copy()
315
330
  branch.sink(
316
331
  otq.WriteToOnetickDb(
317
- date=(start + otp.Day(i)).strftime('%Y%m%d'),
332
+ date=(start_date + otp.Day(i)).strftime('%Y%m%d'),
318
333
  propagate_ticks=propagate,
319
334
  out_of_range_tick_action='IGNORE',
320
335
  **kwargs,
@@ -14,10 +14,7 @@ class DatetimeSubtractionWarning(FutureWarning):
14
14
 
15
15
 
16
16
  def round(prev_op, precision):
17
- if precision is not None:
18
- return MethodResult(f'round_double({str(prev_op)},{str(precision)})', float)
19
- else:
20
- return MethodResult(f'round({str(prev_op)})', int)
17
+ return MethodResult(f'round_double({str(prev_op)},{str(precision)})', float)
21
18
 
22
19
 
23
20
  def isin(prev_op, items):
@@ -11,13 +11,11 @@ class _Accessor:
11
11
  self._base_column = base_column
12
12
 
13
13
  class Formatter(_Operation):
14
+ def __init__(self, dtype, formatter, op_params):
15
+ def op_func(*args, **kwargs):
16
+ return formatter(*args, **kwargs), dtype
14
17
 
15
- def __init__(self, base_column, dtype, formatter):
16
- super().__init__(dtype=dtype, op_params=[base_column])
17
- self._formatter = formatter
18
-
19
- def __str__(self):
20
- return self._formatter(str(self._op_params[0]))
18
+ super().__init__(op_func=op_func, op_params=op_params, dtype=dtype)
21
19
 
22
20
  def _preprocess_tz_and_format(self,
23
21
  timezone: typing.Union[Operation, str, None],
@@ -1,5 +1,6 @@
1
1
  from onetick.py import types as ott
2
2
  from onetick.py.core.column_operations.accessors._accessor import _Accessor
3
+ from onetick.py.core.column_operations.base import _Operation
3
4
 
4
5
 
5
6
  class _DecimalAccessor(_Accessor):
@@ -37,10 +38,16 @@ class _DecimalAccessor(_Accessor):
37
38
  3 3.142
38
39
  Name: X, dtype: object
39
40
  """
41
+ def formatter(column, _precision):
42
+ column = ott.value2str(column)
43
+ _precision = ott.value2str(_precision)
44
+
45
+ return f'decimal_to_string({column}, {_precision})'
46
+
40
47
  return _DecimalAccessor.Formatter(
41
- self._base_column,
42
- str,
43
- formatter=lambda x: f'decimal_to_string({x}, {precision})'
48
+ op_params=[self._base_column, precision],
49
+ dtype=str,
50
+ formatter=formatter,
44
51
  )
45
52
 
46
53
  def cmp(self, other, eps):
@@ -83,10 +90,15 @@ class _DecimalAccessor(_Accessor):
83
90
  4 1.0
84
91
  Name: X, dtype: float64
85
92
  """
86
- other = ott.value2str(other)
87
- eps = ott.value2str(eps)
93
+
94
+ def formatter(column, _other, _eps):
95
+ column = ott.value2str(column)
96
+ _other = ott.value2str(_other)
97
+ _eps = ott.value2str(_eps)
98
+ return f'decimal_compare({column}, {_other}, {_eps})'
99
+
88
100
  return _DecimalAccessor.Formatter(
89
- self._base_column,
90
- ott.decimal,
91
- formatter=lambda x: f'decimal_compare({x}, {other}, {eps})'
101
+ op_params=[self._base_column, other, eps],
102
+ dtype=ott.decimal,
103
+ formatter=formatter,
92
104
  )