Qubx 0.1.82__tar.gz → 0.1.84__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.
- {qubx-0.1.82 → qubx-0.1.84}/PKG-INFO +1 -1
- {qubx-0.1.82 → qubx-0.1.84}/pyproject.toml +1 -1
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/__init__.py +62 -32
- qubx-0.1.84/src/qubx/data/readers.py +1007 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/misc.py +70 -60
- qubx-0.1.82/src/qubx/data/readers.py +0 -695
- {qubx-0.1.82 → qubx-0.1.84}/README.md +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/build.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/_nb_magic.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/__init__.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/account.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/basics.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/helpers.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/loggers.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/lookups.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/series.pxd +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/series.pyx +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/strategy.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/utils.pyx +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/impl/ccxt_connector.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/impl/ccxt_customizations.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/impl/ccxt_trading.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/impl/ccxt_utils.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/math/__init__.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/math/stats.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/pandaz/__init__.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/pandaz/ta.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/pandaz/utils.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/ta/__init__.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/ta/indicators.pyx +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/trackers/__init__.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/trackers/rebalancers.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/__init__.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/_pyxreloader.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/charting/mpl_helpers.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/marketdata/binance.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/runner.py +0 -0
- {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/time.py +0 -0
|
@@ -10,13 +10,20 @@ def formatter(record):
|
|
|
10
10
|
end = record["extra"].get("end", "\n")
|
|
11
11
|
fmt = "<lvl>{message}</lvl>%s" % end
|
|
12
12
|
if record["level"].name in {"WARNING", "SNAKY"}:
|
|
13
|
-
fmt =
|
|
13
|
+
fmt = (
|
|
14
|
+
"<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - %s" % fmt
|
|
15
|
+
)
|
|
14
16
|
|
|
15
|
-
prefix =
|
|
17
|
+
prefix = (
|
|
18
|
+
"<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> [ <level>%s</level> ] "
|
|
19
|
+
% record["level"].icon
|
|
20
|
+
)
|
|
16
21
|
|
|
17
22
|
if record["exception"] is not None:
|
|
18
23
|
# stackprinter.set_excepthook(style='darkbg2')
|
|
19
|
-
record["extra"]["stack"] = stackprinter.format(
|
|
24
|
+
record["extra"]["stack"] = stackprinter.format(
|
|
25
|
+
record["exception"], style="darkbg"
|
|
26
|
+
)
|
|
20
27
|
fmt += "\n{extra[stack]}\n"
|
|
21
28
|
|
|
22
29
|
if record["level"].name in {"TEXT"}:
|
|
@@ -25,24 +32,43 @@ def formatter(record):
|
|
|
25
32
|
return prefix + fmt
|
|
26
33
|
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
"handlers": [ {"sink": sys.stdout, "format": "{time} - {message}"}, ],
|
|
30
|
-
"extra": {"user": "someone"},
|
|
31
|
-
}
|
|
35
|
+
class QubxLogConfig:
|
|
32
36
|
|
|
37
|
+
@staticmethod
|
|
38
|
+
def get_log_level():
|
|
39
|
+
return os.getenv("QUBX_LOG_LEVEL", "DEBUG")
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def set_log_level(level: str):
|
|
43
|
+
os.environ["QUBX_LOG_LEVEL"] = level
|
|
44
|
+
QubxLogConfig.setup_logger(level)
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def setup_logger(level: str | None = None):
|
|
48
|
+
global logger
|
|
49
|
+
config = {
|
|
50
|
+
"handlers": [
|
|
51
|
+
{"sink": sys.stdout, "format": "{time} - {message}"},
|
|
52
|
+
],
|
|
53
|
+
"extra": {"user": "someone"},
|
|
54
|
+
}
|
|
55
|
+
logger.configure(**config)
|
|
56
|
+
logger.remove(None)
|
|
57
|
+
level = level or QubxLogConfig.get_log_level()
|
|
58
|
+
logger.add(sys.stdout, format=formatter, colorize=True, level=level)
|
|
59
|
+
logger = logger.opt(colors=True)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
QubxLogConfig.setup_logger()
|
|
33
63
|
|
|
34
|
-
logger.configure(**config)
|
|
35
|
-
logger.remove(None)
|
|
36
|
-
logger.add(sys.stdout, format=formatter, colorize=True)
|
|
37
|
-
logger = logger.opt(colors=True)
|
|
38
64
|
|
|
39
65
|
# - global lookup helper
|
|
40
66
|
lookup = GlobalLookup(InstrumentsLookup(), FeesLookup())
|
|
41
67
|
|
|
42
68
|
|
|
43
69
|
# registering magic for jupyter notebook
|
|
44
|
-
if runtime_env() in [
|
|
45
|
-
from IPython.core.magic import
|
|
70
|
+
if runtime_env() in ["notebook", "shell"]:
|
|
71
|
+
from IPython.core.magic import Magics, magics_class, line_magic, line_cell_magic
|
|
46
72
|
from IPython import get_ipython
|
|
47
73
|
|
|
48
74
|
@magics_class
|
|
@@ -52,11 +78,11 @@ if runtime_env() in ['notebook', 'shell']:
|
|
|
52
78
|
|
|
53
79
|
@line_magic
|
|
54
80
|
def qubxd(self, line: str):
|
|
55
|
-
self.qubx_setup(
|
|
81
|
+
self.qubx_setup("dark" + " " + line)
|
|
56
82
|
|
|
57
83
|
@line_magic
|
|
58
84
|
def qubxl(self, line: str):
|
|
59
|
-
self.qubx_setup(
|
|
85
|
+
self.qubx_setup("light" + " " + line)
|
|
60
86
|
|
|
61
87
|
@line_magic
|
|
62
88
|
def qubx_setup(self, line: str):
|
|
@@ -64,25 +90,26 @@ if runtime_env() in ['notebook', 'shell']:
|
|
|
64
90
|
QUBX framework initialization
|
|
65
91
|
"""
|
|
66
92
|
import os
|
|
67
|
-
|
|
68
|
-
|
|
93
|
+
|
|
94
|
+
args = [x.strip() for x in line.split(" ")]
|
|
95
|
+
|
|
69
96
|
# setup cython dev hooks - only if 'dev' is passed as argument
|
|
70
|
-
if line and
|
|
97
|
+
if line and "dev" in args:
|
|
71
98
|
install_pyx_recompiler_for_dev()
|
|
72
99
|
|
|
73
100
|
tpl_path = os.path.join(os.path.dirname(__file__), "_nb_magic.py")
|
|
74
|
-
with open(tpl_path,
|
|
101
|
+
with open(tpl_path, "r", encoding="utf8") as myfile:
|
|
75
102
|
s = myfile.read()
|
|
76
103
|
|
|
77
104
|
exec(s, self.shell.user_ns)
|
|
78
105
|
|
|
79
106
|
# setup more funcy mpl theme instead of ugly default
|
|
80
107
|
if line:
|
|
81
|
-
if
|
|
82
|
-
set_mpl_theme(
|
|
108
|
+
if "dark" in line.lower():
|
|
109
|
+
set_mpl_theme("dark")
|
|
83
110
|
|
|
84
|
-
elif
|
|
85
|
-
set_mpl_theme(
|
|
111
|
+
elif "light" in line.lower():
|
|
112
|
+
set_mpl_theme("light")
|
|
86
113
|
|
|
87
114
|
# install additional plotly helpers
|
|
88
115
|
# from qube.charting.plot_helpers import install_plotly_helpers
|
|
@@ -91,6 +118,7 @@ if runtime_env() in ['notebook', 'shell']:
|
|
|
91
118
|
def _get_manager(self):
|
|
92
119
|
if self.__manager is None:
|
|
93
120
|
import multiprocessing as m
|
|
121
|
+
|
|
94
122
|
self.__manager = m.Manager()
|
|
95
123
|
return self.__manager
|
|
96
124
|
|
|
@@ -102,7 +130,7 @@ if runtime_env() in ['notebook', 'shell']:
|
|
|
102
130
|
>>> %%proc x, y as MyProc1
|
|
103
131
|
>>> x.set('Hello')
|
|
104
132
|
>>> y.set([1,2,3,4])
|
|
105
|
-
|
|
133
|
+
|
|
106
134
|
"""
|
|
107
135
|
import multiprocessing as m
|
|
108
136
|
import time, re
|
|
@@ -111,8 +139,8 @@ if runtime_env() in ['notebook', 'shell']:
|
|
|
111
139
|
name = None
|
|
112
140
|
if line:
|
|
113
141
|
# check if custom process name was provided
|
|
114
|
-
if
|
|
115
|
-
line, name = line.split(
|
|
142
|
+
if " as " in line:
|
|
143
|
+
line, name = line.split("as")
|
|
116
144
|
if not name.isspace():
|
|
117
145
|
name = name.strip()
|
|
118
146
|
else:
|
|
@@ -120,11 +148,11 @@ if runtime_env() in ['notebook', 'shell']:
|
|
|
120
148
|
return
|
|
121
149
|
|
|
122
150
|
ipy = get_ipython()
|
|
123
|
-
for a in [x for x in re.split(
|
|
151
|
+
for a in [x for x in re.split("[\ ,;]", line.strip()) if x]:
|
|
124
152
|
ipy.push({a: self._get_manager().Value(None, None)})
|
|
125
153
|
|
|
126
154
|
# code to run
|
|
127
|
-
lines =
|
|
155
|
+
lines = "\n".join([" %s" % x for x in cell.split("\n")])
|
|
128
156
|
|
|
129
157
|
def fn():
|
|
130
158
|
result = get_ipython().run_cell(lines)
|
|
@@ -136,17 +164,18 @@ if runtime_env() in ['notebook', 'shell']:
|
|
|
136
164
|
if result.error_in_exec:
|
|
137
165
|
raise result.error_in_exec
|
|
138
166
|
|
|
139
|
-
t_start = str(time.time()).replace(
|
|
140
|
-
f_id = f
|
|
167
|
+
t_start = str(time.time()).replace(".", "_")
|
|
168
|
+
f_id = f"proc_{t_start}" if name is None else name
|
|
141
169
|
if self._is_task_name_already_used(f_id):
|
|
142
170
|
f_id = f"{f_id}_{t_start}"
|
|
143
171
|
|
|
144
172
|
task = m.Process(target=fn, name=f_id)
|
|
145
173
|
task.start()
|
|
146
|
-
print(
|
|
174
|
+
print(" -> Task %s is started" % f_id)
|
|
147
175
|
|
|
148
176
|
def _is_task_name_already_used(self, name):
|
|
149
177
|
import multiprocessing as m
|
|
178
|
+
|
|
150
179
|
for p in m.active_children():
|
|
151
180
|
if p.name == name:
|
|
152
181
|
return True
|
|
@@ -155,16 +184,17 @@ if runtime_env() in ['notebook', 'shell']:
|
|
|
155
184
|
@line_magic
|
|
156
185
|
def list_proc(self, line):
|
|
157
186
|
import multiprocessing as m
|
|
187
|
+
|
|
158
188
|
for p in m.active_children():
|
|
159
189
|
print(p.name)
|
|
160
190
|
|
|
161
191
|
@line_magic
|
|
162
192
|
def kill_proc(self, line):
|
|
163
193
|
import multiprocessing as m
|
|
194
|
+
|
|
164
195
|
for p in m.active_children():
|
|
165
196
|
if line and p.name.startswith(line):
|
|
166
197
|
p.terminate()
|
|
167
198
|
|
|
168
|
-
|
|
169
199
|
# - registering magic here
|
|
170
200
|
get_ipython().register_magics(QubxMagics)
|