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.
- onetick/py/__init__.py +8 -2
- onetick/py/_version.py +1 -1
- onetick/py/cache.py +3 -3
- onetick/py/callback/callbacks.py +1 -1
- onetick/py/configuration.py +35 -9
- onetick/py/core/_source/source_methods/misc.py +1 -1
- onetick/py/core/_source/source_methods/writes.py +48 -33
- onetick/py/core/column_operations/_methods/methods.py +1 -4
- onetick/py/core/column_operations/accessors/_accessor.py +4 -6
- onetick/py/core/column_operations/accessors/decimal_accessor.py +20 -8
- onetick/py/core/column_operations/accessors/dt_accessor.py +137 -68
- onetick/py/core/column_operations/accessors/float_accessor.py +35 -15
- onetick/py/core/column_operations/accessors/str_accessor.py +0 -7
- onetick/py/core/column_operations/base.py +72 -12
- onetick/py/core/multi_output_source.py +41 -2
- onetick/py/core/per_tick_script.py +2 -0
- onetick/py/db/_inspection.py +82 -49
- onetick/py/db/db.py +2 -2
- onetick/py/functions.py +7 -1
- onetick/py/math.py +374 -386
- onetick/py/misc.py +70 -38
- onetick/py/otq.py +18 -12
- onetick/py/run.py +75 -5
- onetick/py/sources/ticks.py +1 -1
- {onetick_py-1.170.0.dist-info → onetick_py-1.172.0.dist-info}/METADATA +4 -2
- {onetick_py-1.170.0.dist-info → onetick_py-1.172.0.dist-info}/RECORD +30 -30
- {onetick_py-1.170.0.dist-info → onetick_py-1.172.0.dist-info}/WHEEL +0 -0
- {onetick_py-1.170.0.dist-info → onetick_py-1.172.0.dist-info}/entry_points.txt +0 -0
- {onetick_py-1.170.0.dist-info → onetick_py-1.172.0.dist-info}/licenses/LICENSE +0 -0
- {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
|
|
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.
|
|
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`,
|
|
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`,
|
|
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`,
|
|
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.
|
onetick/py/callback/callbacks.py
CHANGED
|
@@ -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.
|
onetick/py/configuration.py
CHANGED
|
@@ -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
|
|
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=
|
|
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='
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
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`,
|
|
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
|
-
|
|
27
|
-
|
|
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
|
-
|
|
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
|
-
|
|
82
|
-
End date for data to save. It is
|
|
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 ``
|
|
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 ``
|
|
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 ``
|
|
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 ``
|
|
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 (
|
|
198
|
-
raise ValueError('date cannot be used with
|
|
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 (
|
|
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(
|
|
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 (
|
|
205
|
-
raise ValueError('
|
|
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
|
|
248
|
-
raise ValueError('LOAD out_of_range_tick_action cannot be used with
|
|
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
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
convert_timestamp = self['TIMESTAMP'].dt.strftime('%Y%m%d%H%M%S.%J', timezone=
|
|
265
|
-
|
|
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
|
-
+
|
|
286
|
+
+ timezone
|
|
274
287
|
),
|
|
275
288
|
inplace=True,
|
|
276
289
|
)
|
|
277
|
-
|
|
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
|
-
+
|
|
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
|
|
307
|
-
days = (
|
|
323
|
+
if start_date and end_date:
|
|
324
|
+
days = (end_date - start_date).days
|
|
308
325
|
if days < 0:
|
|
309
|
-
raise ValueError("Parameter '
|
|
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=(
|
|
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
|
-
|
|
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
|
-
|
|
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=
|
|
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
|
-
|
|
87
|
-
|
|
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=
|
|
101
|
+
op_params=[self._base_column, other, eps],
|
|
102
|
+
dtype=ott.decimal,
|
|
103
|
+
formatter=formatter,
|
|
92
104
|
)
|