Qubx 0.7.6__cp312-cp312-manylinux_2_39_x86_64.whl → 0.7.7__cp312-cp312-manylinux_2_39_x86_64.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.

Potentially problematic release.


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

qubx/core/series.pxd CHANGED
@@ -172,4 +172,13 @@ cdef class GenericSeries(TimeSeries):
172
172
 
173
173
 
174
174
  cdef class IndicatorGeneric(Indicator):
175
- pass
175
+ pass
176
+
177
+
178
+ cdef class SeriesCachedValue:
179
+ cdef double cached_ser_value
180
+ cdef long long cached_ser_time
181
+ cdef int cached_ser_idx
182
+ cdef TimeSeries ser
183
+
184
+ cdef double value(self, long long time)
qubx/core/series.pyi CHANGED
@@ -244,3 +244,5 @@ def lag(series: TimeSeries, period: int) -> "Indicator":
244
244
  Only positive shift (from past) period is allowed.
245
245
  """
246
246
  ...
247
+
248
+ class SeriesCachedValue: ...
qubx/core/series.pyx CHANGED
@@ -554,6 +554,41 @@ cdef class Resampler(TimeSeries):
554
554
  super().update(time, value)
555
555
 
556
556
 
557
+ cdef class SeriesCachedValue:
558
+ def __init__(self, TimeSeries ser):
559
+ # - initialize series cache
560
+ self.cached_ser_value = np.nan
561
+ self.cached_ser_time = -1
562
+ self.cached_ser_idx = -1
563
+ self.ser = ser
564
+
565
+ cdef double value(self, long long time):
566
+ cdef double ser_value
567
+ cdef long long ser_period_start
568
+ cdef int idx
569
+
570
+ if len(self.ser) > 0:
571
+ # - calculate period start for volatility timeframe
572
+ ser_period_start = floor_t64(time, self.ser.series.timeframe)
573
+
574
+ # - only do lookup when period changes (cache within same period)
575
+ if ser_period_start != self.cached_ser_time:
576
+ idx = self.ser.times.lookup_idx(time, 'ffill')
577
+ if idx >= 0:
578
+ self.cached_ser_value = self.ser.values.values[idx]
579
+ self.cached_ser_idx = idx
580
+ else:
581
+ self.cached_ser_value = np.nan
582
+ self.cached_ser_idx = -1
583
+ self.cached_ser_time = ser_period_start
584
+
585
+ ser_value = self.cached_ser_value
586
+ else:
587
+ ser_value = np.nan
588
+
589
+ return ser_value
590
+
591
+
557
592
  cdef class Lag(Indicator):
558
593
  cdef int period
559
594
 
qubx/ta/indicators.pxd CHANGED
@@ -1,5 +1,5 @@
1
1
  cimport numpy as np
2
- from qubx.core.series cimport Indicator, IndicatorOHLC, RollingSum, TimeSeries, OHLCV, Bar
2
+ from qubx.core.series cimport Indicator, IndicatorOHLC, RollingSum, TimeSeries, OHLCV, Bar, SeriesCachedValue
3
3
 
4
4
  cdef class Sma(Indicator):
5
5
  cdef unsigned int period
@@ -200,14 +200,10 @@ cdef class StdEma(Indicator):
200
200
  cpdef double calculate(self, long long time, double value, short new_item_started)
201
201
 
202
202
  cdef class CusumFilter(Indicator):
203
- cdef TimeSeries target
204
203
  cdef double s_pos, s_neg
205
204
  cdef double prev_value
206
205
  cdef double saved_s_pos, saved_s_neg, saved_prev_value
207
- # - cache for target value to avoid repeated lookups
208
- cdef double cached_target_value
209
- cdef long long cached_target_time
210
- cdef int cached_target_idx
206
+ cdef SeriesCachedValue target_cache
211
207
 
212
208
  cdef void _store(self)
213
209
 
qubx/ta/indicators.pyx CHANGED
@@ -4,7 +4,7 @@ cimport numpy as np
4
4
  from scipy.special.cython_special import ndtri, stdtrit, gamma
5
5
  from collections import deque
6
6
 
7
- from qubx.core.series cimport TimeSeries, Indicator, IndicatorOHLC, RollingSum, nans, OHLCV, Bar
7
+ from qubx.core.series cimport TimeSeries, Indicator, IndicatorOHLC, RollingSum, nans, OHLCV, Bar, SeriesCachedValue
8
8
  from qubx.core.utils import time_to_str
9
9
  from qubx.pandaz.utils import scols, srows
10
10
 
@@ -1385,13 +1385,10 @@ cdef class CusumFilter(Indicator):
1385
1385
  """
1386
1386
 
1387
1387
  def __init__(self, str name, TimeSeries series, TimeSeries target):
1388
- self.target = target
1388
+ self.target_cache = SeriesCachedValue(target)
1389
1389
  self.s_pos = 0.0
1390
1390
  self.s_neg = 0.0
1391
1391
  self.prev_value = np.nan
1392
- self.cached_target_value = np.nan
1393
- self.cached_target_time = -1
1394
- self.cached_target_idx = -1
1395
1392
  super().__init__(name, series)
1396
1393
 
1397
1394
  cdef void _store(self):
@@ -1432,28 +1429,8 @@ cdef class CusumFilter(Indicator):
1432
1429
  self.s_neg = min(0.0, self.s_neg + diff)
1433
1430
 
1434
1431
  # - get threshold from target series (it can be from higher timeframe)
1435
- # - use caching to avoid repeated lookups for the same target period
1436
- cdef int idx
1437
- cdef long long target_period_start
1438
-
1439
- if len(self.target) > 0:
1440
- # - calculate the period start time for the target timeframe
1441
- target_period_start = floor_t64(time, self.target.timeframe)
1442
-
1443
- # - check if we need to update the cached value
1444
- if target_period_start != self.cached_target_time:
1445
- idx = self.target.times.lookup_idx(time, 'ffill')
1446
- if idx >= 0:
1447
- self.cached_target_value = self.target.values.values[idx]
1448
- self.cached_target_idx = idx
1449
- else:
1450
- self.cached_target_value = np.nan
1451
- self.cached_target_idx = -1
1452
- self.cached_target_time = target_period_start
1453
-
1454
- target_value = self.cached_target_value
1455
- else:
1456
- target_value = np.nan
1432
+ # - SeriesCachedValue handles caching automatically
1433
+ target_value = self.target_cache.value(time)
1457
1434
 
1458
1435
  # - only check for events if threshold is available
1459
1436
  if not np.isnan(target_value):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: Qubx
3
- Version: 0.7.6
3
+ Version: 0.7.7
4
4
  Summary: Qubx - Quantitative Trading Framework
5
5
  License-File: LICENSE
6
6
  Author: Dmitry Marienko
@@ -103,11 +103,11 @@ qubx/core/mixins/subscription.py,sha256=2nUikNNPsMExS9yO38kNt7jk1vKE-RPm0b3h1bU6
103
103
  qubx/core/mixins/trading.py,sha256=jW4P6Gba0O1kaQIy5rl3UqwPwAmEJrMdGYoWj1AhleI,20422
104
104
  qubx/core/mixins/universe.py,sha256=aj1Ai_WUccotBt419SMPgAf2xPZL5n0U9CdTD4tQGGI,10845
105
105
  qubx/core/mixins/utils.py,sha256=P71cLuqKjId8989MwOL_BtvvCnnwOFMkZyB1SY-0Ork,147
106
- qubx/core/series.cpython-312-x86_64-linux-gnu.so,sha256=raCBNQqOmDLbQriqLeYWGFFv1kf69c-VEgl9tJBxUcw,1175336
107
- qubx/core/series.pxd,sha256=YZ8WWQLjyn6fpIlyfnRlARoY3w0XzrvKZkCRlfkt-C0,4998
108
- qubx/core/series.pyi,sha256=axEc8DBfeCUYu4NZ2eRiL5oWaWhed-uYlR3U0d1QBos,8020
109
- qubx/core/series.pyx,sha256=FMUCWKFyNj08TKVhR7gOR4UHob5ZFvdahc4nipyVKe8,62339
110
- qubx/core/utils.cpython-312-x86_64-linux-gnu.so,sha256=BTSDP0ivS5vJeC88QBJ_LaQYk_L-LFqvSBIqe9DzbD4,86568
106
+ qubx/core/series.cpython-312-x86_64-linux-gnu.so,sha256=Q-6SCxJmZAkuWxWRFphargNO9HWdBJrWlf9Rk0OAXz4,1192328
107
+ qubx/core/series.pxd,sha256=DebCNOl7e7_OIZLTG-vSqubcgYuE0EC2_0-dov7QoIM,5195
108
+ qubx/core/series.pyi,sha256=5xJ0-_SOGhfGgbu1RGyjP4b0T6oRyckS9LoRePPAHqs,8050
109
+ qubx/core/series.pyx,sha256=A-6BbaweFmeuwNvcg-yMrLPQodAFbjZeHqrVfvE2x-o,63520
110
+ qubx/core/utils.cpython-312-x86_64-linux-gnu.so,sha256=XXCpcz4qQ4bz1E9zWRMjqAszANgkS0ybZhVAUCKgC4o,86568
111
111
  qubx/core/utils.pyi,sha256=a-wS13V2p_dM1CnGq40JVulmiAhixTwVwt0ah5By0Hc,348
112
112
  qubx/core/utils.pyx,sha256=UR9achMR-LARsztd2eelFsDsFH3n0gXACIKoGNPI9X4,1766
113
113
  qubx/data/__init__.py,sha256=cCUJjuq0LCBeeOKXIvBh_YQI00je_IQmr9OcHARJCPE,896
@@ -188,10 +188,10 @@ qubx/restorers/signal.py,sha256=5nK5ji8AucyWrFBK9uW619YCI_vPRGFnuDu8JnG3B_Y,1451
188
188
  qubx/restorers/state.py,sha256=I1VIN0ZcOjigc3WMHIYTNJeAAbN9YB21MDcMl04ZWmY,8018
189
189
  qubx/restorers/utils.py,sha256=We2gfqwQKWziUYhuUnjb-xo-5tSlbuHWpPQn0CEMTn0,1155
190
190
  qubx/ta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
191
- qubx/ta/indicators.cpython-312-x86_64-linux-gnu.so,sha256=Ez93JglVhpz7LIzVW6bHloihxmsMssY54hP-kzfyU5A,950440
192
- qubx/ta/indicators.pxd,sha256=khYJZY3nn33jeVaURpDwF-GCMtrNwzMkPv43aB6zOv0,6563
191
+ qubx/ta/indicators.cpython-312-x86_64-linux-gnu.so,sha256=WD50vIgpRAN7bDUP3hgkfdkVWd23U5NJ4LBTaF-QOKM,946344
192
+ qubx/ta/indicators.pxd,sha256=Tp8eBSdur-cAdChZjAow6sJi5URyVr8zkcPYZbu9vVU,6433
193
193
  qubx/ta/indicators.pyi,sha256=XNySCW8WE3j4lpCUU2BKRjnAQ7kjjGBXvdowhLBuEAM,3719
194
- qubx/ta/indicators.pyx,sha256=igtVvX81a3Fv5o_3n4dtCVaom7JN3RP25CT8cwJMz7Y,55757
194
+ qubx/ta/indicators.pyx,sha256=qtI0UbI9C3iwhY4zU1uoNN0kiV-pd-1YU04T7_LObLI,54845
195
195
  qubx/templates/__init__.py,sha256=L2U6tX5DGhtIDRarIo3tHT7ZVQKNJMlpWn_sinJPevk,153
196
196
  qubx/templates/base.py,sha256=cY9Lnvs8hvuqyyBwMN-p7rXWGETrbAx0zmE6Px19Ym4,6844
197
197
  qubx/templates/project/accounts.toml.j2,sha256=LlaYWqOalMimGf7n_4sIzJk9p28tNbhZFogg3SHplSQ,637
@@ -223,7 +223,7 @@ qubx/utils/charting/orderbook.py,sha256=NmeXxru3CUiKLtl1DzCBbQgSdL4qmTDIxV0u81p2
223
223
  qubx/utils/collections.py,sha256=go2sH_q2TlXqI3Vxq8GHLfNGlYL4JwS3X1lwJWbpFLE,7425
224
224
  qubx/utils/hft/__init__.py,sha256=rZjNmRtD1TWAEe7JPgiak9qJftf8yQavLviWReKQJ5w,101
225
225
  qubx/utils/hft/numba_utils.py,sha256=C_C3MwEW5ZbLhOMSH6SSYbQ7BfnvuKhgOtY_N-U-ULM,146
226
- qubx/utils/hft/orderbook.cpython-312-x86_64-linux-gnu.so,sha256=GI8EGU_TOBReSf1uWE07bJXsvWaTTiwdKvAT1me8Y1U,316592
226
+ qubx/utils/hft/orderbook.cpython-312-x86_64-linux-gnu.so,sha256=FTJyDKFdjoB3oQo8j3ArMFxegBxORWwmz2uG-f-2b5c,316592
227
227
  qubx/utils/hft/orderbook.pyi,sha256=F2P9kbh314wjCwfn6BivFWQMEDMLnZDQ2rmWbGoM7-o,5076
228
228
  qubx/utils/hft/orderbook.pyx,sha256=gbNrtpNRZjZ8DjXjrIXsw20UixErDrLzN-8Qep8sSJg,15217
229
229
  qubx/utils/marketdata/binance.py,sha256=hWX3noZj704JIMBqlwsXA5IzUP7EgiLiC2r12dJAKQA,11565
@@ -242,7 +242,7 @@ qubx/utils/plotting/renderers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
242
242
  qubx/utils/plotting/renderers/plotly.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
243
243
  qubx/utils/questdb.py,sha256=fIOMImSa3N3eZKMakHqs5q5ld4m5jkG6IkrTGfuvXFg,5191
244
244
  qubx/utils/rate_limiter.py,sha256=nI4yJ2VjTGoHYPQvURyd7rtpfn37ms6xd0hLt6RJeDc,7008
245
- qubx/utils/ringbuffer.cpython-312-x86_64-linux-gnu.so,sha256=k4G3Gh4RrAxol5ki1Y_EhErw-Iv6P0MknZmbKFJaMR8,108328
245
+ qubx/utils/ringbuffer.cpython-312-x86_64-linux-gnu.so,sha256=DlC_U9OtXmDfVtY-i9W_6lMKNZ24XeIcjm1JAiJ4rjg,108328
246
246
  qubx/utils/ringbuffer.pxd,sha256=NiLNnVwSJuDZj6M99DnHt07OEhKVBlEEf80rNukJJeQ,374
247
247
  qubx/utils/ringbuffer.pyi,sha256=H0MD68jctVlko09KfxI9-1MloapO5Ba6smaqx1_X5Zo,4580
248
248
  qubx/utils/ringbuffer.pyx,sha256=3S8MQreAKMfhaMm3RwztfEQ2AJYDyfPQpfMAsb-JCWA,7069
@@ -270,8 +270,8 @@ qubx/utils/slack.py,sha256=jhos-5pNGomg3TvFZRVvF0b_FrzxfvnTqAEMlDIrgn8,12234
270
270
  qubx/utils/time.py,sha256=SYOiz2UqX7dCUhO_vBeWcm42_LmDl-59wp7INu0R8is,15355
271
271
  qubx/utils/version.py,sha256=e52fIHyxzCiIuH7svCF6pkHuDlqL64rklqz-2XjWons,5309
272
272
  qubx/utils/websocket_manager.py,sha256=ld4jvwnWyIkdKpgpUzyfnXGT3Ul4bGemXjy4HX9XTKs,17182
273
- qubx-0.7.6.dist-info/METADATA,sha256=NoXwGPDHHrP7vctkmbL_pHxpeYA3hiieAUzfF3M1DRM,6062
274
- qubx-0.7.6.dist-info/WHEEL,sha256=RA6gLSyyVpI0R7d3ofBrM1iY5kDUsPwh15AF0XpvgQo,110
275
- qubx-0.7.6.dist-info/entry_points.txt,sha256=VqilDTe8mVuV9SbR-yVlZJBTjbkHIL2JBgXfQw076HY,47
276
- qubx-0.7.6.dist-info/licenses/LICENSE,sha256=qwMHOSJ2TD0nx6VUJvFhu1ynJdBfNozRMt6tnSul-Ts,35140
277
- qubx-0.7.6.dist-info/RECORD,,
273
+ qubx-0.7.7.dist-info/METADATA,sha256=3NMSoJmXAObmWDGUY7XyyVoTfWd8WL_i779zELosbsk,6062
274
+ qubx-0.7.7.dist-info/WHEEL,sha256=RA6gLSyyVpI0R7d3ofBrM1iY5kDUsPwh15AF0XpvgQo,110
275
+ qubx-0.7.7.dist-info/entry_points.txt,sha256=VqilDTe8mVuV9SbR-yVlZJBTjbkHIL2JBgXfQw076HY,47
276
+ qubx-0.7.7.dist-info/licenses/LICENSE,sha256=qwMHOSJ2TD0nx6VUJvFhu1ynJdBfNozRMt6tnSul-Ts,35140
277
+ qubx-0.7.7.dist-info/RECORD,,
File without changes