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,2216 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
|
|
3
|
+
import onetick.py as otp
|
|
4
|
+
from onetick.py.core.column import _Column
|
|
5
|
+
from .compute import Compute
|
|
6
|
+
from .high_low import Max, Min, HighTick, LowTick, HighTime, LowTime
|
|
7
|
+
from .other import (First, Last, FirstTime, LastTime, Count, Vwap, FirstTick,
|
|
8
|
+
LastTick, Distinct, Sum, Average, StdDev, TimeWeightedAvg,
|
|
9
|
+
Median, Correlation, OptionPrice, Ranking, Variance,
|
|
10
|
+
Percentile, FindValueForPercentile, ExpWAverage, ExpTwAverage,
|
|
11
|
+
StandardizedMoment, PortfolioPrice, MultiPortfolioPrice, Return, ImpliedVol,
|
|
12
|
+
LinearRegression)
|
|
13
|
+
from .order_book import (ObSnapshot, OB_SNAPSHOT_DOC_PARAMS,
|
|
14
|
+
ObSnapshotWide, OB_SNAPSHOT_WIDE_DOC_PARAMS,
|
|
15
|
+
ObSnapshotFlat, OB_SNAPSHOT_FLAT_DOC_PARAMS,
|
|
16
|
+
ObSummary, OB_SUMMARY_DOC_PARAMS,
|
|
17
|
+
ObSize, OB_SIZE_DOC_PARAMS,
|
|
18
|
+
ObVwap, OB_VWAP_DOC_PARAMS,
|
|
19
|
+
ObNumLevels, OB_NUM_LEVELS_DOC_PARAMS)
|
|
20
|
+
from .generic import Generic
|
|
21
|
+
from ._docs import (_column_doc,
|
|
22
|
+
_running_doc,
|
|
23
|
+
_all_fields_doc,
|
|
24
|
+
_bucket_interval_doc,
|
|
25
|
+
_bucket_time_doc,
|
|
26
|
+
_bucket_units_doc,
|
|
27
|
+
_bucket_end_condition_doc,
|
|
28
|
+
_end_condition_per_group_doc,
|
|
29
|
+
_boundary_tick_bucket_doc,
|
|
30
|
+
_group_by_doc,
|
|
31
|
+
_groups_to_display_doc,
|
|
32
|
+
_n_doc,
|
|
33
|
+
_keep_timestamp_doc,
|
|
34
|
+
_time_series_type_doc,
|
|
35
|
+
_time_series_type_w_doc,
|
|
36
|
+
_selection_doc,
|
|
37
|
+
_query_fun_doc,
|
|
38
|
+
_bucket_delimiter_doc,
|
|
39
|
+
_biased_doc,
|
|
40
|
+
_large_ints_doc,
|
|
41
|
+
_null_int_val_doc,
|
|
42
|
+
_skip_tick_if_doc,
|
|
43
|
+
_default_tick_doc,
|
|
44
|
+
_decay_doc,
|
|
45
|
+
_decay_value_type_doc,
|
|
46
|
+
_decay_value_type_hl_doc,
|
|
47
|
+
_degree_doc,
|
|
48
|
+
_weight_field_name_doc,
|
|
49
|
+
_weight_multiplier_field_name_doc,
|
|
50
|
+
_portfolio_side_doc,
|
|
51
|
+
_weight_type_doc,
|
|
52
|
+
_symbols_doc,
|
|
53
|
+
_portfolios_query_doc,
|
|
54
|
+
_portfolios_query_params_doc,
|
|
55
|
+
_portfolio_value_field_name_doc,
|
|
56
|
+
_columns_portfolio_doc,
|
|
57
|
+
_interest_rate_doc,
|
|
58
|
+
_price_field_doc,
|
|
59
|
+
_option_price_field_doc,
|
|
60
|
+
_method_doc,
|
|
61
|
+
_precision_doc,
|
|
62
|
+
_value_for_non_converge_doc,
|
|
63
|
+
_option_type_field_doc,
|
|
64
|
+
_strike_price_field_doc,
|
|
65
|
+
_days_in_year_doc,
|
|
66
|
+
_days_till_expiration_field_doc,
|
|
67
|
+
_expiration_date_field_doc)
|
|
68
|
+
from onetick.py.docs.utils import docstring, param_doc
|
|
69
|
+
|
|
70
|
+
# This module mostly focused on providing annotations and documentation for end user
|
|
71
|
+
# If you are looking for implementation check return object of each function
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@docstring(parameters=[_running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc, _bucket_units_doc,
|
|
75
|
+
_bucket_end_condition_doc, _end_condition_per_group_doc, _boundary_tick_bucket_doc,
|
|
76
|
+
_group_by_doc, _groups_to_display_doc])
|
|
77
|
+
def compute(*args, **kwargs):
|
|
78
|
+
"""
|
|
79
|
+
Generate object that collects aggregations
|
|
80
|
+
|
|
81
|
+
See also
|
|
82
|
+
--------
|
|
83
|
+
**COMPUTE** OneTick event processor
|
|
84
|
+
|
|
85
|
+
Examples
|
|
86
|
+
--------
|
|
87
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4], offset=[0, 1000, 1500, 3000])
|
|
88
|
+
>>> c = otp.agg.compute(running=True, bucket_interval=2)
|
|
89
|
+
>>> c.add('X_MEAN', otp.agg.average("X"))
|
|
90
|
+
>>> c.add('X_STD', otp.agg.stddev("X"))
|
|
91
|
+
>>> data = c.apply(data)
|
|
92
|
+
>>> otp.run(data)
|
|
93
|
+
Time X_MEAN X_STD
|
|
94
|
+
0 2003-12-01 00:00:00.000 1.0 0.000000
|
|
95
|
+
1 2003-12-01 00:00:01.000 1.5 0.500000
|
|
96
|
+
2 2003-12-01 00:00:01.500 2.0 0.816497
|
|
97
|
+
3 2003-12-01 00:00:02.000 2.5 0.500000
|
|
98
|
+
4 2003-12-01 00:00:03.000 3.5 0.500000
|
|
99
|
+
5 2003-12-01 00:00:03.500 4.0 0.000000
|
|
100
|
+
6 2003-12-01 00:00:05.000 NaN NaN
|
|
101
|
+
|
|
102
|
+
"""
|
|
103
|
+
return Compute(*args, **kwargs)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
107
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
108
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
109
|
+
_time_series_type_doc, _large_ints_doc,
|
|
110
|
+
_null_int_val_doc])
|
|
111
|
+
def max(*args, **kwargs):
|
|
112
|
+
"""
|
|
113
|
+
Return maximum value of input ``column``
|
|
114
|
+
|
|
115
|
+
See also
|
|
116
|
+
--------
|
|
117
|
+
**HIGH** OneTick event processor
|
|
118
|
+
|
|
119
|
+
Examples
|
|
120
|
+
--------
|
|
121
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4])
|
|
122
|
+
>>> data = data.agg({'RESULT': otp.agg.max('X')}) # OTdirective: snippet-name: Aggregations.max;
|
|
123
|
+
>>> otp.run(data)
|
|
124
|
+
Time RESULT
|
|
125
|
+
0 2003-12-04 4
|
|
126
|
+
"""
|
|
127
|
+
return Max(*args, **kwargs)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
131
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
132
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
133
|
+
_time_series_type_doc, _large_ints_doc,
|
|
134
|
+
_null_int_val_doc])
|
|
135
|
+
def min(*args, **kwargs):
|
|
136
|
+
"""
|
|
137
|
+
Return minimum value of input ``column``
|
|
138
|
+
|
|
139
|
+
See also
|
|
140
|
+
--------
|
|
141
|
+
**LOW** OneTick event processor
|
|
142
|
+
|
|
143
|
+
Examples
|
|
144
|
+
--------
|
|
145
|
+
|
|
146
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4])
|
|
147
|
+
>>> data = data.agg({'RESULT': otp.agg.min('X')}) # OTdirective: snippet-name: Aggregations.min;
|
|
148
|
+
>>> otp.run(data)
|
|
149
|
+
Time RESULT
|
|
150
|
+
0 2003-12-04 1
|
|
151
|
+
"""
|
|
152
|
+
return Min(*args, **kwargs)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
@docstring(parameters=[_column_doc, _n_doc, _running_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
156
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
157
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
158
|
+
_keep_timestamp_doc, _selection_doc,
|
|
159
|
+
_time_series_type_doc])
|
|
160
|
+
def high_tick(*args, **kwargs):
|
|
161
|
+
"""
|
|
162
|
+
Select ``n`` ticks with the highest values in the ``column`` field
|
|
163
|
+
|
|
164
|
+
See also
|
|
165
|
+
--------
|
|
166
|
+
**HIGH_TICK** OneTick event processor
|
|
167
|
+
|
|
168
|
+
Examples
|
|
169
|
+
--------
|
|
170
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4], offset=[0, 1000, 1500, 3000])
|
|
171
|
+
>>> agg = otp.agg.high_tick('X', 2)
|
|
172
|
+
>>> data = agg.apply(data)
|
|
173
|
+
>>> otp.run(data)
|
|
174
|
+
Time X
|
|
175
|
+
0 2003-12-01 00:00:01.500 3
|
|
176
|
+
1 2003-12-01 00:00:03.000 4
|
|
177
|
+
"""
|
|
178
|
+
return HighTick(*args, **kwargs)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@docstring(parameters=[_column_doc, _n_doc, _running_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
182
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
183
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
184
|
+
_keep_timestamp_doc, _selection_doc,
|
|
185
|
+
_time_series_type_doc])
|
|
186
|
+
def low_tick(*args, **kwargs):
|
|
187
|
+
"""
|
|
188
|
+
Select ``n`` ticks with the lowest values in the ``column`` field
|
|
189
|
+
|
|
190
|
+
See also
|
|
191
|
+
--------
|
|
192
|
+
**LOW_TICK** OneTick event processor
|
|
193
|
+
|
|
194
|
+
Examples
|
|
195
|
+
--------
|
|
196
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4], offset=[0, 1000, 1500, 3000])
|
|
197
|
+
>>> agg = otp.agg.low_tick('X', 2)
|
|
198
|
+
>>> data = agg.apply(data)
|
|
199
|
+
>>> otp.run(data)
|
|
200
|
+
Time X
|
|
201
|
+
0 2003-12-01 00:00:00 1
|
|
202
|
+
1 2003-12-01 00:00:01 2
|
|
203
|
+
"""
|
|
204
|
+
return LowTick(*args, **kwargs)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
208
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
209
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
210
|
+
_selection_doc, _time_series_type_doc])
|
|
211
|
+
def high_time(*args, **kwargs):
|
|
212
|
+
"""
|
|
213
|
+
Returns timestamp of tick with highest value of input field
|
|
214
|
+
|
|
215
|
+
See also
|
|
216
|
+
--------
|
|
217
|
+
**HIGH_TIME** OneTick event processor
|
|
218
|
+
|
|
219
|
+
Examples
|
|
220
|
+
--------
|
|
221
|
+
|
|
222
|
+
>>> data = otp.Ticks(X=[1, 2, 4, 3], offset=[0, 1000, 1500, 3000])
|
|
223
|
+
>>> data = data.agg({'RESULT': otp.agg.high_time(['X'])}) # OTdirective: snippet-name: Aggregations.high time;
|
|
224
|
+
>>> otp.run(data)
|
|
225
|
+
Time RESULT
|
|
226
|
+
0 2003-12-04 2003-12-01 00:00:01.500
|
|
227
|
+
"""
|
|
228
|
+
return HighTime(*args, **kwargs)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
232
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
233
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
234
|
+
_selection_doc, _time_series_type_doc])
|
|
235
|
+
def low_time(*args, **kwargs):
|
|
236
|
+
"""
|
|
237
|
+
Returns timestamp of tick with lowest value of input field
|
|
238
|
+
|
|
239
|
+
See also
|
|
240
|
+
--------
|
|
241
|
+
**LOW_TIME** OneTick event processor
|
|
242
|
+
|
|
243
|
+
Examples
|
|
244
|
+
--------
|
|
245
|
+
|
|
246
|
+
>>> data = otp.Ticks(X=[2, 1, 3, 4], offset=[0, 1000, 1500, 3000])
|
|
247
|
+
>>> data = data.agg({'RESULT': otp.agg.low_time(['X'])}) # OTdirective: snippet-name: Aggregations.low time;
|
|
248
|
+
>>> otp.run(data)
|
|
249
|
+
Time RESULT
|
|
250
|
+
0 2003-12-04 2003-12-01 00:00:01
|
|
251
|
+
"""
|
|
252
|
+
return LowTime(*args, **kwargs)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
256
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
257
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
258
|
+
_large_ints_doc, _null_int_val_doc,
|
|
259
|
+
_skip_tick_if_doc, _time_series_type_doc])
|
|
260
|
+
def first(*args, **kwargs):
|
|
261
|
+
"""
|
|
262
|
+
Return first value of input field
|
|
263
|
+
|
|
264
|
+
See also
|
|
265
|
+
--------
|
|
266
|
+
**FIRST** OneTick event processor
|
|
267
|
+
|
|
268
|
+
Examples
|
|
269
|
+
--------
|
|
270
|
+
|
|
271
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4])
|
|
272
|
+
>>> agg = otp.agg.first('X')
|
|
273
|
+
>>> data = agg.apply(data)
|
|
274
|
+
>>> otp.run(data)
|
|
275
|
+
Time X
|
|
276
|
+
0 2003-12-04 1
|
|
277
|
+
"""
|
|
278
|
+
return First(*args, **kwargs)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
282
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
283
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
284
|
+
_large_ints_doc, _null_int_val_doc,
|
|
285
|
+
_skip_tick_if_doc, _time_series_type_doc])
|
|
286
|
+
def last(*args, **kwargs):
|
|
287
|
+
"""
|
|
288
|
+
Return last value of input field
|
|
289
|
+
|
|
290
|
+
See also
|
|
291
|
+
--------
|
|
292
|
+
**LAST** OneTick event processor
|
|
293
|
+
|
|
294
|
+
Examples
|
|
295
|
+
--------
|
|
296
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4])
|
|
297
|
+
>>> agg = otp.agg.last('X')
|
|
298
|
+
>>> data = agg.apply(data)
|
|
299
|
+
>>> otp.run(data)
|
|
300
|
+
Time X
|
|
301
|
+
0 2003-12-04 4
|
|
302
|
+
"""
|
|
303
|
+
return Last(*args, **kwargs)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@docstring(parameters=[_running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
307
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
308
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
309
|
+
_time_series_type_doc])
|
|
310
|
+
def first_time(*args, **kwargs):
|
|
311
|
+
"""
|
|
312
|
+
Return timestamp of first tick
|
|
313
|
+
|
|
314
|
+
See also
|
|
315
|
+
--------
|
|
316
|
+
**FIRST_TIME** OneTick event processor
|
|
317
|
+
|
|
318
|
+
Examples
|
|
319
|
+
--------
|
|
320
|
+
|
|
321
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4], offset=[0, 1000, 1500, 3000])
|
|
322
|
+
>>> data = data.agg({'RESULT': otp.agg.first_time()}) # OTdirective: snippet-name: Aggregations.first time;
|
|
323
|
+
>>> otp.run(data)
|
|
324
|
+
Time RESULT
|
|
325
|
+
0 2003-12-04 2003-12-01
|
|
326
|
+
"""
|
|
327
|
+
return FirstTime(*args, **kwargs)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
@docstring(parameters=[_running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
331
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
332
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
333
|
+
_time_series_type_doc])
|
|
334
|
+
def last_time(*args, **kwargs):
|
|
335
|
+
"""
|
|
336
|
+
Return timestamp of last tick
|
|
337
|
+
|
|
338
|
+
See also
|
|
339
|
+
--------
|
|
340
|
+
**LAST_TIME** OneTick event processor
|
|
341
|
+
|
|
342
|
+
Examples
|
|
343
|
+
--------
|
|
344
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4], offset=[0, 1000, 1500, 3000])
|
|
345
|
+
>>> data = data.agg({'RESULT': otp.agg.last_time()}) # OTdirective: snippet-name: Aggregations.last time;
|
|
346
|
+
>>> otp.run(data)
|
|
347
|
+
Time RESULT
|
|
348
|
+
0 2003-12-04 2003-12-01 00:00:03
|
|
349
|
+
"""
|
|
350
|
+
return LastTime(*args, **kwargs)
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
@docstring(parameters=[_running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc, _bucket_units_doc,
|
|
354
|
+
_bucket_end_condition_doc, _end_condition_per_group_doc, _boundary_tick_bucket_doc,
|
|
355
|
+
_group_by_doc, _groups_to_display_doc])
|
|
356
|
+
def count(*args, **kwargs):
|
|
357
|
+
"""
|
|
358
|
+
Returns number of ticks
|
|
359
|
+
|
|
360
|
+
See also
|
|
361
|
+
--------
|
|
362
|
+
**NUM_TICKS** OneTick event processor
|
|
363
|
+
|
|
364
|
+
Examples
|
|
365
|
+
--------
|
|
366
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4])
|
|
367
|
+
>>> data = data.agg({'RESULT': otp.agg.count()}) # OTdirective: snippet-name: Aggregations.count;
|
|
368
|
+
>>> otp.run(data)
|
|
369
|
+
Time RESULT
|
|
370
|
+
0 2003-12-04 4
|
|
371
|
+
"""
|
|
372
|
+
return Count(*args, **kwargs)
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
_price_doc = param_doc(name='price_column',
|
|
376
|
+
str_annotation='str or Column',
|
|
377
|
+
desc='price column for vwap',
|
|
378
|
+
annotation=Union[str, _Column])
|
|
379
|
+
|
|
380
|
+
_size_doc = param_doc(name='size_column',
|
|
381
|
+
str_annotation='str or Column',
|
|
382
|
+
desc='size column for vwap',
|
|
383
|
+
annotation=Union[str, _Column])
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
@docstring(parameters=[_price_doc, _size_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
387
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
388
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc])
|
|
389
|
+
def vwap(*args, **kwargs):
|
|
390
|
+
"""
|
|
391
|
+
Returns volume weighted average price
|
|
392
|
+
|
|
393
|
+
See also
|
|
394
|
+
--------
|
|
395
|
+
**VWAP** OneTick event processor
|
|
396
|
+
|
|
397
|
+
Examples
|
|
398
|
+
--------
|
|
399
|
+
>>> # OTdirective: snippet-name: Aggregations.vwap;
|
|
400
|
+
>>> data = otp.Ticks(P=[1, 2, 3, 4], S=[10, 20, 30, 40])
|
|
401
|
+
>>> data = data.agg({'RESULT': otp.agg.vwap('P','S')})
|
|
402
|
+
>>> otp.run(data)
|
|
403
|
+
Time RESULT
|
|
404
|
+
0 2003-12-04 3.0
|
|
405
|
+
"""
|
|
406
|
+
return Vwap(*args, **kwargs)
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
@docstring(parameters=[_running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
410
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
411
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc])
|
|
412
|
+
def correlation(*args, **kwargs):
|
|
413
|
+
"""
|
|
414
|
+
Returns Pearson correlation coefficient value between two numeric fields.
|
|
415
|
+
|
|
416
|
+
Parameters
|
|
417
|
+
----------
|
|
418
|
+
column_name_1: str
|
|
419
|
+
The name of the field in the input stream whose value is to be used by the aggregation
|
|
420
|
+
column_name_2: str
|
|
421
|
+
The name of the field in the input stream whose value is to be used by the aggregation
|
|
422
|
+
|
|
423
|
+
See also
|
|
424
|
+
--------
|
|
425
|
+
**CORRELATION** OneTick event processor
|
|
426
|
+
|
|
427
|
+
Examples
|
|
428
|
+
--------
|
|
429
|
+
>>> # OTdirective: snippet-name: Aggregations.correlation;
|
|
430
|
+
>>> data = otp.Ticks(P=[1, 2, 3, 4], S=[10, 20, 30, 40])
|
|
431
|
+
>>> data = data.agg({'RESULT': otp.agg.correlation('P','S')})
|
|
432
|
+
>>> otp.run(data)
|
|
433
|
+
Time RESULT
|
|
434
|
+
0 2003-12-04 1.0
|
|
435
|
+
|
|
436
|
+
>>> data = otp.Ticks(P=[1, 2, 3, 4], S=[40, 30, 20, 10])
|
|
437
|
+
>>> data = otp.agg.correlation('P', 'S').apply(data)
|
|
438
|
+
>>> otp.run(data)
|
|
439
|
+
Time CORRELATION
|
|
440
|
+
0 2003-12-04 -1.0
|
|
441
|
+
|
|
442
|
+
>>> data = otp.Ticks(P=[1, 2, 3, 4], S=[40, 30, 10, 20])
|
|
443
|
+
>>> data = otp.agg.correlation('P', 'S', bucket_units='ticks', bucket_interval=2).apply(data)
|
|
444
|
+
>>> otp.run(data)
|
|
445
|
+
Time CORRELATION
|
|
446
|
+
0 2003-12-01 00:00:00.001 -1.0
|
|
447
|
+
1 2003-12-01 00:00:00.003 1.0
|
|
448
|
+
"""
|
|
449
|
+
return Correlation(*args, **kwargs)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
@docstring(parameters=[_n_doc, _running_doc, _bucket_interval_doc, _bucket_time_doc, _bucket_units_doc,
|
|
453
|
+
_bucket_end_condition_doc, _end_condition_per_group_doc, _boundary_tick_bucket_doc,
|
|
454
|
+
_group_by_doc, _groups_to_display_doc, _keep_timestamp_doc, _default_tick_doc])
|
|
455
|
+
def first_tick(*args, **kwargs):
|
|
456
|
+
"""
|
|
457
|
+
Select the first **n** ticks
|
|
458
|
+
|
|
459
|
+
See also
|
|
460
|
+
--------
|
|
461
|
+
**FIRST_TICK** OneTick event processor
|
|
462
|
+
|
|
463
|
+
Examples
|
|
464
|
+
--------
|
|
465
|
+
>>> data = otp.Ticks(P=[1, 2, 3, 4], S=[10, 20, 30, 40])
|
|
466
|
+
>>> agg = otp.agg.first_tick()
|
|
467
|
+
>>> data = agg.apply(data)
|
|
468
|
+
>>> otp.run(data)
|
|
469
|
+
Time P S
|
|
470
|
+
0 2003-12-01 1 10
|
|
471
|
+
"""
|
|
472
|
+
return FirstTick(*args, **kwargs)
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
@docstring(parameters=[_n_doc, _running_doc, _bucket_interval_doc, _bucket_time_doc, _bucket_units_doc,
|
|
476
|
+
_bucket_end_condition_doc, _end_condition_per_group_doc, _boundary_tick_bucket_doc,
|
|
477
|
+
_group_by_doc, _groups_to_display_doc, _keep_timestamp_doc, _time_series_type_doc])
|
|
478
|
+
def last_tick(*args, **kwargs):
|
|
479
|
+
"""
|
|
480
|
+
Select the last ``n`` ticks
|
|
481
|
+
|
|
482
|
+
See also
|
|
483
|
+
--------
|
|
484
|
+
**LAST_TICK** OneTick event processor
|
|
485
|
+
|
|
486
|
+
Examples
|
|
487
|
+
--------
|
|
488
|
+
>>> data = otp.Ticks(P=[1, 2, 3, 4], S=[10, 20, 30, 40], offset=[0, 1000, 1500, 3000])
|
|
489
|
+
>>> agg = otp.agg.last_tick()
|
|
490
|
+
>>> data = agg.apply(data)
|
|
491
|
+
>>> otp.run(data)
|
|
492
|
+
Time P S
|
|
493
|
+
0 2003-12-01 00:00:03 4 40
|
|
494
|
+
"""
|
|
495
|
+
return LastTick(*args, **kwargs)
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
@docstring(parameters=[_running_doc, _bucket_interval_doc, _bucket_time_doc, _bucket_units_doc,
|
|
499
|
+
_bucket_end_condition_doc, _boundary_tick_bucket_doc, _selection_doc])
|
|
500
|
+
def distinct(*args, **kwargs):
|
|
501
|
+
"""
|
|
502
|
+
Outputs all distinct values for a specified set of key fields.
|
|
503
|
+
|
|
504
|
+
Parameters
|
|
505
|
+
----------
|
|
506
|
+
keys: str or list
|
|
507
|
+
Specifies a list of tick attributes for which unique values are found. The ticks in the input time series
|
|
508
|
+
must contain those attributes.
|
|
509
|
+
key_attrs_only: bool
|
|
510
|
+
If set to true, output ticks will contain only key fields. Otherwise, output ticks will contain all fields
|
|
511
|
+
of an input tick in which a given distinct combination of key values was first encountered.
|
|
512
|
+
|
|
513
|
+
See also
|
|
514
|
+
--------
|
|
515
|
+
**DISTINCT** OneTick event processor
|
|
516
|
+
|
|
517
|
+
Examples
|
|
518
|
+
--------
|
|
519
|
+
>>> data = otp.Ticks(dict(x=[1, 3, 1, 5, 3]))
|
|
520
|
+
>>> d = otp.agg.distinct('x')
|
|
521
|
+
>>> data = d.apply(data)
|
|
522
|
+
>>> otp.run(data)
|
|
523
|
+
Time x
|
|
524
|
+
0 2003-12-04 1
|
|
525
|
+
1 2003-12-04 3
|
|
526
|
+
2 2003-12-04 5
|
|
527
|
+
"""
|
|
528
|
+
return Distinct(*args, **kwargs)
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
532
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
533
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc])
|
|
534
|
+
def sum(*args, **kwargs):
|
|
535
|
+
r"""
|
|
536
|
+
Implement sum aggregation
|
|
537
|
+
|
|
538
|
+
See also
|
|
539
|
+
--------
|
|
540
|
+
**SUM** OneTick event processor
|
|
541
|
+
|
|
542
|
+
Examples
|
|
543
|
+
--------
|
|
544
|
+
|
|
545
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4])
|
|
546
|
+
>>> data = data.agg({'RESULT': otp.agg.sum('X')}) # OTdirective: snippet-name: Aggregations.sum;
|
|
547
|
+
>>> otp.run(data)
|
|
548
|
+
Time RESULT
|
|
549
|
+
0 2003-12-04 10
|
|
550
|
+
|
|
551
|
+
Note that **seconds** bucket unit doesn't take into account daylight-saving time of the timezone,
|
|
552
|
+
so you may not get expected results when using, for example, 24 * 60 * 60 seconds as bucket interval.
|
|
553
|
+
|
|
554
|
+
>>> data = otp.DataSource('CME', symbols=r'NQ\H23', tick_type='TRD') # doctest: +SKIP
|
|
555
|
+
>>> data = data.agg({'VOLUME': otp.agg.sum('SIZE')}, # doctest: +SKIP
|
|
556
|
+
... bucket_interval=24*60*60, bucket_units='seconds', bucket_time='start')
|
|
557
|
+
>>> otp.run(data, start=otp.dt(2023, 3, 11), end=otp.dt(2023, 3, 15), timezone='EST5EDT') # doctest: +SKIP
|
|
558
|
+
Time VOLUME
|
|
559
|
+
0 2023-03-11 00:00:00 0
|
|
560
|
+
1 2023-03-12 00:00:00 66190
|
|
561
|
+
2 2023-03-13 01:00:00 631750
|
|
562
|
+
3 2023-03-14 01:00:00 345952
|
|
563
|
+
|
|
564
|
+
In such case use **days** bucket unit instead:
|
|
565
|
+
|
|
566
|
+
>>> data = otp.DataSource('CME', symbols=r'NQ\H23', tick_type='TRD') # doctest: +SKIP
|
|
567
|
+
>>> data = data.agg({'VOLUME': otp.agg.sum('SIZE')}, # doctest: +SKIP
|
|
568
|
+
... bucket_interval=1, bucket_units='days', bucket_time='start')
|
|
569
|
+
>>> otp.run(data, start=otp.dt(2023, 3, 11), end=otp.dt(2023, 3, 15), timezone='EST5EDT') # doctest: +SKIP
|
|
570
|
+
Time VOLUME
|
|
571
|
+
0 2023-03-11 0
|
|
572
|
+
1 2023-03-12 62940
|
|
573
|
+
2 2023-03-13 634172
|
|
574
|
+
3 2023-03-14 346780
|
|
575
|
+
"""
|
|
576
|
+
return Sum(*args, **kwargs)
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
580
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
581
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc])
|
|
582
|
+
def average(*args, **kwargs):
|
|
583
|
+
"""
|
|
584
|
+
Implement average aggregation
|
|
585
|
+
|
|
586
|
+
See also
|
|
587
|
+
--------
|
|
588
|
+
**AVERAGE** OneTick event processor
|
|
589
|
+
|
|
590
|
+
Examples
|
|
591
|
+
--------
|
|
592
|
+
|
|
593
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4])
|
|
594
|
+
>>> data = data.agg({'RESULT': otp.agg.average('X')}) # OTdirective: snippet-name: Aggregations.average/mean;
|
|
595
|
+
>>> otp.run(data)
|
|
596
|
+
Time RESULT
|
|
597
|
+
0 2003-12-04 2.5
|
|
598
|
+
"""
|
|
599
|
+
return Average(*args, **kwargs)
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
def mean(*args, **kwargs):
|
|
603
|
+
"""
|
|
604
|
+
Implement average aggregation.
|
|
605
|
+
|
|
606
|
+
See also
|
|
607
|
+
--------
|
|
608
|
+
| :func:`average`
|
|
609
|
+
| **AVERAGE** OneTick event processor
|
|
610
|
+
|
|
611
|
+
Examples
|
|
612
|
+
--------
|
|
613
|
+
|
|
614
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4])
|
|
615
|
+
>>> data = data.agg({'RESULT': otp.agg.mean('X')})
|
|
616
|
+
>>> otp.run(data)
|
|
617
|
+
Time RESULT
|
|
618
|
+
0 2003-12-04 2.5
|
|
619
|
+
"""
|
|
620
|
+
return average(*args, **kwargs)
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
624
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
625
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc, _biased_doc])
|
|
626
|
+
def stddev(*args, **kwargs):
|
|
627
|
+
"""
|
|
628
|
+
Implement standard deviation aggregation
|
|
629
|
+
|
|
630
|
+
See also
|
|
631
|
+
--------
|
|
632
|
+
**STDDEV** OneTick event processor
|
|
633
|
+
|
|
634
|
+
Examples
|
|
635
|
+
--------
|
|
636
|
+
|
|
637
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4])
|
|
638
|
+
>>> data = data.agg({'RESULT': otp.agg.stddev('X')}) # OTdirective: snippet-name: Aggregations.stddev;
|
|
639
|
+
>>> otp.run(data)
|
|
640
|
+
Time RESULT
|
|
641
|
+
0 2003-12-04 1.118034
|
|
642
|
+
"""
|
|
643
|
+
return StdDev(*args, **kwargs)
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
647
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
648
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc, _time_series_type_w_doc])
|
|
649
|
+
def tw_average(*args, **kwargs):
|
|
650
|
+
"""
|
|
651
|
+
Returns time weighted average of input field
|
|
652
|
+
|
|
653
|
+
See also
|
|
654
|
+
--------
|
|
655
|
+
**TW_AVERAGE** OneTick event processor
|
|
656
|
+
|
|
657
|
+
Examples
|
|
658
|
+
--------
|
|
659
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4], offset=[0, 1000, 1500, 3000])
|
|
660
|
+
>>> otp.run(data, start=otp.dt(2023, 4, 25), end=otp.dt(2023, 4, 25)+otp.Second(4))
|
|
661
|
+
Time X
|
|
662
|
+
0 2023-04-25 00:00:00.000 1
|
|
663
|
+
1 2023-04-25 00:00:01.000 2
|
|
664
|
+
2 2023-04-25 00:00:01.500 3
|
|
665
|
+
3 2023-04-25 00:00:03.000 4
|
|
666
|
+
|
|
667
|
+
>>> # OTdirective: snippet-name: Aggregations.time weighted average;
|
|
668
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4], offset=[0, 1000, 1500, 3000])
|
|
669
|
+
>>> data = data.agg({'RESULT': otp.agg.tw_average('X')})
|
|
670
|
+
>>> otp.run(data, start=otp.dt(2023, 4, 25), end=otp.dt(2023, 4, 25)+otp.Second(4))
|
|
671
|
+
Time RESULT
|
|
672
|
+
0 2023-04-25 00:00:04 2.625
|
|
673
|
+
"""
|
|
674
|
+
return TimeWeightedAvg(*args, **kwargs)
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
678
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
679
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc])
|
|
680
|
+
def median(*args, **kwargs):
|
|
681
|
+
"""
|
|
682
|
+
Implement median aggregation
|
|
683
|
+
|
|
684
|
+
See also
|
|
685
|
+
--------
|
|
686
|
+
**MEDIAN** OneTick event processor
|
|
687
|
+
|
|
688
|
+
Examples
|
|
689
|
+
--------
|
|
690
|
+
|
|
691
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 3, 4])
|
|
692
|
+
>>> data = data.agg({'RESULT': otp.agg.median('X')}) # OTdirective: snippet-name: Aggregations.median;
|
|
693
|
+
>>> otp.run(data)
|
|
694
|
+
Time RESULT
|
|
695
|
+
0 2003-12-04 3.0
|
|
696
|
+
"""
|
|
697
|
+
return Median(*args, **kwargs)
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
@docstring(parameters=OB_SNAPSHOT_DOC_PARAMS)
|
|
701
|
+
def ob_snapshot(*args, **kwargs):
|
|
702
|
+
"""
|
|
703
|
+
Returns the order book state at the end of each bucket interval:
|
|
704
|
+
the price, the size, the side, and the time of the last update for a specified number of order book levels.
|
|
705
|
+
|
|
706
|
+
See also
|
|
707
|
+
--------
|
|
708
|
+
| :func:`onetick.py.ObSnapshot`
|
|
709
|
+
| **OB_SNAPSHOT** OneTick event processor
|
|
710
|
+
|
|
711
|
+
|
|
712
|
+
Examples
|
|
713
|
+
--------
|
|
714
|
+
>>> data = otp.DataSource(db='SOME_DB', tick_type='PRL', symbols='AA') # doctest: +SKIP
|
|
715
|
+
>>> data = otp.agg.ob_snapshot(max_levels=1).apply(data) # doctest: +SKIP
|
|
716
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
717
|
+
Time PRICE UPDATE_TIME SIZE LEVEL BUY_SELL_FLAG
|
|
718
|
+
0 2003-12-04 2.0 2003-12-01 00:00:00.003 6 1 1
|
|
719
|
+
1 2003-12-04 5.0 2003-12-01 00:00:00.004 7 1 0
|
|
720
|
+
"""
|
|
721
|
+
return ObSnapshot(*args, **kwargs)
|
|
722
|
+
|
|
723
|
+
|
|
724
|
+
@docstring(parameters=OB_SNAPSHOT_WIDE_DOC_PARAMS)
|
|
725
|
+
def ob_snapshot_wide(*args, **kwargs):
|
|
726
|
+
"""
|
|
727
|
+
Returns a side by side order book state at the end of each interval:
|
|
728
|
+
the price, the size, and the time of the last update for a specified number of order book levels.
|
|
729
|
+
|
|
730
|
+
See also
|
|
731
|
+
--------
|
|
732
|
+
| :func:`onetick.py.ObSnapshotWide`
|
|
733
|
+
| **OB_SNAPSHOT_WIDE** OneTick event processor
|
|
734
|
+
|
|
735
|
+
Examples
|
|
736
|
+
--------
|
|
737
|
+
>>> data = otp.DataSource(db='SOME_DB', tick_type='PRL', symbols='AA') # doctest: +SKIP
|
|
738
|
+
>>> data = otp.agg.ob_snapshot_wide(max_levels=1).apply(data) # doctest: +SKIP
|
|
739
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
740
|
+
Time BID_PRICE BID_UPDATE_TIME BID_SIZE ASK_PRICE ASK_UPDATE_TIME ASK_SIZE LEVEL
|
|
741
|
+
0 2003-12-03 5.0 2003-12-01 00:00:00.004 7 2.0 2003-12-01 00:00:00.003 6 1
|
|
742
|
+
"""
|
|
743
|
+
return ObSnapshotWide(*args, **kwargs)
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
@docstring(parameters=OB_SNAPSHOT_FLAT_DOC_PARAMS)
|
|
747
|
+
def ob_snapshot_flat(*args, **kwargs):
|
|
748
|
+
"""
|
|
749
|
+
Returns the snapshot for a specified number of book levels as a single tick
|
|
750
|
+
with multiple field groups corresponding to book levels.
|
|
751
|
+
|
|
752
|
+
See also
|
|
753
|
+
--------
|
|
754
|
+
| :func:`onetick.py.ObSnapshotFlat`
|
|
755
|
+
| **OB_SNAPSHOT_FLAT** OneTick event processor
|
|
756
|
+
|
|
757
|
+
Examples
|
|
758
|
+
--------
|
|
759
|
+
>>> data = otp.DataSource(db='SOME_DB', tick_type='PRL', symbols='AA') # doctest: +SKIP
|
|
760
|
+
>>> data = otp.agg.ob_snapshot_flat(max_levels=1).apply(data) # doctest: +SKIP
|
|
761
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
762
|
+
Time BID_PRICE1 BID_UPDATE_TIME1 BID_SIZE1 ASK_PRICE1 ASK_UPDATE_TIME1 ASK_SIZE1
|
|
763
|
+
0 2003-12-03 5.0 2003-12-01 00:00:00.004 7 2.0 2003-12-01 00:00:00.003 6
|
|
764
|
+
"""
|
|
765
|
+
return ObSnapshotFlat(*args, **kwargs)
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
@docstring(parameters=OB_SUMMARY_DOC_PARAMS)
|
|
769
|
+
def ob_summary(*args, **kwargs):
|
|
770
|
+
"""
|
|
771
|
+
Computes summary statistics, such as:
|
|
772
|
+
VWAP, best and worst price, total size, and number of levels, for one or both sides of an order book.
|
|
773
|
+
|
|
774
|
+
See also
|
|
775
|
+
--------
|
|
776
|
+
| :func:`onetick.py.ObSummary`
|
|
777
|
+
| **OB_SUMMARY** OneTick event processor
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
Examples
|
|
781
|
+
--------
|
|
782
|
+
>>> data = otp.DataSource(db='SOME_DB', tick_type='PRL', symbols='AA') # doctest: +SKIP
|
|
783
|
+
>>> data = otp.agg.ob_summary(max_levels=1).apply(data) # doctest: +SKIP
|
|
784
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
785
|
+
Time BID_PRICE BID_SIZE BID_VWAP BEST_BID_PRICE WORST_BID_SIZE NUM_BID_LEVELS ASK_SIZE\
|
|
786
|
+
ASK_VWAP BEST_ASK_PRICE WORST_ASK_PRICE NUM_ASK_LEVELS
|
|
787
|
+
0 2003-12-04 NaN 7 5.0 5.0 NaN 1 6\
|
|
788
|
+
2.0 2.0 2.0 1
|
|
789
|
+
"""
|
|
790
|
+
return ObSummary(*args, **kwargs)
|
|
791
|
+
|
|
792
|
+
|
|
793
|
+
@docstring(parameters=OB_SIZE_DOC_PARAMS)
|
|
794
|
+
def ob_size(*args, **kwargs):
|
|
795
|
+
"""
|
|
796
|
+
Returns the total size for a specified number of order book levels at the end of each bucket interval.
|
|
797
|
+
|
|
798
|
+
See also
|
|
799
|
+
--------
|
|
800
|
+
| :func:`onetick.py.ObSize`
|
|
801
|
+
| **OB_SIZE** OneTick event processor
|
|
802
|
+
|
|
803
|
+
Examples
|
|
804
|
+
--------
|
|
805
|
+
|
|
806
|
+
Basic example
|
|
807
|
+
|
|
808
|
+
>>> data = otp.DataSource(db='SOME_DB', tick_type='PRL', symbols='AA') # doctest: +SKIP
|
|
809
|
+
>>> data = otp.agg.ob_size(bucket_interval=otp.Second(300), max_levels=10).apply(data) # doctest: +SKIP
|
|
810
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
811
|
+
Time ASK_VALUE BID_VALUE
|
|
812
|
+
0 2003-12-01 00:05:00.000 194800 47200
|
|
813
|
+
1 2003-12-01 00:10:00.000 194800 47200
|
|
814
|
+
2 2003-12-01 00:15:00.000 313400 7700
|
|
815
|
+
...
|
|
816
|
+
|
|
817
|
+
Selecting side via ``side`` parameter
|
|
818
|
+
|
|
819
|
+
>>> data = otp.DataSource(db='SOME_DB', tick_type='PRL', symbols='AA') # doctest: +SKIP
|
|
820
|
+
>>> data = otp.agg.ob_size(bucket_interval=otp.Second(300), max_levels=10, size='ASK').apply(data) # doctest: +SKIP
|
|
821
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
822
|
+
Time VALUE
|
|
823
|
+
0 2003-12-01 00:05:00.000 194800
|
|
824
|
+
1 2003-12-01 00:10:00.000 194800
|
|
825
|
+
2 2003-12-01 00:15:00.000 313400
|
|
826
|
+
...
|
|
827
|
+
"""
|
|
828
|
+
return ObSize(*args, **kwargs)
|
|
829
|
+
|
|
830
|
+
|
|
831
|
+
@docstring(parameters=OB_VWAP_DOC_PARAMS)
|
|
832
|
+
def ob_vwap(*args, **kwargs):
|
|
833
|
+
"""
|
|
834
|
+
Returns the size-weighted price computed over a specified number of order book levels at the end of each interval.
|
|
835
|
+
|
|
836
|
+
See also
|
|
837
|
+
--------
|
|
838
|
+
| :func:`onetick.py.ObVwap`
|
|
839
|
+
| **OB_VWAP** OneTick event processor
|
|
840
|
+
|
|
841
|
+
Examples
|
|
842
|
+
--------
|
|
843
|
+
|
|
844
|
+
Basic example
|
|
845
|
+
|
|
846
|
+
>>> data = otp.DataSource(db='SOME_DB', tick_type='PRL', symbols='AA') # doctest: +SKIP
|
|
847
|
+
>>> data = otp.agg.ob_vwap(bucket_interval=otp.Second(300)).apply(data) # doctest: +SKIP
|
|
848
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
849
|
+
Time ASK_VALUE BID_VALUE
|
|
850
|
+
0 2003-12-01 00:05:00.000 23.93496 23.80502
|
|
851
|
+
1 2003-12-01 00:10:00.000 23.93496 23.80502
|
|
852
|
+
2 2003-12-01 00:15:00.000 24.35387 24.35387
|
|
853
|
+
...
|
|
854
|
+
|
|
855
|
+
Selecting side via ``side`` parameter
|
|
856
|
+
|
|
857
|
+
>>> data = otp.DataSource(db='SOME_DB', tick_type='PRL', symbols='AA') # doctest: +SKIP
|
|
858
|
+
>>> data = otp.agg.ob_vwap(bucket_interval=otp.Second(300), size='BID').apply(data) # doctest: +SKIP
|
|
859
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
860
|
+
Time VALUE
|
|
861
|
+
0 2003-12-01 00:05:00.000 23.80502
|
|
862
|
+
1 2003-12-01 00:10:00.000 23.80502
|
|
863
|
+
2 2003-12-01 00:15:00.000 24.35387
|
|
864
|
+
...
|
|
865
|
+
"""
|
|
866
|
+
return ObVwap(*args, **kwargs)
|
|
867
|
+
|
|
868
|
+
|
|
869
|
+
@docstring(parameters=OB_NUM_LEVELS_DOC_PARAMS)
|
|
870
|
+
def ob_num_levels(*args, **kwargs):
|
|
871
|
+
"""
|
|
872
|
+
Returns the number of levels in the order book at the end of each bucket.
|
|
873
|
+
|
|
874
|
+
Note
|
|
875
|
+
----
|
|
876
|
+
This EP supports only seconds as ``bucket_interval``.
|
|
877
|
+
|
|
878
|
+
See also
|
|
879
|
+
--------
|
|
880
|
+
| :func:`onetick.py.ObNumLevels`
|
|
881
|
+
| **OB_NUM_LEVELS** OneTick event processor
|
|
882
|
+
|
|
883
|
+
Examples
|
|
884
|
+
--------
|
|
885
|
+
|
|
886
|
+
Basic example
|
|
887
|
+
|
|
888
|
+
>>> data = otp.DataSource(db='SOME_DB', tick_type='PRL', symbols='AA') # doctest: +SKIP
|
|
889
|
+
>>> data = otp.agg.ob_num_levels(bucket_interval=otp.Second(300)).apply(data) # doctest: +SKIP
|
|
890
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
891
|
+
Time ASK_VALUE BID_VALUE
|
|
892
|
+
0 2003-12-01 00:05:00.000 243 74
|
|
893
|
+
1 2003-12-01 00:10:00.000 243 74
|
|
894
|
+
2 2003-12-01 00:15:00.000 208 45
|
|
895
|
+
...
|
|
896
|
+
"""
|
|
897
|
+
return ObNumLevels(*args, **kwargs)
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
@docstring(parameters=[
|
|
901
|
+
_query_fun_doc,
|
|
902
|
+
_bucket_delimiter_doc,
|
|
903
|
+
_bucket_interval_doc,
|
|
904
|
+
_bucket_units_doc,
|
|
905
|
+
_bucket_time_doc,
|
|
906
|
+
_bucket_end_condition_doc,
|
|
907
|
+
_running_doc,
|
|
908
|
+
_group_by_doc,
|
|
909
|
+
_groups_to_display_doc,
|
|
910
|
+
_end_condition_per_group_doc,
|
|
911
|
+
_boundary_tick_bucket_doc,
|
|
912
|
+
])
|
|
913
|
+
def generic(*args, **kwargs):
|
|
914
|
+
"""
|
|
915
|
+
Generic aggregation.
|
|
916
|
+
Aggregation logic is provided in ``query_fun`` parameter
|
|
917
|
+
and this logic is applied for ticks in each bucket.
|
|
918
|
+
Currently, this aggregation can be used only with ``.apply()`` method.
|
|
919
|
+
|
|
920
|
+
Note, that ``query_fun`` should return a :py:class:`~onetick.py.Source` object,
|
|
921
|
+
assuming that resulted query have only one tick per bucket.
|
|
922
|
+
|
|
923
|
+
Also, ``query_fun`` could have additional parameters, which will be passed to ``query_fun``
|
|
924
|
+
during aggregation. Those parameters should be specified in ``.apply()`` as keyword arguments,
|
|
925
|
+
ex: ``.apply(src, additional_param=1)``.
|
|
926
|
+
|
|
927
|
+
Generic aggregations could be also used in :py:meth:`onetick.py.Source.agg` method.
|
|
928
|
+
Dict key set for an aggregation in ``aggs`` parameter will be used as prefix
|
|
929
|
+
for each output column of this aggregation.
|
|
930
|
+
Also, all tick fields not contained in the Python-level schema in a passed to generic aggregation
|
|
931
|
+
:class:`Source` object will be removed.
|
|
932
|
+
|
|
933
|
+
Note
|
|
934
|
+
----
|
|
935
|
+
Some functions may be not supported in ``query_fun``.
|
|
936
|
+
For example, :py:func:`~onetick.py.join` and :py:meth:`~onetick.py.Source.rename`.
|
|
937
|
+
|
|
938
|
+
See also
|
|
939
|
+
--------
|
|
940
|
+
**GENERIC_AGGREGATION** OneTick event processor
|
|
941
|
+
|
|
942
|
+
Examples
|
|
943
|
+
--------
|
|
944
|
+
|
|
945
|
+
The simplest case, just copying some other aggregation logic:
|
|
946
|
+
|
|
947
|
+
>>> data = otp.Ticks({'A': [1, 2, 3]})
|
|
948
|
+
>>> def agg_fun(source):
|
|
949
|
+
... return source.agg({'X': otp.agg.count()})
|
|
950
|
+
>>> data = otp.agg.generic(agg_fun).apply(data)
|
|
951
|
+
>>> otp.run(data)
|
|
952
|
+
Time X
|
|
953
|
+
0 2003-12-04 3
|
|
954
|
+
|
|
955
|
+
Passing parameters to aggregation function:
|
|
956
|
+
|
|
957
|
+
>>> data = otp.Ticks({'A': [1, 2, 1]})
|
|
958
|
+
>>> def count_values(source, value):
|
|
959
|
+
... values = source.where(source['A'] == value)
|
|
960
|
+
... return values.agg({'count': otp.agg.count()})
|
|
961
|
+
>>> data = otp.agg.generic(count_values).apply(data, value=1)
|
|
962
|
+
>>> otp.run(data)
|
|
963
|
+
Time count
|
|
964
|
+
0 2003-12-04 2
|
|
965
|
+
|
|
966
|
+
Getting first 3 ticks from 5 milliseconds buckets:
|
|
967
|
+
|
|
968
|
+
>>> data = otp.Ticks({'A': list(range(10))})
|
|
969
|
+
>>> def agg_fun(source, n):
|
|
970
|
+
... return source.first(n)
|
|
971
|
+
>>> data = otp.agg.generic(agg_fun, bucket_interval=0.005).apply(data, n=3)
|
|
972
|
+
>>> otp.run(data, start=otp.config.default_start_time, end=otp.config.default_start_time + otp.Milli(10))
|
|
973
|
+
Time A
|
|
974
|
+
0 2003-12-01 00:00:00.005 0
|
|
975
|
+
1 2003-12-01 00:00:00.005 1
|
|
976
|
+
2 2003-12-01 00:00:00.005 2
|
|
977
|
+
3 2003-12-01 00:00:00.010 5
|
|
978
|
+
4 2003-12-01 00:00:00.010 6
|
|
979
|
+
5 2003-12-01 00:00:00.010 7
|
|
980
|
+
|
|
981
|
+
Using generic aggregation inside :py:meth:`onetick.py.Source.agg` method:
|
|
982
|
+
|
|
983
|
+
>>> def agg_fun(source):
|
|
984
|
+
... return source.agg({'SUM': otp.agg.sum('X'), 'AVG': otp.agg.average('X')})
|
|
985
|
+
...
|
|
986
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 4, 5])
|
|
987
|
+
>>> data = data.agg({'X': otp.agg.generic(agg_fun)})
|
|
988
|
+
>>> otp.run(data)
|
|
989
|
+
Time X.SUM X.AVG
|
|
990
|
+
0 2003-12-04 15 3.0
|
|
991
|
+
"""
|
|
992
|
+
|
|
993
|
+
return Generic(*args, **kwargs)
|
|
994
|
+
|
|
995
|
+
|
|
996
|
+
@docstring(parameters=[_running_doc, _bucket_interval_doc, _bucket_time_doc, _bucket_units_doc,
|
|
997
|
+
_bucket_end_condition_doc, _boundary_tick_bucket_doc])
|
|
998
|
+
def option_price(*args, **kwargs):
|
|
999
|
+
"""
|
|
1000
|
+
This aggregation requires several parameters to compute the option price.
|
|
1001
|
+
Those are, OPTION_TYPE, STRIKE_PRICE, EXPIRATION_DATE or DAYS_TILL_EXPIRATION, VOLATILITY, and INTEREST_RATE.
|
|
1002
|
+
Each parameter can be specified, either via a symbol parameter with the same name or via a tick field,
|
|
1003
|
+
by specifying the name of that field as an EP parameter, as follows.
|
|
1004
|
+
Besides, VOLATILITY and INTEREST_RATE can also be specified as parameters. If they are also specified as fields,
|
|
1005
|
+
the parameters value are ignored.
|
|
1006
|
+
In either case, the OPTION_TYPE value must be set to either CALL or PUT (case insensitive).
|
|
1007
|
+
EXPIRATION_DATE is in YYYYMMDD format, a string in case of a symbol parameter and
|
|
1008
|
+
an integer in case of a tick attribute.
|
|
1009
|
+
Additionally, NUMBER_OF_STEPS should be specified in case of Cox-Ross-Rubinstein method.
|
|
1010
|
+
|
|
1011
|
+
Note
|
|
1012
|
+
----
|
|
1013
|
+
This aggregation is used with ``.apply()``, but latest OneTick builds support also the ``.agg()`` method.
|
|
1014
|
+
|
|
1015
|
+
Parameters
|
|
1016
|
+
----------
|
|
1017
|
+
volatility: float
|
|
1018
|
+
The historical volatility of the asset’s returns.
|
|
1019
|
+
interest_rate: float
|
|
1020
|
+
The risk-free interest rate.
|
|
1021
|
+
compute_model: str
|
|
1022
|
+
Allowed values are `BS` and `CRR`.
|
|
1023
|
+
Choose between Black–Scholes (`BS`) and Cox-Ross-Rubinstein (`CRR`) models for computing call/put option price.
|
|
1024
|
+
Default: `BS`
|
|
1025
|
+
number_of_steps: int
|
|
1026
|
+
Specifies the number of time steps between the valuation and expiration dates.
|
|
1027
|
+
This is a mandatory parameter for `CRR` model.
|
|
1028
|
+
compute_delta: bool
|
|
1029
|
+
Specifies whether Delta is to be computed or not. This parameter is used only in case of `BS` model.
|
|
1030
|
+
Default: False
|
|
1031
|
+
compute_gamma: bool
|
|
1032
|
+
Specifies whether Gamma is to be computed or not. This parameter is used only in case of `BS` model.
|
|
1033
|
+
Default: False
|
|
1034
|
+
compute_theta: bool
|
|
1035
|
+
Specifies whether Theta is to be computed or not. This parameter is used only in case of `BS` model.
|
|
1036
|
+
Default: False
|
|
1037
|
+
compute_vega: bool
|
|
1038
|
+
Specifies whether Vega is to be computed or not. This parameter is used only in case of `BS` model.
|
|
1039
|
+
Default: False
|
|
1040
|
+
compute_rho: bool
|
|
1041
|
+
Specifies whether Rho is to be computed or not. This parameter is used only in case of `BS` model.
|
|
1042
|
+
Default: False
|
|
1043
|
+
volatility_field_name: str
|
|
1044
|
+
Specifies name of the field, which carries the historical volatility of the asset’s returns.
|
|
1045
|
+
Default: empty
|
|
1046
|
+
interest_rate_field_name: str
|
|
1047
|
+
Specifies name of the field, which carries the risk-free interest rate.
|
|
1048
|
+
Default: empty
|
|
1049
|
+
option_type_field_name: str
|
|
1050
|
+
Specifies name of the field, which carries the option type (either CALL or PUT).
|
|
1051
|
+
Default: empty
|
|
1052
|
+
strike_price_field_name: str
|
|
1053
|
+
Specifies name of the field, which carries the strike price of the option.
|
|
1054
|
+
Default: empty
|
|
1055
|
+
days_in_year: int
|
|
1056
|
+
Specifies number of days in a year (say, 365 or 252 (business days, etc.).
|
|
1057
|
+
Used with DAYS_TILL_EXPIRATION parameter to compute the fractional years till expiration.
|
|
1058
|
+
Default: 365
|
|
1059
|
+
days_till_expiration_field_name: str
|
|
1060
|
+
Specifies name of the field, which carries number of days till expiration of the option.
|
|
1061
|
+
Default: empty
|
|
1062
|
+
expiration_date_field_name: str
|
|
1063
|
+
Specifies name of the field, which carries the expiration date of the option, in YYYYMMDD format.
|
|
1064
|
+
Default: empty
|
|
1065
|
+
|
|
1066
|
+
See also
|
|
1067
|
+
--------
|
|
1068
|
+
**OPTION_PRICE** OneTick event processor
|
|
1069
|
+
|
|
1070
|
+
Examples
|
|
1071
|
+
---------
|
|
1072
|
+
Black–Scholes with parameters passed through symbol params and calculated delta:
|
|
1073
|
+
|
|
1074
|
+
>>> symbol = otp.Tick(SYMBOL_NAME='SYMB')
|
|
1075
|
+
>>> symbol['OPTION_TYPE'] = 'CALL'
|
|
1076
|
+
>>> symbol['STRIKE_PRICE'] = 100.0
|
|
1077
|
+
>>> symbol['DAYS_TILL_EXPIRATION'] = 30
|
|
1078
|
+
>>> symbol['VOLATILITY'] = 0.25
|
|
1079
|
+
>>> symbol['INTEREST_RATE'] = 0.05
|
|
1080
|
+
>>> data = otp.Ticks(PRICE=[100.7, 101.1, 99.5], symbol=symbol)
|
|
1081
|
+
>>> data = otp.agg.option_price(compute_delta=True).apply(data)
|
|
1082
|
+
>>> otp.run(data)['SYMB']
|
|
1083
|
+
Time VALUE DELTA
|
|
1084
|
+
0 2003-12-04 2.800999 0.50927
|
|
1085
|
+
>>> data.schema
|
|
1086
|
+
{'VALUE': <class 'float'>, 'DELTA': <class 'float'>}
|
|
1087
|
+
|
|
1088
|
+
Cox-Ross-Rubinstein with parameters passed through fields:
|
|
1089
|
+
|
|
1090
|
+
>>> data = otp.Ticks(
|
|
1091
|
+
... PRICE=[100.7, 101.1, 99.5],
|
|
1092
|
+
... OPTION_TYPE=['CALL']*3,
|
|
1093
|
+
... STRIKE_PRICE=[100.0]*3,
|
|
1094
|
+
... DAYS_TILL_EXPIRATION=[30]*3,
|
|
1095
|
+
... VOLATILITY=[0.25]*3,
|
|
1096
|
+
... INTEREST_RATE=[0.05]*3,
|
|
1097
|
+
... )
|
|
1098
|
+
>>> data = otp.agg.option_price(
|
|
1099
|
+
... compute_model='CRR',
|
|
1100
|
+
... number_of_steps=5,
|
|
1101
|
+
... option_type_field_name='OPTION_TYPE',
|
|
1102
|
+
... strike_price_field_name='STRIKE_PRICE',
|
|
1103
|
+
... days_till_expiration_field_name='DAYS_TILL_EXPIRATION',
|
|
1104
|
+
... volatility_field_name='VOLATILITY',
|
|
1105
|
+
... interest_rate_field_name='INTEREST_RATE',
|
|
1106
|
+
... ).apply(data)
|
|
1107
|
+
>>> otp.run(data)
|
|
1108
|
+
Time VALUE
|
|
1109
|
+
0 2003-12-04 2.937537
|
|
1110
|
+
|
|
1111
|
+
Black–Scholes with some parameters passed through parameters:
|
|
1112
|
+
|
|
1113
|
+
>>> data = otp.Ticks(
|
|
1114
|
+
... PRICE=[100.7, 101.1, 99.5],
|
|
1115
|
+
... OPTION_TYPE=['CALL']*3,
|
|
1116
|
+
... STRIKE_PRICE=[100.0]*3,
|
|
1117
|
+
... DAYS_TILL_EXPIRATION=[30]*3,
|
|
1118
|
+
... )
|
|
1119
|
+
>>> data = otp.agg.option_price(
|
|
1120
|
+
... option_type_field_name='OPTION_TYPE',
|
|
1121
|
+
... strike_price_field_name='STRIKE_PRICE',
|
|
1122
|
+
... days_till_expiration_field_name='DAYS_TILL_EXPIRATION',
|
|
1123
|
+
... volatility=0.25,
|
|
1124
|
+
... interest_rate=0.05,
|
|
1125
|
+
... ).apply(data)
|
|
1126
|
+
>>> otp.run(data)
|
|
1127
|
+
Time VALUE
|
|
1128
|
+
0 2003-12-04 2.800999
|
|
1129
|
+
|
|
1130
|
+
To compute values for each tick in a series, set ``bucket_interval=1`` and ``bucket_units='ticks'``
|
|
1131
|
+
|
|
1132
|
+
>>> data = otp.Ticks(
|
|
1133
|
+
... PRICE=[110.0, 101.0, 112.0],
|
|
1134
|
+
... OPTION_TYPE=["CALL"]*3,
|
|
1135
|
+
... STRIKE_PRICE=[110.0]*3,
|
|
1136
|
+
... DAYS_TILL_EXPIRATION=[30]*3,
|
|
1137
|
+
... VOLATILITY=[0.2]*3,
|
|
1138
|
+
... INTEREST_RATE=[0.05]*3
|
|
1139
|
+
... )
|
|
1140
|
+
>>> data = otp.agg.option_price(
|
|
1141
|
+
... option_type_field_name='OPTION_TYPE',
|
|
1142
|
+
... strike_price_field_name='STRIKE_PRICE',
|
|
1143
|
+
... days_till_expiration_field_name='DAYS_TILL_EXPIRATION',
|
|
1144
|
+
... volatility_field_name='VOLATILITY',
|
|
1145
|
+
... interest_rate_field_name='INTEREST_RATE',
|
|
1146
|
+
... bucket_interval=1,
|
|
1147
|
+
... bucket_units='ticks',
|
|
1148
|
+
... ).apply(data)
|
|
1149
|
+
>>> otp.run(data)
|
|
1150
|
+
Time VALUE
|
|
1151
|
+
0 2003-12-01 00:00:00.000 2.742714
|
|
1152
|
+
1 2003-12-01 00:00:00.001 0.212927
|
|
1153
|
+
2 2003-12-01 00:00:00.002 3.945447
|
|
1154
|
+
|
|
1155
|
+
Usage with the ``.agg()`` method (on the latest OneTick builds).
|
|
1156
|
+
|
|
1157
|
+
.. testcode::
|
|
1158
|
+
:skipif: not otp.compatibility.is_supported_agg_option_price()
|
|
1159
|
+
|
|
1160
|
+
data = otp.Ticks(
|
|
1161
|
+
PRICE=[100.7, 101.1, 99.5],
|
|
1162
|
+
OPTION_TYPE=['CALL']*3,
|
|
1163
|
+
STRIKE_PRICE=[100.0]*3,
|
|
1164
|
+
DAYS_TILL_EXPIRATION=[30]*3,
|
|
1165
|
+
)
|
|
1166
|
+
data = data.agg({
|
|
1167
|
+
'RESULT': otp.agg.option_price(
|
|
1168
|
+
option_type_field_name='OPTION_TYPE',
|
|
1169
|
+
strike_price_field_name='STRIKE_PRICE',
|
|
1170
|
+
days_till_expiration_field_name='DAYS_TILL_EXPIRATION',
|
|
1171
|
+
volatility=0.25,
|
|
1172
|
+
interest_rate=0.05,
|
|
1173
|
+
)
|
|
1174
|
+
})
|
|
1175
|
+
df = otp.run(data)
|
|
1176
|
+
print(df)
|
|
1177
|
+
|
|
1178
|
+
.. testoutput::
|
|
1179
|
+
|
|
1180
|
+
Time RESULT
|
|
1181
|
+
0 2003-12-04 2.800999
|
|
1182
|
+
|
|
1183
|
+
The following examples show results for different cases of option price calculation.
|
|
1184
|
+
Results are compared with two online calculators:
|
|
1185
|
+
`Drexel University <https://www.math.drexel.edu/~pg/fin/VanillaCalculator.html>`_ (DU) and
|
|
1186
|
+
`Wolfram Alpha <https://www.wolframalpha.com/input?i=black+scholes>`_ (WA).
|
|
1187
|
+
|
|
1188
|
+
Call option, strike price 110.0, underlying price 120.0, volatility 20.0%, interest 5.0%, expiring in 15 days.
|
|
1189
|
+
|
|
1190
|
+
>>> data = {
|
|
1191
|
+
... "PRICE": 120.,
|
|
1192
|
+
... "OPTION_TYPE": "call",
|
|
1193
|
+
... "STRIKE_PRICE": 110.,
|
|
1194
|
+
... "DAYS_TILL_EXPIRATION": 15,
|
|
1195
|
+
... "VOLATILITY": 0.2,
|
|
1196
|
+
... "INTEREST_RATE": 0.05,
|
|
1197
|
+
... }
|
|
1198
|
+
>>> data = otp.Tick(**data)
|
|
1199
|
+
>>> data = otp.agg.option_price(
|
|
1200
|
+
... option_type_field_name='OPTION_TYPE',
|
|
1201
|
+
... strike_price_field_name='STRIKE_PRICE',
|
|
1202
|
+
... days_till_expiration_field_name='DAYS_TILL_EXPIRATION',
|
|
1203
|
+
... volatility_field_name='VOLATILITY',
|
|
1204
|
+
... interest_rate_field_name='INTEREST_RATE',
|
|
1205
|
+
... compute_delta=True,
|
|
1206
|
+
... compute_gamma=True,
|
|
1207
|
+
... compute_theta=True,
|
|
1208
|
+
... compute_vega=True,
|
|
1209
|
+
... compute_rho=True
|
|
1210
|
+
... ).apply(data)
|
|
1211
|
+
>>> res = otp.run(data).drop("Time", axis=1)
|
|
1212
|
+
>>> for key, val in res.to_dict(orient='list').items():
|
|
1213
|
+
... print(f"{key}={val[0]}")
|
|
1214
|
+
VALUE=10.248742578738629
|
|
1215
|
+
DELTA=0.9866897658932824
|
|
1216
|
+
GAMMA=0.007022082258701294
|
|
1217
|
+
THETA=-7.430061156928735
|
|
1218
|
+
VEGA=0.8311067221257422
|
|
1219
|
+
RHO=4.444686136785831
|
|
1220
|
+
|
|
1221
|
+
.. csv-table:: Benchmark comparison
|
|
1222
|
+
:widths: 10, 25, 25, 10
|
|
1223
|
+
:header: Field, OneTick, DU benchmark, WA benchmark
|
|
1224
|
+
|
|
1225
|
+
VALUE, 10.248742578738629, 10.248742577611323400, 10.249
|
|
1226
|
+
DELTA, 0.9866897658932824, 0.986689766547165200, 0.987
|
|
1227
|
+
GAMMA, 0.007022082258701294, 0.007022082258701300, 0.007
|
|
1228
|
+
THETA, -7.430061156928735, -7.430061160908399600, -7.430
|
|
1229
|
+
VEGA, 0.8311067221257422, 0.831106722125743000, 0.831
|
|
1230
|
+
RHO, 4.444686136785831, 4.444686140056785400, 4.445
|
|
1231
|
+
|
|
1232
|
+
Put option, strike price 110.0, underlying price 120.0, volatility 20.0%, interest 5.0%, expiring in 15 days.
|
|
1233
|
+
|
|
1234
|
+
.. testcode::
|
|
1235
|
+
:skipif: not otp.compatibility.is_option_price_theta_value_changed()
|
|
1236
|
+
|
|
1237
|
+
data = {
|
|
1238
|
+
"PRICE": 120.,
|
|
1239
|
+
"OPTION_TYPE": "put",
|
|
1240
|
+
"STRIKE_PRICE": 110.,
|
|
1241
|
+
"DAYS_TILL_EXPIRATION": 15,
|
|
1242
|
+
"VOLATILITY": 0.2,
|
|
1243
|
+
"INTEREST_RATE": 0.05,
|
|
1244
|
+
}
|
|
1245
|
+
data = otp.Tick(**data)
|
|
1246
|
+
data = otp.agg.option_price(
|
|
1247
|
+
option_type_field_name='OPTION_TYPE',
|
|
1248
|
+
strike_price_field_name='STRIKE_PRICE',
|
|
1249
|
+
days_till_expiration_field_name='DAYS_TILL_EXPIRATION',
|
|
1250
|
+
volatility_field_name='VOLATILITY',
|
|
1251
|
+
interest_rate_field_name='INTEREST_RATE',
|
|
1252
|
+
compute_delta=True,
|
|
1253
|
+
compute_gamma=True,
|
|
1254
|
+
compute_theta=True,
|
|
1255
|
+
compute_vega=True,
|
|
1256
|
+
compute_rho=True
|
|
1257
|
+
).apply(data)
|
|
1258
|
+
res = otp.run(data).drop("Time", axis=1)
|
|
1259
|
+
for key, val in res.to_dict(orient='list').items():
|
|
1260
|
+
print(f"{key}={val[0]:.14f}")
|
|
1261
|
+
|
|
1262
|
+
.. testoutput::
|
|
1263
|
+
|
|
1264
|
+
VALUE=0.02294724243400
|
|
1265
|
+
DELTA=-0.01331023410672
|
|
1266
|
+
GAMMA=0.00702208225870
|
|
1267
|
+
THETA=-1.94135092374397
|
|
1268
|
+
VEGA=0.83110672212574
|
|
1269
|
+
RHO=-0.06658254802357
|
|
1270
|
+
|
|
1271
|
+
.. csv-table:: Benchmark comparison
|
|
1272
|
+
:widths: 10, 25, 25, 10
|
|
1273
|
+
:header: Field, OneTick, DU benchmark, WA benchmark
|
|
1274
|
+
|
|
1275
|
+
VALUE, 0.022947242433995818, 0.022947241306682900, 0.023
|
|
1276
|
+
DELTA, -0.013310234106717611, -0.013310233452834800, -0.013
|
|
1277
|
+
GAMMA, 0.007022082258701294, 0.007022082258701300, 0.007
|
|
1278
|
+
THETA, -1.94135092374397, -1.941350927723632000, -1.941
|
|
1279
|
+
VEGA, 0.8311067221257422, 0.831106722125743000, 0.831
|
|
1280
|
+
RHO, -0.06658254802356636, -0.066582544752611000, -0.067
|
|
1281
|
+
|
|
1282
|
+
|
|
1283
|
+
Put option, strike price 90.0, underlying price 80.0, volatility 30.0%, interest 8.0%, expiring in 20 days.
|
|
1284
|
+
|
|
1285
|
+
.. testcode::
|
|
1286
|
+
:skipif: not otp.compatibility.is_option_price_theta_value_changed()
|
|
1287
|
+
|
|
1288
|
+
data = {
|
|
1289
|
+
"PRICE": 80.,
|
|
1290
|
+
"OPTION_TYPE": "put",
|
|
1291
|
+
"STRIKE_PRICE": 90.,
|
|
1292
|
+
"DAYS_TILL_EXPIRATION": 20,
|
|
1293
|
+
"VOLATILITY": 0.3,
|
|
1294
|
+
"INTEREST_RATE": 0.08,
|
|
1295
|
+
}
|
|
1296
|
+
data = otp.Tick(**data)
|
|
1297
|
+
data = otp.agg.option_price(
|
|
1298
|
+
option_type_field_name='OPTION_TYPE',
|
|
1299
|
+
strike_price_field_name='STRIKE_PRICE',
|
|
1300
|
+
days_till_expiration_field_name='DAYS_TILL_EXPIRATION',
|
|
1301
|
+
volatility_field_name='VOLATILITY',
|
|
1302
|
+
interest_rate_field_name='INTEREST_RATE',
|
|
1303
|
+
compute_delta=True,
|
|
1304
|
+
compute_gamma=True,
|
|
1305
|
+
compute_theta=True,
|
|
1306
|
+
compute_vega=True,
|
|
1307
|
+
compute_rho=True
|
|
1308
|
+
).apply(data)
|
|
1309
|
+
res = otp.run(data).drop("Time", axis=1)
|
|
1310
|
+
for key, val in res.to_dict(orient='list').items():
|
|
1311
|
+
print(f"{key}={val[0]}")
|
|
1312
|
+
|
|
1313
|
+
.. testoutput::
|
|
1314
|
+
|
|
1315
|
+
VALUE=9.739720671039635
|
|
1316
|
+
DELTA=-0.9429118423759162
|
|
1317
|
+
GAMMA=0.020391626464263516
|
|
1318
|
+
THETA=0.9410250231811439
|
|
1319
|
+
VEGA=2.1453108389800515
|
|
1320
|
+
RHO=-4.666995510197969
|
|
1321
|
+
|
|
1322
|
+
.. csv-table:: Benchmark comparison
|
|
1323
|
+
:widths: 10, 25, 25, 10
|
|
1324
|
+
:header: Field, OneTick, DU benchmark, WA benchmark
|
|
1325
|
+
|
|
1326
|
+
VALUE, 9.739720671039635, 9.739720664487278600, 9.740
|
|
1327
|
+
DELTA, -0.9429118423759162, -0.942911845180447200, -0.943
|
|
1328
|
+
GAMMA, 0.020391626464263516, 0.020391626464263600, 0.020
|
|
1329
|
+
THETA, 0.9410250231811439, 0.941025040605956600, 0.941
|
|
1330
|
+
VEGA, 2.1453108389800515, 2.145310838980050700, 2.145
|
|
1331
|
+
RHO, -4.666995510197969, -4.666995522132770800, -4.667
|
|
1332
|
+
|
|
1333
|
+
Call option, strike price 90.0, underlying price 80.0, volatility 30.0%, interest 8.0%, expiring in 20 days.
|
|
1334
|
+
|
|
1335
|
+
>>> data = {
|
|
1336
|
+
... "PRICE": 80.,
|
|
1337
|
+
... "OPTION_TYPE": "call",
|
|
1338
|
+
... "STRIKE_PRICE": 90.,
|
|
1339
|
+
... "DAYS_TILL_EXPIRATION": 20,
|
|
1340
|
+
... "VOLATILITY": 0.3,
|
|
1341
|
+
... "INTEREST_RATE": 0.08,
|
|
1342
|
+
... }
|
|
1343
|
+
>>> data = otp.Tick(**data)
|
|
1344
|
+
>>> data = otp.agg.option_price(
|
|
1345
|
+
... option_type_field_name='OPTION_TYPE',
|
|
1346
|
+
... strike_price_field_name='STRIKE_PRICE',
|
|
1347
|
+
... days_till_expiration_field_name='DAYS_TILL_EXPIRATION',
|
|
1348
|
+
... volatility_field_name='VOLATILITY',
|
|
1349
|
+
... interest_rate_field_name='INTEREST_RATE',
|
|
1350
|
+
... compute_delta=True,
|
|
1351
|
+
... compute_gamma=True,
|
|
1352
|
+
... compute_theta=True,
|
|
1353
|
+
... compute_vega=True,
|
|
1354
|
+
... compute_rho=True
|
|
1355
|
+
... ).apply(data)
|
|
1356
|
+
>>> res = otp.run(data).drop("Time", axis=1)
|
|
1357
|
+
>>> for key, val in res.to_dict(orient='list').items():
|
|
1358
|
+
... print(f"{key}={val[0]:.13f}")
|
|
1359
|
+
VALUE=0.1333777785229
|
|
1360
|
+
DELTA=0.0570881576241
|
|
1361
|
+
GAMMA=0.0203916264643
|
|
1362
|
+
THETA=-6.2274824082202
|
|
1363
|
+
VEGA=2.1453108389801
|
|
1364
|
+
RHO=0.2429410866523
|
|
1365
|
+
|
|
1366
|
+
.. csv-table:: Benchmark comparison
|
|
1367
|
+
:widths: 10, 25, 25, 10
|
|
1368
|
+
:header: Field, OneTick, DU benchmark, WA benchmark
|
|
1369
|
+
|
|
1370
|
+
VALUE, 0.13337777852292199, 0.133377771970562400, 0.133
|
|
1371
|
+
DELTA, 0.05708815762408384, 0.057088154819552600, 0.057
|
|
1372
|
+
GAMMA, 0.020391626464263516, 0.020391626464263600, 0.020
|
|
1373
|
+
THETA, -6.227482408220195, -6.227482390795381800, -6.227
|
|
1374
|
+
VEGA, 2.1453108389800515, 2.145310838980050700, 2.145
|
|
1375
|
+
RHO, 0.2429410866522622, 0.242941074717460500, 0.243
|
|
1376
|
+
|
|
1377
|
+
|
|
1378
|
+
Call option, strike price 140.0, underlying price 150.0, volatility 60.0%, interest 7.0%, expiring in 10 days.
|
|
1379
|
+
|
|
1380
|
+
>>> data = {
|
|
1381
|
+
... "PRICE": 150.,
|
|
1382
|
+
... "OPTION_TYPE": "call",
|
|
1383
|
+
... "STRIKE_PRICE": 140.,
|
|
1384
|
+
... "DAYS_TILL_EXPIRATION": 10,
|
|
1385
|
+
... "VOLATILITY": 0.6,
|
|
1386
|
+
... "INTEREST_RATE": 0.07,
|
|
1387
|
+
... }
|
|
1388
|
+
>>> data = otp.Tick(**data)
|
|
1389
|
+
>>> data = otp.agg.option_price(
|
|
1390
|
+
... option_type_field_name='OPTION_TYPE',
|
|
1391
|
+
... strike_price_field_name='STRIKE_PRICE',
|
|
1392
|
+
... days_till_expiration_field_name='DAYS_TILL_EXPIRATION',
|
|
1393
|
+
... volatility_field_name='VOLATILITY',
|
|
1394
|
+
... interest_rate_field_name='INTEREST_RATE',
|
|
1395
|
+
... compute_delta=True,
|
|
1396
|
+
... compute_gamma=True,
|
|
1397
|
+
... compute_theta=True,
|
|
1398
|
+
... compute_vega=True,
|
|
1399
|
+
... compute_rho=True
|
|
1400
|
+
... ).apply(data)
|
|
1401
|
+
>>> res = otp.run(data).drop("Time", axis=1)
|
|
1402
|
+
>>> for key, val in res.to_dict(orient='list').items():
|
|
1403
|
+
... print(f"{key}={val[0]:.13f}")
|
|
1404
|
+
VALUE=12.2728332229748
|
|
1405
|
+
DELTA=0.7774682547236
|
|
1406
|
+
GAMMA=0.0200066930955
|
|
1407
|
+
THETA=-88.3314253858302
|
|
1408
|
+
VEGA=7.3997358024512
|
|
1409
|
+
RHO=2.8588330133030
|
|
1410
|
+
|
|
1411
|
+
.. csv-table:: Benchmark comparison
|
|
1412
|
+
:widths: 10, 25, 25, 10
|
|
1413
|
+
:header: Field, OneTick, DU benchmark, WA benchmark
|
|
1414
|
+
|
|
1415
|
+
VALUE, 12.272833222974782, 12.272833124496244700, 12.27
|
|
1416
|
+
DELTA, 0.7774682547235652, 0.777468265655730700, 0.777
|
|
1417
|
+
GAMMA, 0.020006693095516285, 0.020006693095516300, 0.020
|
|
1418
|
+
THETA, -88.33142538583016, -88.331425507511386000, -88.331
|
|
1419
|
+
VEGA, 7.399735802451228, 7.399735802451227600, 7.400
|
|
1420
|
+
RHO, 2.858833013303013, 2.858833060927763500, 2.859
|
|
1421
|
+
|
|
1422
|
+
|
|
1423
|
+
Put option, strike price 140.0, underlying price 150.0, volatility 60.0%, interest 7.0%, expiring in 10 days.
|
|
1424
|
+
|
|
1425
|
+
.. testcode::
|
|
1426
|
+
:skipif: not otp.compatibility.is_option_price_theta_value_changed()
|
|
1427
|
+
|
|
1428
|
+
data = {
|
|
1429
|
+
"PRICE": 150.,
|
|
1430
|
+
"OPTION_TYPE": "put",
|
|
1431
|
+
"STRIKE_PRICE": 140.,
|
|
1432
|
+
"DAYS_TILL_EXPIRATION": 10,
|
|
1433
|
+
"VOLATILITY": 0.6,
|
|
1434
|
+
"INTEREST_RATE": 0.07,
|
|
1435
|
+
}
|
|
1436
|
+
data = otp.Tick(**data)
|
|
1437
|
+
data = otp.agg.option_price(
|
|
1438
|
+
option_type_field_name='OPTION_TYPE',
|
|
1439
|
+
strike_price_field_name='STRIKE_PRICE',
|
|
1440
|
+
days_till_expiration_field_name='DAYS_TILL_EXPIRATION',
|
|
1441
|
+
volatility_field_name='VOLATILITY',
|
|
1442
|
+
interest_rate_field_name='INTEREST_RATE',
|
|
1443
|
+
compute_delta=True,
|
|
1444
|
+
compute_gamma=True,
|
|
1445
|
+
compute_theta=True,
|
|
1446
|
+
compute_vega=True,
|
|
1447
|
+
compute_rho=True).apply(data)
|
|
1448
|
+
res = otp.run(data).drop("Time", axis=1)
|
|
1449
|
+
for key, val in res.to_dict(orient='list').items():
|
|
1450
|
+
print(f"{key}={val[0]:.13f}")
|
|
1451
|
+
|
|
1452
|
+
.. testoutput::
|
|
1453
|
+
|
|
1454
|
+
VALUE=2.0045973669685
|
|
1455
|
+
DELTA=-0.2225317452764
|
|
1456
|
+
GAMMA=0.0200066930955
|
|
1457
|
+
THETA=-78.5502018957506
|
|
1458
|
+
VEGA=7.3997358024512
|
|
1459
|
+
RHO=-0.9694344974913
|
|
1460
|
+
|
|
1461
|
+
.. csv-table:: Benchmark comparison
|
|
1462
|
+
:widths: 10, 25, 25, 10
|
|
1463
|
+
:header: Field, OneTick, DU benchmark, WA benchmark
|
|
1464
|
+
|
|
1465
|
+
VALUE, 2.0045973669685395, 2.004597268490016500, 2.00
|
|
1466
|
+
DELTA, -0.22253174527643482, -0.222531734344269000, -0.223
|
|
1467
|
+
GAMMA, 0.020006693095516285, 0.020006693095516300, 0.020
|
|
1468
|
+
THETA, -78.5502018957506, -78.550202017431814100, -78.550
|
|
1469
|
+
VEGA, 7.399735802451228, 7.399735802451227600, 7.400
|
|
1470
|
+
RHO, -0.9694344974913363, -0.969434449866586000, -0.969
|
|
1471
|
+
|
|
1472
|
+
"""
|
|
1473
|
+
|
|
1474
|
+
return OptionPrice(*args, **kwargs)
|
|
1475
|
+
|
|
1476
|
+
|
|
1477
|
+
@docstring(parameters=[
|
|
1478
|
+
_bucket_interval_doc,
|
|
1479
|
+
_bucket_units_doc,
|
|
1480
|
+
_bucket_time_doc,
|
|
1481
|
+
_bucket_end_condition_doc,
|
|
1482
|
+
_boundary_tick_bucket_doc,
|
|
1483
|
+
_group_by_doc,
|
|
1484
|
+
_groups_to_display_doc,
|
|
1485
|
+
_end_condition_per_group_doc,
|
|
1486
|
+
])
|
|
1487
|
+
def ranking(*args, **kwargs):
|
|
1488
|
+
"""
|
|
1489
|
+
Ranking **running** aggregation.
|
|
1490
|
+
|
|
1491
|
+
Sorts a series of ticks over a bucket interval
|
|
1492
|
+
using a specified set of tick fields specified in ``rank_by``
|
|
1493
|
+
and adds a new field ``RANKING``
|
|
1494
|
+
with the position of the tick in the sort order
|
|
1495
|
+
or the percentage of ticks with values less than (or equal) to the value of the tick.
|
|
1496
|
+
|
|
1497
|
+
Does not change the order of the ticks.
|
|
1498
|
+
|
|
1499
|
+
See also
|
|
1500
|
+
--------
|
|
1501
|
+
**RANKING** OneTick event processor
|
|
1502
|
+
|
|
1503
|
+
Parameters
|
|
1504
|
+
----------
|
|
1505
|
+
rank_by: str or list or dict
|
|
1506
|
+
Set of fields to sort by.
|
|
1507
|
+
Can be one field specified by string, list of fields or dictionary with field names
|
|
1508
|
+
as keys and ``asc`` or ``desc`` string literals as values. Latter allows to specify
|
|
1509
|
+
sorting direction. Default direction is ``desc``.
|
|
1510
|
+
show_rank_as: str
|
|
1511
|
+
|
|
1512
|
+
- ``order``: calculate number that represents the position of the tick in the sort order
|
|
1513
|
+
- ``percent_le_values``: calculate the percentage of ticks that have higher or equal value\
|
|
1514
|
+
of the position in the sort order, relative to the tick
|
|
1515
|
+
- ``percent_lt_values``: calculate the percentage of ticks that have higher value\
|
|
1516
|
+
of the position in the sort order, relative to the tick
|
|
1517
|
+
- ``percentile_standard``: calculate Percentile Rank of the tick in the sort order.
|
|
1518
|
+
include_tick: bool, default=False
|
|
1519
|
+
Specifies whether the current tick should be included in calculations
|
|
1520
|
+
if ``show_rank_as`` is ``percent_lt_values`` or ``percentile_standard``.
|
|
1521
|
+
|
|
1522
|
+
Examples
|
|
1523
|
+
--------
|
|
1524
|
+
>>> t = otp.Ticks({'A': [1, 2, 3]})
|
|
1525
|
+
>>> t = t.ranking('A')
|
|
1526
|
+
>>> otp.run(t)
|
|
1527
|
+
Time A RANKING
|
|
1528
|
+
0 2003-12-01 00:00:00.000 1 3
|
|
1529
|
+
1 2003-12-01 00:00:00.001 2 2
|
|
1530
|
+
2 2003-12-01 00:00:00.002 3 1
|
|
1531
|
+
|
|
1532
|
+
>>> t = otp.Ticks({'A': [1, 2, 3]})
|
|
1533
|
+
>>> t = t.ranking({'A': 'asc'})
|
|
1534
|
+
>>> otp.run(t)
|
|
1535
|
+
Time A RANKING
|
|
1536
|
+
0 2003-12-01 00:00:00.000 1 1
|
|
1537
|
+
1 2003-12-01 00:00:00.001 2 2
|
|
1538
|
+
2 2003-12-01 00:00:00.002 3 3
|
|
1539
|
+
|
|
1540
|
+
>>> t = otp.Ticks({'A': [1, 2, 2, 3, 2, 1]})
|
|
1541
|
+
>>> otp.run(t.ranking({'A': 'asc'}, show_rank_as='percent_lt_values', include_tick=True))
|
|
1542
|
+
Time A RANKING
|
|
1543
|
+
0 2003-12-01 00:00:00.000 1 66.666667
|
|
1544
|
+
1 2003-12-01 00:00:00.001 2 16.666667
|
|
1545
|
+
2 2003-12-01 00:00:00.002 2 16.666667
|
|
1546
|
+
3 2003-12-01 00:00:00.003 3 0.000000
|
|
1547
|
+
4 2003-12-01 00:00:00.004 2 16.666667
|
|
1548
|
+
5 2003-12-01 00:00:00.005 1 66.666667
|
|
1549
|
+
|
|
1550
|
+
>>> otp.run(t.ranking({'A': 'asc'}, show_rank_as='percent_lt_values', include_tick=False))
|
|
1551
|
+
Time A RANKING
|
|
1552
|
+
0 2003-12-01 00:00:00.000 1 80.0
|
|
1553
|
+
1 2003-12-01 00:00:00.001 2 20.0
|
|
1554
|
+
2 2003-12-01 00:00:00.002 2 20.0
|
|
1555
|
+
3 2003-12-01 00:00:00.003 3 0.0
|
|
1556
|
+
4 2003-12-01 00:00:00.004 2 20.0
|
|
1557
|
+
5 2003-12-01 00:00:00.005 1 80.0
|
|
1558
|
+
"""
|
|
1559
|
+
return Ranking(*args, **kwargs)
|
|
1560
|
+
|
|
1561
|
+
|
|
1562
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
1563
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
1564
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc])
|
|
1565
|
+
def variance(*args, **kwargs):
|
|
1566
|
+
"""
|
|
1567
|
+
Implement variance aggregation
|
|
1568
|
+
|
|
1569
|
+
Parameters
|
|
1570
|
+
----------
|
|
1571
|
+
biased: bool
|
|
1572
|
+
Switches between biased and unbiased variance calculation.
|
|
1573
|
+
|
|
1574
|
+
See also
|
|
1575
|
+
--------
|
|
1576
|
+
**VARIANCE** OneTick event processor
|
|
1577
|
+
|
|
1578
|
+
Examples
|
|
1579
|
+
--------
|
|
1580
|
+
|
|
1581
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 3, 4])
|
|
1582
|
+
>>> data = data.agg({'RESULT': otp.agg.variance('X', biased=False)})
|
|
1583
|
+
>>> otp.run(data)
|
|
1584
|
+
Time RESULT
|
|
1585
|
+
0 2003-12-04 1.3
|
|
1586
|
+
|
|
1587
|
+
>>> data = otp.Ticks(X=[1, 2, 3, 3, 4])
|
|
1588
|
+
>>> data = data.agg({'RESULT': otp.agg.variance('X', biased=True)})
|
|
1589
|
+
>>> otp.run(data)
|
|
1590
|
+
Time RESULT
|
|
1591
|
+
0 2003-12-04 1.04
|
|
1592
|
+
"""
|
|
1593
|
+
return Variance(*args, **kwargs)
|
|
1594
|
+
|
|
1595
|
+
|
|
1596
|
+
@docstring(parameters=[
|
|
1597
|
+
_running_doc,
|
|
1598
|
+
_bucket_interval_doc,
|
|
1599
|
+
_bucket_units_doc,
|
|
1600
|
+
_bucket_time_doc,
|
|
1601
|
+
_bucket_end_condition_doc,
|
|
1602
|
+
_boundary_tick_bucket_doc,
|
|
1603
|
+
_group_by_doc,
|
|
1604
|
+
_groups_to_display_doc,
|
|
1605
|
+
_end_condition_per_group_doc,
|
|
1606
|
+
])
|
|
1607
|
+
def percentile(*args, **kwargs):
|
|
1608
|
+
"""
|
|
1609
|
+
Percentile **running** aggregation.
|
|
1610
|
+
|
|
1611
|
+
For each bucket, propagates its ``n-1`` ``n-quantiles`` where a comparison between ticks is done
|
|
1612
|
+
using a specified set of tick fields. A new field (``QUANTILE``) with the quantile number is added.
|
|
1613
|
+
|
|
1614
|
+
See also
|
|
1615
|
+
--------
|
|
1616
|
+
**PERCENTILE** OneTick event processor
|
|
1617
|
+
|
|
1618
|
+
Parameters
|
|
1619
|
+
----------
|
|
1620
|
+
number_of_quantiles: int
|
|
1621
|
+
Specifies the number ``n`` of quantiles. Setting it to 2 will propagate only one tick - the median.
|
|
1622
|
+
|
|
1623
|
+
Default: 2
|
|
1624
|
+
input_field_names: List[Union[Union[str, onetick.py.Column], Tuple[Union[str, onetick.py.Column], str]]]
|
|
1625
|
+
List of numeric field names to run aggregation on.
|
|
1626
|
+
You can use as list elements either string column name, either :py:class:`Columns <onetick.py.Column>`.
|
|
1627
|
+
|
|
1628
|
+
You can change default comparison order (``desc``) for the field,
|
|
1629
|
+
by passing a tuple of column name and comparison order (``desc`` or ``asc``) instead column name.
|
|
1630
|
+
output_field_names: Optional[List[str]]
|
|
1631
|
+
Output columns name in the same order as columns from ``input_field_names``
|
|
1632
|
+
|
|
1633
|
+
``output_field_names`` and ``input_field_names`` must have the same number of fields.
|
|
1634
|
+
|
|
1635
|
+
If not set, ``output_field_names`` will be equal to ``input_field_names``.
|
|
1636
|
+
|
|
1637
|
+
Examples
|
|
1638
|
+
--------
|
|
1639
|
+
>>> t = otp.Ticks({'A': [1, 2, 3, 4]})
|
|
1640
|
+
>>> t = t.percentile(['A'])
|
|
1641
|
+
>>> otp.run(t)
|
|
1642
|
+
Time A QUANTILE
|
|
1643
|
+
0 2003-12-04 2 1
|
|
1644
|
+
|
|
1645
|
+
You can also pass column:
|
|
1646
|
+
|
|
1647
|
+
>>> t = otp.Ticks({'A': [1, 2, 3, 4]})
|
|
1648
|
+
>>> t = t.percentile([t['A']])
|
|
1649
|
+
>>> otp.run(t)
|
|
1650
|
+
Time A QUANTILE
|
|
1651
|
+
0 2003-12-04 2 1
|
|
1652
|
+
|
|
1653
|
+
Change number of quantiles:
|
|
1654
|
+
|
|
1655
|
+
>>> t = otp.Ticks({'A': [1, 2, 3, 4]})
|
|
1656
|
+
>>> t = t.percentile(['A'], number_of_quantiles=3)
|
|
1657
|
+
>>> otp.run(t)
|
|
1658
|
+
Time A QUANTILE
|
|
1659
|
+
0 2003-12-04 3 1
|
|
1660
|
+
1 2003-12-04 2 2
|
|
1661
|
+
|
|
1662
|
+
Or change default comparison order:
|
|
1663
|
+
|
|
1664
|
+
>>> t = otp.Ticks({'A': [1, 2, 3, 4]})
|
|
1665
|
+
>>> t = t.percentile([('A', 'asc')], number_of_quantiles=3)
|
|
1666
|
+
>>> otp.run(t)
|
|
1667
|
+
Time A QUANTILE
|
|
1668
|
+
0 2003-12-04 2 1
|
|
1669
|
+
1 2003-12-04 3 2
|
|
1670
|
+
|
|
1671
|
+
You can also change output column name via ``output_field_names`` parameter:
|
|
1672
|
+
|
|
1673
|
+
>>> t = otp.Ticks({'A': [1, 2, 3, 4]})
|
|
1674
|
+
>>> t = t.percentile(['A'], output_field_names=['B'])
|
|
1675
|
+
>>> otp.run(t)
|
|
1676
|
+
Time B QUANTILE
|
|
1677
|
+
0 2003-12-04 2 1
|
|
1678
|
+
"""
|
|
1679
|
+
return Percentile(*args, **kwargs)
|
|
1680
|
+
|
|
1681
|
+
|
|
1682
|
+
@docstring(parameters=[
|
|
1683
|
+
_running_doc,
|
|
1684
|
+
_bucket_interval_doc,
|
|
1685
|
+
_bucket_units_doc,
|
|
1686
|
+
_bucket_time_doc,
|
|
1687
|
+
_bucket_end_condition_doc,
|
|
1688
|
+
_boundary_tick_bucket_doc,
|
|
1689
|
+
_group_by_doc,
|
|
1690
|
+
_groups_to_display_doc,
|
|
1691
|
+
_end_condition_per_group_doc,
|
|
1692
|
+
])
|
|
1693
|
+
def find_value_for_percentile(*args, **kwargs):
|
|
1694
|
+
"""
|
|
1695
|
+
For each bucket, finds the value which has percentile rank closest to ``percentile`` parameter.
|
|
1696
|
+
|
|
1697
|
+
For more details, see `Percentile rank <https://en.wikipedia.org/wiki/Percentile_rank>`_.
|
|
1698
|
+
|
|
1699
|
+
See also
|
|
1700
|
+
--------
|
|
1701
|
+
**FIND_VALUE_FOR_PERCENTILE** OneTick event processor
|
|
1702
|
+
|
|
1703
|
+
Parameters
|
|
1704
|
+
----------
|
|
1705
|
+
percentile: int
|
|
1706
|
+
Specifies the percentile number in 0-100% range
|
|
1707
|
+
for which find the value of input field that has percentile rank close to it.
|
|
1708
|
+
show_percentile_as: str
|
|
1709
|
+
* By default (when parameter is not set),
|
|
1710
|
+
the output field contains the value which has percentile rank closest to ``percentile`` parameter.
|
|
1711
|
+
* When set to *interpolated_value*, the output field contains the interpolated value of:
|
|
1712
|
+
The value above and below specified ``percentile``, or one of them if it's biggest or smallest value.
|
|
1713
|
+
* When set to *first_value_with_ge_percentile*, the output field contains
|
|
1714
|
+
the value which has greater or equal than specified ``percentile``.
|
|
1715
|
+
|
|
1716
|
+
Examples
|
|
1717
|
+
--------
|
|
1718
|
+
|
|
1719
|
+
Find interpolated value of 50% percentile rank:
|
|
1720
|
+
|
|
1721
|
+
.. testcode::
|
|
1722
|
+
:skipif: not otp.compatibility.is_find_value_for_percentile_supported()
|
|
1723
|
+
|
|
1724
|
+
t = otp.Ticks({'A': [1, 2, 3, 4]})
|
|
1725
|
+
data = t.find_value_for_percentile('A', 50, 'interpolated_value')
|
|
1726
|
+
df = otp.run(data)
|
|
1727
|
+
print(df)
|
|
1728
|
+
|
|
1729
|
+
.. testoutput::
|
|
1730
|
+
|
|
1731
|
+
Time A
|
|
1732
|
+
0 2003-12-04 2.5
|
|
1733
|
+
|
|
1734
|
+
Find first value greater or equal to 50% percentile rank:
|
|
1735
|
+
|
|
1736
|
+
.. testcode::
|
|
1737
|
+
:skipif: not otp.compatibility.is_find_value_for_percentile_supported()
|
|
1738
|
+
|
|
1739
|
+
data = t.find_value_for_percentile('A', 50, 'first_value_with_ge_percentile')
|
|
1740
|
+
df = otp.run(data)
|
|
1741
|
+
print(df)
|
|
1742
|
+
|
|
1743
|
+
.. testoutput::
|
|
1744
|
+
|
|
1745
|
+
Time A
|
|
1746
|
+
0 2003-12-04 3.0
|
|
1747
|
+
|
|
1748
|
+
Use :py:meth:`~onetick.py.Source.agg` method to apply several aggregations at the same time:
|
|
1749
|
+
|
|
1750
|
+
.. testcode::
|
|
1751
|
+
:skipif: not otp.compatibility.is_find_value_for_percentile_supported()
|
|
1752
|
+
|
|
1753
|
+
data = t.agg({
|
|
1754
|
+
'X': otp.agg.find_value_for_percentile('A', 50, 'interpolated_value'),
|
|
1755
|
+
'COUNT': otp.agg.count(),
|
|
1756
|
+
})
|
|
1757
|
+
df = otp.run(data)
|
|
1758
|
+
print(df)
|
|
1759
|
+
|
|
1760
|
+
.. testoutput::
|
|
1761
|
+
|
|
1762
|
+
Time X COUNT
|
|
1763
|
+
0 2003-12-04 2.5 4
|
|
1764
|
+
"""
|
|
1765
|
+
return FindValueForPercentile(*args, **kwargs)
|
|
1766
|
+
|
|
1767
|
+
|
|
1768
|
+
@docstring(parameters=[
|
|
1769
|
+
_decay_doc,
|
|
1770
|
+
_decay_value_type_doc,
|
|
1771
|
+
_running_doc,
|
|
1772
|
+
_bucket_interval_doc,
|
|
1773
|
+
_bucket_units_doc,
|
|
1774
|
+
_bucket_time_doc,
|
|
1775
|
+
_bucket_end_condition_doc,
|
|
1776
|
+
_boundary_tick_bucket_doc,
|
|
1777
|
+
_all_fields_doc,
|
|
1778
|
+
_group_by_doc,
|
|
1779
|
+
_groups_to_display_doc,
|
|
1780
|
+
_end_condition_per_group_doc,
|
|
1781
|
+
_time_series_type_w_doc,
|
|
1782
|
+
])
|
|
1783
|
+
def exp_w_average(*args, **kwargs):
|
|
1784
|
+
"""
|
|
1785
|
+
``EXP_W_AVERAGE`` aggregation.
|
|
1786
|
+
|
|
1787
|
+
For each bucket, computes the **exponentially weighted average** value of the specified numeric attribute.
|
|
1788
|
+
Weights of data points in a bucket decrease exponentially in the direction from the most recent tick
|
|
1789
|
+
to the most aged one, being equal to ``exp(-Lambda * N)`` for a fixed weight decay value **Lambda**,
|
|
1790
|
+
where **N** ranges over **0, 1, 2, …** as ticks in reverse order of their arrival are treated.
|
|
1791
|
+
Once the weights are known, the average is found using the formula ``sum(weight*value)/sum(weight)``,
|
|
1792
|
+
where the sum is computed across all data points.
|
|
1793
|
+
|
|
1794
|
+
See also
|
|
1795
|
+
--------
|
|
1796
|
+
**EXP_W_AVERAGE** OneTick event processor
|
|
1797
|
+
|
|
1798
|
+
Examples
|
|
1799
|
+
--------
|
|
1800
|
+
|
|
1801
|
+
Basic example
|
|
1802
|
+
|
|
1803
|
+
>>> data = otp.Ticks({'A': [1.0, 2.0, 3.0, 3.0, 4.0]})
|
|
1804
|
+
>>> data = data.exp_w_average('A', decay=2, bucket_interval=2, bucket_units='ticks')
|
|
1805
|
+
>>> otp.run(data)
|
|
1806
|
+
Time A
|
|
1807
|
+
0 2003-12-01 00:00:00.001 1.880797
|
|
1808
|
+
1 2003-12-01 00:00:00.003 2.984124
|
|
1809
|
+
2 2003-12-04 00:00:00.000 3.880797
|
|
1810
|
+
|
|
1811
|
+
You can switch to ``half_life_index`` as ``decay_value_type``
|
|
1812
|
+
|
|
1813
|
+
>>> data = otp.Ticks({'A': [1.0, 2.0, 3.0, 3.0, 4.0]})
|
|
1814
|
+
>>> data = data.exp_w_average(
|
|
1815
|
+
... 'A', decay=2, decay_value_type='half_life_index', bucket_interval=2, bucket_units='ticks',
|
|
1816
|
+
... )
|
|
1817
|
+
>>> otp.run(data)
|
|
1818
|
+
Time A
|
|
1819
|
+
0 2003-12-01 00:00:00.001 1.585786
|
|
1820
|
+
1 2003-12-01 00:00:00.003 2.773459
|
|
1821
|
+
2 2003-12-04 00:00:00.000 3.585786
|
|
1822
|
+
"""
|
|
1823
|
+
return ExpWAverage(*args, **kwargs)
|
|
1824
|
+
|
|
1825
|
+
|
|
1826
|
+
@docstring(parameters=[
|
|
1827
|
+
_decay_doc,
|
|
1828
|
+
_decay_value_type_hl_doc,
|
|
1829
|
+
_running_doc,
|
|
1830
|
+
_bucket_interval_doc,
|
|
1831
|
+
_bucket_units_doc,
|
|
1832
|
+
_bucket_time_doc,
|
|
1833
|
+
_bucket_end_condition_doc,
|
|
1834
|
+
_boundary_tick_bucket_doc,
|
|
1835
|
+
_all_fields_doc,
|
|
1836
|
+
_group_by_doc,
|
|
1837
|
+
_groups_to_display_doc,
|
|
1838
|
+
_end_condition_per_group_doc,
|
|
1839
|
+
])
|
|
1840
|
+
def exp_tw_average(*args, **kwargs):
|
|
1841
|
+
"""
|
|
1842
|
+
``EXP_TW_AVERAGE`` aggregation.
|
|
1843
|
+
|
|
1844
|
+
For each bucket, computes the **exponentially time-weighted average** value of a specified numeric field.
|
|
1845
|
+
The weight of each point in the time series is computed relative to the end time of the bucket,
|
|
1846
|
+
so that the value which is in effect during some infinitely small time interval `delta t`
|
|
1847
|
+
has weight **(delta t)*exp(-Lambda*(end_time - t))**,
|
|
1848
|
+
where `Lambda` is a constant, `end_time` represents end time of the bucket,
|
|
1849
|
+
and `t` represents the timestamp of that infinitely small time interval.
|
|
1850
|
+
|
|
1851
|
+
See also
|
|
1852
|
+
--------
|
|
1853
|
+
**EXP_TW_AVERAGE** OneTick event processor
|
|
1854
|
+
|
|
1855
|
+
Examples
|
|
1856
|
+
--------
|
|
1857
|
+
|
|
1858
|
+
Basic example
|
|
1859
|
+
|
|
1860
|
+
>>> data = otp.Ticks({'A': [1.0, 2.0, 3.0, 3.0, 4.0]})
|
|
1861
|
+
>>> data = data.exp_tw_average('A', decay=2, bucket_interval=2, bucket_units='ticks')
|
|
1862
|
+
>>> otp.run(data)
|
|
1863
|
+
Time A
|
|
1864
|
+
0 2003-12-01 00:00:00.001 1.000000
|
|
1865
|
+
1 2003-12-01 00:00:00.003 2.500087
|
|
1866
|
+
2 2003-12-04 00:00:00.000 4.000000
|
|
1867
|
+
|
|
1868
|
+
You can switch to ``lambda`` as ``decay_value_type``
|
|
1869
|
+
|
|
1870
|
+
>>> data = otp.Ticks({'A': [1.0, 2.0, 3.0, 3.0, 4.0]})
|
|
1871
|
+
>>> data = data.exp_tw_average(
|
|
1872
|
+
... 'A', decay=2, decay_value_type='lambda', bucket_interval=2, bucket_units='ticks',
|
|
1873
|
+
... )
|
|
1874
|
+
>>> otp.run(data)
|
|
1875
|
+
Time A
|
|
1876
|
+
0 2003-12-01 00:00:00.001 1.0000
|
|
1877
|
+
1 2003-12-01 00:00:00.003 2.5005
|
|
1878
|
+
2 2003-12-04 00:00:00.000 4.0000
|
|
1879
|
+
"""
|
|
1880
|
+
return ExpTwAverage(*args, **kwargs)
|
|
1881
|
+
|
|
1882
|
+
|
|
1883
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
1884
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
1885
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc, _degree_doc])
|
|
1886
|
+
def standardized_moment(*args, **kwargs):
|
|
1887
|
+
"""
|
|
1888
|
+
``STANDARDIZED_MOMENT`` aggregation.
|
|
1889
|
+
|
|
1890
|
+
Computes the standardized statistical moment of degree **k** of the input ``column``
|
|
1891
|
+
over the specified bucket interval.
|
|
1892
|
+
The standardized moment of degree **k** is defined
|
|
1893
|
+
as the expected value of the expression ``((X - mean) / stddev)^k``.
|
|
1894
|
+
|
|
1895
|
+
See also
|
|
1896
|
+
--------
|
|
1897
|
+
**STANDARDIZED_MOMENT** OneTick event processor
|
|
1898
|
+
|
|
1899
|
+
Examples
|
|
1900
|
+
--------
|
|
1901
|
+
|
|
1902
|
+
Basic example
|
|
1903
|
+
|
|
1904
|
+
.. testcode::
|
|
1905
|
+
:skipif: not otp.compatibility.is_standardized_moment_supported()
|
|
1906
|
+
|
|
1907
|
+
data = otp.Ticks({'A': [1, 2, 4, 4, 4, 6]})
|
|
1908
|
+
data = data.standardized_moment('A', degree=3, bucket_interval=3, bucket_units='ticks')
|
|
1909
|
+
df = otp.run(data)
|
|
1910
|
+
print(df)
|
|
1911
|
+
|
|
1912
|
+
.. testoutput::
|
|
1913
|
+
Time A
|
|
1914
|
+
0 2003-12-01 00:00:00.002 0.381802
|
|
1915
|
+
1 2003-12-01 00:00:00.005 0.707107
|
|
1916
|
+
"""
|
|
1917
|
+
return StandardizedMoment(*args, **kwargs)
|
|
1918
|
+
|
|
1919
|
+
|
|
1920
|
+
@docstring(parameters=[_column_doc, _running_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
1921
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
1922
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
1923
|
+
_weight_field_name_doc, _portfolio_side_doc,
|
|
1924
|
+
_weight_type_doc, _symbols_doc])
|
|
1925
|
+
def portfolio_price(*args, **kwargs):
|
|
1926
|
+
"""
|
|
1927
|
+
``PORTFOLIO_PRICE`` aggregation.
|
|
1928
|
+
|
|
1929
|
+
For each bucket, computes weighted portfolio price.
|
|
1930
|
+
|
|
1931
|
+
See also
|
|
1932
|
+
--------
|
|
1933
|
+
**PORTFOLIO_PRICE** OneTick event processor
|
|
1934
|
+
|
|
1935
|
+
Examples
|
|
1936
|
+
--------
|
|
1937
|
+
|
|
1938
|
+
Basic example, by default this EP takes ``PRICE`` column as input
|
|
1939
|
+
|
|
1940
|
+
>>> data = otp.DataSource(
|
|
1941
|
+
... 'US_COMP', symbol='AAPL', tick_type='TRD',
|
|
1942
|
+
... start=otp.dt(2022, 3, 1), end=otp.dt(2022, 3, 2),
|
|
1943
|
+
... )
|
|
1944
|
+
>>> data = data.portfolio_price()
|
|
1945
|
+
>>> otp.run(data)
|
|
1946
|
+
Time VALUE NUM_SYMBOLS
|
|
1947
|
+
0 2022-03-02 1.4 1
|
|
1948
|
+
|
|
1949
|
+
Getting portfolio price for multiple symbols:
|
|
1950
|
+
|
|
1951
|
+
>>> data = otp.DataSource('US_COMP', tick_type='TRD', start=otp.dt(2022, 3, 1), end=otp.dt(2022, 3, 2))
|
|
1952
|
+
>>> data = data.portfolio_price(symbols=['AAPL', 'AAP'])
|
|
1953
|
+
>>> otp.run(data)
|
|
1954
|
+
Time VALUE NUM_SYMBOLS
|
|
1955
|
+
0 2022-03-02 46.81 2
|
|
1956
|
+
|
|
1957
|
+
Applying **PORTFOLIO_PRICE** on custom column
|
|
1958
|
+
|
|
1959
|
+
>>> data = otp.Ticks(X=[10.0, 12.5, 11.0, 10.2, 15])
|
|
1960
|
+
>>> data = data.portfolio_price('X')
|
|
1961
|
+
>>> otp.run(data)
|
|
1962
|
+
Time VALUE NUM_SYMBOLS
|
|
1963
|
+
0 2003-12-04 15.0 1
|
|
1964
|
+
|
|
1965
|
+
Specifying weights via column 'WEIGHS'
|
|
1966
|
+
|
|
1967
|
+
>>> data = otp.Ticks(PRICE=[10.0, 12.5, 11.0, 10.2, 15], WEIGHTS=[1, 2, -1, 2, 2])
|
|
1968
|
+
>>> data = data.portfolio_price(weight_field_name=data['WEIGHTS'])
|
|
1969
|
+
>>> otp.run(data)
|
|
1970
|
+
Time VALUE NUM_SYMBOLS
|
|
1971
|
+
0 2003-12-04 30.0 1
|
|
1972
|
+
"""
|
|
1973
|
+
return PortfolioPrice(*args, **kwargs)
|
|
1974
|
+
|
|
1975
|
+
|
|
1976
|
+
@docstring(parameters=[_portfolios_query_doc, _columns_portfolio_doc, _running_doc, _bucket_interval_doc,
|
|
1977
|
+
_bucket_time_doc, _bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
1978
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
1979
|
+
_weight_field_name_doc,
|
|
1980
|
+
_weight_multiplier_field_name_doc, _portfolio_side_doc, _weight_type_doc,
|
|
1981
|
+
_portfolios_query_params_doc, _portfolio_value_field_name_doc, _symbols_doc])
|
|
1982
|
+
def multi_portfolio_price(*args, **kwargs):
|
|
1983
|
+
"""
|
|
1984
|
+
``MULTI_PORTFOLIO_PRICE`` aggregation.
|
|
1985
|
+
|
|
1986
|
+
For each bucket, computes weighted portfolio price for multiple portfolios.
|
|
1987
|
+
|
|
1988
|
+
See also
|
|
1989
|
+
--------
|
|
1990
|
+
**MULTI_PORTFOLIO_PRICE** OneTick event processor
|
|
1991
|
+
|
|
1992
|
+
Examples
|
|
1993
|
+
--------
|
|
1994
|
+
|
|
1995
|
+
Basic example, by default this EP takes ``PRICE`` column as input
|
|
1996
|
+
|
|
1997
|
+
>>> data = otp.DataSource(
|
|
1998
|
+
... 'US_COMP', tick_type='TRD', date=otp.dt(2022, 3, 1)
|
|
1999
|
+
... )
|
|
2000
|
+
>>> data = data.multi_portfolio_price(
|
|
2001
|
+
... portfolios_query='some_query.otq::portfolios_query',
|
|
2002
|
+
... symbols=['US_COMP::AAPL', 'US_COMP::MSFT', 'US_COMP::ORCL'],
|
|
2003
|
+
... )
|
|
2004
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
2005
|
+
Time VALUE NUM_SYMBOLS PORTFOLIO_NAME
|
|
2006
|
+
0 2003-12-01 95.0 3 PORTFOLIO_1
|
|
2007
|
+
1 2003-12-01 47.5 1 PORTFOLIO_2
|
|
2008
|
+
2 2003-12-01 32.5 2 PORTFOLIO_3
|
|
2009
|
+
|
|
2010
|
+
Override ``weight`` returned by ``portfolios_query`` with ``weight_field_name``
|
|
2011
|
+
|
|
2012
|
+
>>> data = otp.DataSource(
|
|
2013
|
+
... 'US_COMP', tick_type='TRD', date=otp.dt(2022, 3, 1)
|
|
2014
|
+
... )
|
|
2015
|
+
>>> data['WEIGHT'] = 2
|
|
2016
|
+
>>> data = data.multi_portfolio_price(
|
|
2017
|
+
... portfolios_query='some_query.otq::portfolios_query',
|
|
2018
|
+
... weight_field_name='WEIGHT',
|
|
2019
|
+
... symbols=['US_COMP::AAPL', 'US_COMP::MSFT', 'US_COMP::ORCL'],
|
|
2020
|
+
... )
|
|
2021
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
2022
|
+
Time VALUE NUM_SYMBOLS PORTFOLIO_NAME
|
|
2023
|
+
0 2003-12-01 38.0 3 PORTFOLIO_1
|
|
2024
|
+
1 2003-12-01 19.0 1 PORTFOLIO_2
|
|
2025
|
+
2 2003-12-01 13.0 2 PORTFOLIO_3
|
|
2026
|
+
|
|
2027
|
+
Pass parameters to the query from ``portfolios_query`` via ``portfolios_query_params``
|
|
2028
|
+
|
|
2029
|
+
>>> data = otp.DataSource(
|
|
2030
|
+
... 'US_COMP', tick_type='TRD', date=otp.dt(2022, 3, 1)
|
|
2031
|
+
... )
|
|
2032
|
+
>>> data = data.multi_portfolio_price(
|
|
2033
|
+
... portfolios_query='some_query.otq::portfolios_query_with_param',
|
|
2034
|
+
... symbols=['US_COMP::AAPL', 'US_COMP::MSFT', 'US_COMP::ORCL'],
|
|
2035
|
+
... portfolios_query_params={'PORTFOLIO_1_NAME': 'CUSTOM_NAME'}
|
|
2036
|
+
... )
|
|
2037
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
2038
|
+
Time VALUE NUM_SYMBOLS PORTFOLIO_NAME
|
|
2039
|
+
0 2003-12-01 95.0 3 CUSTOM_NAME
|
|
2040
|
+
1 2003-12-01 47.5 1 PORTFOLIO_2
|
|
2041
|
+
2 2003-12-01 32.5 2 PORTFOLIO_3
|
|
2042
|
+
|
|
2043
|
+
Use ``otp.Source`` object as ``portfolios_query`` (only for local queries)
|
|
2044
|
+
|
|
2045
|
+
>>> portfolios = otp.Ticks(
|
|
2046
|
+
... SYMBOL_NAME=['US_COMP::AAPL', 'US_COMP::MSFT', 'US_COMP::AAPL'],
|
|
2047
|
+
... PORTFOLIO_NAME=['PORTFOLIO_1', 'PORTFOLIO_1', 'PORTFOLIO_2'],
|
|
2048
|
+
... WEIGHT=[1, 1, 2],
|
|
2049
|
+
... )
|
|
2050
|
+
>>> data = otp.DataSource(
|
|
2051
|
+
... 'US_COMP', tick_type='TRD', date=otp.dt(2022, 3, 1)
|
|
2052
|
+
... )
|
|
2053
|
+
>>> data = data.multi_portfolio_price(
|
|
2054
|
+
... portfolios_query=portfolios,
|
|
2055
|
+
... symbols=['US_COMP::AAPL', 'US_COMP::MSFT'],
|
|
2056
|
+
... )
|
|
2057
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
2058
|
+
Time VALUE NUM_SYMBOLS PORTFOLIO_NAME
|
|
2059
|
+
0 2003-12-01 47.5 2 PORTFOLIO_1
|
|
2060
|
+
1 2003-12-01 46.0 1 PORTFOLIO_2
|
|
2061
|
+
"""
|
|
2062
|
+
return MultiPortfolioPrice(*args, **kwargs)
|
|
2063
|
+
|
|
2064
|
+
|
|
2065
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
2066
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
2067
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc])
|
|
2068
|
+
def return_ep(*args, **kwargs):
|
|
2069
|
+
"""
|
|
2070
|
+
``RETURN`` aggregation.
|
|
2071
|
+
|
|
2072
|
+
Computes the ratio between the value of the input field at the end of a bucket interval and the value
|
|
2073
|
+
of this field at the start of a bucket interval.
|
|
2074
|
+
If ``running`` is set to ``True``, then ``RETURN`` is calculated as the ratio between latest tick
|
|
2075
|
+
and the first tick from the start time. Below, the input field is referred to as 'price'.
|
|
2076
|
+
|
|
2077
|
+
``Return for an interval = ending price for the interval / starting price for the interval``
|
|
2078
|
+
|
|
2079
|
+
where
|
|
2080
|
+
|
|
2081
|
+
* ``ending price for the interval`` is taken from the last tick observed in the stream
|
|
2082
|
+
up to the end of the interval.
|
|
2083
|
+
* ``starting price for the interval`` is taken from the first tick in the interval for the first bucket interval
|
|
2084
|
+
that has any ticks. For all other intervals, it is the price of the first tick with timestamp of the start
|
|
2085
|
+
of interval or, if no such tick is present, the ending price of the previous interval. The ending price
|
|
2086
|
+
for the interval is taken from the last tick observed in the stream up to the end of the interval.
|
|
2087
|
+
|
|
2088
|
+
See also
|
|
2089
|
+
--------
|
|
2090
|
+
**RETURN** OneTick event processor
|
|
2091
|
+
|
|
2092
|
+
Examples
|
|
2093
|
+
--------
|
|
2094
|
+
|
|
2095
|
+
Basic example as :py:class:`~onetick.py.Source` method
|
|
2096
|
+
|
|
2097
|
+
>>> data = otp.DataSource('US_COMP', symbol='AAPL', tick_type='TRD')
|
|
2098
|
+
>>> data = data.return_ep(data['PRICE'], bucket_interval=otp.Minute(10))
|
|
2099
|
+
>>> otp.run(data, date=otp.dt(2022, 3, 1)) # doctest: +SKIP
|
|
2100
|
+
Time PRICE
|
|
2101
|
+
0 2022-03-01 00:00:00.000 0.99953
|
|
2102
|
+
1 2022-03-01 00:10:00.000 1.0043
|
|
2103
|
+
2 2022-03-01 00:20:00.000 0.9986
|
|
2104
|
+
3 2022-03-01 00:30:00.000 0.99643
|
|
2105
|
+
4 2022-03-01 00:40:00.000 1.042
|
|
2106
|
+
...
|
|
2107
|
+
|
|
2108
|
+
Basic example as aggregation
|
|
2109
|
+
|
|
2110
|
+
>>> data = otp.DataSource('US_COMP', symbol='AAPL', tick_type='TRD')
|
|
2111
|
+
>>> data = otp.agg.return_ep(data['PRICE'], bucket_interval=otp.Minute(10)).apply(data)
|
|
2112
|
+
>>> otp.run(data, date=otp.dt(2022, 3, 1)) # doctest: +SKIP
|
|
2113
|
+
Time PRICE
|
|
2114
|
+
0 2022-03-01 00:00:00.000 0.99953
|
|
2115
|
+
1 2022-03-01 00:10:00.000 1.0043
|
|
2116
|
+
2 2022-03-01 00:20:00.000 0.9986
|
|
2117
|
+
3 2022-03-01 00:30:00.000 0.99643
|
|
2118
|
+
4 2022-03-01 00:40:00.000 1.042
|
|
2119
|
+
...
|
|
2120
|
+
"""
|
|
2121
|
+
return Return(*args, **kwargs)
|
|
2122
|
+
|
|
2123
|
+
|
|
2124
|
+
@docstring(parameters=[_column_doc, _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
2125
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
2126
|
+
_boundary_tick_bucket_doc, _group_by_doc, _groups_to_display_doc,
|
|
2127
|
+
_interest_rate_doc, _price_field_doc, _option_price_field_doc,
|
|
2128
|
+
_method_doc, _precision_doc, _value_for_non_converge_doc, _option_type_field_doc,
|
|
2129
|
+
_strike_price_field_doc, _days_in_year_doc, _days_till_expiration_field_doc,
|
|
2130
|
+
_expiration_date_field_doc,
|
|
2131
|
+
])
|
|
2132
|
+
def implied_vol(*args, **kwargs):
|
|
2133
|
+
"""
|
|
2134
|
+
``IMPLIED_VOL`` aggregation.
|
|
2135
|
+
|
|
2136
|
+
For each bucket, computes implied volatility value for the last tick in the bucket,
|
|
2137
|
+
based on the Black-Scholes option pricing model.
|
|
2138
|
+
|
|
2139
|
+
This EP requires a time series of ticks, having the ``PRICE`` and ``OPTION_PRICE`` attributes.
|
|
2140
|
+
|
|
2141
|
+
It also requires several parameters to compute the implied volatility.
|
|
2142
|
+
Those are, ``OPTION_TYPE``, ``STRIKE_PRICE``, ``EXPIRATION_DATE`` or ``DAYS_TILL_EXPIRATION`` and ``INTEREST_RATE``.
|
|
2143
|
+
Each parameter can be specified either via a symbol parameter with the same name, or via a tick field,
|
|
2144
|
+
by specifying name of that field as an EP parameter.
|
|
2145
|
+
Besides, ``interest_rate`` can also be specified as aggregation parameter.
|
|
2146
|
+
In either case ``OPTION_TYPE`` must have either ``CALL`` value, or ``PUT``.
|
|
2147
|
+
``EXPIRATION_DATE`` is in ``YYYYMMDD`` format, a string in case of a symbol parameter and an integer
|
|
2148
|
+
in case of a tick attribute.
|
|
2149
|
+
|
|
2150
|
+
See also
|
|
2151
|
+
--------
|
|
2152
|
+
**IMPLIED_VOL** OneTick event processor
|
|
2153
|
+
|
|
2154
|
+
Examples
|
|
2155
|
+
--------
|
|
2156
|
+
|
|
2157
|
+
Basic example:
|
|
2158
|
+
|
|
2159
|
+
>>> data = otp.DataSource('SOME_DB', symbol='AAA', tick_type='TT') # doctest: +SKIP
|
|
2160
|
+
>>> data = data.implied_vol(
|
|
2161
|
+
... interest_rate=0.05, option_type_field=data['OPTION_TYPE'],
|
|
2162
|
+
... strike_price_field=data['STRIKE_PRICE'], days_till_expiration_field=data['DAYS_TILL_EXPIRATION'],
|
|
2163
|
+
... ) # doctest: +SKIP
|
|
2164
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
2165
|
+
Time VALUE
|
|
2166
|
+
0 2003-12-04 0.889491
|
|
2167
|
+
|
|
2168
|
+
Specifying ``interest_rate`` and ``strike_price`` as symbol parameters:
|
|
2169
|
+
|
|
2170
|
+
>>> sym = otp.Ticks({
|
|
2171
|
+
... 'SYMBOL_NAME': ['TEST'],
|
|
2172
|
+
... 'INTEREST_RATE': [0.05],
|
|
2173
|
+
... 'STRIKE_PRICE': [100.0],
|
|
2174
|
+
... }) # doctest: +SKIP
|
|
2175
|
+
>>> data = otp.DataSource('SOME_DB', symbol='AAA', tick_type='TT') # doctest: +SKIP
|
|
2176
|
+
>>> data = data.implied_vol(
|
|
2177
|
+
... option_type_field=data['OPTION_TYPE'], days_till_expiration_field=data['DAYS_TILL_EXPIRATION'],
|
|
2178
|
+
... ) # doctest: +SKIP
|
|
2179
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
2180
|
+
Time VALUE
|
|
2181
|
+
0 2003-12-04 0.889491
|
|
2182
|
+
"""
|
|
2183
|
+
return ImpliedVol(*args, **kwargs)
|
|
2184
|
+
|
|
2185
|
+
|
|
2186
|
+
@docstring(parameters=[_running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
|
|
2187
|
+
_bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
|
|
2188
|
+
_boundary_tick_bucket_doc,
|
|
2189
|
+
])
|
|
2190
|
+
def linear_regression(*args, **kwargs):
|
|
2191
|
+
"""
|
|
2192
|
+
``LINEAR_REGRESSION`` aggregation.
|
|
2193
|
+
|
|
2194
|
+
For each bucket, computes the linear regression parameters slope and intercept of specified input fields
|
|
2195
|
+
``dependent_variable_field_name`` and ``independent_variable_field_name``.
|
|
2196
|
+
Adds computed parameters as `SLOPE` and `INTERCEPT` fields in output time series.
|
|
2197
|
+
The relationship between the dependent variable (``Y``) and the independent variable (``X``) is defined
|
|
2198
|
+
by the formula: Y = SLOPE * X + INTERCEPT, where `SLOPE` and `INTERCEPT` are the calculated output parameters.
|
|
2199
|
+
|
|
2200
|
+
See also
|
|
2201
|
+
--------
|
|
2202
|
+
**LINEAR_REGRESSION** OneTick event processor
|
|
2203
|
+
|
|
2204
|
+
Examples
|
|
2205
|
+
--------
|
|
2206
|
+
|
|
2207
|
+
>>> data = otp.Ticks({'X': [10.0, 9.5, 8.0, 8.5], 'Y': [3.0, 5.0, 4.5, 3.5]})
|
|
2208
|
+
>>> data = data.linear_regression(
|
|
2209
|
+
... dependent_variable_field_name=data['Y'],
|
|
2210
|
+
... independent_variable_field_name=data['X'],
|
|
2211
|
+
... ) # doctest: +SKIP
|
|
2212
|
+
>>> otp.run(data) # doctest: +SKIP
|
|
2213
|
+
Time SLOPE INTERCEPT
|
|
2214
|
+
0 2003-12-04 -0.3 6.7
|
|
2215
|
+
"""
|
|
2216
|
+
return LinearRegression(*args, **kwargs)
|