Qubx 0.2.75__cp311-cp311-manylinux_2_35_x86_64.whl → 0.2.76__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/__init__.py CHANGED
@@ -70,6 +70,10 @@ if runtime_env() in ["notebook", "shell"]:
70
70
  # process data manager
71
71
  __manager = None
72
72
 
73
+ @line_magic
74
+ def qubx(self, line: str):
75
+ self.qubx_setup("dark" + " " + line)
76
+
73
77
  @line_magic
74
78
  def qubxd(self, line: str):
75
79
  self.qubx_setup("dark" + " " + line)
qubx/_nb_magic.py CHANGED
@@ -1,5 +1,5 @@
1
1
  """"
2
- Here stuff we want to have in every Jupyter notebook after calling %qube magic
2
+ Here stuff we want to have in every Jupyter notebook after calling %qubx magic
3
3
  """
4
4
 
5
5
  import qubx
@@ -29,7 +29,7 @@ def np_fmt_reset():
29
29
  if runtime_env() in ["notebook", "shell"]:
30
30
 
31
31
  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
32
- # -- all imports below will appear in notebook after calling %%alphalab magic ---
32
+ # -- all imports below will appear in notebook after calling %%qubx magic ---
33
33
  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
34
34
 
35
35
  # - - - - Common stuff - - - -
@@ -40,16 +40,52 @@ if runtime_env() in ["notebook", "shell"]:
40
40
 
41
41
  # - - - - TA stuff and indicators - - - -
42
42
  import qubx.pandaz.ta as pta
43
+ import qubx.ta.indicators as ta
43
44
 
44
45
  # - - - - Portfolio analysis - - - -
46
+ from qubx.core.metrics import (
47
+ tearsheet,
48
+ chart_signals,
49
+ get_symbol_pnls,
50
+ get_equity,
51
+ portfolio_metrics,
52
+ pnl,
53
+ drop_symbols,
54
+ pick_symbols,
55
+ )
56
+
57
+ # - - - - Data reading - - - -
58
+ from qubx.data.readers import (
59
+ CsvStorageDataReader,
60
+ MultiQdbConnector,
61
+ QuestDBConnector,
62
+ AsOhlcvSeries,
63
+ AsPandasFrame,
64
+ AsQuotes,
65
+ AsTimestampedRecords,
66
+ RestoreTicksFromOHLC,
67
+ )
68
+
45
69
  # - - - - Simulator stuff - - - -
46
- # - - - - Learn stuff - - - -
70
+ from qubx.backtester.simulator import simulate
71
+ from qubx.backtester.optimization import variate
72
+
47
73
  # - - - - Charting stuff - - - -
48
74
  from matplotlib import pyplot as plt
49
75
  from qubx.utils.charting.mpl_helpers import fig, subplot, sbp, plot_trends, ohlc_plot
76
+ from qubx.utils.charting.lookinglass import LookingGlass
50
77
 
51
78
  # - - - - Utils - - - -
52
- from qubx.pandaz.utils import scols, srows, ohlc_resample, continuous_periods, generate_equal_date_ranges
79
+ from qubx.pandaz.utils import (
80
+ scols,
81
+ srows,
82
+ ohlc_resample,
83
+ continuous_periods,
84
+ generate_equal_date_ranges,
85
+ drop_duplicated_indexes,
86
+ retain_columns_and_join,
87
+ rolling_forward_test_split,
88
+ )
53
89
 
54
90
  # - setup short numpy output format
55
91
  np_fmt_short()
qubx/core/helpers.py CHANGED
@@ -357,4 +357,4 @@ def set_parameters_to_object(strategy: Any, **kwargs):
357
357
  _log_info += f"\n\tset <green>{k}</green> <- <red>{v_str}</red>"
358
358
 
359
359
  if _log_info:
360
- logger.info(f"<yellow>{strategy.__class__.__name__}</yellow> new parameters:" + _log_info)
360
+ logger.debug(f"<yellow>{strategy.__class__.__name__}</yellow> new parameters:" + _log_info)
qubx/core/lookups.py CHANGED
@@ -152,8 +152,8 @@ class InstrumentsLookup:
152
152
  v["base"],
153
153
  v["quote"],
154
154
  v["settle"],
155
- min_tick=float(info["tickSize"]),
156
- min_size_step=float(v["precision"]["price"]),
155
+ min_tick=float(v["precision"]["price"]),
156
+ min_size_step=float(v["precision"]["amount"]),
157
157
  min_size=v["precision"]["amount"],
158
158
  futures_info=FuturesInfo(
159
159
  contract_type=info["type"],
qubx/core/metrics.py CHANGED
@@ -33,6 +33,9 @@ MINUTELY = HOURLY * 60
33
33
  HOURLY_FX = DAILY * 24
34
34
  MINUTELY_FX = HOURLY_FX * 60
35
35
 
36
+ _D1 = pd.Timedelta("1D")
37
+ _W1 = pd.Timedelta("1W")
38
+
36
39
 
37
40
  def absmaxdd(data: List | Tuple | pd.Series | np.ndarray) -> Tuple[float, int, int, int, pd.Series]:
38
41
  """
@@ -113,7 +116,7 @@ def max_drawdown_pct(returns):
113
116
  return np.nanmin((cumrets - max_return) / max_return)
114
117
 
115
118
 
116
- def portfolio_returns(portfolio_log: pd.DataFrame, method="pct", init_cash=0) -> pd.Series:
119
+ def portfolio_returns(portfolio_log: pd.DataFrame, method="pct", init_cash: float = 0.0) -> pd.Series:
117
120
  """
118
121
  Calculates returns based on specified method.
119
122
 
@@ -323,7 +326,7 @@ def omega_ratio(returns, risk_free=0.0, required_return=0.0, periods=DAILY):
323
326
  return (numer / denom) if denom > 0.0 else np.nan
324
327
 
325
328
 
326
- def aggregate_returns(returns, convert_to):
329
+ def aggregate_returns(returns: pd.Series, convert_to: str) -> pd.DataFrame | pd.Series:
327
330
  """
328
331
  Aggregates returns by specified time period
329
332
  :param returns: pd.Series or np.ndarray periodic returns of the strategy, noncumulative
@@ -583,17 +586,21 @@ def monthly_returns(
583
586
  return pd.concat((100 * r_month, acc_balance), axis=1, keys=["Returns", "Balance"])
584
587
 
585
588
 
586
- def portfolio_symbols(df: pd.DataFrame) -> List[str]:
589
+ def portfolio_symbols(src: pd.DataFrame | TradingSessionResult) -> List[str]:
587
590
  """
588
591
  Get list of symbols from portfolio log
589
592
  """
593
+ df = src.portfolio_log if isinstance(src, TradingSessionResult) else src
590
594
  return list(df.columns[::5].str.split("_").str.get(0).values)
591
595
 
592
596
 
593
- def pnl(x: pd.DataFrame, c=1, cum=False, total=False, resample=None):
597
+ def pnl(
598
+ src: pd.DataFrame | TradingSessionResult, c=1, cum=False, total=False, resample=None
599
+ ) -> pd.Series | pd.DataFrame:
594
600
  """
595
601
  Extract PnL from portfolio log
596
602
  """
603
+ x = src.portfolio_log if isinstance(src, TradingSessionResult) else src
597
604
  pl = x.filter(regex=".*_PnL").rename(lambda x: x.split("_")[0], axis=1)
598
605
  comms = x.filter(regex=".*_Commissions").rename(lambda x: x.split("_")[0], axis=1)
599
606
  r = pl - c * comms
@@ -603,18 +610,21 @@ def pnl(x: pd.DataFrame, c=1, cum=False, total=False, resample=None):
603
610
  return r.sum(axis=1) if total else r
604
611
 
605
612
 
606
- def drop_symbols(df: pd.DataFrame, *args, quoted="USDT"):
613
+ def drop_symbols(src: pd.DataFrame | TradingSessionResult, *args, quoted="USDT") -> pd.DataFrame:
607
614
  """
608
615
  Drop symbols (is quoted currency) from portfolio log
609
616
  """
610
617
  s = "|".join([f"{a}{quoted}" if not a.endswith(quoted) else a for a in args])
618
+ df = src.portfolio_log if isinstance(src, TradingSessionResult) else src
611
619
  return df.filter(filter(lambda si: not re.match(f"^{s}_.*", si), df.columns))
612
620
 
613
621
 
614
- def pick_symbols(df: pd.DataFrame, *args, quoted="USDT"):
622
+ def pick_symbols(src: pd.DataFrame | TradingSessionResult, *args, quoted="USDT") -> pd.DataFrame:
615
623
  """
616
624
  Select symbols (is quoted currency) from portfolio log
617
625
  """
626
+ df = src.portfolio_log if isinstance(src, TradingSessionResult) else src
627
+
618
628
  # - pick up from execution report
619
629
  if "instrument" in df.columns and "quantity" in df.columns:
620
630
  rx = "|".join([f"{a}.*" for a in args])
@@ -663,11 +673,19 @@ def portfolio_metrics(
663
673
  returns = returns[:end]
664
674
  returns_on_init_bp = returns_on_init_bp[:end]
665
675
 
666
- # aggregate them to daily (if we have intraday portfolio)
676
+ # - aggregate returns to higher timeframe
667
677
  try:
668
- if infer_series_frequency(returns) < pd.Timedelta("1D").to_timedelta64():
669
- returns_daily = aggregate_returns(returns, "daily")
670
- returns_on_init_bp = aggregate_returns(returns_on_init_bp, "daily")
678
+ _conversion = "daily"
679
+ match (_s_freq := infer_series_frequency(returns)):
680
+ case _ if _s_freq <= _D1.to_timedelta64():
681
+ _conversion = "daily"
682
+ case _ if _s_freq > _D1.to_timedelta64() and _s_freq <= _W1.to_timedelta64():
683
+ _conversion = "weekly"
684
+ case _:
685
+ _conversion = "monthly"
686
+
687
+ returns_daily = aggregate_returns(returns, _conversion)
688
+ returns_on_init_bp = aggregate_returns(returns_on_init_bp, _conversion)
671
689
  except:
672
690
  returns_daily = returns
673
691
 
@@ -792,7 +810,7 @@ def get_equity(
792
810
  sessions: TradingSessionResult | list[TradingSessionResult],
793
811
  account_transactions: bool = True,
794
812
  timeframe: str | None = None,
795
- ) -> pd.DataFrame:
813
+ ) -> pd.DataFrame | pd.Series:
796
814
  if timeframe is None:
797
815
  timeframe = _estimate_timeframe(sessions)
798
816
 
qubx/data/__init__.py ADDED
@@ -0,0 +1,11 @@
1
+ from .readers import (
2
+ DataReader,
3
+ CsvStorageDataReader,
4
+ MultiQdbConnector,
5
+ QuestDBConnector,
6
+ AsOhlcvSeries,
7
+ AsPandasFrame,
8
+ AsQuotes,
9
+ AsTimestampedRecords,
10
+ RestoreTicksFromOHLC,
11
+ )
qubx/data/readers.py CHANGED
@@ -903,7 +903,7 @@ class QuestDBConnector(DataReader):
903
903
  where = f"where symbol in ({', '.join(quoted_symbols)}) and timestamp >= '{start}' and timestamp < '{stop}'"
904
904
  table_name = QuestDBSqlCandlesBuilder().get_table_name(f"{exchange}:{symbols[0]}")
905
905
 
906
- _rsmpl = f"sample by {timeframe}"
906
+ _rsmpl = f"sample by {QuestDBSqlCandlesBuilder._convert_time_delta_to_qdb_resample_format(timeframe)}"
907
907
 
908
908
  query = f"""
909
909
  select timestamp,
@@ -934,7 +934,7 @@ class QuestDBConnector(DataReader):
934
934
  select timestamp, symbol, sum(quote_volume) as qvolume
935
935
  from "{table_name}"
936
936
  where timestamp >= '{start}' and timestamp < '{stop}'
937
- SAMPLE BY {timeframe}
937
+ SAMPLE BY {QuestDBSqlCandlesBuilder._convert_time_delta_to_qdb_resample_format(timeframe)}
938
938
  )
939
939
  select symbol, avg(qvolume) as quote_volume from sampled
940
940
  group by symbol
qubx/pandaz/__init__.py CHANGED
@@ -1,4 +1,15 @@
1
1
  from .utils import (
2
- srows, scols, continuous_periods, ohlc_resample, retain_columns_and_join, dict_to_frame,
3
- generate_equal_date_ranges, rolling_forward_test_split
4
- )
2
+ srows,
3
+ scols,
4
+ continuous_periods,
5
+ ohlc_resample,
6
+ retain_columns_and_join,
7
+ select_column_and_join,
8
+ dict_to_frame,
9
+ drop_duplicated_indexes,
10
+ process_duplicated_indexes,
11
+ generate_equal_date_ranges,
12
+ rolling_forward_test_split,
13
+ shift_series,
14
+ check_frame_columns,
15
+ )
qubx/pandaz/utils.py CHANGED
@@ -90,11 +90,11 @@ def rolling_forward_test_split(
90
90
  yield (np.array(range(i - training_period, i)), np.array(range(i, i + test_period)))
91
91
 
92
92
 
93
- def generate_equal_date_ranges(start: str | pd.Timestamp, end: str | pd.Timestamp, freq: int, units: str) -> Iterable:
93
+ def generate_equal_date_ranges(start: str, end: str, freq, units):
94
94
  """
95
95
  Generator for date ranges:
96
96
 
97
- for s,e in generate_equal_date_ranges('2019-01-01', '2022-05-17', 1, 'Y'):
97
+ for s,e in generate_ranges('2019-01-01', '2022-05-17', 1, 'Y'):
98
98
  print(s, e)
99
99
  ------------------
100
100
  2019-01-01 2019-12-31
@@ -103,9 +103,8 @@ def generate_equal_date_ranges(start: str | pd.Timestamp, end: str | pd.Timestam
103
103
  2022-01-01 2022-05-17
104
104
  """
105
105
  _as_f = lambda x: pd.Timestamp(x).strftime("%Y-%m-%d")
106
-
107
- # - for case when end - start < freq it won't got into the loop
108
- b = [start, start] if _as_f(start) > _as_f(end) else [start, end]
106
+ if pd.Timestamp(end) - pd.Timestamp(start) < freq * pd.Timedelta(f"1{units}"):
107
+ b = [start, end]
109
108
 
110
109
  for a, b in rolling_forward_test_split(pd.Series(0, pd.date_range(start, end)), freq, freq, units=units):
111
110
  yield _as_f(a[0]), _as_f(a[-1])
qubx/utils/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  from .time import convert_seconds_to_str, convert_tf_str_td64, floor_t64, time_to_str, infer_series_frequency
2
2
  from .misc import runtime_env, version, Struct, Stopwatch
3
- from .charting.mpl_helpers import set_mpl_theme, fig, sbp, vline, hline, ellips, set_mpl_theme, ohlc_plot
3
+ from .charting.mpl_helpers import fig, sbp, vline, hline, ellips, set_mpl_theme, ohlc_plot, plot_trends
4
4
  from .charting.lookinglass import LookingGlass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Qubx
3
- Version: 0.2.75
3
+ Version: 0.2.76
4
4
  Summary: Qubx - quantitative trading framework
5
5
  Home-page: https://github.com/dmarienko/Qubx
6
6
  Author: Dmitry Marienko
@@ -1,5 +1,5 @@
1
- qubx/__init__.py,sha256=dIHcfXv3uDX-kJ6qRGrH5OUW7evnGFf6A2VsLQlr2jc,6047
2
- qubx/_nb_magic.py,sha256=vfV892I5rkA_Zbno5Dsl9osPTGiXTCV3afZRDrTlcOQ,1915
1
+ qubx/__init__.py,sha256=4WwQDq3Se_Vi3exTyYFnEAz1QuB-0aQWIexMbg0STgY,6152
2
+ qubx/_nb_magic.py,sha256=_acaAfFSAYZNm2I3iuSyrl8e7_gp26VnP2u6hx25HXg,2729
3
3
  qubx/backtester/__init__.py,sha256=g9K4pp4ieY4rRKE0eA_02LMo-c4vnk-QqtVn_ff9F5U,66
4
4
  qubx/backtester/ome.py,sha256=FmtRMDCeEo8ZZP-yLswLilX6zx6SjJeieMiaLS7zrn0,11145
5
5
  qubx/backtester/optimization.py,sha256=ATHoiEGwbDIk0-lbFIxvVDmH_f-vtS10YV41pfOTCBA,7297
@@ -10,20 +10,21 @@ qubx/core/account.py,sha256=uIU-EUMuH5owWhHTmU1pZ0WrkQkiv9YiFqSZW9dFDK8,9066
10
10
  qubx/core/basics.py,sha256=WA6LrmCG1si6pfyvezLRkfts575912AhGJMVbwBWSa0,21802
11
11
  qubx/core/context.py,sha256=WnHsItJ1OQ2jD0cHbYOMQ9ck4txLTwtf8Dp-zCLsUww,37759
12
12
  qubx/core/exceptions.py,sha256=W1gG_0fE3o2EMGUfOeOl3vVJDp8Z1iHLv4iZ0ThNkTs,306
13
- qubx/core/helpers.py,sha256=R-xi4lgmYvWpUARIYcbcrNrRlEap5wc-GQ5sE4riUxQ,12663
13
+ qubx/core/helpers.py,sha256=V_3505UiQhQcNwKVFN3S7hQAgmfU0Lly3JX1kk3GW8E,12664
14
14
  qubx/core/loggers.py,sha256=zpehm2-RdKG1ISe6t3DiM3RrL_zzGni3YFcxfgDkV24,16575
15
- qubx/core/lookups.py,sha256=qGOSb2SIxmgVPGJFLJnPDI1P9hCzFMVipRDcVLUm8qk,14599
16
- qubx/core/metrics.py,sha256=pL1obxnk8I7bDF41bQcOZ7MDsq4Wmj6g5cRiV7cFZKQ,38657
17
- qubx/core/series.cpython-311-x86_64-linux-gnu.so,sha256=HwGNM0szT5qwZX6C2RS5W4kRqMtJhVpckokYeHnWMmM,779016
15
+ qubx/core/lookups.py,sha256=2TH9kySRnUMTm_1uMVqk-FisyofWT22u7KGLicWzlhU,14607
16
+ qubx/core/metrics.py,sha256=Y33YgwyGbbZ7KGAcmcQ1mNi8Rg_D76b3704Q8TrQL5s,39521
17
+ qubx/core/series.cpython-311-x86_64-linux-gnu.so,sha256=Bion-CubUyl6u0Cbq28o2weEYilyB4PIUDIh8LguiAQ,779016
18
18
  qubx/core/series.pxd,sha256=kF7QeLFgCM-C2hDxVvJM97ZOmyw1v7JEI9WfPKtQ6xs,3002
19
19
  qubx/core/series.pyi,sha256=bRBWOaDUBe4Hm2SvraoVeT-n5NFLA92fi8ezrArx9nY,2831
20
20
  qubx/core/series.pyx,sha256=UhZsnT7R3-UED05Fnp3mGxr4RSdMpWAHB4lkcz46MFo,32598
21
21
  qubx/core/strategy.py,sha256=tTXhDbFTH63yj53mLgVEDBZxYOxC51prcsyXWkdTgLs,10991
22
- qubx/core/utils.cpython-311-x86_64-linux-gnu.so,sha256=BKuT2LUOVCVEen9gT8XNhwKxmFjr1SEJXZyDqb16nZg,82504
22
+ qubx/core/utils.cpython-311-x86_64-linux-gnu.so,sha256=zbA9MBzGwbiGVsyI1WMk68YBIg_JviygAt6s6NGeH1E,82504
23
23
  qubx/core/utils.pyi,sha256=DAjyRVPJSxK4Em-9wui2F0yYHfP5tI5DjKavXNOnHa8,276
24
24
  qubx/core/utils.pyx,sha256=-8ek58CrbqWZq0-OY7WSREsCXBoBeWrD_wEYbIBS9rI,1696
25
+ qubx/data/__init__.py,sha256=Ln1GB07OWaD5BcwlapaoHBxUvw2kUGXXS24vgfeRdhk,216
25
26
  qubx/data/helpers.py,sha256=A0NGzhpXYWD92-GeB8TghwMnR0NW8bjcNJOCXybQw3g,782
26
- qubx/data/readers.py,sha256=2VgaHKpHg67qej0Ty6D9q-zLRKEMamQY5pEIIJJcAZw,40062
27
+ qubx/data/readers.py,sha256=t6bG1NSzYZzJc8IYIGnrP-W3RS1ioWkeEX1byaQSQsc,40200
27
28
  qubx/gathering/simplest.py,sha256=Ez3YFZMKH3o0jV0Qbg1SuZiuFNs_5No_C7wZ6vOeqfo,3814
28
29
  qubx/impl/ccxt_connector.py,sha256=ja_0WJDyZfkzqhNvoV-c5CCg15YnbRIThxw0TTNdwcc,13066
29
30
  qubx/impl/ccxt_customizations.py,sha256=WUhDT9x2SYuFrOyBIbk2D9Q_U_5QZhtLomLq88Egf_c,6230
@@ -31,11 +32,11 @@ qubx/impl/ccxt_trading.py,sha256=OW0s_kW7GZlbDz_pGBlzLCUT2iDK4dhaBtmIAvj7QDw,988
31
32
  qubx/impl/ccxt_utils.py,sha256=IS5st30L9wkK0akUy2gyPXju3ewk0Obnsdh0R-I_s98,4134
32
33
  qubx/math/__init__.py,sha256=QRat0pqEqmbJF7CIHBuqnB1xUek4CsDDhv7SpgssnFw,57
33
34
  qubx/math/stats.py,sha256=xgzBU3PLxQ42jBMpI57UVuQ2uGGRYxGKuEd4eiGvjnE,1695
34
- qubx/pandaz/__init__.py,sha256=Iw5uzicYGSC3FEKZ-W1O5-7cXq_P0kH11-EcXV0zZhs,175
35
+ qubx/pandaz/__init__.py,sha256=xlZvm48eBur0U7N4F4xTKqh7-n5fN0wghj1Tb8lCCNk,332
35
36
  qubx/pandaz/ta.py,sha256=NthiiueUoqWGRcjovcKKThcCcdImZn3JRdWDA2vL28k,85075
36
- qubx/pandaz/utils.py,sha256=XB28Zwv3cXWbKFXbcV5QGj_d6w-i8Yo4LYkX8aPuCHo,19613
37
+ qubx/pandaz/utils.py,sha256=O5wXkYKiTCdGR7hZR4tQtFTbTF-q_kEk-n1DyR-P3X0,19519
37
38
  qubx/ta/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- qubx/ta/indicators.cpython-311-x86_64-linux-gnu.so,sha256=GNi4LN7GZgIfQOSKMEW19CmctnUW84lulZkdLbwq7TM,576168
39
+ qubx/ta/indicators.cpython-311-x86_64-linux-gnu.so,sha256=My1BpH0ZeZqsobY-j2HT6sWxVsFyvIHIfv5QVrXyahc,576168
39
40
  qubx/ta/indicators.pxd,sha256=YzPDhbbNPmy3m4NafwIRF5sNFsmkq-MM1gbeAygtBwM,4007
40
41
  qubx/ta/indicators.pyi,sha256=mM_7ISmGQDgjhwxCoZXDw7Rm9fynQSYjevV7fRoLdNc,1683
41
42
  qubx/ta/indicators.pyx,sha256=GuxB63YApFnA9IWNJDbBt90J1sOoxTf3jDWYQ3uD9So,24306
@@ -44,7 +45,7 @@ qubx/trackers/composite.py,sha256=rYQCaxu4IKLf5sS3DCyUUJaSUQwbCy6UMoVjsS-481A,62
44
45
  qubx/trackers/rebalancers.py,sha256=dp-jemxczT8ndkjjzljsIgGnnA6lZQhsf5c4YdmHKCw,6048
45
46
  qubx/trackers/riskctrl.py,sha256=URRZmYgb1-jcW4RTb2QXUozTnBiGhFEWHtTEjaqow5Q,23491
46
47
  qubx/trackers/sizers.py,sha256=vh49p2I_5LxYfznOQxlM6f0K1wadgtz7y9NSxg3WdNQ,5953
47
- qubx/utils/__init__.py,sha256=AL2YibJ3tqBKsZZLUjM9N2J5yy-Kq__k_44oTODQ5sM,321
48
+ qubx/utils/__init__.py,sha256=W9_1KPjh4E9p6E6HzG9aRcTr7hn0PVz42Agi_WfWfJc,319
48
49
  qubx/utils/_pyxreloader.py,sha256=FyqGzfSpZGYziB8JYS5AP3cLRAvJSIPAKgwQn0E4YQ0,12017
49
50
  qubx/utils/charting/lookinglass.py,sha256=VNSFVfEyAH6NbsvJYcbMvPyGRIRKtLTK1WQ-adH4qkA,39580
50
51
  qubx/utils/charting/mpl_helpers.py,sha256=z6vL0IllTZeD-Oe-alVW-kYOP_deHyyoFcukvOVwSz8,35354
@@ -53,6 +54,6 @@ qubx/utils/misc.py,sha256=Av0mhrPCy5NZRrRmjOAhTKusa8wVdL7vCQtEy9bVnz4,10450
53
54
  qubx/utils/ntp.py,sha256=LZo4FPVY3rqLUV9VWkLcZaPOpUDFC8Qleynmfggg9No,1758
54
55
  qubx/utils/runner.py,sha256=Czo01KUCc9Oj9TIcs03d6Qh7fOpQV5w8oH6UDZ6Yqn0,9539
55
56
  qubx/utils/time.py,sha256=fIVWYRmqRT1zkLIWy9jo_Fpfpc03S0sYyOcrHZcfF74,5198
56
- qubx-0.2.75.dist-info/METADATA,sha256=yq_PoJL-wZQFfQ_Ccmci1z7MNvatP0NL79SIomC421U,2573
57
- qubx-0.2.75.dist-info/WHEEL,sha256=MLOa6LysROdjgj4FVxsHitAnIh8Be2D_c9ZSBHKrz2M,110
58
- qubx-0.2.75.dist-info/RECORD,,
57
+ qubx-0.2.76.dist-info/METADATA,sha256=1cu9k670WYRhCYjWj7EOfdyI_kAe6PYmufXJJ7TOa0A,2573
58
+ qubx-0.2.76.dist-info/WHEEL,sha256=MLOa6LysROdjgj4FVxsHitAnIh8Be2D_c9ZSBHKrz2M,110
59
+ qubx-0.2.76.dist-info/RECORD,,
File without changes