Qubx 0.1.5__cp311-cp311-manylinux_2_35_x86_64.whl → 0.1.6__cp311-cp311-manylinux_2_35_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.cpython-311-x86_64-linux-gnu.so +0 -0
- qubx/core/utils.cpython-311-x86_64-linux-gnu.so +0 -0
- qubx/data/readers.py +66 -16
- qubx/ta/indicators.cpython-311-x86_64-linux-gnu.so +0 -0
- qubx/utils/_pyxreloader.py +8 -4
- qubx/utils/time.py +2 -2
- {qubx-0.1.5.dist-info → qubx-0.1.6.dist-info}/METADATA +9 -1
- {qubx-0.1.5.dist-info → qubx-0.1.6.dist-info}/RECORD +9 -9
- {qubx-0.1.5.dist-info → qubx-0.1.6.dist-info}/WHEEL +0 -0
|
Binary file
|
|
Binary file
|
qubx/data/readers.py
CHANGED
|
@@ -465,15 +465,26 @@ class QuestDBConnector(DataReader):
|
|
|
465
465
|
chunksize=0, # TODO: use self._cursor.fetchmany in this case !!!!
|
|
466
466
|
timeframe: str='1m') -> Any:
|
|
467
467
|
start, end = handle_start_stop(start, stop)
|
|
468
|
-
|
|
469
|
-
w1 = f"timestamp <= '{end}'" if end else ''
|
|
470
|
-
where = f'where {w0} and {w1}' if (w0 and w1) else f"where {(w0 or w1)}"
|
|
468
|
+
_req = self._prepare_data_sql(data_id, start, end, timeframe)
|
|
471
469
|
|
|
470
|
+
self._cursor.execute(_req) # type: ignore
|
|
471
|
+
records = self._cursor.fetchall() # TODO: for chunksize > 0 use fetchmany etc
|
|
472
|
+
|
|
473
|
+
names = [d.name for d in self._cursor.description] # type: ignore
|
|
474
|
+
transform.start_transform(data_id, names)
|
|
475
|
+
|
|
476
|
+
transform.process_data(records)
|
|
477
|
+
return transform.collect()
|
|
478
|
+
|
|
479
|
+
def _prepare_data_sql(self, data_id: str, start: str|None, end: str|None, resample: str) -> str:
|
|
472
480
|
# just a temp hack - actually we need to discuss symbology etc
|
|
473
481
|
symbol = data_id#.split('.')[-1]
|
|
474
482
|
|
|
475
|
-
|
|
476
|
-
|
|
483
|
+
w0 = f"timestamp >= '{start}'" if start else ''
|
|
484
|
+
w1 = f"timestamp <= '{end}'" if end else ''
|
|
485
|
+
where = f'where {w0} and {w1}' if (w0 and w1) else f"where {(w0 or w1)}"
|
|
486
|
+
|
|
487
|
+
return f"""
|
|
477
488
|
select timestamp,
|
|
478
489
|
first(open) as open,
|
|
479
490
|
max(high) as high,
|
|
@@ -485,21 +496,15 @@ class QuestDBConnector(DataReader):
|
|
|
485
496
|
sum(taker_buy_volume) as taker_buy_volume,
|
|
486
497
|
sum(taker_buy_quote_volume) as taker_buy_quote_volume
|
|
487
498
|
from "{symbol.upper()}" {where}
|
|
488
|
-
SAMPLE by {
|
|
489
|
-
"""
|
|
490
|
-
)
|
|
491
|
-
records = self._cursor.fetchall() # TODO: for chunksize > 0 use fetchmany etc
|
|
492
|
-
names = [d.name for d in self._cursor.description]
|
|
499
|
+
SAMPLE by {resample};
|
|
500
|
+
"""
|
|
493
501
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
# d = np.array(records)
|
|
497
|
-
transform.process_data(records)
|
|
498
|
-
return transform.collect()
|
|
502
|
+
def _prepare_names_sql(self) -> str:
|
|
503
|
+
return "select table_name from tables()"
|
|
499
504
|
|
|
500
505
|
@_retry
|
|
501
506
|
def get_names(self) -> List[str] :
|
|
502
|
-
self._cursor.execute(
|
|
507
|
+
self._cursor.execute(self._prepare_names_sql()) # type: ignore
|
|
503
508
|
records = self._cursor.fetchall()
|
|
504
509
|
return [r[0] for r in records]
|
|
505
510
|
|
|
@@ -511,3 +516,48 @@ class QuestDBConnector(DataReader):
|
|
|
511
516
|
except:
|
|
512
517
|
pass
|
|
513
518
|
|
|
519
|
+
|
|
520
|
+
class SnapshotsBuilder(DataTransformer):
|
|
521
|
+
"""
|
|
522
|
+
Snapshots assembler from OB updates
|
|
523
|
+
"""
|
|
524
|
+
def __init__(self,
|
|
525
|
+
levels: int=-1, # how many levels restore, 1 - TOB, -1 - all
|
|
526
|
+
as_frame=False # result is dataframe
|
|
527
|
+
):
|
|
528
|
+
self.buffer = []
|
|
529
|
+
self.levels = levels
|
|
530
|
+
self.as_frame = as_frame
|
|
531
|
+
|
|
532
|
+
def start_transform(self, name: str, column_names: List[str]):
|
|
533
|
+
# initialize buffer / series etc
|
|
534
|
+
# let's keep restored snapshots into some buffer etc
|
|
535
|
+
self.buffer = []
|
|
536
|
+
|
|
537
|
+
# do additional init stuff here
|
|
538
|
+
|
|
539
|
+
def process_data(self, rows_data:List[List]) -> Any:
|
|
540
|
+
for r in rows_data:
|
|
541
|
+
# restore snapshots and put into buffer or series
|
|
542
|
+
pass
|
|
543
|
+
|
|
544
|
+
def collect(self) -> Any:
|
|
545
|
+
# - may be convert it to pandas DataFrame ?
|
|
546
|
+
if self.as_frame:
|
|
547
|
+
return pd.DataFrame.from_records(self.buffer) # or custom transform
|
|
548
|
+
|
|
549
|
+
# - or just returns as plain list
|
|
550
|
+
return self.buffer
|
|
551
|
+
|
|
552
|
+
|
|
553
|
+
class QuestDBOrderBookConnector(QuestDBConnector):
|
|
554
|
+
"""
|
|
555
|
+
Example of custom OrderBook data connector
|
|
556
|
+
"""
|
|
557
|
+
|
|
558
|
+
def _prepare_data_sql(self, data_id: str, start: str|None, end: str|None, resample: str|None) -> str:
|
|
559
|
+
raise NotImplemented("TODO")
|
|
560
|
+
|
|
561
|
+
def _prepare_names_sql(self) -> str:
|
|
562
|
+
# return "select table_name from tables() where ..."
|
|
563
|
+
raise NotImplemented("TODO")
|
|
Binary file
|
qubx/utils/_pyxreloader.py
CHANGED
|
@@ -5,10 +5,6 @@ from importlib.util import spec_from_file_location
|
|
|
5
5
|
from importlib.machinery import ExtensionFileLoader, SourceFileLoader
|
|
6
6
|
from typing import List
|
|
7
7
|
|
|
8
|
-
# - disable warn about deprecation of imp module: after dev stage _pyxreloader will be removed
|
|
9
|
-
import warnings
|
|
10
|
-
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
|
11
|
-
import imp
|
|
12
8
|
|
|
13
9
|
PYX_EXT = ".pyx"
|
|
14
10
|
PYXDEP_EXT = ".pyxdep"
|
|
@@ -49,6 +45,10 @@ def handle_dependencies(pyxfilename):
|
|
|
49
45
|
|
|
50
46
|
|
|
51
47
|
def handle_special_build(modname, pyxfilename):
|
|
48
|
+
try:
|
|
49
|
+
import imp
|
|
50
|
+
except:
|
|
51
|
+
return None, None
|
|
52
52
|
special_build = os.path.splitext(pyxfilename)[0] + PYXBLD_EXT
|
|
53
53
|
ext = None
|
|
54
54
|
setup_args={}
|
|
@@ -135,6 +135,10 @@ def build_module(name, pyxfilename, user_setup_args, pyxbuild_dir=None, inplace=
|
|
|
135
135
|
|
|
136
136
|
|
|
137
137
|
def load_module(name, pyxfilename, pyxbuild_dir=None, is_package=False, build_inplace=False, language_level=None, so_path=None):
|
|
138
|
+
try:
|
|
139
|
+
import imp
|
|
140
|
+
except:
|
|
141
|
+
return None
|
|
138
142
|
try:
|
|
139
143
|
if so_path is None:
|
|
140
144
|
if is_package:
|
qubx/utils/time.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
|
-
from typing import List, Optional, Union
|
|
2
|
+
from typing import List, Optional, Tuple, Union
|
|
3
3
|
import numpy as np
|
|
4
4
|
import re
|
|
5
5
|
|
|
@@ -115,7 +115,7 @@ def infer_series_frequency(series: Union[List, pd.DataFrame, pd.Series, pd.Datet
|
|
|
115
115
|
return np.timedelta64(max(freqs, key=freqs.get))
|
|
116
116
|
|
|
117
117
|
|
|
118
|
-
def handle_start_stop(s: Optional[str], e: Optional[str], convert=str) ->
|
|
118
|
+
def handle_start_stop(s: Optional[str], e: Optional[str], convert=str) -> Tuple[str|None, str|None]:
|
|
119
119
|
"""
|
|
120
120
|
Process start/stop times
|
|
121
121
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: Qubx
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: Qubx - quantitative trading framework
|
|
5
5
|
Home-page: https://github.com/dmarienko/Qubx
|
|
6
6
|
Author: Dmitry Marienko
|
|
@@ -15,17 +15,25 @@ Requires-Dist: croniter (>=2.0.5,<3.0.0)
|
|
|
15
15
|
Requires-Dist: cython (==3.0.8)
|
|
16
16
|
Requires-Dist: importlib-metadata
|
|
17
17
|
Requires-Dist: loguru (>=0.7.2,<0.8.0)
|
|
18
|
+
Requires-Dist: matplotlib (>=3.8.4,<4.0.0)
|
|
18
19
|
Requires-Dist: ntplib (>=0.4.0,<0.5.0)
|
|
20
|
+
Requires-Dist: numba (>=0.59.1,<0.60.0)
|
|
19
21
|
Requires-Dist: numpy (>=1.26.3,<2.0.0)
|
|
22
|
+
Requires-Dist: pandas (>=2.2.2,<3.0.0)
|
|
23
|
+
Requires-Dist: plotly (>=5.22.0,<6.0.0)
|
|
20
24
|
Requires-Dist: psycopg (>=3.1.18,<4.0.0)
|
|
25
|
+
Requires-Dist: psycopg-binary (>=3.1.19,<4.0.0)
|
|
26
|
+
Requires-Dist: psycopg-pool (>=3.2.2,<4.0.0)
|
|
21
27
|
Requires-Dist: pyarrow (>=15.0.0,<16.0.0)
|
|
22
28
|
Requires-Dist: pydantic (>=1.10.2,<2.0.0)
|
|
23
29
|
Requires-Dist: pymongo (>=4.6.1,<5.0.0)
|
|
24
30
|
Requires-Dist: pytest[lazyfixture] (>=7.2.0,<8.0.0)
|
|
25
31
|
Requires-Dist: python-binance (>=1.0.19,<2.0.0)
|
|
26
32
|
Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
|
|
33
|
+
Requires-Dist: scikit-learn (>=1.4.2,<2.0.0)
|
|
27
34
|
Requires-Dist: scipy (>=1.12.0,<2.0.0)
|
|
28
35
|
Requires-Dist: stackprinter (>=0.2.10,<0.3.0)
|
|
36
|
+
Requires-Dist: statsmodels (>=0.14.2,<0.15.0)
|
|
29
37
|
Requires-Dist: tqdm
|
|
30
38
|
Project-URL: Repository, https://github.com/dmarienko/Qubx
|
|
31
39
|
Description-Content-Type: text/markdown
|
|
@@ -6,13 +6,13 @@ qubx/core/basics.py,sha256=2u7WV5KX-RbTmzoKfi1yT4HNLDPfQcFMCUZ1pVsM_VE,14777
|
|
|
6
6
|
qubx/core/helpers.py,sha256=gPE78dO718NBY0-JbfqNGCzIvr4BVatFntNIy2RUrEY,11559
|
|
7
7
|
qubx/core/loggers.py,sha256=HpgavBZegoDv9ssihtqX0pitXKULVAPHUpoE_volJw0,11910
|
|
8
8
|
qubx/core/lookups.py,sha256=4aEC7b2AyEXFqHHGDenex3Z1FZGrpDSb8IwzBZrSqIA,13688
|
|
9
|
-
qubx/core/series.cpython-311-x86_64-linux-gnu.so,sha256=
|
|
9
|
+
qubx/core/series.cpython-311-x86_64-linux-gnu.so,sha256=48xXevH8u0RzK6uWFve0vgd6cCFBQcUqyXWRzOww198,698952
|
|
10
10
|
qubx/core/series.pxd,sha256=IS89NQ5FYp3T0YIHe1lELKZIAKrNvX8K6WlLyac44I4,2847
|
|
11
11
|
qubx/core/series.pyx,sha256=WEAjn4j3zn540Cxx68X5gRXilvwa7NGdbki6myzZbIM,28108
|
|
12
12
|
qubx/core/strategy.py,sha256=Fs4fFyHaEGYuz7mBeQHBWFu3Ipg0yFzcxXhskgsPxJE,30330
|
|
13
|
-
qubx/core/utils.cpython-311-x86_64-linux-gnu.so,sha256=
|
|
13
|
+
qubx/core/utils.cpython-311-x86_64-linux-gnu.so,sha256=bNoo-8OPy-YeF0AgPNPhBkcWjHuMWSIke-WiAKlA6wU,74216
|
|
14
14
|
qubx/core/utils.pyx,sha256=6dQ8R02bl8V3f-W3Wk9-e86D9OvDz-5-4NA_dlF_xwc,1368
|
|
15
|
-
qubx/data/readers.py,sha256=
|
|
15
|
+
qubx/data/readers.py,sha256=i_QbRaCXc5Lf4G22XIsl86YZBS0OrFSJq4wDuo3k-5w,21310
|
|
16
16
|
qubx/impl/ccxt_connector.py,sha256=NqF-tgxfTATnmVqKUonNXCAzECrDU8YrgqM3Nq06fw8,9150
|
|
17
17
|
qubx/impl/ccxt_customizations.py,sha256=kK_4KmOyKvDVgd4MTkVg4CyqdjE-6r41siZIvLj-A-Q,3488
|
|
18
18
|
qubx/impl/ccxt_trading.py,sha256=cmg4P-zd78w-V8j3-IGS2LFxikGhxFPgmCvz3sr065Q,9097
|
|
@@ -23,17 +23,17 @@ qubx/pandaz/__init__.py,sha256=Iw5uzicYGSC3FEKZ-W1O5-7cXq_P0kH11-EcXV0zZhs,175
|
|
|
23
23
|
qubx/pandaz/ta.py,sha256=TUvjrvmk4EQvDcXoRp6Os08-HUap-ZvpSDGawhViOgg,85271
|
|
24
24
|
qubx/pandaz/utils.py,sha256=FyLKQy8spkqxhBij_nPFC_ZzI_L3-IgB9O53MqWKmq0,19109
|
|
25
25
|
qubx/ta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
-
qubx/ta/indicators.cpython-311-x86_64-linux-gnu.so,sha256=
|
|
26
|
+
qubx/ta/indicators.cpython-311-x86_64-linux-gnu.so,sha256=ktYA1gKh1Lo-rNWs7LkeVcBu_6r4duK_Ju9hyzlKgQ8,284552
|
|
27
27
|
qubx/ta/indicators.pyx,sha256=P-GEYUks2lSHo6hbtUFAB7TWE1AunjLR4jIjwqPHrwU,7708
|
|
28
28
|
qubx/trackers/__init__.py,sha256=1y_yvIy0OQwBqfhAW_EY33NxFzFSWvI0qNAPU6zchYc,60
|
|
29
29
|
qubx/trackers/rebalancers.py,sha256=QCzANCooZBi2VMCBjjCPMq_Dt1h1zrBelATnfmVve74,5522
|
|
30
30
|
qubx/utils/__init__.py,sha256=XJFje4jP69pnPTp7fpTUmqwXz9PKzGYtJf8-kBofum0,273
|
|
31
|
-
qubx/utils/_pyxreloader.py,sha256=
|
|
31
|
+
qubx/utils/_pyxreloader.py,sha256=FyqGzfSpZGYziB8JYS5AP3cLRAvJSIPAKgwQn0E4YQ0,12017
|
|
32
32
|
qubx/utils/charting/mpl_helpers.py,sha256=ZaBrF0yOBOoVEk4TCBFi9KPyL3O5GPoteDglIzL8uSs,35158
|
|
33
33
|
qubx/utils/marketdata/binance.py,sha256=36dl4rxOAGTeY3uoONmiPanj8BkP0oBdDiH-URJJo9A,10993
|
|
34
34
|
qubx/utils/misc.py,sha256=z5rdz5hbRu9-F2QgF47OCkMvhfIkRKs-PHR8L5DWkBM,9831
|
|
35
35
|
qubx/utils/runner.py,sha256=OY7SoRfxHwzn0rKTGB_lbg5zNASEL_49hQXWqs-LiMk,9306
|
|
36
|
-
qubx/utils/time.py,sha256=
|
|
37
|
-
qubx-0.1.
|
|
38
|
-
qubx-0.1.
|
|
39
|
-
qubx-0.1.
|
|
36
|
+
qubx/utils/time.py,sha256=_DjCdQditzZwMy_8rvPdWyw5tjw__2p24LMPgXdZ8i0,4911
|
|
37
|
+
qubx-0.1.6.dist-info/METADATA,sha256=y_DcaF5WFk44CtZCJVQWfsON1wEAa1iSvz5cZjshGA8,2490
|
|
38
|
+
qubx-0.1.6.dist-info/WHEEL,sha256=MLOa6LysROdjgj4FVxsHitAnIh8Be2D_c9ZSBHKrz2M,110
|
|
39
|
+
qubx-0.1.6.dist-info/RECORD,,
|
|
File without changes
|