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 +4 -0
- qubx/_nb_magic.py +40 -4
- qubx/core/helpers.py +1 -1
- qubx/core/lookups.py +2 -2
- qubx/core/metrics.py +29 -11
- 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/__init__.py +11 -0
- qubx/data/readers.py +2 -2
- qubx/pandaz/__init__.py +14 -3
- qubx/pandaz/utils.py +4 -5
- qubx/ta/indicators.cpython-311-x86_64-linux-gnu.so +0 -0
- qubx/utils/__init__.py +1 -1
- {qubx-0.2.75.dist-info → qubx-0.2.76.dist-info}/METADATA +1 -1
- {qubx-0.2.75.dist-info → qubx-0.2.76.dist-info}/RECORD +16 -15
- {qubx-0.2.75.dist-info → qubx-0.2.76.dist-info}/WHEEL +0 -0
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 %
|
|
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 %%
|
|
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
|
-
|
|
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
|
|
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.
|
|
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(
|
|
156
|
-
min_size_step=float(v["precision"]["
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
676
|
+
# - aggregate returns to higher timeframe
|
|
667
677
|
try:
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
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
|
|
|
Binary file
|
|
Binary file
|
qubx/data/__init__.py
ADDED
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,
|
|
3
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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])
|
|
Binary file
|
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
|
|
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,5 +1,5 @@
|
|
|
1
|
-
qubx/__init__.py,sha256=
|
|
2
|
-
qubx/_nb_magic.py,sha256=
|
|
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=
|
|
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=
|
|
16
|
-
qubx/core/metrics.py,sha256=
|
|
17
|
-
qubx/core/series.cpython-311-x86_64-linux-gnu.so,sha256=
|
|
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=
|
|
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=
|
|
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=
|
|
35
|
+
qubx/pandaz/__init__.py,sha256=xlZvm48eBur0U7N4F4xTKqh7-n5fN0wghj1Tb8lCCNk,332
|
|
35
36
|
qubx/pandaz/ta.py,sha256=NthiiueUoqWGRcjovcKKThcCcdImZn3JRdWDA2vL28k,85075
|
|
36
|
-
qubx/pandaz/utils.py,sha256=
|
|
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=
|
|
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=
|
|
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.
|
|
57
|
-
qubx-0.2.
|
|
58
|
-
qubx-0.2.
|
|
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
|