Qubx 0.6.9__tar.gz → 0.6.11__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.

Potentially problematic release.


This version of Qubx might be problematic. Click here for more details.

Files changed (141) hide show
  1. {qubx-0.6.9 → qubx-0.6.11}/PKG-INFO +1 -1
  2. {qubx-0.6.9 → qubx-0.6.11}/pyproject.toml +1 -1
  3. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/account.py +1 -2
  4. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/basics.py +14 -5
  5. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/runner/configs.py +1 -1
  6. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/runner/runner.py +20 -10
  7. {qubx-0.6.9 → qubx-0.6.11}/README.md +0 -0
  8. {qubx-0.6.9 → qubx-0.6.11}/build.py +0 -0
  9. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/__init__.py +0 -0
  10. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/_nb_magic.py +0 -0
  11. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/backtester/__init__.py +0 -0
  12. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/backtester/account.py +0 -0
  13. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/backtester/broker.py +0 -0
  14. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/backtester/data.py +0 -0
  15. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/backtester/management.py +0 -0
  16. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/backtester/ome.py +0 -0
  17. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/backtester/optimization.py +0 -0
  18. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/backtester/runner.py +0 -0
  19. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/backtester/simulated_data.py +0 -0
  20. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/backtester/simulator.py +0 -0
  21. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/backtester/utils.py +0 -0
  22. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/cli/__init__.py +0 -0
  23. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/cli/commands.py +0 -0
  24. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/cli/deploy.py +0 -0
  25. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/cli/misc.py +0 -0
  26. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/cli/release.py +0 -0
  27. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/connectors/ccxt/__init__.py +0 -0
  28. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/connectors/ccxt/account.py +0 -0
  29. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/connectors/ccxt/broker.py +0 -0
  30. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/connectors/ccxt/customizations.py +0 -0
  31. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/connectors/ccxt/data.py +0 -0
  32. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/connectors/ccxt/exceptions.py +0 -0
  33. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/connectors/ccxt/factory.py +0 -0
  34. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/connectors/ccxt/reader.py +0 -0
  35. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/connectors/ccxt/utils.py +0 -0
  36. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/__init__.py +0 -0
  37. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/context.py +0 -0
  38. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/exceptions.py +0 -0
  39. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/helpers.py +0 -0
  40. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/initializer.py +0 -0
  41. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/interfaces.py +0 -0
  42. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/loggers.py +0 -0
  43. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/lookups.py +0 -0
  44. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/metrics.py +0 -0
  45. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/mixins/__init__.py +0 -0
  46. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/mixins/market.py +0 -0
  47. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/mixins/processing.py +0 -0
  48. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/mixins/subscription.py +0 -0
  49. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/mixins/trading.py +0 -0
  50. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/mixins/universe.py +0 -0
  51. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/series.pxd +0 -0
  52. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/series.pyi +0 -0
  53. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/series.pyx +0 -0
  54. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/utils.pyi +0 -0
  55. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/core/utils.pyx +0 -0
  56. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/data/__init__.py +0 -0
  57. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/data/composite.py +0 -0
  58. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/data/helpers.py +0 -0
  59. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/data/hft.py +0 -0
  60. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/data/readers.py +0 -0
  61. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/data/registry.py +0 -0
  62. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/data/tardis.py +0 -0
  63. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/emitters/__init__.py +0 -0
  64. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/emitters/base.py +0 -0
  65. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/emitters/composite.py +0 -0
  66. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/emitters/prometheus.py +0 -0
  67. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/emitters/questdb.py +0 -0
  68. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/exporters/__init__.py +0 -0
  69. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/exporters/composite.py +0 -0
  70. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/exporters/formatters/__init__.py +0 -0
  71. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/exporters/formatters/base.py +0 -0
  72. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/exporters/formatters/incremental.py +0 -0
  73. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/exporters/formatters/slack.py +0 -0
  74. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/exporters/redis_streams.py +0 -0
  75. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/exporters/slack.py +0 -0
  76. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/features/__init__.py +0 -0
  77. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/features/core.py +0 -0
  78. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/features/orderbook.py +0 -0
  79. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/features/price.py +0 -0
  80. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/features/trades.py +0 -0
  81. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/features/utils.py +0 -0
  82. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/gathering/simplest.py +0 -0
  83. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/math/__init__.py +0 -0
  84. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/math/stats.py +0 -0
  85. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/notifications/__init__.py +0 -0
  86. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/notifications/composite.py +0 -0
  87. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/notifications/slack.py +0 -0
  88. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/pandaz/__init__.py +0 -0
  89. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/pandaz/ta.py +0 -0
  90. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/pandaz/utils.py +0 -0
  91. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/resources/_build.py +0 -0
  92. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/resources/instruments/symbols-binance.cm.json +0 -0
  93. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/resources/instruments/symbols-binance.json +0 -0
  94. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/resources/instruments/symbols-binance.um.json +0 -0
  95. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/resources/instruments/symbols-bitfinex.f.json +0 -0
  96. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/resources/instruments/symbols-bitfinex.json +0 -0
  97. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/resources/instruments/symbols-kraken.f.json +0 -0
  98. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/resources/instruments/symbols-kraken.json +0 -0
  99. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/restarts/__init__.py +0 -0
  100. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/restarts/state_resolvers.py +0 -0
  101. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/restarts/time_finders.py +0 -0
  102. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/restorers/__init__.py +0 -0
  103. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/restorers/balance.py +0 -0
  104. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/restorers/factory.py +0 -0
  105. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/restorers/interfaces.py +0 -0
  106. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/restorers/position.py +0 -0
  107. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/restorers/signal.py +0 -0
  108. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/restorers/state.py +0 -0
  109. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/restorers/utils.py +0 -0
  110. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/ta/__init__.py +0 -0
  111. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/ta/indicators.pxd +0 -0
  112. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/ta/indicators.pyi +0 -0
  113. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/ta/indicators.pyx +0 -0
  114. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/trackers/__init__.py +0 -0
  115. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/trackers/advanced.py +0 -0
  116. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/trackers/composite.py +0 -0
  117. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/trackers/rebalancers.py +0 -0
  118. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/trackers/riskctrl.py +0 -0
  119. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/trackers/sizers.py +0 -0
  120. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/__init__.py +0 -0
  121. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/_pyxreloader.py +0 -0
  122. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/charting/lookinglass.py +0 -0
  123. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/charting/mpl_helpers.py +0 -0
  124. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/marketdata/binance.py +0 -0
  125. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/marketdata/ccxt.py +0 -0
  126. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/marketdata/dukas.py +0 -0
  127. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/misc.py +0 -0
  128. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/ntp.py +0 -0
  129. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/numbers_utils.py +0 -0
  130. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/orderbook.py +0 -0
  131. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/plotting/__init__.py +0 -0
  132. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/plotting/dashboard.py +0 -0
  133. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/plotting/data.py +0 -0
  134. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/plotting/interfaces.py +0 -0
  135. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/plotting/renderers/__init__.py +0 -0
  136. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/plotting/renderers/plotly.py +0 -0
  137. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/runner/__init__.py +0 -0
  138. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/runner/_jupyter_runner.pyt +0 -0
  139. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/runner/accounts.py +0 -0
  140. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/time.py +0 -0
  141. {qubx-0.6.9 → qubx-0.6.11}/src/qubx/utils/version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: Qubx
3
- Version: 0.6.9
3
+ Version: 0.6.11
4
4
  Summary: Qubx - Quantitative Trading Framework
5
5
  Author: Dmitry Marienko
6
6
  Author-email: dmitry.marienko@xlydian.com
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "Qubx"
7
- version = "0.6.9"
7
+ version = "0.6.11"
8
8
  description = "Qubx - Quantitative Trading Framework"
9
9
  authors = [ "Dmitry Marienko <dmitry.marienko@xlydian.com>", "Yuriy Arabskyy <yuriy.arabskyy@xlydian.com>",]
10
10
  readme = "README.md"
@@ -62,9 +62,8 @@ class BasicAccountProcessor(IAccountProcessor):
62
62
  def get_total_capital(self) -> float:
63
63
  # sum of cash + market value of all positions
64
64
  _cash_amount = self._balances[self.base_currency].total
65
- _r_pnl = sum([p.r_pnl for p in self._positions.values()])
66
65
  _positions_value = sum([p.market_value_funds for p in self._positions.values()])
67
- return _cash_amount + _positions_value + _r_pnl
66
+ return _cash_amount + _positions_value
68
67
 
69
68
  def get_balances(self) -> dict[str, AssetBalance]:
70
69
  return self._balances
@@ -8,6 +8,7 @@ from typing import Any, Literal, Optional, TypeAlias, Union
8
8
  import numpy as np
9
9
  import pandas as pd
10
10
 
11
+ from qubx import logger
11
12
  from qubx.core.exceptions import QueueTimeout
12
13
  from qubx.core.series import Bar, OrderBook, Quote, Trade, time_as_nsec
13
14
  from qubx.core.utils import prec_ceil, prec_floor, time_delta_to_str
@@ -550,7 +551,7 @@ class Position:
550
551
  qty_opening = pos_change if prev_direction == direction else pos_change - qty_closing
551
552
 
552
553
  # - extract realized part of PnL
553
- if qty_closing != 0:
554
+ if not np.isclose(qty_closing, 0.0):
554
555
  _abs_qty_close = abs(qty_closing)
555
556
  deal_pnl = qty_closing * (self.position_avg_price - exec_price)
556
557
 
@@ -564,11 +565,19 @@ class Position:
564
565
  self.__pos_incr_qty = 0
565
566
 
566
567
  # - if it has something to add to position let's update price and cost
567
- if qty_opening != 0:
568
+ if not np.isclose(qty_opening, 0.0):
568
569
  _abs_qty_open = abs(qty_opening)
569
- pos_avg_price_raw = (_abs_qty_open * exec_price + self.__pos_incr_qty * self.position_avg_price) / (
570
- self.__pos_incr_qty + _abs_qty_open
571
- )
570
+ try:
571
+ pos_avg_price_raw = (_abs_qty_open * exec_price + self.__pos_incr_qty * self.position_avg_price) / (
572
+ self.__pos_incr_qty + _abs_qty_open
573
+ )
574
+ except ZeroDivisionError:
575
+ logger.warning(
576
+ "Zero division error in position update: "
577
+ f"qty_opening={qty_opening}, exec_price={exec_price}, pos_incr_qty={self.__pos_incr_qty}, position_avg_price={self.position_avg_price}"
578
+ )
579
+ pos_avg_price_raw = self.position_avg_price
580
+
572
581
  # - round position average price to be in line with how it's calculated by broker
573
582
  self.position_avg_price = self.instrument.round_price_down(pos_avg_price_raw)
574
583
  self.__pos_incr_qty += _abs_qty_open
@@ -16,7 +16,7 @@ class ReaderConfig(BaseModel):
16
16
 
17
17
 
18
18
  class TypedReaderConfig(BaseModel):
19
- data_type: str
19
+ data_type: list[str] | str
20
20
  readers: list[ReaderConfig]
21
21
 
22
22
 
@@ -742,13 +742,19 @@ def _create_data_type_readers(warmup: WarmupConfig | None) -> dict[str, DataRead
742
742
  data_type_to_reader = {} # Maps data type to reader instance
743
743
 
744
744
  for typed_reader_config in warmup.readers:
745
- data_type = typed_reader_config.data_type
746
- readers_for_type = []
745
+ data_types = typed_reader_config.data_type
746
+ if isinstance(data_types, str):
747
+ data_types = [data_types]
748
+ readers_for_types = []
747
749
 
748
750
  for reader_config in typed_reader_config.readers:
749
751
  # Create a hashable representation of the reader config
750
- # TODO: maybe include args as well, but they are not always hashable
751
- reader_key = reader_config.reader
752
+ # Create a hashable key from reader name and stringified args
753
+ if reader_config.args:
754
+ args_str = str(reader_config.args)
755
+ reader_key = f"{reader_config.reader}:{args_str}"
756
+ else:
757
+ reader_key = reader_config.reader
752
758
 
753
759
  # Check if we've already created this reader
754
760
  if reader_key not in unique_readers:
@@ -761,14 +767,18 @@ def _create_data_type_readers(warmup: WarmupConfig | None) -> dict[str, DataRead
761
767
  logger.error(f"Reader {reader_config.reader} could not be created: {e}")
762
768
  raise
763
769
 
764
- # Add the reader to the list for this data type
765
- readers_for_type.append(unique_readers[reader_key])
770
+ # Add the reader to the list for these data types
771
+ readers_for_types.append(unique_readers[reader_key])
766
772
 
767
773
  # Create a composite reader if needed, or use the single reader
768
- if len(readers_for_type) > 1:
769
- data_type_to_reader[data_type] = CompositeReader(readers_for_type)
770
- elif len(readers_for_type) == 1:
771
- data_type_to_reader[data_type] = readers_for_type[0]
774
+ if len(readers_for_types) > 1:
775
+ composite_reader = CompositeReader(readers_for_types)
776
+ for data_type in data_types:
777
+ data_type_to_reader[data_type] = composite_reader
778
+ elif len(readers_for_types) == 1:
779
+ single_reader = readers_for_types[0]
780
+ for data_type in data_types:
781
+ data_type_to_reader[data_type] = single_reader
772
782
 
773
783
  return data_type_to_reader
774
784
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes