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.

Files changed (38) hide show
  1. {qubx-0.1.82 → qubx-0.1.84}/PKG-INFO +1 -1
  2. {qubx-0.1.82 → qubx-0.1.84}/pyproject.toml +1 -1
  3. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/__init__.py +62 -32
  4. qubx-0.1.84/src/qubx/data/readers.py +1007 -0
  5. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/misc.py +70 -60
  6. qubx-0.1.82/src/qubx/data/readers.py +0 -695
  7. {qubx-0.1.82 → qubx-0.1.84}/README.md +0 -0
  8. {qubx-0.1.82 → qubx-0.1.84}/build.py +0 -0
  9. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/_nb_magic.py +0 -0
  10. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/__init__.py +0 -0
  11. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/account.py +0 -0
  12. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/basics.py +0 -0
  13. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/helpers.py +0 -0
  14. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/loggers.py +0 -0
  15. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/lookups.py +0 -0
  16. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/series.pxd +0 -0
  17. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/series.pyx +0 -0
  18. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/strategy.py +0 -0
  19. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/core/utils.pyx +0 -0
  20. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/impl/ccxt_connector.py +0 -0
  21. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/impl/ccxt_customizations.py +0 -0
  22. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/impl/ccxt_trading.py +0 -0
  23. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/impl/ccxt_utils.py +0 -0
  24. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/math/__init__.py +0 -0
  25. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/math/stats.py +0 -0
  26. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/pandaz/__init__.py +0 -0
  27. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/pandaz/ta.py +0 -0
  28. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/pandaz/utils.py +0 -0
  29. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/ta/__init__.py +0 -0
  30. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/ta/indicators.pyx +0 -0
  31. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/trackers/__init__.py +0 -0
  32. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/trackers/rebalancers.py +0 -0
  33. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/__init__.py +0 -0
  34. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/_pyxreloader.py +0 -0
  35. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/charting/mpl_helpers.py +0 -0
  36. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/marketdata/binance.py +0 -0
  37. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/runner.py +0 -0
  38. {qubx-0.1.82 → qubx-0.1.84}/src/qubx/utils/time.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Qubx
3
- Version: 0.1.82
3
+ Version: 0.1.84
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.1.82"
3
+ version = "0.1.84"
4
4
  description = "Qubx - quantitative trading framework"
5
5
  authors = ["Dmitry Marienko <dmitry@gmail.com>"]
6
6
  readme = "README.md"
@@ -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 = "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - %s" % fmt
13
+ fmt = (
14
+ "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - %s" % fmt
15
+ )
14
16
 
15
- prefix = "<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green> [ <level>%s</level> ] " % record["level"].icon
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(record["exception"], style="darkbg")
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
- config = {
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 ['notebook', 'shell']:
45
- from IPython.core.magic import (Magics, magics_class, line_magic, line_cell_magic)
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('dark' + ' ' + line)
81
+ self.qubx_setup("dark" + " " + line)
56
82
 
57
83
  @line_magic
58
84
  def qubxl(self, line: str):
59
- self.qubx_setup('light' + ' ' + line)
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
- args = [x.strip() for x in line.split(' ')]
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 'dev' in args:
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, 'r', encoding="utf8") as myfile:
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 'dark' in line.lower():
82
- set_mpl_theme('dark')
108
+ if "dark" in line.lower():
109
+ set_mpl_theme("dark")
83
110
 
84
- elif 'light' in line.lower():
85
- set_mpl_theme('light')
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 ' as ' in line:
115
- line, name = line.split('as')
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('[\ ,;]', line.strip()) if x]:
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 = '\n'.join([' %s' % x for x in cell.split('\n')])
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'proc_{t_start}' if name is None else name
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(' -> Task %s is started' % f_id)
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)