Qubx 0.6.56__cp312-cp312-manylinux_2_39_x86_64.whl → 0.6.57__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/context.py +7 -0
- qubx/core/helpers.py +8 -5
- qubx/core/interfaces.py +14 -0
- qubx/core/mixins/market.py +21 -0
- qubx/core/mixins/processing.py +1 -1
- qubx/core/series.cpython-312-x86_64-linux-gnu.so +0 -0
- qubx/core/series.pyx +1 -1
- qubx/core/utils.cpython-312-x86_64-linux-gnu.so +0 -0
- qubx/ta/indicators.cpython-312-x86_64-linux-gnu.so +0 -0
- {qubx-0.6.56.dist-info → qubx-0.6.57.dist-info}/METADATA +1 -1
- {qubx-0.6.56.dist-info → qubx-0.6.57.dist-info}/RECORD +14 -14
- {qubx-0.6.56.dist-info → qubx-0.6.57.dist-info}/LICENSE +0 -0
- {qubx-0.6.56.dist-info → qubx-0.6.57.dist-info}/WHEEL +0 -0
- {qubx-0.6.56.dist-info → qubx-0.6.57.dist-info}/entry_points.txt +0 -0
qubx/core/context.py
CHANGED
|
@@ -2,6 +2,8 @@ import traceback
|
|
|
2
2
|
from threading import Thread
|
|
3
3
|
from typing import Any, Callable
|
|
4
4
|
|
|
5
|
+
import pandas as pd
|
|
6
|
+
|
|
5
7
|
from qubx import logger
|
|
6
8
|
from qubx.core.basics import (
|
|
7
9
|
AssetBalance,
|
|
@@ -396,6 +398,11 @@ class StrategyContext(IStrategyContext):
|
|
|
396
398
|
def ohlc(self, instrument: Instrument, timeframe: str | None = None, length: int | None = None):
|
|
397
399
|
return self._market_data_provider.ohlc(instrument, timeframe, length)
|
|
398
400
|
|
|
401
|
+
def ohlc_pd(
|
|
402
|
+
self, instrument: Instrument, timeframe: str | None = None, length: int | None = None, consolidated: bool = True
|
|
403
|
+
) -> pd.DataFrame:
|
|
404
|
+
return self._market_data_provider.ohlc_pd(instrument, timeframe, length, consolidated)
|
|
405
|
+
|
|
399
406
|
def quote(self, instrument: Instrument):
|
|
400
407
|
return self._market_data_provider.quote(instrument)
|
|
401
408
|
|
qubx/core/helpers.py
CHANGED
|
@@ -156,7 +156,7 @@ class CachedMarketDataHolder:
|
|
|
156
156
|
|
|
157
157
|
# Update the last update for this instrument
|
|
158
158
|
if bars:
|
|
159
|
-
self._updates[instrument] = bars[
|
|
159
|
+
self._updates[instrument] = bars[-1] # Use the last bar as the last update
|
|
160
160
|
|
|
161
161
|
return ohlc
|
|
162
162
|
|
|
@@ -179,7 +179,10 @@ class CachedMarketDataHolder:
|
|
|
179
179
|
if instrument in self._ohlcvs:
|
|
180
180
|
self._last_bar[instrument] = bar
|
|
181
181
|
for ser in self._ohlcvs[instrument].values():
|
|
182
|
-
|
|
182
|
+
try:
|
|
183
|
+
ser.update_by_bar(bar.time, bar.open, bar.high, bar.low, bar.close, v_tot_inc, v_buy_inc)
|
|
184
|
+
except ValueError as e:
|
|
185
|
+
logger.warning(f"Can't update ohlc series for [{instrument.symbol}] ::: {str(e)}")
|
|
183
186
|
|
|
184
187
|
@SW.watch("CachedMarketDataHolder")
|
|
185
188
|
def update_by_quote(self, instrument: Instrument, quote: Quote):
|
|
@@ -203,12 +206,12 @@ class CachedMarketDataHolder:
|
|
|
203
206
|
continue
|
|
204
207
|
ser.update(trade.time, trade.price, total_vol, bought_vol)
|
|
205
208
|
|
|
206
|
-
def
|
|
209
|
+
def finalize_ohlc_for_instruments(self, time: dt_64, instruments: list[Instrument]):
|
|
207
210
|
"""
|
|
208
|
-
Finalize all OHLCV series at the given time.
|
|
211
|
+
Finalize all OHLCV series at the given time for the given instruments.
|
|
209
212
|
FIXME: (2025-06-17) This is part of urgent live fix and must be removed in future !!!.
|
|
210
213
|
"""
|
|
211
|
-
for instrument in
|
|
214
|
+
for instrument in instruments:
|
|
212
215
|
# - use most recent update
|
|
213
216
|
if (_u := self._updates.get(instrument)) is not None:
|
|
214
217
|
_px = extract_price(_u)
|
qubx/core/interfaces.py
CHANGED
|
@@ -508,6 +508,20 @@ class IMarketManager(ITimeProvider):
|
|
|
508
508
|
"""
|
|
509
509
|
...
|
|
510
510
|
|
|
511
|
+
def ohlc_pd(self, instrument: Instrument, timeframe: str | None = None, length: int | None = None, consolidated: bool = True) -> pd.DataFrame:
|
|
512
|
+
"""Get OHLCV data for an instrument as pandas DataFrame.
|
|
513
|
+
|
|
514
|
+
Args:
|
|
515
|
+
instrument: The instrument to get data for
|
|
516
|
+
timeframe (optional): The timeframe of the data. If None, the default timeframe is used.
|
|
517
|
+
length (optional): Number of bars to retrieve. If None, full cached data is returned.
|
|
518
|
+
consolidated (optional): If True, only finished bars are returned.
|
|
519
|
+
|
|
520
|
+
Returns:
|
|
521
|
+
pd.DataFrame: The OHLCV data as pandas DataFrame
|
|
522
|
+
"""
|
|
523
|
+
...
|
|
524
|
+
|
|
511
525
|
def quote(self, instrument: Instrument) -> Quote | None:
|
|
512
526
|
"""Get latest quote for an instrument.
|
|
513
527
|
|
qubx/core/mixins/market.py
CHANGED
|
@@ -73,6 +73,27 @@ class MarketManager(IMarketManager):
|
|
|
73
73
|
rc = self._cache.update_by_bars(instrument, timeframe, bars)
|
|
74
74
|
return rc
|
|
75
75
|
|
|
76
|
+
def ohlc_pd(
|
|
77
|
+
self,
|
|
78
|
+
instrument: Instrument,
|
|
79
|
+
timeframe: str | None = None,
|
|
80
|
+
length: int | None = None,
|
|
81
|
+
consolidated: bool = True,
|
|
82
|
+
) -> pd.DataFrame:
|
|
83
|
+
ohlc = self.ohlc(instrument, timeframe, length).pd()
|
|
84
|
+
|
|
85
|
+
if consolidated and timeframe:
|
|
86
|
+
_time = pd.Timestamp(self._time_provider.time())
|
|
87
|
+
_timedelta = pd.Timedelta(timeframe)
|
|
88
|
+
_last_bar_time = ohlc.index[-1]
|
|
89
|
+
if _last_bar_time + _timedelta >= _time:
|
|
90
|
+
ohlc = ohlc.iloc[:-1]
|
|
91
|
+
|
|
92
|
+
if length:
|
|
93
|
+
ohlc = ohlc.tail(length)
|
|
94
|
+
|
|
95
|
+
return ohlc
|
|
96
|
+
|
|
76
97
|
def quote(self, instrument: Instrument) -> Quote | None:
|
|
77
98
|
_data_provider = self._exchange_to_data_provider[instrument.exchange]
|
|
78
99
|
return _data_provider.get_quote(instrument)
|
qubx/core/mixins/processing.py
CHANGED
|
@@ -222,7 +222,7 @@ class ProcessingManager(IProcessingManager):
|
|
|
222
222
|
# - - - - - - - - - - - - - - - - - - - -
|
|
223
223
|
|
|
224
224
|
# - finalize OHLC data for all instruments
|
|
225
|
-
self._cache.
|
|
225
|
+
self._cache.finalize_ohlc_for_instruments(event.time, self._context.instruments)
|
|
226
226
|
|
|
227
227
|
with self._health_monitor("stg.trigger_event"):
|
|
228
228
|
_signals = self._wrap_signal_list(self._strategy.on_event(self._context, _trigger_event))
|
|
Binary file
|
qubx/core/series.pyx
CHANGED
|
@@ -273,7 +273,7 @@ cdef class TimeSeries:
|
|
|
273
273
|
return self._is_new_item
|
|
274
274
|
else:
|
|
275
275
|
if _dt < 0:
|
|
276
|
-
raise ValueError(f"Attempt to update past data at {time_to_str(time)} !")
|
|
276
|
+
raise ValueError(f"{self.name}.{self.timeframe}: Attempt to update past data at {time_to_str(time)} !")
|
|
277
277
|
self._update_last_item(item_start_time, value)
|
|
278
278
|
|
|
279
279
|
# - update indicators by new data
|
|
Binary file
|
|
Binary file
|
|
@@ -37,27 +37,27 @@ qubx/connectors/tardis/utils.py,sha256=epThu9DwqbDb7BgScH6fHa_FVpKUaItOqp3JwtKGc
|
|
|
37
37
|
qubx/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
38
|
qubx/core/account.py,sha256=4_XskMLR9Uh-rpJBDYMrceYiGMvAZw56k1ve-unIW8w,19417
|
|
39
39
|
qubx/core/basics.py,sha256=0Kk0LwBU4FqxGhzw9Mb3kgf692xZHjRs5Ogy6JW6C94,32928
|
|
40
|
-
qubx/core/context.py,sha256
|
|
40
|
+
qubx/core/context.py,sha256=-1WnpHXmxclCuWvq4_d5bBg02r6dtbpPrn2tEmKIoP4,23228
|
|
41
41
|
qubx/core/deque.py,sha256=3PsmJ5LF76JpsK4Wp5LLogyE15rKn6EDCkNOOWT6EOk,6203
|
|
42
42
|
qubx/core/errors.py,sha256=LENtlgmVzxxUFNCsuy4PwyHYhkZkxuZQ2BPif8jaGmw,1411
|
|
43
43
|
qubx/core/exceptions.py,sha256=11wQC3nnNLsl80zBqbE6xiKCqm31kctqo6W_gdnZkg8,581
|
|
44
|
-
qubx/core/helpers.py,sha256=
|
|
44
|
+
qubx/core/helpers.py,sha256=O6d813A5sdJfH-gfvWTpXuV-iQ4xkxxLu8iPMwAbMbw,19926
|
|
45
45
|
qubx/core/initializer.py,sha256=YgTBs5LpIk6ZFdmMD8zCnJnVNcMh1oeYvt157jhwyMg,4242
|
|
46
|
-
qubx/core/interfaces.py,sha256=
|
|
46
|
+
qubx/core/interfaces.py,sha256=7mY-2obGPyoKHq4Kv5b7g_70-OP6o69VWyRg_2gIcfE,59768
|
|
47
47
|
qubx/core/loggers.py,sha256=85Xgt1-Hh-2gAlJez3TxTHr32KSWYNqNhmbeWZwhw0o,13340
|
|
48
48
|
qubx/core/lookups.py,sha256=2UmODxDeDQqi-xHOvjm2_GckC4piKI3x4ZEf5vny8YI,18275
|
|
49
49
|
qubx/core/metrics.py,sha256=74xIecCvlxVXl0gy0JvgjJ2X5gg-RMmVZw9hQikkHE0,60269
|
|
50
50
|
qubx/core/mixins/__init__.py,sha256=AMCLvfNuIb1kkQl3bhCj9jIOEl2eKcVPJeyLgrkB-rk,329
|
|
51
|
-
qubx/core/mixins/market.py,sha256=
|
|
52
|
-
qubx/core/mixins/processing.py,sha256=
|
|
51
|
+
qubx/core/mixins/market.py,sha256=MH7A2jZFEClrfeioio1lPgYBbxVZCL1Af-b-DSFvSM4,4567
|
|
52
|
+
qubx/core/mixins/processing.py,sha256=pgzDCrB9A6SvsWaZ1Op-M22yvcWy6Y8L1IIef6rwpGM,30655
|
|
53
53
|
qubx/core/mixins/subscription.py,sha256=V_g9wCPQ8S5SHkU-qOZ84cV5nReAUrV7DoSNAGG0LPY,10372
|
|
54
54
|
qubx/core/mixins/trading.py,sha256=idfRPaqrvkfMxzu9mXr9i_xfqLee-ZAOrERxkxv6Ruo,7256
|
|
55
55
|
qubx/core/mixins/universe.py,sha256=tsMpBriLHwK9lAVYvIrO94EIx8_ETSXUlzxN_sDOsL8,9838
|
|
56
|
-
qubx/core/series.cpython-312-x86_64-linux-gnu.so,sha256=
|
|
56
|
+
qubx/core/series.cpython-312-x86_64-linux-gnu.so,sha256=CtCikl3YWB60CW205Dm9MwlVtjgcB5zuj5sXZ0PEpyo,978280
|
|
57
57
|
qubx/core/series.pxd,sha256=jBdMwgO8J4Zrue0e_xQ5RlqTXqihpzQNu6V3ckZvvpY,3978
|
|
58
58
|
qubx/core/series.pyi,sha256=RaHm_oHHiWiNUMJqVfx5FXAXniGLsHxUFOUpacn7GC0,4604
|
|
59
|
-
qubx/core/series.pyx,sha256=
|
|
60
|
-
qubx/core/utils.cpython-312-x86_64-linux-gnu.so,sha256=
|
|
59
|
+
qubx/core/series.pyx,sha256=ZQPp1-Kp2lX22n04gaBWak9mW139e-uc8bhsbZMohgs,46507
|
|
60
|
+
qubx/core/utils.cpython-312-x86_64-linux-gnu.so,sha256=Sg9UQCj4hovrE6dWSuTEbss5s82m19b9ScA6ECE7tQ4,86568
|
|
61
61
|
qubx/core/utils.pyi,sha256=a-wS13V2p_dM1CnGq40JVulmiAhixTwVwt0ah5By0Hc,348
|
|
62
62
|
qubx/core/utils.pyx,sha256=k5QHfEFvqhqWfCob89ANiJDKNG8gGbOh-O4CVoneZ8M,1696
|
|
63
63
|
qubx/data/__init__.py,sha256=ELZykvpPGWc5rX7QoNyNQwMLgdKMG8MACOByA4pM5hA,549
|
|
@@ -129,7 +129,7 @@ qubx/restorers/signal.py,sha256=0QFoy7OzDkK6AAmJEbbmSsHwmAhjMJYYggVFuLraKjk,1089
|
|
|
129
129
|
qubx/restorers/state.py,sha256=dLaVnUwRCNRkUqbYyi0RfZs3Q3AdglkI_qTtQ8GDD5Y,7289
|
|
130
130
|
qubx/restorers/utils.py,sha256=We2gfqwQKWziUYhuUnjb-xo-5tSlbuHWpPQn0CEMTn0,1155
|
|
131
131
|
qubx/ta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
132
|
-
qubx/ta/indicators.cpython-312-x86_64-linux-gnu.so,sha256=
|
|
132
|
+
qubx/ta/indicators.cpython-312-x86_64-linux-gnu.so,sha256=RxL_qH6tyCoHddeu7BwOmhkmV2aWPWGafq-My49AoX0,654440
|
|
133
133
|
qubx/ta/indicators.pxd,sha256=Goo0_N0Xnju8XGo3Xs-3pyg2qr_0Nh5C-_26DK8U_IE,4224
|
|
134
134
|
qubx/ta/indicators.pyi,sha256=19W0uERft49In5bf9jkJHkzJYEyE9gzudN7_DJ5Vdv8,1963
|
|
135
135
|
qubx/ta/indicators.pyx,sha256=Xgpew46ZxSXsdfSEWYn3A0Q35MLsopB9n7iyCsXTufs,25969
|
|
@@ -166,8 +166,8 @@ qubx/utils/runner/factory.py,sha256=eM4-Etcq-FewD2AjH_srFGzP413pm8er95KIZixXRpM,
|
|
|
166
166
|
qubx/utils/runner/runner.py,sha256=PnSQ_soWXzjcIYxG5HHUtbZnWSaoeSXr7VxbQWtOsII,31444
|
|
167
167
|
qubx/utils/time.py,sha256=J0ZFGjzFL5T6GA8RPAel8hKG0sg2LZXeQ5YfDCfcMHA,10055
|
|
168
168
|
qubx/utils/version.py,sha256=e52fIHyxzCiIuH7svCF6pkHuDlqL64rklqz-2XjWons,5309
|
|
169
|
-
qubx-0.6.
|
|
170
|
-
qubx-0.6.
|
|
171
|
-
qubx-0.6.
|
|
172
|
-
qubx-0.6.
|
|
173
|
-
qubx-0.6.
|
|
169
|
+
qubx-0.6.57.dist-info/LICENSE,sha256=qwMHOSJ2TD0nx6VUJvFhu1ynJdBfNozRMt6tnSul-Ts,35140
|
|
170
|
+
qubx-0.6.57.dist-info/METADATA,sha256=udbK6RAZPp6B3-XXug773pK6FZg3PFnYuUFuoYzrbOE,4612
|
|
171
|
+
qubx-0.6.57.dist-info/WHEEL,sha256=UckHTmFUCaLKpi4yFY8Dewu0c6XkY-KvEAGzGOnaWo8,110
|
|
172
|
+
qubx-0.6.57.dist-info/entry_points.txt,sha256=VqilDTe8mVuV9SbR-yVlZJBTjbkHIL2JBgXfQw076HY,47
|
|
173
|
+
qubx-0.6.57.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|