onetick-py 1.182.0__tar.gz → 1.184.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. {onetick_py-1.182.0/src/onetick_py.egg-info → onetick_py-1.184.0}/PKG-INFO +2 -1
  2. {onetick_py-1.182.0 → onetick_py-1.184.0}/pyproject.toml +1 -3
  3. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/locator_parser/locator.py +5 -0
  4. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/_version.py +1 -1
  5. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/aggregations/__init__.py +1 -1
  6. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/aggregations/_docs.py +38 -0
  7. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/aggregations/functions.py +45 -3
  8. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/aggregations/other.py +53 -0
  9. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/compatibility.py +50 -23
  10. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_csv_inspector.py +1 -1
  11. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/aggregations.py +6 -0
  12. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/debugs.py +14 -2
  13. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/source.py +11 -3
  14. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/db/_inspection.py +3 -1
  15. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/license.py +1 -1
  16. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/run.py +28 -16
  17. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/ticks.py +1 -1
  18. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/types.py +10 -1
  19. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/render.py +36 -2
  20. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/render_cli.py +9 -1
  21. {onetick_py-1.182.0 → onetick_py-1.184.0/src/onetick_py.egg-info}/PKG-INFO +2 -1
  22. {onetick_py-1.182.0 → onetick_py-1.184.0}/LICENSE +0 -0
  23. {onetick_py-1.182.0 → onetick_py-1.184.0}/README.md +0 -0
  24. {onetick_py-1.182.0 → onetick_py-1.184.0}/requirements.strict.txt +0 -0
  25. {onetick_py-1.182.0 → onetick_py-1.184.0}/requirements.txt +0 -0
  26. {onetick_py-1.182.0 → onetick_py-1.184.0}/setup.cfg +0 -0
  27. {onetick_py-1.182.0 → onetick_py-1.184.0}/setup.py +0 -0
  28. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/locator_parser/__init__.py +0 -0
  29. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/locator_parser/acl.py +0 -0
  30. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/locator_parser/actions.py +0 -0
  31. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/locator_parser/common.py +0 -0
  32. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/locator_parser/io.py +0 -0
  33. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/__init__.py +0 -0
  34. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/doc_utilities/__init__.py +0 -0
  35. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/doc_utilities/napoleon.py +0 -0
  36. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/doc_utilities/ot_doctest.py +0 -0
  37. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/doc_utilities/snippets.py +0 -0
  38. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/lib/__init__.py +0 -0
  39. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/lib/instance.py +0 -0
  40. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/__init__.py +0 -0
  41. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/_stack_info.py +0 -0
  42. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/aggregations/_base.py +0 -0
  43. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/aggregations/compute.py +0 -0
  44. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/aggregations/generic.py +0 -0
  45. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/aggregations/high_low.py +0 -0
  46. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/aggregations/num_distinct.py +0 -0
  47. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/aggregations/order_book.py +0 -0
  48. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/backports.py +0 -0
  49. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/cache.py +0 -0
  50. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/callback/__init__.py +0 -0
  51. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/callback/callback.py +0 -0
  52. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/callback/callbacks.py +0 -0
  53. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/configuration.py +0 -0
  54. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/__init__.py +0 -0
  55. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_internal/__init__.py +0 -0
  56. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_internal/_manually_bound_value.py +0 -0
  57. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_internal/_nodes_history.py +0 -0
  58. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_internal/_op_utils/__init__.py +0 -0
  59. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_internal/_op_utils/every_operand.py +0 -0
  60. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_internal/_op_utils/is_const.py +0 -0
  61. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_internal/_per_tick_scripts/tick_list_sort_template.script +0 -0
  62. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_internal/_proxy_node.py +0 -0
  63. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_internal/_state_objects.py +0 -0
  64. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_internal/_state_vars.py +0 -0
  65. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/__init__.py +0 -0
  66. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/_symbol_param.py +0 -0
  67. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/schema.py +0 -0
  68. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/__init__.py +0 -0
  69. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/applyers.py +0 -0
  70. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/columns.py +0 -0
  71. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/data_quality.py +0 -0
  72. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/drops.py +0 -0
  73. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/fields.py +0 -0
  74. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/filters.py +0 -0
  75. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/joins.py +0 -0
  76. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/merges.py +0 -0
  77. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/misc.py +0 -0
  78. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/pandases.py +0 -0
  79. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/renames.py +0 -0
  80. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/sorts.py +0 -0
  81. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/switches.py +0 -0
  82. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/symbols.py +0 -0
  83. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/times.py +0 -0
  84. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/source_methods/writes.py +0 -0
  85. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/symbol.py +0 -0
  86. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/_source/tmp_otq.py +0 -0
  87. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column.py +0 -0
  88. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/__init__.py +0 -0
  89. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/_methods/__init__.py +0 -0
  90. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/_methods/_internal.py +0 -0
  91. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/_methods/conversions.py +0 -0
  92. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/_methods/methods.py +0 -0
  93. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/_methods/op_types.py +0 -0
  94. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/accessors/__init__.py +0 -0
  95. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/accessors/_accessor.py +0 -0
  96. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/accessors/decimal_accessor.py +0 -0
  97. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/accessors/dt_accessor.py +0 -0
  98. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/accessors/float_accessor.py +0 -0
  99. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/accessors/str_accessor.py +0 -0
  100. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/column_operations/base.py +0 -0
  101. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/cut_builder.py +0 -0
  102. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/db_constants.py +0 -0
  103. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/eval_query.py +0 -0
  104. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/lambda_object.py +0 -0
  105. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/multi_output_source.py +0 -0
  106. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/per_tick_script.py +0 -0
  107. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/core/query_inspector.py +0 -0
  108. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/db/__init__.py +0 -0
  109. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/db/db.py +0 -0
  110. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/db/utils.py +0 -0
  111. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/docs/__init__.py +0 -0
  112. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/docs/docstring_parser.py +0 -0
  113. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/docs/utils.py +0 -0
  114. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/functions.py +0 -0
  115. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/log.py +0 -0
  116. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/math.py +0 -0
  117. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/misc.py +0 -0
  118. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/oqd/__init__.py +0 -0
  119. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/oqd/eps.py +0 -0
  120. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/oqd/sources.py +0 -0
  121. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/otq.py +0 -0
  122. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/pyomd_mock.py +0 -0
  123. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/servers.py +0 -0
  124. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/session.py +0 -0
  125. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/__init__.py +0 -0
  126. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/cache.py +0 -0
  127. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/common.py +0 -0
  128. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/csv.py +0 -0
  129. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/custom.py +0 -0
  130. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/data_file.py +0 -0
  131. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/data_source.py +0 -0
  132. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/dataframe.py +0 -0
  133. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/empty.py +0 -0
  134. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/odbc.py +0 -0
  135. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/order_book.py +0 -0
  136. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/parquet.py +0 -0
  137. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/pit.py +0 -0
  138. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/query.py +0 -0
  139. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/snapshots.py +0 -0
  140. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/split_query_output_by_symbol.py +0 -0
  141. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/symbology_mapping.py +0 -0
  142. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sources/symbols.py +0 -0
  143. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/sql.py +0 -0
  144. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/state.py +0 -0
  145. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/__init__.py +0 -0
  146. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/acl.py +0 -0
  147. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/config.py +0 -0
  148. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/debug.py +0 -0
  149. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/default.py +0 -0
  150. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/file.py +0 -0
  151. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/helpers.py +0 -0
  152. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/locator.py +0 -0
  153. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/perf.py +0 -0
  154. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/query.py +0 -0
  155. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/script.py +0 -0
  156. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/temp.py +0 -0
  157. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/types.py +0 -0
  158. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick/py/utils/tz.py +0 -0
  159. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick_py.egg-info/SOURCES.txt +0 -0
  160. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick_py.egg-info/dependency_links.txt +0 -0
  161. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick_py.egg-info/entry_points.txt +0 -0
  162. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick_py.egg-info/requires.txt +0 -0
  163. {onetick_py-1.182.0 → onetick_py-1.184.0}/src/onetick_py.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: onetick-py
3
- Version: 1.182.0
3
+ Version: 1.184.0
4
4
  Summary: Python package that allows you to work with OneTick
5
5
  Author-email: solutions <solutions@onetick.com>
6
6
  License-Expression: MIT
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3.10
15
15
  Classifier: Programming Language :: Python :: 3.11
16
16
  Classifier: Programming Language :: Python :: 3.12
17
17
  Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
18
19
  Classifier: Operating System :: OS Independent
19
20
  Classifier: Environment :: Console
20
21
  Requires-Python: >=3.9
@@ -28,9 +28,7 @@ classifiers = [
28
28
  "Programming Language :: Python :: 3.11",
29
29
  "Programming Language :: Python :: 3.12",
30
30
  "Programming Language :: Python :: 3.13",
31
- # OneTick server and onetick.query-webapi do not support it yet
32
- # mantis [onetick 0037046]: Add support of python 3.14
33
- # "Programming Language :: Python :: 3.14",
31
+ "Programming Language :: Python :: 3.14",
34
32
  "Operating System :: OS Independent",
35
33
  "Environment :: Console",
36
34
  ]
@@ -135,6 +135,11 @@ def parse_locator(reader, writer, action=DoNothing(), recursively=False):
135
135
  cep_tick_servers_p(reader, writer, action)
136
136
  includes_p(reader, writer, action)
137
137
 
138
+ # force reset not full conditions match after processing root tags
139
+ if 0 < list(action.conditions.values()).count(True) < len(action.conditions):
140
+ for k in action.conditions:
141
+ action.conditions[k] = False
142
+
138
143
 
139
144
  # ----------------------------------------- #
140
145
  # set parent
@@ -1,2 +1,2 @@
1
1
  # This file was generated automatically. DO NOT CHANGE.
2
- VERSION = '1.182.0'
2
+ VERSION = '1.184.0'
@@ -3,7 +3,7 @@ from .functions import (compute, max, min, high_tick, low_tick, high_time, low_t
3
3
  ob_num_levels, ob_size, ob_snapshot, ob_snapshot_wide, ob_snapshot_flat, ob_summary, ob_vwap,
4
4
  generic, correlation, option_price, ranking, variance, percentile, find_value_for_percentile,
5
5
  exp_w_average, exp_tw_average, standardized_moment, portfolio_price, multi_portfolio_price,
6
- return_ep, implied_vol, linear_regression)
6
+ return_ep, implied_vol, linear_regression, partition_evenly_into_groups)
7
7
 
8
8
  try:
9
9
  from .num_distinct import num_distinct
@@ -858,6 +858,44 @@ _expiration_date_field_doc = param_doc(
858
858
  annotation=Union[str, Column],
859
859
  default='',
860
860
  )
861
+ _dependent_variable_field_name_doc = param_doc(
862
+ name='dependent_variable_field_name',
863
+ desc='''
864
+ Specifies the attribute used as the dependent variable in the calculation of the slope and intercept.
865
+ The ticks in the input time series must contain this attribute.
866
+ ''',
867
+ annotation=Union[str, Column],
868
+ )
869
+ _independent_variable_field_name_doc = param_doc(
870
+ name='independent_variable_field_name',
871
+ desc='''
872
+ Specifies the attribute used as the independent variable in the calculation of the slope and intercept.
873
+ The ticks in the input time series must contain this attribute.
874
+ ''',
875
+ annotation=Union[str, Column],
876
+ )
877
+ _field_to_partition_doc = param_doc(
878
+ name='field_to_partition',
879
+ desc='''
880
+ Specifies the tick field that will be partitioned.
881
+ ''',
882
+ annotation=Union[str, Column],
883
+ )
884
+ _weight_field_doc = param_doc(
885
+ name='weight_field',
886
+ desc='''
887
+ Specifies the tick field, the values of which are evaluated as weight; and then, the partitioning is be applied,
888
+ so that the total weight of the groups are as close as possible.
889
+ ''',
890
+ annotation=Union[str, Column],
891
+ )
892
+ _number_of_groups_doc = param_doc(
893
+ name='number_of_groups',
894
+ desc='''
895
+ Specifies the target number of partitions to which the tick should be divided.
896
+ ''',
897
+ annotation=int,
898
+ )
861
899
 
862
900
 
863
901
  class DocMetaclass(type):
@@ -9,7 +9,7 @@ from .other import (First, Last, FirstTime, LastTime, Count, Vwap, FirstTick,
9
9
  Median, Correlation, OptionPrice, Ranking, Variance,
10
10
  Percentile, FindValueForPercentile, ExpWAverage, ExpTwAverage,
11
11
  StandardizedMoment, PortfolioPrice, MultiPortfolioPrice, Return, ImpliedVol,
12
- LinearRegression)
12
+ LinearRegression, PartitionEvenlyIntoGroups)
13
13
  from .order_book import (ObSnapshot, OB_SNAPSHOT_DOC_PARAMS,
14
14
  ObSnapshotWide, OB_SNAPSHOT_WIDE_DOC_PARAMS,
15
15
  ObSnapshotFlat, OB_SNAPSHOT_FLAT_DOC_PARAMS,
@@ -64,7 +64,13 @@ from ._docs import (_column_doc,
64
64
  _strike_price_field_doc,
65
65
  _days_in_year_doc,
66
66
  _days_till_expiration_field_doc,
67
- _expiration_date_field_doc)
67
+ _expiration_date_field_doc,
68
+ _dependent_variable_field_name_doc,
69
+ _independent_variable_field_name_doc,
70
+ _field_to_partition_doc,
71
+ _weight_field_doc,
72
+ _number_of_groups_doc)
73
+
68
74
  from onetick.py.docs.utils import docstring, param_doc
69
75
 
70
76
  # This module mostly focused on providing annotations and documentation for end user
@@ -2183,7 +2189,8 @@ def implied_vol(*args, **kwargs):
2183
2189
  return ImpliedVol(*args, **kwargs)
2184
2190
 
2185
2191
 
2186
- @docstring(parameters=[_running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
2192
+ @docstring(parameters=[_dependent_variable_field_name_doc, _independent_variable_field_name_doc,
2193
+ _running_doc, _all_fields_doc, _bucket_interval_doc, _bucket_time_doc,
2187
2194
  _bucket_units_doc, _bucket_end_condition_doc, _end_condition_per_group_doc,
2188
2195
  _boundary_tick_bucket_doc,
2189
2196
  ])
@@ -2214,3 +2221,38 @@ def linear_regression(*args, **kwargs):
2214
2221
  0 2003-12-04 -0.3 6.7
2215
2222
  """
2216
2223
  return LinearRegression(*args, **kwargs)
2224
+
2225
+
2226
+ @docstring(parameters=[_field_to_partition_doc, _weight_field_doc, _number_of_groups_doc,
2227
+ _running_doc, _bucket_interval_doc, _bucket_time_doc,
2228
+ _bucket_units_doc, _bucket_end_condition_doc, _boundary_tick_bucket_doc,
2229
+ ])
2230
+ def partition_evenly_into_groups(*args, **kwargs):
2231
+ """
2232
+ ``PARTITION_EVENLY_INTO_GROUPS`` aggregation.
2233
+
2234
+ For each bucket, this EP breaks ticks into the specified number of groups (``number_of_groups``)
2235
+ by the specified field (``field_to_partition``) in a way that the sums
2236
+ of the specified weight fields (``weight_field``) in each group are as close as possible.
2237
+
2238
+ See also
2239
+ --------
2240
+ **PARTITION_EVENLY_INTO_GROUPS** OneTick event processor
2241
+
2242
+ Examples
2243
+ --------
2244
+
2245
+ >>> data = otp.Ticks(X=['A', 'B', 'A', 'C', 'D'], SIZE=[10, 30, 20, 15, 14])
2246
+ >>> data = data.partition_evenly_into_groups(
2247
+ ... field_to_partition=data['X'],
2248
+ ... weight_field=data['SIZE'],
2249
+ ... number_of_groups=3,
2250
+ ... )
2251
+ >>> otp.run(data)
2252
+ Time FIELD_TO_PARTITION GROUP_ID
2253
+ 0 2003-12-04 A 0
2254
+ 1 2003-12-04 B 1
2255
+ 2 2003-12-04 C 2
2256
+ 3 2003-12-04 D 2
2257
+ """
2258
+ return PartitionEvenlyIntoGroups(*args, **kwargs)
@@ -1012,3 +1012,56 @@ class LinearRegression(_Aggregation, _MultiColumnAggregation):
1012
1012
  'SLOPE': float,
1013
1013
  'INTERCEPT': float,
1014
1014
  }
1015
+
1016
+
1017
+ class PartitionEvenlyIntoGroups(_Aggregation, _MultiColumnAggregation):
1018
+ NAME = 'PARTITION_EVENLY_INTO_GROUPS'
1019
+ EP = otq.PartitionEvenlyIntoGroups
1020
+
1021
+ FIELDS_MAPPING = deepcopy(_Aggregation.FIELDS_MAPPING)
1022
+ FIELDS_MAPPING['field_to_partition'] = 'FIELD_TO_PARTITION'
1023
+ FIELDS_MAPPING['weight_field'] = 'WEIGHT_FIELD'
1024
+ FIELDS_MAPPING['number_of_groups'] = 'NUMBER_OF_GROUPS'
1025
+
1026
+ FIELDS_TO_SKIP = ['column_name', 'output_field_name']
1027
+
1028
+ def __init__(
1029
+ self,
1030
+ field_to_partition: Union[_Column, str, OnetickParameter],
1031
+ weight_field: Union[_Column, str, OnetickParameter],
1032
+ number_of_groups: Union[int, OnetickParameter],
1033
+ *args, **kwargs,
1034
+ ):
1035
+ if isinstance(field_to_partition, _Column):
1036
+ field_to_partition = str(field_to_partition)
1037
+ if isinstance(weight_field, _Column):
1038
+ weight_field = str(weight_field)
1039
+
1040
+ if number_of_groups <= 0:
1041
+ raise ValueError('Parameter `number_of_groups` value should be greater than zero')
1042
+
1043
+ self.field_to_partition = field_to_partition
1044
+ self.weight_field = weight_field
1045
+ self.number_of_groups = number_of_groups
1046
+
1047
+ super().__init__(_Column('TIMESTAMP'), *args, **kwargs)
1048
+
1049
+ def validate_input_columns(self, src: 'Source'):
1050
+ super().validate_input_columns(src)
1051
+
1052
+ for column in [self.field_to_partition, self.weight_field]:
1053
+ if isinstance(column, OnetickParameter):
1054
+ continue
1055
+
1056
+ if column not in src.schema:
1057
+ raise TypeError(f"Aggregation `{self.NAME}` uses column `{column}` as input, which doesn't exist")
1058
+
1059
+ for out_field in ['FIELD_TO_PARTITION', 'GROUP_ID']:
1060
+ if out_field in src.schema:
1061
+ raise TypeError(f"Field `{out_field}`, which is `{self.NAME}` aggregation output column, is in schema.")
1062
+
1063
+ def _get_output_schema(self, src: 'Source', name: Optional[str] = None) -> dict:
1064
+ return {
1065
+ 'FIELD_TO_PARTITION': str,
1066
+ 'GROUP_ID': int,
1067
+ }
@@ -1,14 +1,13 @@
1
1
  import os
2
2
  import warnings
3
3
  from dataclasses import dataclass, astuple
4
- from datetime import datetime
4
+ from datetime import datetime, timezone as dt_timezone
5
5
  from typing import Optional
6
6
 
7
- import pandas as pd
8
7
  from packaging.version import parse as parse_version
9
8
 
10
9
  import onetick.py as otp
11
- from onetick.py.otq import otq, otli
10
+ from onetick.py.otq import otq, otli, pyomd
12
11
  from onetick.py.backports import cache
13
12
 
14
13
 
@@ -104,34 +103,57 @@ def _parse_release_string(release_string: str, build_number: int) -> OnetickVers
104
103
  raise ValueError(f"Unknown release type '{release_type}' in release string '{release_string}'")
105
104
 
106
105
 
107
- def _get_locator_min_date(db_name, context):
106
+ def _get_locator_intervals(db_name, context) -> list[tuple[datetime, datetime]]:
108
107
  graph = otq.GraphQuery(otq.DbShowConfiguredTimeRanges(db_name=db_name).tick_type('ANY')
109
108
  >> otq.Table(fields='long START_DATE, long END_DATE'))
110
109
  symbols = f'{db_name}::'
110
+
111
+ # setting this is important so we don't get access error
112
+ qp = pyomd.QueryProperties()
113
+ qp.set_property_value('IGNORE_TICKS_IN_UNENTITLED_TIME_RANGE', 'TRUE')
114
+
111
115
  result = otq.run(graph,
112
116
  symbols=symbols,
113
117
  # start and end times don't matter for this query, use some constants
114
118
  start=datetime(2003, 12, 1),
115
119
  end=datetime(2003, 12, 1),
116
- # GMT, because start/end timestamp in locator are in GMT
117
- timezone='GMT',
120
+ # timezone is irrelevant, because times are returned as epoch numbers
121
+ timezone='UTC',
122
+ query_properties=qp,
118
123
  context=context)
119
124
  data = result.output(symbols).data
120
- first_date = data['START_DATE'][0]
121
- return datetime.fromtimestamp(first_date / 1000)
125
+ if not data:
126
+ raise RuntimeError(f"Database '{db_name}' doesn't have locations")
127
+ return [
128
+ (
129
+ datetime.fromtimestamp(data['START_DATE'][i] / 1000, dt_timezone.utc).replace(tzinfo=None),
130
+ datetime.fromtimestamp(data['END_DATE'][i] / 1000, dt_timezone.utc).replace(tzinfo=None),
131
+ )
132
+ for i in range(len(data['START_DATE']))
133
+ ]
122
134
 
123
135
 
124
- def _get_onetick_version(symbols, context, start, end):
136
+ def _get_onetick_version(db_name, context, start, end) -> dict:
125
137
  node = otq.TickGenerator(bucket_interval=0,
126
138
  fields='BUILD=GET_ONETICK_VERSION(), RELEASE=GET_ONETICK_RELEASE()')
127
139
  graph = otq.GraphQuery(node.tick_type('DUMMY'))
140
+ symbols = f'{db_name}::'
141
+
142
+ # setting this is important so we don't get access error
143
+ qp = pyomd.QueryProperties()
144
+ qp.set_property_value('IGNORE_TICKS_IN_UNENTITLED_TIME_RANGE', 'TRUE')
145
+
128
146
  result = otq.run(graph,
129
147
  symbols=symbols,
130
148
  start=start,
131
149
  end=end,
132
150
  context=context,
151
+ query_properties=qp,
133
152
  timezone='UTC')
134
- return result
153
+ data = result.output(symbols).data
154
+ if not data:
155
+ raise RuntimeError(f"Can't get OneTick version from database '{db_name}'")
156
+ return data
135
157
 
136
158
 
137
159
  @cache
@@ -166,28 +188,33 @@ def get_onetick_version(db=None, context=None) -> OnetickVersionFromServer:
166
188
 
167
189
  # if otp.config.default_db is set, then we use it to check compatibility
168
190
  # otherwise we use LOCAL database available everywhere
169
- db = db or otp.config.get('default_db', 'LOCAL')
170
- symbols = f'{db}::'
191
+ db_name = db or otp.config.get('default_db', 'LOCAL')
171
192
  context = context or otp.config.context
172
193
 
173
194
  try:
174
- # let's try some default time range first
175
- start = end = datetime(2003, 12, 1)
176
- result = _get_onetick_version(symbols, context, start, end)
177
- except Exception:
178
- if db != 'LOCAL':
195
+ if db_name == 'LOCAL':
196
+ # for LOCAL db any date will do
197
+ start = end = datetime(2003, 12, 1)
198
+ result_data = _get_onetick_version(db_name, context, start, end)
199
+ else:
179
200
  # for real db we need to set time range correctly
180
201
  # otherwise we may get error "Database locator has a gap"
181
- start = end = _get_locator_min_date(db, context)
182
- result = _get_onetick_version(symbols, context, start, end)
183
- else:
184
- raise
202
+ locator_intervals = _get_locator_intervals(db_name, context)
203
+ for i, (start, end) in enumerate(locator_intervals):
204
+ try:
205
+ result_data = _get_onetick_version(db_name, context, start, end)
206
+ break
207
+ except Exception as e:
208
+ if i < len(locator_intervals) - 1:
209
+ continue
210
+ else:
211
+ raise e
185
212
  finally:
186
213
  if s:
187
214
  s.close()
188
215
 
189
- build_number = result[symbols]["BUILD"][0]
190
- release_string = result[symbols]["RELEASE"][0]
216
+ build_number = result_data["BUILD"][0]
217
+ release_string = result_data["RELEASE"][0]
191
218
 
192
219
  try:
193
220
  onetick_version = _parse_release_string(release_string, build_number=build_number)
@@ -44,7 +44,7 @@ def inspect_by_pandas(path_to_csv, first_line_is_title=True, names=None, field_d
44
44
  first_column = "COLUMN_0"
45
45
  if names:
46
46
  first_column = names[0]
47
- if len(df) > 0 and len(df.columns) > 0 and df.dtypes[first_column] == np.dtype("O"):
47
+ if len(df) > 0 and len(df.columns) > 0 and pd.api.types.is_string_dtype(df.dtypes[first_column]):
48
48
  if df[first_column][0].startswith("#"):
49
49
  raise ValueError(
50
50
  "If first line of CSV starts with #, you must set first_line_is_title=True, "
@@ -615,6 +615,12 @@ def linear_regression(self: 'Source', *args, **kwargs):
615
615
  pass
616
616
 
617
617
 
618
+ @copy_method(aggregations.functions.partition_evenly_into_groups)
619
+ def partition_evenly_into_groups(self: 'Source', *args, **kwargs):
620
+ # method implementation is copied by decorator
621
+ pass
622
+
623
+
618
624
  @inplace_operation
619
625
  def process_by_group(
620
626
  self: 'Source', process_source_func, group_by=None, source_name=None, num_threads=None, inplace=False
@@ -103,7 +103,9 @@ def throw(
103
103
  >>> t = otp.Ticks(A=[1, 2, 3, 4])
104
104
  >>> t = t.throw(message='warning A=1', scope='symbol', error_code=2, where=(t['A']==1))
105
105
  >>> t = t.throw(message='error A=3', scope='symbol', error_code=1502, where=(t['A']==3))
106
- >>> otp.run(t)
106
+ >>> otp.run(t) # doctest: +SKIP
107
+ UserWarning: Symbol error: [2] warning A=1
108
+ UserWarning: Symbol error: [1502] error A=3
107
109
  Time A
108
110
  0 2003-12-01 00:00:00.000 1
109
111
  1 2003-12-01 00:00:00.001 2
@@ -246,7 +248,17 @@ def dump(
246
248
 
247
249
  # print <no data> in case there are 0 ticks
248
250
  if hasattr(otq, 'InsertAtEnd'):
249
- self_c.sink(otq.InsertAtEnd(delimiter_name='AT_END'))
251
+ ep_kwargs = {}
252
+ if {'propagate_ticks', 'insert_if_input_is_empty', 'fields_of_added_tick'}.issubset(
253
+ otq.InsertAtEnd.Parameters.list_parameters()
254
+ ):
255
+ # if supported, fix PY-1433
256
+ ep_kwargs = dict(
257
+ propagate_ticks=True,
258
+ insert_if_input_is_empty=True,
259
+ fields_of_added_tick='AT_END=1'
260
+ )
261
+ self_c.sink(otq.InsertAtEnd(delimiter_name='AT_END', **ep_kwargs))
250
262
  self_c.schema['AT_END'] = int
251
263
  self_c.state_vars['COUNT'] = otp.state.var(0, scope='branch')
252
264
  self_c.state_vars['COUNT'] += 1
@@ -5,7 +5,7 @@ import warnings
5
5
  from collections import defaultdict
6
6
  from datetime import datetime, date
7
7
  import pandas as pd
8
- from typing import Optional, Tuple
8
+ from typing import Optional, Tuple, Union
9
9
 
10
10
  from onetick.py.otq import otq
11
11
 
@@ -979,6 +979,8 @@ class Source:
979
979
  render_debug_info: bool = False,
980
980
  debug: bool = False,
981
981
  graphviz_compat_mode: bool = False,
982
+ font_family: Optional[str] = None,
983
+ font_size: Optional[Union[int, float]] = None,
982
984
  **kwargs,
983
985
  ):
984
986
  """
@@ -1011,6 +1013,12 @@ class Source:
1011
1013
  graphviz_compat_mode: bool
1012
1014
  Change internal parameters of result graph for better compatibility with old `Graphviz` versions.
1013
1015
  Could produce larger and less readable graphs.
1016
+ font_family: str, optional
1017
+ Font name
1018
+
1019
+ Default: **Monospace**
1020
+ font_size: int, float, str, optional
1021
+ Font size
1014
1022
  kwargs:
1015
1023
  Additional arguments to be passed to :py:meth:`onetick.py.Source.to_otq` method (except
1016
1024
  ``file_name``, ``file_suffix`` and ``query_name`` parameters)
@@ -1043,7 +1051,7 @@ class Source:
1043
1051
  otq_path = self.to_otq(**kwargs)
1044
1052
  return render_otq(
1045
1053
  otq_path, image_path, output_format, load_external_otqs, view, line_limit, parse_eval_from_params,
1046
- render_debug_info, debug, graphviz_compat_mode,
1054
+ render_debug_info, debug, graphviz_compat_mode, font_family, font_size,
1047
1055
  )
1048
1056
 
1049
1057
  def copy(self, ep=None, columns=None, deep=False) -> 'Source':
@@ -1652,7 +1660,7 @@ class Source:
1652
1660
  ranking, percentile, find_value_for_percentile,
1653
1661
  exp_w_average, exp_tw_average, standardized_moment,
1654
1662
  portfolio_price, multi_portfolio_price, return_ep, implied_vol,
1655
- linear_regression,
1663
+ linear_regression, partition_evenly_into_groups,
1656
1664
  process_by_group,
1657
1665
  )
1658
1666
  from ._source.source_methods.joins import ( # type: ignore[misc]
@@ -165,7 +165,9 @@ class DB:
165
165
  # ACCESS_INFO can return ACL violation error if we use database name as symbol
166
166
  query_properties={'IGNORE_TICKS_IN_UNENTITLED_TIME_RANGE': 'TRUE'},
167
167
  username=username,
168
- context=self.context)
168
+ context=self.context,
169
+ # don't print symbol error from onetick about start/end time adjusted due to entitlement checks
170
+ print_symbol_errors=False)
169
171
  if not df.empty:
170
172
  df = df.drop(columns='Time')
171
173
  if deep_scan:
@@ -114,7 +114,7 @@ class Server(_LicenseBase):
114
114
  if file is None:
115
115
  file = utils.TmpFile()
116
116
  else:
117
- if isinstance(reload, pd.tseries.offsets.Tick):
117
+ if isinstance(reload, pd.offsets.Tick):
118
118
  modify = datetime.fromtimestamp(os.path.getmtime(file))
119
119
  current = datetime.now()
120
120
  diff_ms = (current - modify).total_seconds() * 1000000
@@ -60,7 +60,8 @@ def run(query: Union[Callable, Dict, otp.Source, otp.MultiOutputSource, # NOSON
60
60
  max_expected_ticks_per_symbol: Optional[int] = None,
61
61
  log_symbol: Union[bool, Type[utils.default]] = utils.default,
62
62
  encoding: Optional[str] = None,
63
- manual_dataframe_callback: bool = False):
63
+ manual_dataframe_callback: bool = False,
64
+ print_symbol_errors: bool = True):
64
65
  """
65
66
  Executes a query and returns its result.
66
67
 
@@ -214,6 +215,9 @@ def run(query: Union[Callable, Dict, otp.Source, otp.MultiOutputSource, # NOSON
214
215
  Create dataframe manually with ``callback`` mode.
215
216
  Only works if ``output_structure='df'`` is specified and parameter ``callback`` is not.
216
217
  May improve performance in some cases.
218
+ print_symbol_errors_from_onetick: bool
219
+ Applicable only when ``output_structure`` is set to *df*.
220
+ Print symbol errors from OneTick as python warnings.
217
221
 
218
222
  Returns
219
223
  -------
@@ -614,7 +618,8 @@ def run(query: Union[Callable, Dict, otp.Source, otp.MultiOutputSource, # NOSON
614
618
  _process_empty_results(result, query_schema, output_structure)
615
619
 
616
620
  return _format_call_output(result, output_structure=output_structure,
617
- require_dict=require_dict, node_names=node_names)
621
+ require_dict=require_dict, node_names=node_names,
622
+ print_symbol_errors=print_symbol_errors)
618
623
 
619
624
 
620
625
  async def run_async(*args, **kwargs):
@@ -698,7 +703,7 @@ def _filter_returned_map_by_node(result, _node_names):
698
703
 
699
704
  def _filter_returned_list_by_node(result, node_names):
700
705
  """
701
- Here, result has the following format: [(symbol, data_1, data_2, node_name)]
706
+ Here, result has the following format: [(symbol, ticks_data, error_data, node_name)]
702
707
  We need to filter by correct node_names
703
708
  """
704
709
  if not node_names:
@@ -708,12 +713,12 @@ def _filter_returned_list_by_node(result, node_names):
708
713
 
709
714
  res = []
710
715
  empty_result = True
711
- for symbol, data_1, data_2, node, *_ in result:
712
- if len(data_1) > 0:
716
+ for symbol, ticks_data, error_data, node, *_ in result:
717
+ if len(ticks_data) > 0:
713
718
  empty_result = False
714
719
  if node in node_names:
715
720
  node_found = True
716
- res.append((symbol, data_1, data_2, node))
721
+ res.append((symbol, ticks_data, error_data, node))
717
722
 
718
723
  if not empty_result and not node_found:
719
724
  # TODO: Do we even want to raise it?
@@ -721,19 +726,19 @@ def _filter_returned_list_by_node(result, node_names):
721
726
  return res
722
727
 
723
728
 
724
- def _form_dict_from_list(data_list, output_structure):
729
+ def _form_dict_from_list(data_list, output_structure, print_symbol_errors):
725
730
  """
726
- Here, data_list has the following format: [(symbol, data_1, data_2, node_name), ...]
731
+ Here, data_list has the following format: [(symbol, ticks_data, error_data, node_name), ...]
727
732
  We need to create the following result:
728
- either {symbol: DataFrame(data_1)} if there is only one result per symbol
729
- or {symbol: [DataFrame(data_1)]} if there are multiple results for symbol for a single node_name
730
- or {symbol: {node_name: DataFrame(data_1)}} if there are single results for multiple node names for a symbol
731
- or {symbol: {node_name: [DataFrame(data_1)]}} if there are multiple results for multiple node names for a symbol
733
+ either {symbol: DataFrame(ticks_data)} if there is only one result per symbol
734
+ or {symbol: [DataFrame(ticks_data)]} if there are multiple results for symbol for a single node_name
735
+ or {symbol: {node_name: DataFrame(ticks_data)}} if there are single results for multiple node names for a symbol
736
+ or {symbol: {node_name: [DataFrame(ticks_data)]}} if there are multiple results for multiple node names for a symbol
732
737
  """
733
738
 
734
739
  def form_node_name_dict(lst):
735
740
  """
736
- lst is a lit of (node, dataframe)
741
+ lst is a list of (node, dataframe)
737
742
  """
738
743
  d = defaultdict(list)
739
744
  for node, df in lst:
@@ -760,7 +765,12 @@ def _form_dict_from_list(data_list, output_structure):
760
765
  return polars.DataFrame()
761
766
 
762
767
  symbols_dict = defaultdict(list)
763
- for symbol, data, _, node, *_ in data_list:
768
+ for symbol, data, error_data, node, *_ in data_list:
769
+
770
+ if print_symbol_errors:
771
+ for err_code, err_msg, *_ in error_data:
772
+ warnings.warn(f"Symbol error: [{err_code}] {err_msg}")
773
+
764
774
  df = get_dataframe(data)
765
775
 
766
776
  list_item = (node, df)
@@ -772,7 +782,7 @@ def _form_dict_from_list(data_list, output_structure):
772
782
  return dict(symbols_dict)
773
783
 
774
784
 
775
- def _format_call_output(result, output_structure, node_names, require_dict):
785
+ def _format_call_output(result, output_structure, node_names, require_dict, print_symbol_errors):
776
786
  """Formats output of otq.run() according to passed parameters.
777
787
  See parameters' description for more information
778
788
 
@@ -795,6 +805,8 @@ def _format_call_output(result, output_structure, node_names, require_dict):
795
805
  require_dict: bool
796
806
  If True, forces output for output_structure='df' to always be a dictionary, even if only one symbol is returned
797
807
  Has no effect for other values of output_structure
808
+ print_symbol_errors: bool
809
+ Print OneTick symbol errors in when ``output_structure`` is set to 'df' or not.
798
810
 
799
811
  Returns
800
812
  ----------
@@ -811,7 +823,7 @@ def _format_call_output(result, output_structure, node_names, require_dict):
811
823
 
812
824
  # "df" output structure implies that raw results came as a list
813
825
  result_list = _filter_returned_list_by_node(result, node_names)
814
- result_dict = _form_dict_from_list(result_list, output_structure)
826
+ result_dict = _form_dict_from_list(result_list, output_structure, print_symbol_errors)
815
827
 
816
828
  if len(result_dict) == 1 and not require_dict:
817
829
  return list(result_dict.values())[0]
@@ -572,7 +572,7 @@ def Ticks(data=None, # NOSONAR
572
572
  offset_values = []
573
573
  offset_parts = []
574
574
  for ofv in data['offset']:
575
- if isinstance(ofv, ott.offsets.Tick):
575
+ if isinstance(ofv, pd.offsets.BaseOffset):
576
576
  offset_values.append(ofv.n)
577
577
  try:
578
578
  str_repr = str(ofv.datepart)[1:-1]
@@ -1211,7 +1211,12 @@ class datetime(AbstractTime):
1211
1211
  )
1212
1212
  if isinstance(first_arg, (datetime, date)):
1213
1213
  first_arg = first_arg.ts
1214
- result = pd.Timestamp(first_arg, tzinfo=tzinfo, tz=tz)
1214
+ kwargs = {}
1215
+ if tzinfo is not None:
1216
+ kwargs['tzinfo'] = tzinfo
1217
+ if tz is not None:
1218
+ kwargs['tz'] = tz
1219
+ result = pd.Timestamp(first_arg, **kwargs)
1215
1220
  return result
1216
1221
 
1217
1222
  @property
@@ -1876,10 +1881,14 @@ def np2type(t):
1876
1881
  return bool
1877
1882
  elif t.name.startswith('datetime64[ns'):
1878
1883
  return nsectime
1884
+ elif t.name.startswith('datetime64[us'):
1885
+ return nsectime
1879
1886
  elif t.name.startswith('datetime64[ms'):
1880
1887
  return msectime
1881
1888
  elif t.name == 'object':
1882
1889
  return str
1890
+ elif t.name == 'str':
1891
+ return str
1883
1892
  elif t.str.startswith('<U'):
1884
1893
  length = t.name[2:]
1885
1894
  if length: