Qubx 0.2.63__tar.gz → 0.2.64__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.2.63 → qubx-0.2.64}/PKG-INFO +1 -1
- {qubx-0.2.63 → qubx-0.2.64}/pyproject.toml +1 -1
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/metrics.py +5 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/utils/charting/lookinglass.py +41 -53
- {qubx-0.2.63 → qubx-0.2.64}/README.md +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/build.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/__init__.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/_nb_magic.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/backtester/__init__.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/backtester/ome.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/backtester/optimization.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/backtester/queue.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/backtester/simulator.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/__init__.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/account.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/basics.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/context.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/exceptions.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/helpers.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/loggers.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/lookups.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/series.pxd +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/series.pyi +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/series.pyx +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/strategy.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/utils.pyi +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/core/utils.pyx +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/data/helpers.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/data/readers.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/gathering/simplest.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/impl/ccxt_connector.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/impl/ccxt_customizations.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/impl/ccxt_trading.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/impl/ccxt_utils.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/math/__init__.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/math/stats.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/pandaz/__init__.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/pandaz/ta.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/pandaz/utils.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/ta/__init__.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/ta/indicators.pxd +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/ta/indicators.pyi +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/ta/indicators.pyx +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/trackers/__init__.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/trackers/composite.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/trackers/rebalancers.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/trackers/riskctrl.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/trackers/sizers.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/utils/__init__.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/utils/_pyxreloader.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/utils/charting/mpl_helpers.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/utils/marketdata/binance.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/utils/misc.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/utils/ntp.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/utils/runner.py +0 -0
- {qubx-0.2.63 → qubx-0.2.64}/src/qubx/utils/time.py +0 -0
|
@@ -892,6 +892,7 @@ def chart_signals(
|
|
|
892
892
|
overlay=[],
|
|
893
893
|
info=True,
|
|
894
894
|
show_trades: bool = True,
|
|
895
|
+
show_signals: bool = False,
|
|
895
896
|
show_quantity: bool = False,
|
|
896
897
|
show_value: bool = False,
|
|
897
898
|
show_leverage: bool = True,
|
|
@@ -965,6 +966,10 @@ def chart_signals(
|
|
|
965
966
|
]
|
|
966
967
|
overlay = list(overlay) + [excs]
|
|
967
968
|
|
|
969
|
+
if show_signals:
|
|
970
|
+
sigs = result.signals_log[result.signals_log["instrument_id"] == symbol]
|
|
971
|
+
overlay = list(overlay) + [sigs]
|
|
972
|
+
|
|
968
973
|
chart = LookingGlass([bars, *overlay], indicators).look(start, end, title=symbol).hover(show_info=info, h=height)
|
|
969
974
|
if not show_table:
|
|
970
975
|
return chart.show()
|
|
@@ -544,6 +544,23 @@ class LookingGlassPlotly(AbstractLookingGlass):
|
|
|
544
544
|
def __plt_series(self, y, zoom, study_name, k, row, col, plot_style="line"):
|
|
545
545
|
_lbl = y.name if hasattr(y, "name") and y.name else ("%s_%d" % (study_name, k))
|
|
546
546
|
|
|
547
|
+
def _scatter(
|
|
548
|
+
xs: pd.Series, comments: pd.Series | None, name: str, marker: str, color: str, size: int = 11
|
|
549
|
+
) -> None:
|
|
550
|
+
_args = dict(
|
|
551
|
+
x=xs.index,
|
|
552
|
+
y=xs,
|
|
553
|
+
mode="markers",
|
|
554
|
+
name=name,
|
|
555
|
+
text=comments,
|
|
556
|
+
marker={
|
|
557
|
+
"symbol": marker,
|
|
558
|
+
"size": size,
|
|
559
|
+
"color": color,
|
|
560
|
+
},
|
|
561
|
+
)
|
|
562
|
+
self.fig.add_trace(go.Scatter(**_args), row=row, col=col)
|
|
563
|
+
|
|
547
564
|
if isinstance(y, pd.DataFrame):
|
|
548
565
|
yy = y[zoom] if zoom else y
|
|
549
566
|
|
|
@@ -760,65 +777,36 @@ class LookingGlassPlotly(AbstractLookingGlass):
|
|
|
760
777
|
elif self._frame_has_cols(y, ["Type", "Time", "Price", "PriceOccured"]):
|
|
761
778
|
_bot = yy[yy.Type == "-"]
|
|
762
779
|
_top = yy[yy.Type == "+"]
|
|
763
|
-
self.fig.add_trace(
|
|
764
|
-
go.Scatter(
|
|
765
|
-
x=_bot.index,
|
|
766
|
-
y=_bot.PriceOccured,
|
|
767
|
-
mode="markers",
|
|
768
|
-
name="B",
|
|
769
|
-
marker={"symbol": "triangle-right"},
|
|
770
|
-
),
|
|
771
|
-
row=row,
|
|
772
|
-
col=col,
|
|
773
|
-
)
|
|
774
780
|
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
x=_top.index,
|
|
778
|
-
y=_top.PriceOccured,
|
|
779
|
-
mode="markers",
|
|
780
|
-
name="T",
|
|
781
|
-
marker={"symbol": "triangle-right"},
|
|
782
|
-
),
|
|
783
|
-
row=row,
|
|
784
|
-
col=col,
|
|
785
|
-
)
|
|
781
|
+
_scatter(_bot.PriceOccured, None, "B", "triangle-right", "#3cfa00", 12)
|
|
782
|
+
_scatter(_top.PriceOccured, None, "T", "triangle-right", "#3cfa00", 12)
|
|
786
783
|
|
|
787
|
-
#
|
|
784
|
+
# executions from executor's log
|
|
788
785
|
elif self._frame_has_cols(y, ["exec_price", "quantity"]):
|
|
789
786
|
_b_ords = yy[yy.quantity > 0]
|
|
790
787
|
_s_ords = yy[yy.quantity < 0]
|
|
791
|
-
self.fig.add_trace(
|
|
792
|
-
go.Scatter(
|
|
793
|
-
x=_b_ords.index,
|
|
794
|
-
y=_b_ords.exec_price,
|
|
795
|
-
mode="markers",
|
|
796
|
-
name="BOT",
|
|
797
|
-
marker={
|
|
798
|
-
"symbol": "triangle-up",
|
|
799
|
-
"size": 13,
|
|
800
|
-
"color": "#3cfa00",
|
|
801
|
-
},
|
|
802
|
-
),
|
|
803
|
-
row=row,
|
|
804
|
-
col=col,
|
|
805
|
-
)
|
|
806
788
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
789
|
+
_scatter(_b_ords.exec_price, None, "BOT", "triangle-up", "#3cfa00", 12)
|
|
790
|
+
_scatter(_s_ords.exec_price, None, "SLD", "triangle-down", "#20ffff", 12)
|
|
791
|
+
|
|
792
|
+
# 27-aug-2024: show generated signals from Qubx backtester
|
|
793
|
+
elif self._frame_has_cols(y, ["signal", "reference_price", "price", "take", "stop", "group", "comment"]):
|
|
794
|
+
_sel_price = lambda x: x["reference_price"].where(x["price"].isna(), x["price"])
|
|
795
|
+
_b_sigs = yy[yy.signal > 0]
|
|
796
|
+
_z_sigs = yy[yy.signal == 0]
|
|
797
|
+
_s_sigs = yy[yy.signal < 0]
|
|
798
|
+
# - Longs
|
|
799
|
+
_scatter(_sel_price(_b_sigs), _b_sigs["comment"], "LONG", "triangle-up-open-dot", "#3cfa00")
|
|
800
|
+
_scatter(_b_sigs[~_b_sigs["take"].isna()]["take"], None, "Take", "line-ew-open", "#3cfa00")
|
|
801
|
+
_scatter(_b_sigs[~_b_sigs["stop"].isna()]["stop"], None, "Stop", "line-ew-open", "#fa3c00")
|
|
802
|
+
|
|
803
|
+
# - Shorts
|
|
804
|
+
_scatter(_sel_price(_s_sigs), _s_sigs["comment"], "SHORTS", "triangle-down-open-dot", "#20ffff")
|
|
805
|
+
_scatter(_s_sigs[~_s_sigs["take"].isna()]["take"], None, "Take", "line-ew-open", "#3cfa00")
|
|
806
|
+
_scatter(_s_sigs[~_s_sigs["stop"].isna()]["stop"], None, "Stop", "line-ew-open", "#fa3c00")
|
|
807
|
+
|
|
808
|
+
# - Exits
|
|
809
|
+
_scatter(_sel_price(_z_sigs), _z_sigs["comment"], "EXITS", "circle-open-dot", "#ffffff")
|
|
822
810
|
|
|
823
811
|
else:
|
|
824
812
|
for _col in yy.columns:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|