Qubx 0.2.5__tar.gz → 0.2.6__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 (56) hide show
  1. {qubx-0.2.5 → qubx-0.2.6}/PKG-INFO +1 -1
  2. {qubx-0.2.5 → qubx-0.2.6}/pyproject.toml +1 -1
  3. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/backtester/simulator.py +6 -0
  4. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/basics.py +3 -2
  5. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/metrics.py +13 -8
  6. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/series.pyi +5 -1
  7. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/ta/indicators.pyx +1 -1
  8. {qubx-0.2.5 → qubx-0.2.6}/README.md +0 -0
  9. {qubx-0.2.5 → qubx-0.2.6}/build.py +0 -0
  10. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/__init__.py +0 -0
  11. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/_nb_magic.py +0 -0
  12. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/backtester/__init__.py +0 -0
  13. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/backtester/ome.py +0 -0
  14. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/backtester/optimization.py +0 -0
  15. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/backtester/queue.py +0 -0
  16. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/__init__.py +0 -0
  17. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/account.py +0 -0
  18. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/context.py +0 -0
  19. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/exceptions.py +0 -0
  20. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/helpers.py +0 -0
  21. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/loggers.py +0 -0
  22. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/lookups.py +0 -0
  23. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/series.pxd +0 -0
  24. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/series.pyx +0 -0
  25. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/strategy.py +0 -0
  26. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/utils.pyi +0 -0
  27. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/core/utils.pyx +0 -0
  28. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/data/helpers.py +0 -0
  29. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/data/readers.py +0 -0
  30. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/gathering/simplest.py +0 -0
  31. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/impl/ccxt_connector.py +0 -0
  32. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/impl/ccxt_customizations.py +0 -0
  33. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/impl/ccxt_trading.py +0 -0
  34. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/impl/ccxt_utils.py +0 -0
  35. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/math/__init__.py +0 -0
  36. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/math/stats.py +0 -0
  37. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/pandaz/__init__.py +0 -0
  38. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/pandaz/ta.py +0 -0
  39. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/pandaz/utils.py +0 -0
  40. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/ta/__init__.py +0 -0
  41. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/ta/indicators.pxd +0 -0
  42. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/ta/indicators.pyi +0 -0
  43. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/trackers/__init__.py +0 -0
  44. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/trackers/composite.py +0 -0
  45. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/trackers/rebalancers.py +0 -0
  46. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/trackers/riskctrl.py +0 -0
  47. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/trackers/sizers.py +0 -0
  48. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/utils/__init__.py +0 -0
  49. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/utils/_pyxreloader.py +0 -0
  50. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/utils/charting/lookinglass.py +0 -0
  51. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/utils/charting/mpl_helpers.py +0 -0
  52. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/utils/marketdata/binance.py +0 -0
  53. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/utils/misc.py +0 -0
  54. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/utils/ntp.py +0 -0
  55. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/utils/runner.py +0 -0
  56. {qubx-0.2.5 → qubx-0.2.6}/src/qubx/utils/time.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Qubx
3
- Version: 0.2.5
3
+ Version: 0.2.6
4
4
  Summary: Qubx - quantitative trading framework
5
5
  Home-page: https://github.com/dmarienko/Qubx
6
6
  Author: Dmitry Marienko
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "Qubx"
3
- version = "0.2.5"
3
+ version = "0.2.6"
4
4
  description = "Qubx - quantitative trading framework"
5
5
  authors = ["Dmitry Marienko <dmitry@gmail.com>", "Yuriy Arabskyy <yuriy.arabskyy@gmail.com>"]
6
6
  readme = "README.md"
@@ -871,6 +871,9 @@ def _run_setup(
871
871
  _trigger = "bar: 0s"
872
872
  _stop = setup.generator.index[-1] # type: ignore
873
873
 
874
+ # - no historical data for generated signals, so disable it
875
+ enable_event_batching = False
876
+
874
877
  case _Types.SIGNAL_AND_TRACKER:
875
878
  strat = _GeneratedSignalsStrategy()
876
879
  strat.tracker = lambda ctx: setup.tracker
@@ -879,6 +882,9 @@ def _run_setup(
879
882
  _trigger = "bar: 0s"
880
883
  _stop = setup.generator.index[-1] # type: ignore
881
884
 
885
+ # - no historical data for generated signals, so disable it
886
+ enable_event_batching = False
887
+
882
888
  case _:
883
889
  raise ValueError(f"Unsupported setup type: {setup.setup_type} !")
884
890
 
@@ -146,7 +146,8 @@ class Instrument:
146
146
  take: float | None = None,
147
147
  group: str = "",
148
148
  comment: str = "",
149
- options: dict[str, Any] = None,
149
+ options: dict[str, Any] | None = None, # - probably we need to remove it ?
150
+ **kwargs,
150
151
  ) -> Signal:
151
152
  return Signal(
152
153
  self,
@@ -156,7 +157,7 @@ class Instrument:
156
157
  take=take,
157
158
  group=group,
158
159
  comment=comment,
159
- options=options or {},
160
+ options=(options or {}) | kwargs,
160
161
  )
161
162
 
162
163
  def __hash__(self) -> int:
@@ -794,9 +794,11 @@ def get_equity(
794
794
  return _get_single_equity(sessions)
795
795
 
796
796
 
797
- def _estimate_timeframe(session: TradingSessionResult | list[TradingSessionResult]) -> str:
797
+ def _estimate_timeframe(
798
+ session: TradingSessionResult | list[TradingSessionResult], start: str | None = None, stop: str | None = None
799
+ ) -> str:
798
800
  session = session[0] if isinstance(session, list) else session
799
- start, end = pd.Timestamp(session.start), pd.Timestamp(session.stop)
801
+ start, end = pd.Timestamp(start or session.start), pd.Timestamp(stop or session.stop)
800
802
  diff = end - start
801
803
  if diff > pd.Timedelta("360d"):
802
804
  return "1d"
@@ -889,6 +891,7 @@ def chart_signals(
889
891
  indicators={},
890
892
  overlay=[],
891
893
  info=True,
894
+ show_trades: bool = True,
892
895
  show_quantity: bool = False,
893
896
  show_value: bool = False,
894
897
  show_leverage: bool = True,
@@ -899,6 +902,8 @@ def chart_signals(
899
902
  Show trading signals on chart
900
903
  """
901
904
  indicators = indicators | {}
905
+ if timeframe is None:
906
+ timeframe = _estimate_timeframe(result, start, end)
902
907
 
903
908
  executions = result.executions_log.rename(
904
909
  columns={"instrument_id": "instrument", "filled_qty": "quantity", "price": "exec_price"}
@@ -954,13 +959,13 @@ def chart_signals(
954
959
 
955
960
  indicators = {k: __resample(v) for k, v in indicators.items()}
956
961
 
957
- excs = executions[executions["instrument"] == symbol][
958
- ["quantity", "exec_price", "commissions", "commissions_quoted"]
959
- ]
962
+ if show_trades:
963
+ excs = executions[executions["instrument"] == symbol][
964
+ ["quantity", "exec_price", "commissions", "commissions_quoted"]
965
+ ]
966
+ overlay = list(overlay) + [excs]
960
967
 
961
- chart = (
962
- LookingGlass([bars, excs, *overlay], indicators).look(start, end, title=symbol).hover(show_info=info, h=height)
963
- )
968
+ chart = LookingGlass([bars, *overlay], indicators).look(start, end, title=symbol).hover(show_info=info, h=height)
964
969
  if not show_table:
965
970
  return chart.show()
966
971
 
@@ -37,8 +37,9 @@ class Indexed:
37
37
  def __getitem__(self, idx): ...
38
38
 
39
39
  class TimeSeries:
40
+ name: str
40
41
  loc: Locator
41
- timeframe: str
42
+ timeframe: int
42
43
  max_series_length: int
43
44
  times: Indexed
44
45
  values: Indexed
@@ -77,6 +78,9 @@ class OHLCV(TimeSeries):
77
78
  def pd(self) -> pd.DataFrame: ...
78
79
 
79
80
  class Indicator(TimeSeries):
81
+ name: str
82
+ series: TimeSeries
83
+
80
84
  def update(self, time: int, value, new_item_started: bool) -> object: ...
81
85
 
82
86
  class IndicatorOHLC(Indicator): ...
@@ -144,7 +144,7 @@ cdef class Kama(Indicator):
144
144
  self._x_past[-1] = value
145
145
 
146
146
  cdef double rs = self.summator.update(abs(value - self._x_past[-2]), new_item_started)
147
- cdef double er = abs(value - self._x_past[0]) / rs
147
+ cdef double er = (abs(value - self._x_past[0]) / rs) if rs != 0.0 else 1.0
148
148
  cdef double sc = (er * self._K1 + self._S1) ** 2
149
149
 
150
150
  if self.summator.is_init_stage:
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